diff options
231 files changed, 4633 insertions, 1840 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 3897b2a..1f762f4 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20150506 +OLD_FILES+=usr/share/man/man9/NDHASGIANT.9.gz # 20150504 OLD_LIBS+=usr/lib32/private/libatf-c++.so.2 OLD_LIBS+=usr/lib32/private/libbsdstat.so.1 @@ -430,10 +432,6 @@ OLD_FILES+=usr/lib/debug/usr/lib32/i18n OLD_FILES+=usr/lib/debug/usr/lib32/private # 20141015: OpenSSL 1.0.1j import OLD_FILES+=usr/share/openssl/man/man3/CMS_sign_add1_signer.3.gz -.if ${MK_GCC} == "no" -# 20141009: gperf disabled by default -OLD_FILES+=usr/bin/gperf -.endif # 20140922: sleepq_calc_signal_retval.9 and sleepq_catch_signals.9 removed OLD_FILES+=usr/share/man/man9/sleepq_calc_signal_retval.9.gz OLD_FILES+=usr/share/man/man9/sleepq_catch_signals.9.gz diff --git a/bin/date/date.1 b/bin/date/date.1 index 5e9e664..dd791ec 100644 --- a/bin/date/date.1 +++ b/bin/date/date.1 @@ -32,7 +32,7 @@ .\" @(#)date.1 8.3 (Berkeley) 4/28/95 .\" $FreeBSD$ .\" -.Dd April 26, 2014 +.Dd May 7, 2015 .Dt DATE 1 .Os .Sh NAME @@ -41,7 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl jRu -.Op Fl r Ar seconds +.Op Fl r Ar seconds | Ar filename .Oo .Fl v .Sm off @@ -150,6 +150,9 @@ is the number of seconds since the Epoch see .Xr time 3 ) , and can be specified in decimal, octal, or hex. +.It Fl r Ar filename +Print the date and time of the last modification of +.Ar filename . .It Fl t Ar minutes_west Set the system's value for minutes west of .Tn GMT . diff --git a/bin/date/date.c b/bin/date/date.c index 2c09848..9ae6502 100644 --- a/bin/date/date.c +++ b/bin/date/date.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/time.h> +#include <sys/stat.h> #include <ctype.h> #include <err.h> @@ -85,6 +86,7 @@ main(int argc, char *argv[]) struct vary *v; const struct vary *badv; struct tm lt; + struct stat sb; v = NULL; fmt = NULL; @@ -116,8 +118,12 @@ main(int argc, char *argv[]) case 'r': /* user specified seconds */ rflag = 1; tval = strtoq(optarg, &tmp, 0); - if (*tmp != 0) - usage(); + if (*tmp != 0) { + if (stat(optarg, &sb) == 0) + tval = sb.st_mtim.tv_sec; + else + usage(); + } break; case 't': /* minutes west of UTC */ /* error check; don't allow "PST" */ diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c index bb853c9..041fff8 100644 --- a/contrib/netcat/netcat.c +++ b/contrib/netcat/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.122 2014/07/20 01:38:40 guenther Exp $ */ +/* $OpenBSD: netcat.c,v 1.127 2015/02/14 22:40:22 jca Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * @@ -42,7 +42,6 @@ #include <sys/un.h> #include <netinet/in.h> -#include <netinet/in_systm.h> #ifdef IPSEC #include <netipsec/ipsec.h> #endif @@ -73,6 +72,12 @@ #define PORT_MAX_LEN 6 #define UNIX_DG_TMP_SOCKET_SIZE 19 +#define POLL_STDIN 0 +#define POLL_NETOUT 1 +#define POLL_NETIN 2 +#define POLL_STDOUT 3 +#define BUFSIZE 16384 + /* Command Line Options */ int dflag; /* detached, no stdin */ int Fflag; /* fdpass sock to stdout */ @@ -117,10 +122,12 @@ int udptest(int); int unix_bind(char *); int unix_connect(char *); int unix_listen(char *); -void set_common_sockopts(int); +void set_common_sockopts(int, int); int map_tos(char *, int *); void report_connect(const struct sockaddr *, socklen_t); void usage(int); +ssize_t drainbuf(int, unsigned char *, size_t *); +ssize_t fillbuf(int, unsigned char *, size_t *); #ifdef IPSEC void add_ipsec_policy(int, char *); @@ -436,7 +443,7 @@ main(int argc, char *argv[]) &len); if (connfd == -1) { /* For now, all errnos are fatal */ - err(1, "accept"); + err(1, "accept"); } if (vflag) report_connect((struct sockaddr *)&cliaddr, len); @@ -663,7 +670,7 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) freeaddrinfo(ares); } - set_common_sockopts(s); + set_common_sockopts(s, res0->ai_family); if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) break; @@ -767,6 +774,8 @@ local_listen(char *host, char *port, struct addrinfo hints) err(1, "disable TCP options"); } + set_common_sockopts(s, res0->ai_family); + if (bind(s, (struct sockaddr *)res0->ai_addr, res0->ai_addrlen) == 0) break; @@ -790,68 +799,224 @@ local_listen(char *host, char *port, struct addrinfo hints) * Loop that polls on the network file descriptor and stdin. */ void -readwrite(int nfd) +readwrite(int net_fd) { - struct pollfd pfd[2]; - unsigned char buf[16 * 1024]; - int n, wfd = fileno(stdin); - int lfd = fileno(stdout); - int plen; - - plen = sizeof(buf); - - /* Setup Network FD */ - pfd[0].fd = nfd; - pfd[0].events = POLLIN; - - /* Set up STDIN FD. */ - pfd[1].fd = wfd; - pfd[1].events = POLLIN; + struct pollfd pfd[4]; + int stdin_fd = STDIN_FILENO; + int stdout_fd = STDOUT_FILENO; + unsigned char netinbuf[BUFSIZE]; + size_t netinbufpos = 0; + unsigned char stdinbuf[BUFSIZE]; + size_t stdinbufpos = 0; + int n, num_fds; + ssize_t ret; + + /* don't read from stdin if requested */ + if (dflag) + stdin_fd = -1; + + /* stdin */ + pfd[POLL_STDIN].fd = stdin_fd; + pfd[POLL_STDIN].events = POLLIN; + + /* network out */ + pfd[POLL_NETOUT].fd = net_fd; + pfd[POLL_NETOUT].events = 0; + + /* network in */ + pfd[POLL_NETIN].fd = net_fd; + pfd[POLL_NETIN].events = POLLIN; + + /* stdout */ + pfd[POLL_STDOUT].fd = stdout_fd; + pfd[POLL_STDOUT].events = 0; + + while (1) { + /* both inputs are gone, buffers are empty, we are done */ + if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + /* both outputs are gone, we can't continue */ + if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { + close(net_fd); + return; + } + /* listen and net in gone, queues empty, done */ + if (lflag && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } - while (pfd[0].fd != -1) { + /* help says -i is for "wait between lines sent". We read and + * write arbitrary amounts of data, and we don't want to start + * scanning for newlines, so this is as good as it gets */ if (iflag) sleep(iflag); - if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { - int saved_errno = errno; - close(nfd); - errc(1, saved_errno, "Polling Error"); + /* poll */ + num_fds = poll(pfd, 4, timeout); + + /* treat poll errors */ + if (num_fds == -1) { + close(net_fd); + err(1, "polling error"); } - if (n == 0) + /* timeout happened */ + if (num_fds == 0) return; - if (pfd[0].revents & POLLIN) { - if ((n = read(nfd, buf, plen)) < 0) - return; - else if (n == 0) { - shutdown(nfd, SHUT_RD); - pfd[0].fd = -1; - pfd[0].events = 0; - } else { - if (tflag) - atelnet(nfd, buf, n); - if (atomicio(vwrite, lfd, buf, n) != n) - return; + /* treat socket error conditions */ + for (n = 0; n < 4; n++) { + if (pfd[n].revents & (POLLERR|POLLNVAL)) { + pfd[n].fd = -1; } } + /* reading is possible after HUP */ + if (pfd[POLL_STDIN].events & POLLIN && + pfd[POLL_STDIN].revents & POLLHUP && + ! (pfd[POLL_STDIN].revents & POLLIN)) + pfd[POLL_STDIN].fd = -1; + + if (pfd[POLL_NETIN].events & POLLIN && + pfd[POLL_NETIN].revents & POLLHUP && + ! (pfd[POLL_NETIN].revents & POLLIN)) + pfd[POLL_NETIN].fd = -1; + + if (pfd[POLL_NETOUT].revents & POLLHUP) { + if (Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* if HUP, stop watching stdout */ + if (pfd[POLL_STDOUT].revents & POLLHUP) + pfd[POLL_STDOUT].fd = -1; + /* if no net out, stop watching stdin */ + if (pfd[POLL_NETOUT].fd == -1) + pfd[POLL_STDIN].fd = -1; + /* if no stdout, stop watching net in */ + if (pfd[POLL_STDOUT].fd == -1) { + if (pfd[POLL_NETIN].fd != -1) + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } - if (!dflag && pfd[1].revents & POLLIN) { - if ((n = read(wfd, buf, plen)) < 0) - return; - else if (n == 0) { - if (Nflag) - shutdown(nfd, SHUT_WR); - pfd[1].fd = -1; - pfd[1].events = 0; - } else { - if (atomicio(vwrite, nfd, buf, n) != n) - return; + /* try to read from stdin */ + if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, + &stdinbufpos); + /* error or eof on stdin - remove from pfd */ + if (ret == 0 || ret == -1) + pfd[POLL_STDIN].fd = -1; + /* read something - poll net out */ + if (stdinbufpos > 0) + pfd[POLL_NETOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (stdinbufpos == BUFSIZE) + pfd[POLL_STDIN].events = 0; + } + /* try to write to network */ + if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { + ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, + &stdinbufpos); + if (ret == -1) + pfd[POLL_NETOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (stdinbufpos == 0) + pfd[POLL_NETOUT].events = 0; + /* buffer no longer full - poll stdin again */ + if (stdinbufpos < BUFSIZE) + pfd[POLL_STDIN].events = POLLIN; + } + /* try to read from network */ + if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_NETIN].fd = -1; + /* eof on net in - remove from pfd */ + if (ret == 0) { + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; } + /* read something - poll stdout */ + if (netinbufpos > 0) + pfd[POLL_STDOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (netinbufpos == BUFSIZE) + pfd[POLL_NETIN].events = 0; + /* handle telnet */ + if (tflag) + atelnet(pfd[POLL_NETIN].fd, netinbuf, + netinbufpos); + } + /* try to write to stdout */ + if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { + ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_STDOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (netinbufpos == 0) + pfd[POLL_STDOUT].events = 0; + /* buffer no longer full - poll net in again */ + if (netinbufpos < BUFSIZE) + pfd[POLL_NETIN].events = POLLIN; + } + + /* stdin gone and queue empty? */ + if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { + if (pfd[POLL_NETOUT].fd != -1 && Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* net in gone and queue empty? */ + if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { + pfd[POLL_STDOUT].fd = -1; } } } +ssize_t +drainbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + ssize_t n; + ssize_t adjust; + + n = write(fd, buf, *bufpos); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + /* adjust buffer */ + adjust = *bufpos - n; + if (adjust > 0) + memmove(buf, buf + n, adjust); + *bufpos -= n; + return n; +} + + +ssize_t +fillbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + size_t num = BUFSIZE - *bufpos; + ssize_t n; + + n = read(fd, buf + *bufpos, num); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + *bufpos += n; + return n; +} + /* * fdpass() * Pass the connected file descriptor to stdout and exit. @@ -1025,7 +1190,7 @@ udptest(int s) } void -set_common_sockopts(int s) +set_common_sockopts(int s, int af) { int x = 1; @@ -1040,8 +1205,17 @@ set_common_sockopts(int s) err(1, NULL); } if (Tflag != -1) { - if (setsockopt(s, IPPROTO_IP, IP_TOS, - &Tflag, sizeof(Tflag)) == -1) + int proto, option; + + if (af == AF_INET6) { + proto = IPPROTO_IPV6; + option = IPV6_TCLASS; + } else { + proto = IPPROTO_IP; + option = IP_TOS; + } + + if (setsockopt(s, proto, option, &Tflag, sizeof(Tflag)) == -1) err(1, "set IP ToS"); } if (Iflag) { diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c index 91ab39a..2a1cf22 100644 --- a/contrib/ntp/ntpd/ntp_control.c +++ b/contrib/ntp/ntpd/ntp_control.c @@ -4,7 +4,7 @@ */ /* - * $FreeBSD: projects/release-arm-redux/contrib/ntp/ntpd/ntp_control.c 276071 2014-12-22 18:54:55Z delphij $ + * $FreeBSD: head/contrib/ntp/ntpd/ntp_control.c 276071 2014-12-22 18:54:55Z delphij $ */ #ifdef HAVE_CONFIG_H diff --git a/etc/rc.d/hostid b/etc/rc.d/hostid index 281b241..a26cbc0 100755 --- a/etc/rc.d/hostid +++ b/etc/rc.d/hostid @@ -58,7 +58,7 @@ hostid_set() valid_hostid() { - uuid=$1 + uuid=$(echo $1 | tr '[:upper:]' '[:lower:]') x="[0-9a-f]" y=$x$x$x$x diff --git a/include/Makefile b/include/Makefile index fe29186..d7badd7 100644 --- a/include/Makefile +++ b/include/Makefile @@ -57,18 +57,14 @@ LSUBDIRS= cam/ata cam/scsi \ security/mac_mls security/mac_partition \ ufs/ffs ufs/ufs -.if ${MK_USB} != "no" -LSUBDIRS+= dev/usb -.endif - LSUBSUBDIRS= dev/mpt/mpilib -.if ${MK_CUSE} != "no" -LSUBDIRS+= fs/cuse +.if ${MK_BLUETOOTH} != "no" +LSUBSUBDIRS+= netgraph/bluetooth/include .endif -.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" -_dev_powermac_nvram= dev/powermac_nvram +.if ${MK_CUSE} != "no" +LSUBDIRS+= fs/cuse .endif .if ${MK_GSSAPI} != "no" @@ -80,15 +76,18 @@ INCS+= gssapi.h INCS+= hesiod.h .endif -.if ${MK_BLUETOOTH} != "no" -LSUBSUBDIRS+= netgraph/bluetooth/include -.endif - # Handle the #define aliases for libiconv .if ${MK_ICONV} == "yes" INCS+= iconv.h .endif - + +.if ${MK_USB} != "no" +LSUBDIRS+= dev/usb +.endif + +.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" +_dev_powermac_nvram= dev/powermac_nvram +.endif # Define SHARED to indicate whether you want symbolic links to the system # source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is diff --git a/lib/libc/gen/directory.3 b/lib/libc/gen/directory.3 index e1874da..f0d0f4b 100644 --- a/lib/libc/gen/directory.3 +++ b/lib/libc/gen/directory.3 @@ -28,7 +28,7 @@ .\" @(#)directory.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd July 28, 2014 +.Dd May 6, 2015 .Dt DIRECTORY 3 .Os .Sh NAME @@ -263,12 +263,6 @@ function appeared in function appeared in .Fx 10.0 . .Sh BUGS -The invalidation of -.Fn telldir -tokens when calling -.Fn seekdir -is non-standard. This is a compile time option. -.Pp The behaviour of .Fn telldir and diff --git a/lib/libc/gen/telldir.c b/lib/libc/gen/telldir.c index 54cab5b..19cd6ee 100644 --- a/lib/libc/gen/telldir.c +++ b/lib/libc/gen/telldir.c @@ -101,11 +101,12 @@ _seekdir(dirp, loc) return; if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) return; - /* If it's within the same chunk of data, don't bother reloading */ + + /* If it's within the same chunk of data, don't bother reloading. */ if (lp->loc_seek == dirp->dd_seek) { /* * If we go back to 0 don't make the next readdir - * trigger a call to getdirentries() + * trigger a call to getdirentries(). */ if (lp->loc_loc == 0) dirp->dd_flags |= __DTF_SKIPREAD; @@ -124,10 +125,13 @@ _seekdir(dirp, loc) } /* - * when we do a read and cross a boundary, any telldir we - * just did will have wrong information in it. - * We need to move it from "beyond the end of the previous chunk" - * to "the beginning of the new chunk" + * After readdir returns the last entry in a block, a call to telldir + * returns a location that is after the end of that last entry. + * However, that location doesn't refer to a valid directory entry. + * Ideally, the call to telldir would return a location that refers to + * the first entry in the next block. That location is not known + * until the next block is read, so readdir calls this function after + * fetching a new block to fix any such telldir locations. */ void _fixtelldir(DIR *dirp, long oldseek, long oldloc) diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 57205a7..7cee03a 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -10,7 +10,8 @@ MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c quick_exit.c \ radixsort.c rand.c \ - random.c reallocf.c realpath.c remque.c strfmon.c strtoimax.c \ + random.c reallocarray.c reallocf.c realpath.c remque.c strfmon.c \ + strtoimax.c \ strtol.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c @@ -25,7 +26,7 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \ hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \ lsearch.3 memory.3 ptsname.3 qsort.3 \ quick_exit.3 \ - radixsort.3 rand.3 random.3 reallocf.3 \ + radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 \ realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \ tsearch.3 diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 39eab7d..782023e 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -113,6 +113,7 @@ FBSD_1.4 { hcreate_r; hdestroy_r; hsearch_r; + reallocarray; }; FBSDprivate_1.0 { diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3 new file mode 100644 index 0000000..8e714f4 --- /dev/null +++ b/lib/libc/stdlib/reallocarray.3 @@ -0,0 +1,142 @@ +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the American National Standards Committee X3, on Information +.\" Processing Systems. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 1, 2015 +.Dt REALLOCARRAY 3 +.Os +.Sh NAME +.Nm reallocarray +.Nd memory reallocation function +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In stdlib.h +.Ft void * +.Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" +.Sh DESCRIPTION +The +.Fn reallocarray +function is similar to the +.Fn realloc +function +except it operates on +.Fa nmemb +members of size +.Fa size +and checks for integer overflow in the calculation +.Fa nmemb +* +.Fa size . +.Sh RETURN VALUES +The +.Fn reallocarray +function returns a pointer to the allocated space; otherwise, a +.Dv NULL +pointer is returned and +.Va errno +is set to +.Er ENOMEM . +.Sh EXAMPLES +Consider +.Fn reallocarray +when there is multiplication in the +.Fa size +argument of +.Fn malloc +or +.Fn realloc . +For example, avoid this common idiom as it may lead to integer overflow: +.Bd -literal -offset indent +if ((p = malloc(num * size)) == NULL) + err(1, "malloc"); +.Ed +.Pp +A drop-in replacement is the +.Ox +extension +.Fn reallocarray : +.Bd -literal -offset indent +if ((p = reallocarray(NULL, num, size)) == NULL) + err(1, "reallocarray"); +.Ed +.Pp +When using +.Fn realloc , +be careful to avoid the following idiom: +.Bd -literal -offset indent +size += 50; +if ((p = realloc(p, size)) == NULL) + return (NULL); +.Ed +.Pp +Do not adjust the variable describing how much memory has been allocated +until the allocation has been successful. +This can cause aberrant program behavior if the incorrect size value is used. +In most cases, the above sample will also result in a leak of memory. +As stated earlier, a return value of +.Dv NULL +indicates that the old object still remains allocated. +Better code looks like this: +.Bd -literal -offset indent +newsize = size + 50; +if ((newp = realloc(p, newsize)) == NULL) { + free(p); + p = NULL; + size = 0; + return (NULL); +} +p = newp; +size = newsize; +.Ed +.Pp +As with +.Fn malloc , +it is important to ensure the new size value will not overflow; +i.e. avoid allocations like the following: +.Bd -literal -offset indent +if ((newp = realloc(p, num * size)) == NULL) { + ... +.Ed +.Pp +Instead, use +.Fn reallocarray : +.Bd -literal -offset indent +if ((newp = reallocarray(p, num, size)) == NULL) { + ... +.Ed +.Sh SEE ALSO +.Xr realloc 3 +.Sh HISTORY +The +.Fn reallocarray +function first appeared in +.Ox 5.6 +and +.Fx 11.0 . diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c new file mode 100644 index 0000000..e1e9b7c --- /dev/null +++ b/lib/libc/stdlib/reallocarray.c @@ -0,0 +1,42 @@ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return (NULL); + } + return (realloc(optr, size * nmemb)); +} diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c index 0c15845..1e6e627 100644 --- a/lib/libvmmapi/vmmapi.c +++ b/lib/libvmmapi/vmmapi.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #include <machine/param.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -958,9 +959,9 @@ vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities) return (error); } -static int -gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint64_t gla, int prot, int *fault, uint64_t *gpa) +int +vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, + uint64_t gla, int prot, uint64_t *gpa, int *fault) { struct vm_gla2gpa gg; int error; @@ -979,29 +980,18 @@ gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, return (error); } -int -vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint64_t gla, int prot, uint64_t *gpa) -{ - int error, fault; - - error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, gpa); - if (fault) - error = fault; - return (error); -} - #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif int vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt) + uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt, + int *fault) { void *va; uint64_t gpa; - int error, fault, i, n, off; + int error, i, n, off; for (i = 0; i < iovcnt; i++) { iov[i].iov_base = 0; @@ -1010,18 +1000,16 @@ vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, while (len) { assert(iovcnt > 0); - error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, &gpa); - if (error) - return (-1); - if (fault) - return (1); + error = vm_gla2gpa(ctx, vcpu, paging, gla, prot, &gpa, fault); + if (error || *fault) + return (error); off = gpa & PAGE_MASK; n = min(len, PAGE_SIZE - off); va = vm_map_gpa(ctx, gpa, n); if (va == NULL) - return (-1); + return (EFAULT); iov->iov_base = va; iov->iov_len = n; diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h index d001cd8..d3ecdc4 100644 --- a/lib/libvmmapi/vmmapi.h +++ b/lib/libvmmapi/vmmapi.h @@ -64,7 +64,7 @@ int vm_setup_memory(struct vmctx *ctx, size_t len, enum vm_mmap_style s); void *vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len); int vm_get_gpa_pmap(struct vmctx *, uint64_t gpa, uint64_t *pte, int *num); int vm_gla2gpa(struct vmctx *, int vcpuid, struct vm_guest_paging *paging, - uint64_t gla, int prot, uint64_t *gpa); + uint64_t gla, int prot, uint64_t *gpa, int *fault); uint32_t vm_get_lowmem_limit(struct vmctx *ctx); void vm_set_lowmem_limit(struct vmctx *ctx, uint32_t limit); void vm_set_memflags(struct vmctx *ctx, int flags); @@ -131,10 +131,15 @@ int vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities); /* * Translate the GLA range [gla,gla+len) into GPA segments in 'iov'. * The 'iovcnt' should be big enough to accomodate all GPA segments. - * Returns 0 on success, 1 on a guest fault condition and -1 otherwise. + * + * retval fault Interpretation + * 0 0 Success + * 0 1 An exception was injected into the guest + * EFAULT N/A Error */ int vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *pg, - uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt); + uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt, + int *fault); void vm_copyin(struct vmctx *ctx, int vcpu, struct iovec *guest_iov, void *host_dst, size_t len); void vm_copyout(struct vmctx *ctx, int vcpu, const void *host_src, diff --git a/libexec/rtld-elf/debug.h b/libexec/rtld-elf/debug.h index 98fdfb4..ed65227 100644 --- a/libexec/rtld-elf/debug.h +++ b/libexec/rtld-elf/debug.h @@ -32,10 +32,6 @@ #ifndef DEBUG_H #define DEBUG_H 1 -#ifndef __GNUC__ -#error "This file must be compiled with GCC" -#endif - #include <sys/cdefs.h> #include <string.h> diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 3ac4467..1d91460 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -34,10 +34,6 @@ * John Polstra <jdp@polstra.com>. */ -#ifndef __GNUC__ -#error "GCC is needed to compile this file" -#endif - #include <sys/param.h> #include <sys/mount.h> #include <sys/mman.h> diff --git a/release/arm/BEAGLEBONE.conf b/release/arm/BEAGLEBONE.conf index 87d2ffe..3ae4871 100644 --- a/release/arm/BEAGLEBONE.conf +++ b/release/arm/BEAGLEBONE.conf @@ -17,22 +17,21 @@ MD_ARGS="-x 63 -y 255" NODOC=1 arm_install_uboot() { - UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-beaglebone" - FATMOUNT="${DESTDIR##${KERNEL}}/fat" - UFSMOUNT="${DESTDIR##${KERNEL}}/ufs" + UBOOT_DIR="/usr/local/share/u-boot/u-boot-beaglebone" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} - cp -p ${UBOOT_DIR}/MLO ${CHROOTDIR}/${FATMOUNT}/MLO - cp -p ${UBOOT_DIR}/u-boot.img ${CHROOTDIR}/${FATMOUNT}/u-boot.img - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \ - ${CHROOTDIR}/${FATMOUNT}/ubldr - touch ${CHROOTDIR}/${UFSMOUNT}/firstboot + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} umount_loop ${CHROOTDIR}/${UFSMOUNT} - rmdir ${CHROOTDIR}/${FATMOUNT} - rmdir ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} return 0 } diff --git a/release/arm/PANDABOARD.conf b/release/arm/PANDABOARD.conf index 28a4639..b5a120e 100644 --- a/release/arm/PANDABOARD.conf +++ b/release/arm/PANDABOARD.conf @@ -17,22 +17,21 @@ FAT_TYPE="12" MD_ARGS="-x 63 -y 255" arm_install_uboot() { - UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-pandaboard" - FATMOUNT="${DESTDIR##${KERNEL}}/fat" - UFSMOUNT="${DESTDIR##${KERNEL}}/ufs" + UBOOT_DIR="/usr/local/share/u-boot/u-boot-pandaboard" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} - cp -p ${UBOOT_DIR}/MLO ${CHROOTDIR}/${FATMOUNT}/MLO - cp -p ${UBOOT_DIR}/u-boot.img ${CHROOTDIR}/${FATMOUNT}/u-boot.img - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \ - ${CHROOTDIR}/${FATMOUNT}/ubldr - touch ${CHROOTDIR}/${UFSMOUNT}/firstboot + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/MLO ${FATMOUNT}/MLO + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/u-boot.img ${FATMOUNT}/u-boot.img + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} umount_loop ${CHROOTDIR}/${UFSMOUNT} - rmdir ${CHROOTDIR}/${FATMOUNT} - rmdir ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} return 0 } diff --git a/release/arm/RPI-B.conf b/release/arm/RPI-B.conf index db3c102..e5abaab 100644 --- a/release/arm/RPI-B.conf +++ b/release/arm/RPI-B.conf @@ -17,27 +17,27 @@ MD_ARGS="-x 63 -y 255" NODOC=1 arm_install_uboot() { - UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-rpi" + UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi" UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \ start.elf start_cd.elf u-boot.img" - FATMOUNT="${DESTDIR##${KERNEL}}/fat" - UFSMOUNT="${DESTDIR##${KERNEL}}/ufs" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} for _UF in ${UBOOT_FILES}; do - cp -p ${UBOOT_DIR}/${_UF} ${CHROOTDIR}/${FATMOUNT}/${_UF} + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \ + ${FATMOUNT}/${_UF} done - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \ - ${CHROOTDIR}/${FATMOUNT}/ubldr - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/dtb/rpi.dtb \ - ${CHROOTDIR}/${FATMOUNT}/rpi.dtb - touch ${CHROOTDIR}/${UFSMOUNT}/firstboot + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi.dtb \ + ${FATMOUNT}/rpi.dtb + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} umount_loop ${CHROOTDIR}/${UFSMOUNT} - rmdir ${CHROOTDIR}/${FATMOUNT} - rmdir ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} return 0 } diff --git a/release/arm/RPI2.conf b/release/arm/RPI2.conf index aadd458..e1d15d1 100644 --- a/release/arm/RPI2.conf +++ b/release/arm/RPI2.conf @@ -17,27 +17,27 @@ FAT_TYPE="16" MD_ARGS="-x 63 -y 255" arm_install_uboot() { - UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-rpi2" + UBOOT_DIR="/usr/local/share/u-boot/u-boot-rpi2" UBOOT_FILES="bootcode.bin config.txt fixup.dat fixup_cd.dat \ fixup_x.dat start.elf start_cd.elf start_x.elf u-boot.bin" - FATMOUNT="${DESTDIR##${KERNEL}}/fat" - UFSMOUNT="${DESTDIR##${KERNEL}}/ufs" + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} for _UF in ${UBOOT_FILES}; do - cp -p ${UBOOT_DIR}/${_UF} ${CHROOTDIR}/${FATMOUNT}/${_UF} + chroot ${CHROOTDIR} cp -p ${UBOOT_DIR}/${_UF} \ + ${FATMOUNT}/${_UF} done - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \ - ${CHROOTDIR}/${FATMOUNT}/ubldr - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/dtb/rpi2.dtb \ - ${CHROOTDIR}/${FATMOUNT}/rpi2.dtb - touch ${CHROOTDIR}/${UFSMOUNT}/firstboot + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/dtb/rpi2.dtb \ + ${FATMOUNT}/rpi2.dtb + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} umount_loop ${CHROOTDIR}/${UFSMOUNT} - rmdir ${CHROOTDIR}/${FATMOUNT} - rmdir ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} return 0 } diff --git a/release/arm/WANDBOARD.conf b/release/arm/WANDBOARD.conf index 63614d7..42b4523 100644 --- a/release/arm/WANDBOARD.conf +++ b/release/arm/WANDBOARD.conf @@ -17,26 +17,25 @@ MD_ARGS="-x 63 -y 255" NODOC=1 arm_install_uboot() { - UBOOT_DIR="${CHROOTDIR}/usr/local/share/u-boot/u-boot-wandboard" + UBOOT_DIR="/usr/local/share/u-boot/u-boot-wandboard" UBOOT_FILES="u-boot.imx" - FATMOUNT="${DESTDIR##${KERNEL}}/fat" - UFSMOUNT="${DESTDIR##${KERNEL}}/ufs" - chroot ${CHROOTDIR} dd if=${UBOOT_DIR##${CHROOTDIR}}/${UBOOT_FILES} \ + FATMOUNT="${DESTDIR%${KERNEL}}/fat" + UFSMOUNT="${DESTDIR%${KERNEL}}/ufs" + chroot ${CHROOTDIR} dd if=${UBOOT_DIR}/${UBOOT_FILES} \ of=/dev/${mddev} bs=512 seek=2 chroot ${CHROOTDIR} mkdir -p "${FATMOUNT}" "${UFSMOUNT}" chroot ${CHROOTDIR} mount_msdosfs /dev/${mddev}s1 ${FATMOUNT} chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${UFSMOUNT} - cp -p ${CHROOTDIR}/${UFSMOUNT}/boot/ubldr \ - ${CHROOTDIR}/${FATMOUNT}/ubldr - chroot ${CHROOTDIR} echo \ - 'setenv fdt_file wandboard-quad.dtb; fatload mmc 0:1 11000000 ubldr; bootelf 11000000;' \ - > ${FATMOUNT}/boot.txt - touch ${CHROOTDIR}/${UFSMOUNT}/firstboot + chroot ${CHROOTDIR} cp -p ${UFSMOUNT}/boot/ubldr ${FATMOUNT}/ubldr + chroot ${CHROOTDIR} /bin/sh -c 'echo \ + setenv fdt_file wandboard-quad.dtb\; fatload mmc 0:1 11000000 ubldr\; bootelf 11000000\; \ + > ${FATMOUNT}/boot.txt' + chroot ${CHROOTDIR} touch ${UFSMOUNT}/firstboot sync umount_loop ${CHROOTDIR}/${FATMOUNT} umount_loop ${CHROOTDIR}/${UFSMOUNT} - rmdir ${CHROOTDIR}/${FATMOUNT} - rmdir ${CHROOTDIR}/${UFSMOUNT} + chroot ${CHROOTDIR} rmdir ${FATMOUNT} + chroot ${CHROOTDIR} rmdir ${UFSMOUNT} return 0 } diff --git a/release/release.sh b/release/release.sh index 6c1226c..94a9bb6 100755 --- a/release/release.sh +++ b/release/release.sh @@ -56,7 +56,7 @@ usage() { env_setup() { # The directory within which the release will be built. CHROOTDIR="/scratch" - RELENGDIR="$(realpath $(dirname $(basename ${0})))" + RELENGDIR="$(dirname $(realpath ${0}))" # The default version control system command to obtain the sources. for _dir in /usr/bin /usr/local/bin; do @@ -325,11 +325,10 @@ chroot_build_release() { chroot_arm_armv6_build_release() { load_target_env eval chroot ${CHROOTDIR} make -C /usr/src/release obj - # XXX: In progress. if [ -e "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr" ]; then . "${RELENGDIR}/tools/${EMBEDDED_TARGET}.subr" fi - . "${RELENGDIR}/arm/${KERNEL}.conf" + [ ! -z "${RELEASECONF}" ] && . "${RELEASECONF}" WORLDDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V WORLDDIR)" OBJDIR="$(eval chroot ${CHROOTDIR} make -C /usr/src/release -V .OBJDIR)" DESTDIR="${OBJDIR}/${KERNEL}" @@ -337,14 +336,15 @@ chroot_arm_armv6_build_release() { OSRELEASE="$(eval chroot ${CHROOTDIR} make -C /usr/src/release \ TARGET=${EMBEDDED_TARGET} TARGET_ARCH=${EMBEDDED_TARGET_ARCH} \ -V OSRELEASE)" - mkdir -p ${CHROOTDIR}/${DESTDIR} - truncate -s ${IMAGE_SIZE} ${IMGBASE} - export mddev=$(mdconfig -f ${IMGBASE} ${MD_ARGS}) + chroot ${CHROOTDIR} mkdir -p ${DESTDIR} + chroot ${CHROOTDIR} truncate -s ${IMAGE_SIZE} ${IMGBASE##${CHROOTDIR}} + export mddev=$(chroot ${CHROOTDIR} \ + mdconfig -f ${IMGBASE##${CHROOTDIR}} ${MD_ARGS}) arm_create_disk arm_install_base arm_install_uboot mdconfig -d -u ${mddev} - rmdir ${CHROOTDIR}/${DESTDIR} + chroot ${CHROOTDIR} rmdir ${DESTDIR} mv ${IMGBASE} ${CHROOTDIR}/${OBJDIR}/${OSRELEASE}-${KERNEL}.img chroot ${CHROOTDIR} mkdir -p /R chroot ${CHROOTDIR} cp -p ${OBJDIR}/${OSRELEASE}-${KERNEL}.img \ diff --git a/release/tools/arm.subr b/release/tools/arm.subr index c42cf0d..5cc61e3 100644 --- a/release/tools/arm.subr +++ b/release/tools/arm.subr @@ -77,6 +77,18 @@ arm_create_disk() { return 0 } +arm_create_user() { + # Create a default user account 'freebsd' with the password 'freebsd', + # and set the default password for the 'root' user to 'root'. + chroot ${CHROOTDIR} /usr/sbin/pw groupadd freebsd -g 1001 + chroot ${CHROOTDIR} /usr/sbin/pw useradd freebsd \ + -m -M 0755 -w yes -n freebsd -u 1001 -g 1001 -G 0 \ + -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh' + chroot ${CHROOTDIR} /usr/sbin/pw usermod root -w yes + + return 0 +} + arm_install_base() { chroot ${CHROOTDIR} mount /dev/${mddev}s2a ${DESTDIR} eval chroot ${CHROOTDIR} make -C ${WORLDDIR} \ @@ -86,6 +98,8 @@ arm_install_base() { installworld installkernel distribution chroot ${CHROOTDIR} mkdir -p ${DESTDIR}/boot/msdos + arm_create_user + echo '# Custom /etc/fstab for FreeBSD embedded images' \ > ${CHROOTDIR}/${DESTDIR}/etc/fstab echo "/dev/ufs/rootfs / ufs rw 1 1" \ diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4 index 17cf1cb..8c221be 100644 --- a/share/man/man4/acpi.4 +++ b/share/man/man4/acpi.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 23, 2014 +.Dd May 9, 2015 .Dt ACPI 4 .Os .Sh NAME @@ -69,14 +69,12 @@ them (such as Enable dumping Debug objects without .Cd "options ACPI_DEBUG" . Default is 0, ignore Debug objects. -.It Va hw.acpi.acline -AC line state (1 means online, 0 means on battery power). -.It Va hw.acpi.cpu.cx_usage +.It Va dev.cpu.N.cx_usage Debugging information listing the percent of total usage for each sleep state. The values are reset when -.Va hw.acpi.cpu.cx_lowest +.Va dev.cpu.N.cx_lowest is modified. -.It Va hw.acpi.cpu.cx_lowest +.It Va dev.cpu.N.cx_lowest Lowest Cx state to use for idling the CPU. A scheduling algorithm will select states between .Li C1 @@ -111,6 +109,11 @@ semantics as the state. Deeper sleeps provide more power savings but increased transition latency when an interrupt occurs. +.It Va dev.cpu.N.cx_method +List of supported CPU idle states and their transition methods, as +directed by the firmware. +.It Va hw.acpi.acline +AC line state (1 means online, 0 means on battery power). .It Va hw.acpi.disable_on_reboot Disable ACPI during the reboot process. Most systems reboot fine with ACPI still enabled, but some require @@ -374,6 +377,14 @@ typically as a child of a PCI bus. .Pq Vt device Supports an ACPI laptop lid switch, which typically puts a system to sleep. +.It Li mwait +.Pq Vt feature +Do not ask firmware for available x86-vendor specific methods to enter +.Li Cx +sleep states. +Only query and use the generic I/O-based entrance method. +The knob is provided to work around inconsistencies in the tables +filled by firmware. .It Li quirks .Pq Vt feature Do not honor quirks. diff --git a/share/man/man4/usb_quirk.4 b/share/man/man4/usb_quirk.4 index 9352e76..d7686fd 100644 --- a/share/man/man4/usb_quirk.4 +++ b/share/man/man4/usb_quirk.4 @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 21, 2013 +.Dd May 7, 2015 .Dt USB_QUIRK 4 .Os .Sh NAME @@ -170,6 +170,9 @@ ejects after Huawei SCSI command .It UQ_MSC_EJECT_TCT ejects after TCT SCSI command .Dv 0x06f504025270 +.It UQ_MSC_DYMO_EJECT +ejects after HID command +.Dv 0x1b5a01 .El .Pp See diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 7f79156..11dcb01 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1113,7 +1113,6 @@ MLINKS+=mutex.9 mtx_assert.9 \ mutex.9 mtx_unlock_spin.9 \ mutex.9 mtx_unlock_spin_flags.9 MLINKS+=namei.9 NDFREE.9 \ - namei.9 NDHASGIANT.9 \ namei.9 NDINIT.9 MLINKS+=netisr.9 netisr_clearqdrops.9 \ netisr.9 netisr_default_flow2cpu.9 \ diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9 index 0bd827f..305665a 100644 --- a/share/man/man9/namei.9 +++ b/share/man/man9/namei.9 @@ -33,14 +33,13 @@ .\" .\" $FreeBSD$ .\" -.Dd March 1, 2012 +.Dd May 6, 2015 .Dt NAMEI 9 .Os .Sh NAME .Nm namei , .Nm NDINIT , .Nm NDFREE , -.Nm NDHASGIANT .Nd pathname translation and lookup operations .Sh SYNOPSIS .In sys/param.h @@ -55,8 +54,6 @@ .Fc .Ft void .Fn NDFREE "struct nameidata *ndp" "const uint flags" -.Ft int -.Fn NDHASGIANT "struct nameidata *ndp" .Sh DESCRIPTION The .Nm @@ -73,16 +70,6 @@ or depending on whether the .Dv LOCKLEAF flag was specified or not. -If the -.Va Giant -lock is required, -.Nm -will acquire it if the caller indicates it is -.Dv MPSAFE , -in which case the caller must later release -.Va Giant -based on the results of -.Fn NDHASGIANT . .Pp The .Fn NDINIT @@ -362,6 +349,3 @@ In order to solve this for the cases where both and .Dv LOCKLEAF are used, it is necessary to resort to recursive locking. -.Pp -Non-MPSAFE file systems exist, requiring callers to conditionally unlock -.Va Giant . diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 192bc00..6279e90 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -24,7 +24,7 @@ _PRIVATELIBS= \ ucl \ unbound -_INTERNALIBS= \ +_INTERNALLIBS= \ amu \ bsnmptools \ cron \ @@ -49,7 +49,7 @@ _INTERNALIBS= \ _LIBRARIES= \ ${_PRIVATELIBS} \ - ${_INTERNALIBS} \ + ${_INTERNALLIBS} \ alias \ archive \ asn1 \ @@ -243,7 +243,7 @@ LIB${_l:tu}?= ${DESTDIR}${LIBDIR}/libprivate${_l}.a .endfor .for _l in ${_LIBRARIES} -.if ${_INTERNALIBS:M${_l}} +.if ${_INTERNALLIBS:M${_l}} LDADD_${_l}_L+= -L${LIB${_l:tu}DIR} .endif DPADD_${_l}?= ${LIB${_l:tu}} diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c index 049b51bb4e..8f88a00 100644 --- a/sys/amd64/acpica/acpi_machdep.c +++ b/sys/amd64/acpica/acpi_machdep.c @@ -87,13 +87,6 @@ acpi_machdep_quirks(int *quirks) return (0); } -void -acpi_cpu_c1() -{ - - __asm __volatile("sti; hlt"); -} - /* * Support for mapping ACPI tables during early boot. Currently this * uses the crashdump map to map each table. However, the crashdump diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 4455cab..a1279e6 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -196,8 +196,6 @@ IDTVEC(hv_vmbus_callback) */ .text -#define NAKE_INTR_CS 24 - SUPERALIGN_TEXT invltlb_ret: call as_lapic_eoi @@ -205,30 +203,28 @@ invltlb_ret: jmp doreti_iret SUPERALIGN_TEXT +IDTVEC(invltlb) + PUSH_FRAME + + call invltlb_handler + jmp invltlb_ret + IDTVEC(invltlb_pcid) PUSH_FRAME call invltlb_pcid_handler jmp invltlb_ret - - SUPERALIGN_TEXT -IDTVEC(invltlb) +IDTVEC(invltlb_invpcid) PUSH_FRAME - call invltlb_handler + call invltlb_invpcid_handler jmp invltlb_ret /* * Single page TLB shootdown */ .text - SUPERALIGN_TEXT -IDTVEC(invlpg_pcid) - PUSH_FRAME - - call invlpg_pcid_handler - jmp invltlb_ret SUPERALIGN_TEXT IDTVEC(invlpg) diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index eb0ee8b..e292797 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -69,16 +69,10 @@ * %rsi = newtd */ ENTRY(cpu_throw) - movl PCPU(CPUID),%eax - testq %rdi,%rdi - jz 1f - /* release bit from old pm_active */ - movq PCPU(CURPMAP),%rdx - LK btrl %eax,PM_ACTIVE(%rdx) /* clear old */ -1: - movq TD_PCB(%rsi),%r8 /* newtd->td_pcb */ - movq PCB_CR3(%r8),%rcx /* new address space */ - jmp swact + movq %rsi,%r12 + movq %rsi,%rdi + call pmap_activate_sw + jmp sw1 END(cpu_throw) /* @@ -132,59 +126,20 @@ ctx_switch_xsave: xorl %eax,%eax movq %rax,PCPU(FPCURTHREAD) 3: - /* Save is done. Now fire up new thread. Leave old vmspace. */ - movq TD_PCB(%rsi),%r8 - - /* switch address space */ - movq PCB_CR3(%r8),%rcx - movq %cr3,%rax - cmpq %rcx,%rax /* Same address space? */ - jne swinact - SETLK %rdx, TD_LOCK(%rdi) /* Release the old thread */ - jmp sw1 -swinact: - movl PCPU(CPUID),%eax - /* Release bit from old pmap->pm_active */ - movq PCPU(CURPMAP),%r12 - LK btrl %eax,PM_ACTIVE(%r12) /* clear old */ - SETLK %rdx,TD_LOCK(%rdi) /* Release the old thread */ -swact: - /* Set bit in new pmap->pm_active */ - movq TD_PROC(%rsi),%rdx /* newproc */ - movq P_VMSPACE(%rdx), %rdx - addq $VM_PMAP,%rdx - cmpl $-1,PM_PCID(%rdx) - je 1f - LK btsl %eax,PM_SAVE(%rdx) - jnc 1f - btsq $63,%rcx /* CR3_PCID_SAVE */ - incq PCPU(PM_SAVE_CNT) -1: - movq %rcx,%cr3 /* new address space */ - LK btsl %eax,PM_ACTIVE(%rdx) /* set new */ - movq %rdx,PCPU(CURPMAP) - - /* - * We might lose the race and other CPU might have changed - * the pmap after we set our bit in pmap->pm_save. Recheck. - * Reload %cr3 with CR3_PCID_SAVE bit cleared if pmap was - * modified, causing TLB flush for this pcid. - */ - btrq $63,%rcx - jnc 1f - LK btsl %eax,PM_SAVE(%rdx) - jc 1f - decq PCPU(PM_SAVE_CNT) - movq %rcx,%cr3 -1: - + movq %rsi,%r12 + movq %rdi,%r13 + movq %rdx,%r15 + movq %rsi,%rdi + callq pmap_activate_sw + SETLK %r15,TD_LOCK(%r13) /* Release the old thread */ sw1: + movq TD_PCB(%r12),%r8 #if defined(SCHED_ULE) && defined(SMP) /* Wait for the new thread to become unblocked */ movq $blocked_lock, %rdx 1: - movq TD_LOCK(%rsi),%rcx + movq TD_LOCK(%r12),%rcx cmpq %rcx, %rdx pause je 1b @@ -195,13 +150,13 @@ sw1: */ /* Skip loading user fsbase/gsbase for kthreads */ - testl $TDP_KTHREAD,TD_PFLAGS(%rsi) + testl $TDP_KTHREAD,TD_PFLAGS(%r12) jnz do_kthread /* * Load ldt register */ - movq TD_PROC(%rsi),%rcx + movq TD_PROC(%r12),%rcx cmpq $0, P_MD+MD_LDT(%rcx) jne do_ldt xorl %eax,%eax @@ -238,7 +193,7 @@ done_tss: movq %r8,PCPU(CURPCB) /* Update the TSS_RSP0 pointer for the next interrupt */ movq %r8,COMMON_TSS_RSP0(%rdx) - movq %rsi,PCPU(CURTHREAD) /* into next thread */ + movq %r12,PCPU(CURTHREAD) /* into next thread */ /* Test if debug registers should be restored. */ testl $PCB_DBREGS,PCB_FLAGS(%r8) diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 3ffefc0..11012c4 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -71,8 +71,6 @@ __FBSDID("$FreeBSD$"); ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); -ASSYM(PM_SAVE, offsetof(struct pmap, pm_save)); -ASSYM(PM_PCID, offsetof(struct pmap, pm_pcid)); ASSYM(P_MD, offsetof(struct proc, p_md)); ASSYM(MD_LDT, offsetof(struct mdproc, md_ldt)); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 3230937..7cd58b1 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1718,7 +1718,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree) /* setup proc 0's pcb */ thread0.td_pcb->pcb_flags = 0; - thread0.td_pcb->pcb_cr3 = KPML4phys; /* PCID 0 is reserved for kernel */ thread0.td_frame = &proc0_tf; env = kern_getenv("kernelname"); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 83ca548..e91e6d5 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -88,12 +88,9 @@ char *doublefault_stack; char *nmi_stack; /* Variables needed for SMP tlb shootdown. */ -vm_offset_t smp_tlb_addr2; -struct invpcid_descr smp_tlb_invpcid; +static vm_offset_t smp_tlb_addr1, smp_tlb_addr2; +static pmap_t smp_tlb_pmap; volatile int smp_tlb_wait; -uint64_t pcid_cr3; -pmap_t smp_tlb_pmap; -extern int invpcid_works; extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); @@ -139,14 +136,17 @@ cpu_mp_start(void) /* Install an inter-CPU IPI for TLB invalidation */ if (pmap_pcid_enabled) { - setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT, - SEL_KPL, 0); - setidt(IPI_INVLPG, IDTVEC(invlpg_pcid), SDT_SYSIGT, - SEL_KPL, 0); + if (invpcid_works) { + setidt(IPI_INVLTLB, IDTVEC(invltlb_invpcid), + SDT_SYSIGT, SEL_KPL, 0); + } else { + setidt(IPI_INVLTLB, IDTVEC(invltlb_pcid), SDT_SYSIGT, + SEL_KPL, 0); + } } else { setidt(IPI_INVLTLB, IDTVEC(invltlb), SDT_SYSIGT, SEL_KPL, 0); - setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); } + setidt(IPI_INVLPG, IDTVEC(invlpg), SDT_SYSIGT, SEL_KPL, 0); setidt(IPI_INVLRNG, IDTVEC(invlrng), SDT_SYSIGT, SEL_KPL, 0); /* Install an inter-CPU IPI for cache invalidation. */ @@ -242,6 +242,9 @@ init_secondary(void) pc->pc_gs32p = &gdt[NGDT * cpu + GUGS32_SEL]; pc->pc_ldt = (struct system_segment_descriptor *)&gdt[NGDT * cpu + GUSERLDT_SEL]; + pc->pc_curpmap = kernel_pmap; + pc->pc_pcid_gen = 1; + pc->pc_pcid_next = PMAP_PCID_KERN + 1; /* Save the per-cpu pointer for use by the NMI handler. */ np->np_pcpu = (register_t) pc; @@ -407,35 +410,8 @@ start_ap(int apic_id) } /* - * Flush the TLB on all other CPU's + * Flush the TLB on other CPU's */ -static void -smp_tlb_shootdown(u_int vector, pmap_t pmap, vm_offset_t addr1, - vm_offset_t addr2) -{ - u_int ncpu; - - ncpu = mp_ncpus - 1; /* does not shootdown self */ - if (ncpu < 1) - return; /* no other cpus */ - if (!(read_rflags() & PSL_I)) - panic("%s: interrupts disabled", __func__); - mtx_lock_spin(&smp_ipi_mtx); - smp_tlb_invpcid.addr = addr1; - if (pmap == NULL) { - smp_tlb_invpcid.pcid = 0; - } else { - smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = pmap->pm_cr3; - } - smp_tlb_addr2 = addr2; - smp_tlb_pmap = pmap; - atomic_store_rel_int(&smp_tlb_wait, 0); - ipi_all_but_self(vector); - while (smp_tlb_wait < ncpu) - ia32_pause(); - mtx_unlock_spin(&smp_ipi_mtx); -} static void smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, @@ -443,7 +419,11 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, { int cpu, ncpu, othercpus; - othercpus = mp_ncpus - 1; + othercpus = mp_ncpus - 1; /* does not shootdown self */ + + /* + * Check for other cpus. Return if none. + */ if (CPU_ISFULLSET(&mask)) { if (othercpus < 1) return; @@ -452,16 +432,11 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, if (CPU_EMPTY(&mask)) return; } + if (!(read_rflags() & PSL_I)) panic("%s: interrupts disabled", __func__); mtx_lock_spin(&smp_ipi_mtx); - smp_tlb_invpcid.addr = addr1; - if (pmap == NULL) { - smp_tlb_invpcid.pcid = 0; - } else { - smp_tlb_invpcid.pcid = pmap->pm_pcid; - pcid_cr3 = pmap->pm_cr3; - } + smp_tlb_addr1 = addr1; smp_tlb_addr2 = addr2; smp_tlb_pmap = pmap; atomic_store_rel_int(&smp_tlb_wait, 0); @@ -485,65 +460,39 @@ smp_targeted_tlb_shootdown(cpuset_t mask, u_int vector, pmap_t pmap, } void -smp_invlpg(pmap_t pmap, vm_offset_t addr) -{ - - if (smp_started) { - smp_tlb_shootdown(IPI_INVLPG, pmap, addr, 0); -#ifdef COUNT_XINVLTLB_HITS - ipi_page++; -#endif - } -} - -void -smp_invlpg_range(pmap_t pmap, vm_offset_t addr1, vm_offset_t addr2) -{ - - if (smp_started) { - smp_tlb_shootdown(IPI_INVLRNG, pmap, addr1, addr2); -#ifdef COUNT_XINVLTLB_HITS - ipi_range++; - ipi_range_size += (addr2 - addr1) / PAGE_SIZE; -#endif - } -} - -void smp_masked_invltlb(cpuset_t mask, pmap_t pmap) { if (smp_started) { smp_targeted_tlb_shootdown(mask, IPI_INVLTLB, pmap, 0, 0); #ifdef COUNT_XINVLTLB_HITS - ipi_masked_global++; + ipi_global++; #endif } } void -smp_masked_invlpg(cpuset_t mask, pmap_t pmap, vm_offset_t addr) +smp_masked_invlpg(cpuset_t mask, vm_offset_t addr) { if (smp_started) { - smp_targeted_tlb_shootdown(mask, IPI_INVLPG, pmap, addr, 0); + smp_targeted_tlb_shootdown(mask, IPI_INVLPG, NULL, addr, 0); #ifdef COUNT_XINVLTLB_HITS - ipi_masked_page++; + ipi_page++; #endif } } void -smp_masked_invlpg_range(cpuset_t mask, pmap_t pmap, vm_offset_t addr1, - vm_offset_t addr2) +smp_masked_invlpg_range(cpuset_t mask, vm_offset_t addr1, vm_offset_t addr2) { if (smp_started) { - smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, pmap, addr1, - addr2); + smp_targeted_tlb_shootdown(mask, IPI_INVLRNG, NULL, + addr1, addr2); #ifdef COUNT_XINVLTLB_HITS - ipi_masked_range++; - ipi_masked_range_size += (addr2 - addr1) / PAGE_SIZE; + ipi_range++; + ipi_range_size += (addr2 - addr1) / PAGE_SIZE; #endif } } @@ -552,19 +501,9 @@ void smp_cache_flush(void) { - if (smp_started) - smp_tlb_shootdown(IPI_INVLCACHE, NULL, 0, 0); -} - -void -smp_invltlb(pmap_t pmap) -{ - if (smp_started) { - smp_tlb_shootdown(IPI_INVLTLB, pmap, 0, 0); -#ifdef COUNT_XINVLTLB_HITS - ipi_global++; -#endif + smp_targeted_tlb_shootdown(all_cpus, IPI_INVLCACHE, NULL, + 0, 0); } } @@ -586,10 +525,10 @@ invltlb_handler(void) } void -invltlb_pcid_handler(void) +invltlb_invpcid_handler(void) { - uint64_t cr3; - u_int cpuid; + struct invpcid_descr d; + #ifdef COUNT_XINVLTLB_HITS xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ @@ -597,49 +536,45 @@ invltlb_pcid_handler(void) (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ - if (smp_tlb_invpcid.pcid != (uint64_t)-1 && - smp_tlb_invpcid.pcid != 0) { - if (invpcid_works) { - invpcid(&smp_tlb_invpcid, INVPCID_CTX); - } else { - /* Otherwise reload %cr3 twice. */ - cr3 = rcr3(); - if (cr3 != pcid_cr3) { - load_cr3(pcid_cr3); - cr3 |= CR3_PCID_SAVE; - } - load_cr3(cr3); - } - } else { - invltlb_globpcid(); - } - if (smp_tlb_pmap != NULL) { - cpuid = PCPU_GET(cpuid); - if (!CPU_ISSET(cpuid, &smp_tlb_pmap->pm_active)) - CPU_CLR_ATOMIC(cpuid, &smp_tlb_pmap->pm_save); - } - + d.pcid = smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid; + d.pad = 0; + d.addr = 0; + invpcid(&d, smp_tlb_pmap == kernel_pmap ? INVPCID_CTXGLOB : + INVPCID_CTX); atomic_add_int(&smp_tlb_wait, 1); } void -invlpg_handler(void) +invltlb_pcid_handler(void) { #ifdef COUNT_XINVLTLB_HITS - xhits_pg[PCPU_GET(cpuid)]++; + xhits_gbl[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ #ifdef COUNT_IPIS - (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; + (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ - invlpg(smp_tlb_invpcid.addr); + if (smp_tlb_pmap == kernel_pmap) { + invltlb_globpcid(); + } else { + /* + * The current pmap might not be equal to + * smp_tlb_pmap. The clearing of the pm_gen in + * pmap_invalidate_all() takes care of TLB + * invalidation when switching to the pmap on this + * CPU. + */ + if (PCPU_GET(curpmap) == smp_tlb_pmap) { + load_cr3(smp_tlb_pmap->pm_cr3 | + smp_tlb_pmap->pm_pcids[PCPU_GET(cpuid)].pm_pcid); + } + } atomic_add_int(&smp_tlb_wait, 1); } void -invlpg_pcid_handler(void) +invlpg_handler(void) { - uint64_t cr3; #ifdef COUNT_XINVLTLB_HITS xhits_pg[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ @@ -647,45 +582,15 @@ invlpg_pcid_handler(void) (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ - if (smp_tlb_invpcid.pcid == (uint64_t)-1) { - invltlb_globpcid(); - } else if (smp_tlb_invpcid.pcid == 0) { - invlpg(smp_tlb_invpcid.addr); - } else if (invpcid_works) { - invpcid(&smp_tlb_invpcid, INVPCID_ADDR); - } else { - /* - * PCID supported, but INVPCID is not. - * Temporarily switch to the target address - * space and do INVLPG. - */ - cr3 = rcr3(); - if (cr3 != pcid_cr3) - load_cr3(pcid_cr3 | CR3_PCID_SAVE); - invlpg(smp_tlb_invpcid.addr); - load_cr3(cr3 | CR3_PCID_SAVE); - } - + invlpg(smp_tlb_addr1); atomic_add_int(&smp_tlb_wait, 1); } -static inline void -invlpg_range(vm_offset_t start, vm_offset_t end) -{ - - do { - invlpg(start); - start += PAGE_SIZE; - } while (start < end); -} - void invlrng_handler(void) { - struct invpcid_descr d; vm_offset_t addr; - uint64_t cr3; - u_int cpuid; + #ifdef COUNT_XINVLTLB_HITS xhits_rng[PCPU_GET(cpuid)]++; #endif /* COUNT_XINVLTLB_HITS */ @@ -693,38 +598,11 @@ invlrng_handler(void) (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; #endif /* COUNT_IPIS */ - addr = smp_tlb_invpcid.addr; - if (pmap_pcid_enabled) { - if (smp_tlb_invpcid.pcid == 0) { - /* - * kernel pmap - use invlpg to invalidate - * global mapping. - */ - invlpg_range(addr, smp_tlb_addr2); - } else if (smp_tlb_invpcid.pcid == (uint64_t)-1) { - invltlb_globpcid(); - if (smp_tlb_pmap != NULL) { - cpuid = PCPU_GET(cpuid); - if (!CPU_ISSET(cpuid, &smp_tlb_pmap->pm_active)) - CPU_CLR_ATOMIC(cpuid, - &smp_tlb_pmap->pm_save); - } - } else if (invpcid_works) { - d = smp_tlb_invpcid; - do { - invpcid(&d, INVPCID_ADDR); - d.addr += PAGE_SIZE; - } while (d.addr <= smp_tlb_addr2); - } else { - cr3 = rcr3(); - if (cr3 != pcid_cr3) - load_cr3(pcid_cr3 | CR3_PCID_SAVE); - invlpg_range(addr, smp_tlb_addr2); - load_cr3(cr3 | CR3_PCID_SAVE); - } - } else { - invlpg_range(addr, smp_tlb_addr2); - } + addr = smp_tlb_addr1; + do { + invlpg(addr); + addr += PAGE_SIZE; + } while (addr < smp_tlb_addr2); atomic_add_int(&smp_tlb_wait, 1); } diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index dc823fa..e18676a 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -273,6 +273,8 @@ pmap_modified_bit(pmap_t pmap) return (mask); } +extern struct pcpu __pcpu[]; + #if !defined(DIAGNOSTIC) #ifdef __GNUC_GNU_INLINE__ #define PMAP_INLINE __attribute__((__gnu_inline__)) inline @@ -379,8 +381,6 @@ caddr_t CADDR1 = 0; static int pmap_flags = PMAP_PDE_SUPERPAGE; /* flags for x86 pmaps */ -static struct unrhdr pcid_unr; -static struct mtx pcid_mtx; int pmap_pcid_enabled = 0; SYSCTL_INT(_vm_pmap, OID_AUTO, pcid_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &pmap_pcid_enabled, 0, "Is TLB Context ID enabled ?"); @@ -827,6 +827,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr) { vm_offset_t va; pt_entry_t *pte; + int i; /* * Create an initial set of page tables to run the kernel in. @@ -861,7 +862,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr) kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys); kernel_pmap->pm_cr3 = KPML4phys; CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */ - CPU_FILL(&kernel_pmap->pm_save); /* always superset of pm_active */ TAILQ_INIT(&kernel_pmap->pm_pvchunk); kernel_pmap->pm_flags = pmap_flags; @@ -895,18 +895,28 @@ pmap_bootstrap(vm_paddr_t *firstaddr) /* Initialize TLB Context Id. */ TUNABLE_INT_FETCH("vm.pmap.pcid_enabled", &pmap_pcid_enabled); if ((cpu_feature2 & CPUID2_PCID) != 0 && pmap_pcid_enabled) { - load_cr4(rcr4() | CR4_PCIDE); - mtx_init(&pcid_mtx, "pcid", NULL, MTX_DEF); - init_unrhdr(&pcid_unr, 1, (1 << 12) - 1, &pcid_mtx); /* Check for INVPCID support */ invpcid_works = (cpu_stdext_feature & CPUID_STDEXT_INVPCID) != 0; - kernel_pmap->pm_pcid = 0; -#ifndef SMP + for (i = 0; i < MAXCPU; i++) { + kernel_pmap->pm_pcids[i].pm_pcid = PMAP_PCID_KERN; + kernel_pmap->pm_pcids[i].pm_gen = 1; + } + __pcpu[0].pc_pcid_next = PMAP_PCID_KERN + 1; + __pcpu[0].pc_pcid_gen = 1; + /* + * pcpu area for APs is zeroed during AP startup. + * pc_pcid_next and pc_pcid_gen are initialized by AP + * during pcpu setup. + */ +#ifdef SMP + load_cr4(rcr4() | CR4_PCIDE); +#else pmap_pcid_enabled = 0; #endif - } else + } else { pmap_pcid_enabled = 0; + } } /* @@ -1277,28 +1287,6 @@ pmap_update_pde_invalidate(pmap_t pmap, vm_offset_t va, pd_entry_t newpde) } #ifdef SMP -static void -pmap_invalidate_page_pcid(pmap_t pmap, vm_offset_t va) -{ - struct invpcid_descr d; - uint64_t cr3; - - if (invpcid_works) { - d.pcid = pmap->pm_pcid; - d.pad = 0; - d.addr = va; - invpcid(&d, INVPCID_ADDR); - return; - } - - cr3 = rcr3(); - critical_enter(); - load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); - invlpg(va); - load_cr3(cr3 | CR3_PCID_SAVE); - critical_exit(); -} - /* * For SMP, these functions have to use the IPI mechanism for coherence. * @@ -1361,8 +1349,8 @@ pmap_invalidate_ept(pmap_t pmap) void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { - cpuset_t other_cpus; - u_int cpuid; + cpuset_t *mask; + u_int cpuid, i; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1373,74 +1361,33 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va) ("pmap_invalidate_page: invalid type %d", pmap->pm_type)); sched_pin(); - if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) { - if (!pmap_pcid_enabled) { - invlpg(va); - } else { - if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) { - if (pmap == PCPU_GET(curpmap)) - invlpg(va); - else - pmap_invalidate_page_pcid(pmap, va); - } else { - invltlb_globpcid(); - } - } - smp_invlpg(pmap, va); + if (pmap == kernel_pmap) { + invlpg(va); + mask = &all_cpus; } else { cpuid = PCPU_GET(cpuid); - other_cpus = all_cpus; - CPU_CLR(cpuid, &other_cpus); - if (CPU_ISSET(cpuid, &pmap->pm_active)) + if (pmap == PCPU_GET(curpmap)) invlpg(va); - else if (pmap_pcid_enabled) { - if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) - pmap_invalidate_page_pcid(pmap, va); - else - invltlb_globpcid(); + else if (pmap_pcid_enabled) + pmap->pm_pcids[cpuid].pm_gen = 0; + if (pmap_pcid_enabled) { + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } } - if (pmap_pcid_enabled) - CPU_AND(&other_cpus, &pmap->pm_save); - else - CPU_AND(&other_cpus, &pmap->pm_active); - if (!CPU_EMPTY(&other_cpus)) - smp_masked_invlpg(other_cpus, pmap, va); + mask = &pmap->pm_active; } + smp_masked_invlpg(*mask, va); sched_unpin(); } -static void -pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) -{ - struct invpcid_descr d; - uint64_t cr3; - vm_offset_t addr; - - if (invpcid_works) { - d.pcid = pmap->pm_pcid; - d.pad = 0; - for (addr = sva; addr < eva; addr += PAGE_SIZE) { - d.addr = addr; - invpcid(&d, INVPCID_ADDR); - } - return; - } - - cr3 = rcr3(); - critical_enter(); - load_cr3(pmap->pm_cr3 | CR3_PCID_SAVE); - for (addr = sva; addr < eva; addr += PAGE_SIZE) - invlpg(addr); - load_cr3(cr3 | CR3_PCID_SAVE); - critical_exit(); -} - void pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { - cpuset_t other_cpus; + cpuset_t *mask; vm_offset_t addr; - u_int cpuid; + u_int cpuid, i; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1451,55 +1398,36 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) ("pmap_invalidate_range: invalid type %d", pmap->pm_type)); sched_pin(); - if (pmap == kernel_pmap || !CPU_CMP(&pmap->pm_active, &all_cpus)) { - if (!pmap_pcid_enabled) { - for (addr = sva; addr < eva; addr += PAGE_SIZE) - invlpg(addr); - } else { - if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) { - if (pmap == PCPU_GET(curpmap)) { - for (addr = sva; addr < eva; - addr += PAGE_SIZE) - invlpg(addr); - } else { - pmap_invalidate_range_pcid(pmap, - sva, eva); - } - } else { - invltlb_globpcid(); - } - } - smp_invlpg_range(pmap, sva, eva); + cpuid = PCPU_GET(cpuid); + if (pmap == kernel_pmap) { + for (addr = sva; addr < eva; addr += PAGE_SIZE) + invlpg(addr); + mask = &all_cpus; } else { - cpuid = PCPU_GET(cpuid); - other_cpus = all_cpus; - CPU_CLR(cpuid, &other_cpus); - if (CPU_ISSET(cpuid, &pmap->pm_active)) { + if (pmap == PCPU_GET(curpmap)) { for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); } else if (pmap_pcid_enabled) { - if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) - pmap_invalidate_range_pcid(pmap, sva, eva); - else - invltlb_globpcid(); + pmap->pm_pcids[cpuid].pm_gen = 0; } - if (pmap_pcid_enabled) - CPU_AND(&other_cpus, &pmap->pm_save); - else - CPU_AND(&other_cpus, &pmap->pm_active); - if (!CPU_EMPTY(&other_cpus)) - smp_masked_invlpg_range(other_cpus, pmap, sva, eva); + if (pmap_pcid_enabled) { + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + } + mask = &pmap->pm_active; } + smp_masked_invlpg_range(*mask, sva, eva); sched_unpin(); } void pmap_invalidate_all(pmap_t pmap) { - cpuset_t other_cpus; + cpuset_t *mask; struct invpcid_descr d; - uint64_t cr3; - u_int cpuid; + u_int cpuid, i; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1510,60 +1438,42 @@ pmap_invalidate_all(pmap_t pmap) ("pmap_invalidate_all: invalid type %d", pmap->pm_type)); sched_pin(); - cpuid = PCPU_GET(cpuid); - if (pmap == kernel_pmap || - (pmap_pcid_enabled && !CPU_CMP(&pmap->pm_save, &all_cpus)) || - !CPU_CMP(&pmap->pm_active, &all_cpus)) { - if (invpcid_works) { + if (pmap == kernel_pmap) { + if (pmap_pcid_enabled && invpcid_works) { bzero(&d, sizeof(d)); invpcid(&d, INVPCID_CTXGLOB); } else { invltlb_globpcid(); } - if (!CPU_ISSET(cpuid, &pmap->pm_active)) - CPU_CLR_ATOMIC(cpuid, &pmap->pm_save); - smp_invltlb(pmap); + mask = &all_cpus; } else { - other_cpus = all_cpus; - CPU_CLR(cpuid, &other_cpus); - - /* - * This logic is duplicated in the Xinvltlb shootdown - * IPI handler. - */ - if (pmap_pcid_enabled) { - if (pmap->pm_pcid != -1 && pmap->pm_pcid != 0) { + cpuid = PCPU_GET(cpuid); + if (pmap == PCPU_GET(curpmap)) { + if (pmap_pcid_enabled) { if (invpcid_works) { - d.pcid = pmap->pm_pcid; + d.pcid = pmap->pm_pcids[cpuid].pm_pcid; d.pad = 0; d.addr = 0; invpcid(&d, INVPCID_CTX); } else { - cr3 = rcr3(); - critical_enter(); - - /* - * Bit 63 is clear, pcid TLB - * entries are invalidated. - */ - load_cr3(pmap->pm_cr3); - load_cr3(cr3 | CR3_PCID_SAVE); - critical_exit(); + load_cr3(pmap->pm_cr3 | pmap->pm_pcids + [PCPU_GET(cpuid)].pm_pcid); } } else { - invltlb_globpcid(); + invltlb(); } - } else if (CPU_ISSET(cpuid, &pmap->pm_active)) - invltlb(); - if (!CPU_ISSET(cpuid, &pmap->pm_active)) - CPU_CLR_ATOMIC(cpuid, &pmap->pm_save); - if (pmap_pcid_enabled) - CPU_AND(&other_cpus, &pmap->pm_save); - else - CPU_AND(&other_cpus, &pmap->pm_active); - if (!CPU_EMPTY(&other_cpus)) - smp_masked_invltlb(other_cpus, pmap); + } else if (pmap_pcid_enabled) { + pmap->pm_pcids[cpuid].pm_gen = 0; + } + if (pmap_pcid_enabled) { + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + } + mask = &pmap->pm_active; } + smp_masked_invltlb(*mask, pmap); sched_unpin(); } @@ -1627,7 +1537,6 @@ pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) active = all_cpus; else { active = pmap->pm_active; - CPU_AND_ATOMIC(&pmap->pm_save, &active); } if (CPU_OVERLAP(&active, &other_cpus)) { act.store = cpuid; @@ -2205,11 +2114,9 @@ pmap_pinit0(pmap_t pmap) pmap->pm_cr3 = KPML4phys; pmap->pm_root.rt_root = 0; CPU_ZERO(&pmap->pm_active); - CPU_ZERO(&pmap->pm_save); PCPU_SET(curpmap, pmap); TAILQ_INIT(&pmap->pm_pvchunk); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); - pmap->pm_pcid = pmap_pcid_enabled ? 0 : -1; pmap->pm_flags = pmap_flags; } @@ -2233,7 +2140,10 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags) pml4phys = VM_PAGE_TO_PHYS(pml4pg); pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(pml4phys); - pmap->pm_pcid = -1; + CPU_FOREACH(i) { + pmap->pm_pcids[i].pm_pcid = PMAP_PCID_NONE; + pmap->pm_pcids[i].pm_gen = 0; + } pmap->pm_cr3 = ~0; /* initialize to an invalid value */ if ((pml4pg->flags & PG_ZERO) == 0) @@ -2260,12 +2170,6 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags) /* install self-referential address mapping entry(s) */ pmap->pm_pml4[PML4PML4I] = VM_PAGE_TO_PHYS(pml4pg) | X86_PG_V | X86_PG_RW | X86_PG_A | X86_PG_M; - - if (pmap_pcid_enabled) { - pmap->pm_pcid = alloc_unr(&pcid_unr); - if (pmap->pm_pcid != -1) - pmap->pm_cr3 |= pmap->pm_pcid; - } } pmap->pm_root.rt_root = 0; @@ -2274,7 +2178,6 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags) bzero(&pmap->pm_stats, sizeof pmap->pm_stats); pmap->pm_flags = flags; pmap->pm_eptgen = 0; - CPU_ZERO(&pmap->pm_save); return (1); } @@ -2535,14 +2438,6 @@ pmap_release(pmap_t pmap) KASSERT(CPU_EMPTY(&pmap->pm_active), ("releasing active pmap %p", pmap)); - if (pmap_pcid_enabled) { - /* - * Invalidate any left TLB entries, to allow the reuse - * of the pcid. - */ - pmap_invalidate_all(pmap); - } - m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4)); for (i = 0; i < NKPML4E; i++) /* KVA */ @@ -2554,8 +2449,6 @@ pmap_release(pmap_t pmap) m->wire_count--; atomic_subtract_int(&vm_cnt.v_wire_count, 1); vm_page_free_zero(m); - if (pmap->pm_pcid != -1) - free_unr(&pcid_unr, pmap->pm_pcid); } static int @@ -6657,28 +6550,84 @@ retry: return (val); } +static uint64_t +pmap_pcid_alloc(pmap_t pmap, u_int cpuid) +{ + uint32_t gen, new_gen, pcid_next; + + CRITICAL_ASSERT(curthread); + gen = PCPU_GET(pcid_gen); + if (pmap->pm_pcids[cpuid].pm_pcid == PMAP_PCID_KERN || + pmap->pm_pcids[cpuid].pm_gen == gen) + return (CR3_PCID_SAVE); + pcid_next = PCPU_GET(pcid_next); + KASSERT(pcid_next <= PMAP_PCID_OVERMAX, ("cpu %d pcid_next %#x", + cpuid, pcid_next)); + if (pcid_next == PMAP_PCID_OVERMAX) { + new_gen = gen + 1; + if (new_gen == 0) + new_gen = 1; + PCPU_SET(pcid_gen, new_gen); + pcid_next = PMAP_PCID_KERN + 1; + } else { + new_gen = gen; + } + pmap->pm_pcids[cpuid].pm_pcid = pcid_next; + pmap->pm_pcids[cpuid].pm_gen = new_gen; + PCPU_SET(pcid_next, pcid_next + 1); + return (0); +} + void -pmap_activate(struct thread *td) +pmap_activate_sw(struct thread *td) { - pmap_t pmap, oldpmap; - u_int cpuid; + pmap_t oldpmap, pmap; + uint64_t cached, cr3; + u_int cpuid; - critical_enter(); - pmap = vmspace_pmap(td->td_proc->p_vmspace); oldpmap = PCPU_GET(curpmap); + pmap = vmspace_pmap(td->td_proc->p_vmspace); + if (oldpmap == pmap) + return; cpuid = PCPU_GET(cpuid); #ifdef SMP - CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active); CPU_SET_ATOMIC(cpuid, &pmap->pm_active); - CPU_SET_ATOMIC(cpuid, &pmap->pm_save); #else - CPU_CLR(cpuid, &oldpmap->pm_active); CPU_SET(cpuid, &pmap->pm_active); - CPU_SET(cpuid, &pmap->pm_save); #endif - td->td_pcb->pcb_cr3 = pmap->pm_cr3; - load_cr3(pmap->pm_cr3); + cr3 = rcr3(); + if (pmap_pcid_enabled) { + cached = pmap_pcid_alloc(pmap, cpuid); + KASSERT(pmap->pm_pcids[cpuid].pm_pcid >= 0 && + pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX, + ("pmap %p cpu %d pcid %#x", pmap, cpuid, + pmap->pm_pcids[cpuid].pm_pcid)); + KASSERT(pmap != PMAP_PCID_KERN || pmap == kernel_pmap, + ("non-kernel pmap %p cpu %d pcid %#x", pmap, cpuid, + pmap->pm_pcids[cpuid].pm_pcid)); + if (!cached || (cr3 & ~CR3_PCID_MASK) != pmap->pm_cr3) { + load_cr3(pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid | + cached); + if (cached) + PCPU_INC(pm_save_cnt); + } + } else if (cr3 != pmap->pm_cr3) { + load_cr3(pmap->pm_cr3); + } PCPU_SET(curpmap, pmap); +#ifdef SMP + CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active); +#else + CPU_CLR(cpuid, &oldpmap->pm_active); +#endif +} + +void +pmap_activate(struct thread *td) +{ + + critical_enter(); + pmap_activate_sw(td); critical_exit(); } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index 26ac7ab..0d03ed6 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -219,7 +219,6 @@ cpu_fork(td1, p2, td2, flags) * return address on stack. These are the kernel mode register values. */ pmap2 = vmspace_pmap(p2->p_vmspace); - pcb2->pcb_cr3 = pmap2->pm_cr3; pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */ pcb2->pcb_rbp = 0; pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *); @@ -477,7 +476,6 @@ cpu_set_upcall(struct thread *td, struct thread *td0) pcb2->pcb_rip = (register_t)fork_trampoline; /* * If we didn't copy the pcb, we'd need to do the following registers: - * pcb2->pcb_cr3: cloned above. * pcb2->pcb_dr*: cloned above. * pcb2->pcb_savefpu: cloned above. * pcb2->pcb_onfault: cloned above (always NULL here?). diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 7ea4bcf..c0c5b0a 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -540,9 +540,8 @@ static __inline void invpcid(struct invpcid_descr *d, int type) { - /* invpcid (%rdx),%rax */ - __asm __volatile(".byte 0x66,0x0f,0x38,0x82,0x02" - : : "d" (d), "a" ((u_long)type) : "memory"); + __asm __volatile("invpcid (%0),%1" + : : "r" (d), "r" ((u_long)type) : "memory"); } static __inline u_short diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index 9083421..0813e5f 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -91,6 +91,7 @@ struct dumperinfo; void *alloc_fpusave(int flags); void amd64_syscall(struct thread *td, int traced); void busdma_swi(void); +bool cpu_mwait_usable(void); void cpu_probe_amdc1e(void); void cpu_setregs(void); void doreti_iret(void) __asm(__STRING(doreti_iret)); diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h index fe898e9..91e8fb2 100644 --- a/sys/amd64/include/pcpu.h +++ b/sys/amd64/include/pcpu.h @@ -63,7 +63,9 @@ uint64_t pc_dbreg[16]; /* ddb debugging regs */ \ int pc_dbreg_cmd; /* ddb debugging reg cmd */ \ u_int pc_vcpu_id; /* Xen vCPU ID */ \ - char __pad[157] /* be divisor of PAGE_SIZE \ + uint32_t pc_pcid_next; \ + uint32_t pc_pcid_gen; \ + char __pad[149] /* be divisor of PAGE_SIZE \ after cache alignment */ #define PC_DBREG_CMD_NONE 0 diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 868db7d..39df87a 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -219,6 +219,10 @@ #define ISA_HOLE_START 0xa0000 #define ISA_HOLE_LENGTH (0x100000-ISA_HOLE_START) +#define PMAP_PCID_NONE 0xffffffff +#define PMAP_PCID_KERN 0 +#define PMAP_PCID_OVERMAX 0x1000 + #ifndef LOCORE #include <sys/queue.h> @@ -292,6 +296,11 @@ enum pmap_type { PT_RVI, /* AMD's nested page tables */ }; +struct pmap_pcids { + uint32_t pm_pcid; + uint32_t pm_gen; +}; + /* * The kernel virtual address (KVA) of the level 4 page table page is always * within the direct map (DMAP) region. @@ -302,13 +311,12 @@ struct pmap { uint64_t pm_cr3; TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */ cpuset_t pm_active; /* active on cpus */ - cpuset_t pm_save; /* Context valid on cpus mask */ - int pm_pcid; /* context id */ enum pmap_type pm_type; /* regular or nested tables */ struct pmap_statistics pm_stats; /* pmap statistics */ struct vm_radix pm_root; /* spare page table pages */ long pm_eptgen; /* EPT pmap generation id */ int pm_flags; + struct pmap_pcids pm_pcids[MAXCPU]; }; /* flags */ @@ -375,6 +383,9 @@ extern vm_paddr_t dmaplimit; #define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0) #define pmap_unmapbios(va, sz) pmap_unmapdev((va), (sz)) +struct thread; + +void pmap_activate_sw(struct thread *); void pmap_bootstrap(vm_paddr_t *); int pmap_change_attr(vm_offset_t, vm_size_t, int); void pmap_demote_DMAP(vm_paddr_t base, vm_size_t len, boolean_t invalidate); diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 034a693..4fd6aac 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -46,6 +46,7 @@ extern struct mtx ap_boot_mtx; extern int cpu_logical; extern int cpu_cores; extern int pmap_pcid_enabled; +extern int invpcid_works; extern u_int xhits_gbl[]; extern u_int xhits_pg[]; extern u_int xhits_rng[]; @@ -53,10 +54,6 @@ extern u_int ipi_global; extern u_int ipi_page; extern u_int ipi_range; extern u_int ipi_range_size; -extern u_int ipi_masked_global; -extern u_int ipi_masked_page; -extern u_int ipi_masked_range; -extern u_int ipi_masked_range_size; extern volatile int smp_tlb_wait; @@ -78,9 +75,9 @@ extern u_long *ipi_rendezvous_counts[MAXCPU]; /* IPI handlers */ inthand_t - IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid enabled */ IDTVEC(invltlb), /* TLB shootdowns - global */ - IDTVEC(invlpg_pcid), /* TLB shootdowns - 1 page, pcid enabled */ + IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid */ + IDTVEC(invltlb_invpcid),/* TLB shootdowns - global, invpcid */ IDTVEC(invlpg), /* TLB shootdowns - 1 page */ IDTVEC(invlrng), /* TLB shootdowns - page range */ IDTVEC(invlcache), /* Write back and invalidate cache */ @@ -100,8 +97,8 @@ void cpususpend_handler(void); void init_secondary_tail(void); void invltlb_handler(void); void invltlb_pcid_handler(void); +void invltlb_invpcid_handler(void); void invlpg_handler(void); -void invlpg_pcid_handler(void); void invlrng_handler(void); void invlcache_handler(void); void init_secondary(void); @@ -114,13 +111,9 @@ void ipi_selected(cpuset_t cpus, u_int ipi); u_int mp_bootaddress(u_int); void set_interrupt_apic_ids(void); void smp_cache_flush(void); -void smp_invlpg(struct pmap *pmap, vm_offset_t addr); -void smp_masked_invlpg(cpuset_t mask, struct pmap *pmap, vm_offset_t addr); -void smp_invlpg_range(struct pmap *pmap, vm_offset_t startva, +void smp_masked_invlpg(cpuset_t mask, vm_offset_t addr); +void smp_masked_invlpg_range(cpuset_t mask, vm_offset_t startva, vm_offset_t endva); -void smp_masked_invlpg_range(cpuset_t mask, struct pmap *pmap, - vm_offset_t startva, vm_offset_t endva); -void smp_invltlb(struct pmap *pmap); void smp_masked_invltlb(cpuset_t mask, struct pmap *pmap); int native_start_all_aps(void); void mem_range_AP_init(void); diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 7c617be..d3798bc 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -276,7 +276,13 @@ vcpu_is_running(struct vm *vm, int vcpu, int *hostcpu) static int __inline vcpu_should_yield(struct vm *vm, int vcpu) { - return (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)); + + if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) + return (1); + else if (curthread->td_owepreempt) + return (1); + else + return (0); } #endif @@ -345,9 +351,10 @@ struct vm_copyinfo { * at 'gla' and 'len' bytes long. The 'prot' should be set to PROT_READ for * a copyin or PROT_WRITE for a copyout. * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. + * retval is_fault Intepretation + * 0 0 Success + * 0 1 An exception was injected into the guest + * EFAULT N/A Unrecoverable error * * The 'copyinfo[]' can be passed to 'vm_copyin()' or 'vm_copyout()' only if * the return value is 0. The 'copyinfo[]' resources should be freed by calling @@ -355,7 +362,7 @@ struct vm_copyinfo { */ int vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo, - int num_copyinfo); + int num_copyinfo, int *is_fault); void vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, int num_copyinfo); void vm_copyin(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, diff --git a/sys/amd64/include/vmm_instruction_emul.h b/sys/amd64/include/vmm_instruction_emul.h index 651b3b3..5e7127f 100644 --- a/sys/amd64/include/vmm_instruction_emul.h +++ b/sys/amd64/include/vmm_instruction_emul.h @@ -81,17 +81,19 @@ int vie_calculate_gla(enum vm_cpu_mode cpu_mode, enum vm_reg_name seg, */ int vmm_fetch_instruction(struct vm *vm, int cpuid, struct vm_guest_paging *guest_paging, - uint64_t rip, int inst_length, struct vie *vie); + uint64_t rip, int inst_length, struct vie *vie, + int *is_fault); /* * Translate the guest linear address 'gla' to a guest physical address. * - * Returns 0 on success and '*gpa' contains the result of the translation. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. + * retval is_fault Interpretation + * 0 0 'gpa' contains result of the translation + * 0 1 An exception was injected into the guest + * EFAULT N/A An unrecoverable hypervisor error occurred */ int vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, - uint64_t gla, int prot, uint64_t *gpa); + uint64_t gla, int prot, uint64_t *gpa, int *is_fault); void vie_init(struct vie *vie, const char *inst_bytes, int inst_length); diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index bca9b98..51c63f5 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1256,7 +1256,7 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu) mem_region_read_t mread; mem_region_write_t mwrite; enum vm_cpu_mode cpu_mode; - int cs_d, error, length; + int cs_d, error, fault, length; vcpu = &vm->vcpu[vcpuid]; vme = &vcpu->exitinfo; @@ -1279,19 +1279,15 @@ vm_handle_inst_emul(struct vm *vm, int vcpuid, bool *retu) */ length = vme->inst_length ? vme->inst_length : VIE_INST_SIZE; error = vmm_fetch_instruction(vm, vcpuid, paging, vme->rip + - cs_base, length, vie); + cs_base, length, vie, &fault); } else { /* * The instruction bytes have already been copied into 'vie' */ - error = 0; + error = fault = 0; } - if (error == 1) - return (0); /* Resume guest to handle page fault */ - else if (error == -1) - return (EFAULT); - else if (error != 0) - panic("%s: vmm_fetch_instruction error %d", __func__, error); + if (error || fault) + return (error); if (vmm_decode_instruction(vm, vcpuid, gla, cpu_mode, cs_d, vie) != 0) { VCPU_CTR1(vm, vcpuid, "Error decoding instruction at %#lx", @@ -2323,7 +2319,7 @@ vm_copy_teardown(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, int vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, uint64_t gla, size_t len, int prot, struct vm_copyinfo *copyinfo, - int num_copyinfo) + int num_copyinfo, int *fault) { int error, idx, nused; size_t n, off, remaining; @@ -2336,8 +2332,8 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, remaining = len; while (remaining > 0) { KASSERT(nused < num_copyinfo, ("insufficient vm_copyinfo")); - error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa); - if (error) + error = vm_gla2gpa(vm, vcpuid, paging, gla, prot, &gpa, fault); + if (error || *fault) return (error); off = gpa & PAGE_MASK; n = min(remaining, PAGE_SIZE - off); @@ -2359,8 +2355,9 @@ vm_copy_setup(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, if (idx != nused) { vm_copy_teardown(vm, vcpuid, copyinfo, num_copyinfo); - return (-1); + return (EFAULT); } else { + *fault = 0; return (0); } } diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index 5be99cb..e3e140a 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -441,19 +441,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, CTASSERT(PROT_EXEC == VM_PROT_EXECUTE); gg = (struct vm_gla2gpa *)data; error = vm_gla2gpa(sc->vm, gg->vcpuid, &gg->paging, gg->gla, - gg->prot, &gg->gpa); - KASSERT(error == 0 || error == 1 || error == -1, + gg->prot, &gg->gpa, &gg->fault); + KASSERT(error == 0 || error == EFAULT, ("%s: vm_gla2gpa unknown error %d", __func__, error)); - if (error >= 0) { - /* - * error = 0: the translation was successful - * error = 1: a fault was injected into the guest - */ - gg->fault = error; - error = 0; - } else { - error = EFAULT; - } break; } case VM_ACTIVATE_CPU: diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c index c83f3e0..9c6158a 100644 --- a/sys/amd64/vmm/vmm_instruction_emul.c +++ b/sys/amd64/vmm/vmm_instruction_emul.c @@ -597,13 +597,11 @@ emulate_movx(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, /* * Helper function to calculate and validate a linear address. - * - * Returns 0 on success and 1 if an exception was injected into the guest. */ static int get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging, int opsize, int addrsize, int prot, enum vm_reg_name seg, - enum vm_reg_name gpr, uint64_t *gla) + enum vm_reg_name gpr, uint64_t *gla, int *fault) { struct seg_desc desc; uint64_t cr0, val, rflags; @@ -629,7 +627,7 @@ get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging, vm_inject_ss(vm, vcpuid, 0); else vm_inject_gp(vm, vcpuid); - return (1); + goto guest_fault; } if (vie_canonical_check(paging->cpu_mode, *gla)) { @@ -637,14 +635,19 @@ get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging, vm_inject_ss(vm, vcpuid, 0); else vm_inject_gp(vm, vcpuid); - return (1); + goto guest_fault; } if (vie_alignment_check(paging->cpl, opsize, cr0, rflags, *gla)) { vm_inject_ac(vm, vcpuid, 0); - return (1); + goto guest_fault; } + *fault = 0; + return (0); + +guest_fault: + *fault = 1; return (0); } @@ -660,7 +663,7 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, #endif uint64_t dstaddr, srcaddr, dstgpa, srcgpa, val; uint64_t rcx, rdi, rsi, rflags; - int error, opsize, seg, repeat; + int error, fault, opsize, seg, repeat; opsize = (vie->op.op_byte == 0xA4) ? 1 : vie->opsize; val = 0; @@ -683,8 +686,10 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, * The count register is %rcx, %ecx or %cx depending on the * address size of the instruction. */ - if ((rcx & vie_size2mask(vie->addrsize)) == 0) - return (0); + if ((rcx & vie_size2mask(vie->addrsize)) == 0) { + error = 0; + goto done; + } } /* @@ -705,13 +710,16 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, seg = vie->segment_override ? vie->segment_register : VM_REG_GUEST_DS; error = get_gla(vm, vcpuid, vie, paging, opsize, vie->addrsize, - PROT_READ, seg, VM_REG_GUEST_RSI, &srcaddr); - if (error) + PROT_READ, seg, VM_REG_GUEST_RSI, &srcaddr, &fault); + if (error || fault) goto done; error = vm_copy_setup(vm, vcpuid, paging, srcaddr, opsize, PROT_READ, - copyinfo, nitems(copyinfo)); + copyinfo, nitems(copyinfo), &fault); if (error == 0) { + if (fault) + goto done; /* Resume guest to handle fault */ + /* * case (2): read from system memory and write to mmio. */ @@ -720,11 +728,6 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, error = memwrite(vm, vcpuid, gpa, val, opsize, arg); if (error) goto done; - } else if (error > 0) { - /* - * Resume guest execution to handle fault. - */ - goto done; } else { /* * 'vm_copy_setup()' is expected to fail for cases (3) and (4) @@ -732,13 +735,17 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, */ error = get_gla(vm, vcpuid, vie, paging, opsize, vie->addrsize, - PROT_WRITE, VM_REG_GUEST_ES, VM_REG_GUEST_RDI, &dstaddr); - if (error) + PROT_WRITE, VM_REG_GUEST_ES, VM_REG_GUEST_RDI, &dstaddr, + &fault); + if (error || fault) goto done; error = vm_copy_setup(vm, vcpuid, paging, dstaddr, opsize, - PROT_WRITE, copyinfo, nitems(copyinfo)); + PROT_WRITE, copyinfo, nitems(copyinfo), &fault); if (error == 0) { + if (fault) + goto done; /* Resume guest to handle fault */ + /* * case (3): read from MMIO and write to system memory. * @@ -754,27 +761,29 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, vm_copyout(vm, vcpuid, &val, copyinfo, opsize); vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo)); - } else if (error > 0) { - /* - * Resume guest execution to handle fault. - */ - goto done; } else { /* * Case (4): read from and write to mmio. + * + * Commit to the MMIO read/write (with potential + * side-effects) only after we are sure that the + * instruction is not going to be restarted due + * to address translation faults. */ error = vm_gla2gpa(vm, vcpuid, paging, srcaddr, - PROT_READ, &srcgpa); - if (error) - goto done; - error = memread(vm, vcpuid, srcgpa, &val, opsize, arg); - if (error) + PROT_READ, &srcgpa, &fault); + if (error || fault) goto done; error = vm_gla2gpa(vm, vcpuid, paging, dstaddr, - PROT_WRITE, &dstgpa); + PROT_WRITE, &dstgpa, &fault); + if (error || fault) + goto done; + + error = memread(vm, vcpuid, srcgpa, &val, opsize, arg); if (error) goto done; + error = memwrite(vm, vcpuid, dstgpa, val, opsize, arg); if (error) goto done; @@ -819,10 +828,9 @@ emulate_movs(void *vm, int vcpuid, uint64_t gpa, struct vie *vie, vm_restart_instruction(vm, vcpuid); } done: - if (error < 0) - return (EFAULT); - else - return (0); + KASSERT(error == 0 || error == EFAULT, ("%s: unexpected error %d", + __func__, error)); + return (error); } static int @@ -1185,7 +1193,7 @@ emulate_stack_op(void *vm, int vcpuid, uint64_t mmio_gpa, struct vie *vie, #endif struct seg_desc ss_desc; uint64_t cr0, rflags, rsp, stack_gla, val; - int error, size, stackaddrsize, pushop; + int error, fault, size, stackaddrsize, pushop; val = 0; size = vie->opsize; @@ -1251,18 +1259,10 @@ emulate_stack_op(void *vm, int vcpuid, uint64_t mmio_gpa, struct vie *vie, } error = vm_copy_setup(vm, vcpuid, paging, stack_gla, size, - pushop ? PROT_WRITE : PROT_READ, copyinfo, nitems(copyinfo)); - if (error == -1) { - /* - * XXX cannot return a negative error value here because it - * ends up being the return value of the VM_RUN() ioctl and - * is interpreted as a pseudo-error (for e.g. ERESTART). - */ - return (EFAULT); - } else if (error == 1) { - /* Resume guest execution to handle page fault */ - return (0); - } + pushop ? PROT_WRITE : PROT_READ, copyinfo, nitems(copyinfo), + &fault); + if (error || fault) + return (error); if (pushop) { error = memread(vm, vcpuid, mmio_gpa, &val, size, arg); @@ -1672,7 +1672,7 @@ ptp_hold(struct vm *vm, vm_paddr_t ptpphys, size_t len, void **cookie) int vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, - uint64_t gla, int prot, uint64_t *gpa) + uint64_t gla, int prot, uint64_t *gpa, int *guest_fault) { int nlevels, pfcode, ptpshift, ptpindex, retval, usermode, writable; u_int retries; @@ -1680,6 +1680,8 @@ vm_gla2gpa(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, uint32_t *ptpbase32, pte32; void *cookie; + *guest_fault = 0; + usermode = (paging->cpl == 3 ? 1 : 0); writable = prot & VM_PROT_WRITE; cookie = NULL; @@ -1842,18 +1844,20 @@ restart: *gpa = pte | (gla & (pgsize - 1)); done: ptp_release(&cookie); + KASSERT(retval == 0 || retval == EFAULT, ("%s: unexpected retval %d", + __func__, retval)); return (retval); error: - retval = -1; + retval = EFAULT; goto done; fault: - retval = 1; + *guest_fault = 1; goto done; } int vmm_fetch_instruction(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, - uint64_t rip, int inst_length, struct vie *vie) + uint64_t rip, int inst_length, struct vie *vie, int *faultptr) { struct vm_copyinfo copyinfo[2]; int error, prot; @@ -1863,13 +1867,14 @@ vmm_fetch_instruction(struct vm *vm, int vcpuid, struct vm_guest_paging *paging, prot = PROT_READ | PROT_EXEC; error = vm_copy_setup(vm, vcpuid, paging, rip, inst_length, prot, - copyinfo, nitems(copyinfo)); - if (error == 0) { - vm_copyin(vm, vcpuid, copyinfo, vie->inst, inst_length); - vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo)); - vie->num_valid = inst_length; - } - return (error); + copyinfo, nitems(copyinfo), faultptr); + if (error || *faultptr) + return (error); + + vm_copyin(vm, vcpuid, copyinfo, vie->inst, inst_length); + vm_copy_teardown(vm, vcpuid, copyinfo, nitems(copyinfo)); + vie->num_valid = inst_length; + return (0); } static int diff --git a/sys/arm/amlogic/aml8726/aml8726_pic.c b/sys/arm/amlogic/aml8726/aml8726_pic.c index 5ef1403..565d157 100644 --- a/sys/arm/amlogic/aml8726/aml8726_pic.c +++ b/sys/arm/amlogic/aml8726/aml8726_pic.c @@ -121,6 +121,8 @@ aml8726_pic_eoi(void *arg) if (nb >= AML_PIC_NIRQS) return; + arm_irq_memory_barrier(nb); + CSR_WRITE_4(aml8726_pic_sc, AML_PIC_STAT_CLR_REG(nb), AML_PIC_BIT(nb)); CSR_BARRIER(aml8726_pic_sc, AML_PIC_STAT_CLR_REG(nb)); @@ -265,8 +267,12 @@ arm_unmask_irq(uintptr_t nb) if (nb >= AML_PIC_NIRQS) return; + arm_irq_memory_barrier(nb); + mask = CSR_READ_4(aml8726_pic_sc, AML_PIC_MASK_REG(nb)); mask |= AML_PIC_BIT(nb); CSR_WRITE_4(aml8726_pic_sc, AML_PIC_MASK_REG(nb), mask); + + CSR_BARRIER(aml8726_pic_sc, AML_PIC_MASK_REG(nb)); } #endif diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index a76e18a4..3ef156b 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -114,7 +114,57 @@ __FBSDID("$FreeBSD$"); #ifdef DDB #include <ddb/ddb.h> -#endif + +#if __ARM_ARCH >= 6 +#include <machine/cpu-v6.h> + +DB_SHOW_COMMAND(cp15, db_show_cp15) +{ + u_int reg; + + reg = cp15_midr_get(); + db_printf("Cpu ID: 0x%08x\n", reg); + reg = cp15_ctr_get(); + db_printf("Current Cache Lvl ID: 0x%08x\n",reg); + + reg = cp15_sctlr_get(); + db_printf("Ctrl: 0x%08x\n",reg); + reg = cp15_actlr_get(); + db_printf("Aux Ctrl: 0x%08x\n",reg); + + reg = cp15_id_pfr0_get(); + db_printf("Processor Feat 0: 0x%08x\n", reg); + reg = cp15_id_pfr1_get(); + db_printf("Processor Feat 1: 0x%08x\n", reg); + reg = cp15_id_dfr0_get(); + db_printf("Debug Feat 0: 0x%08x\n", reg); + reg = cp15_id_afr0_get(); + db_printf("Auxiliary Feat 0: 0x%08x\n", reg); + reg = cp15_id_mmfr0_get(); + db_printf("Memory Model Feat 0: 0x%08x\n", reg); + reg = cp15_id_mmfr1_get(); + db_printf("Memory Model Feat 1: 0x%08x\n", reg); + reg = cp15_id_mmfr2_get(); + db_printf("Memory Model Feat 2: 0x%08x\n", reg); + reg = cp15_id_mmfr3_get(); + db_printf("Memory Model Feat 3: 0x%08x\n", reg); + reg = cp15_ttbr_get(); + db_printf("TTB0: 0x%08x\n", reg); +} + +DB_SHOW_COMMAND(vtop, db_show_vtop) +{ + u_int reg; + + if (have_addr) { + cp15_ats1cpr_set(addr); + reg = cp15_par_get(); + db_printf("Physical address reg: 0x%08x\n",reg); + } else + db_printf("show vtop <virt_addr>\n"); +} +#endif /* __ARM_ARCH >= 6 */ +#endif /* DDB */ #ifdef DEBUG #define debugf(fmt, args...) printf(fmt, ##args) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c index ab0f901..1466313 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c @@ -1425,7 +1425,10 @@ static int bcm2835_cpufreq_probe(device_t dev) { + if (device_get_unit(dev) != 0) + return (ENXIO); device_set_desc(dev, "CPU Frequency Control"); + return (0); } diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c index 3e89eae..58ad8e4 100644 --- a/sys/arm/broadcom/bcm2835/bcm2836.c +++ b/sys/arm/broadcom/bcm2835/bcm2836.c @@ -52,7 +52,9 @@ __FBSDID("$FreeBSD$"); #define ARM_LOCAL_INT_TIMER(n) (0x40 + (n) * 4) #define ARM_LOCAL_INT_MAILBOX(n) (0x50 + (n) * 4) #define ARM_LOCAL_INT_PENDING(n) (0x60 + (n) * 4) -#define INT_PENDING_MASK 0x0f +#define INT_PENDING_MASK 0x01f +#define MAILBOX0_IRQ 4 +#define MAILBOX0_IRQEN (1 << 0) /* * A driver for features of the bcm2836. @@ -141,12 +143,27 @@ void bcm2836_mask_irq(uintptr_t irq) { uint32_t reg; +#ifdef SMP + int cpu; +#endif int i; - for (i = 0; i < 4; i++) { - reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i)); - reg &= ~(1 << irq); - bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg); + if (irq < MAILBOX0_IRQ) { + for (i = 0; i < 4; i++) { + reg = bus_read_4(softc->sc_mem, + ARM_LOCAL_INT_TIMER(i)); + reg &= ~(1 << irq); + bus_write_4(softc->sc_mem, + ARM_LOCAL_INT_TIMER(i), reg); + } +#ifdef SMP + } else if (irq == MAILBOX0_IRQ) { + /* Mailbox 0 for IPI */ + cpu = PCPU_GET(cpuid); + reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu)); + reg &= ~MAILBOX0_IRQEN; + bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg); +#endif } } @@ -154,12 +171,27 @@ void bcm2836_unmask_irq(uintptr_t irq) { uint32_t reg; +#ifdef SMP + int cpu; +#endif int i; - for (i = 0; i < 4; i++) { - reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i)); - reg |= (1 << irq); - bus_write_4(softc->sc_mem, ARM_LOCAL_INT_TIMER(i), reg); + if (irq < MAILBOX0_IRQ) { + for (i = 0; i < 4; i++) { + reg = bus_read_4(softc->sc_mem, + ARM_LOCAL_INT_TIMER(i)); + reg |= (1 << irq); + bus_write_4(softc->sc_mem, + ARM_LOCAL_INT_TIMER(i), reg); + } +#ifdef SMP + } else if (irq == MAILBOX0_IRQ) { + /* Mailbox 0 for IPI */ + cpu = PCPU_GET(cpuid); + reg = bus_read_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu)); + reg |= MAILBOX0_IRQEN; + bus_write_4(softc->sc_mem, ARM_LOCAL_INT_MAILBOX(cpu), reg); +#endif } } diff --git a/sys/arm/broadcom/bcm2835/bcm2836_mp.c b/sys/arm/broadcom/bcm2835/bcm2836_mp.c new file mode 100644 index 0000000..177f41e --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2836_mp.c @@ -0,0 +1,207 @@ +/*- + * Copyright (C) 2015 Daisuke Aoyama <aoyama@peach.ne.jp> + * 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 + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/smp.h> + +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <machine/smp.h> +#include <machine/bus.h> +#include <machine/fdt.h> +#include <machine/intr.h> + +#ifdef DEBUG +#define DPRINTF(fmt, ...) do { \ + printf("%s:%u: ", __func__, __LINE__); \ + printf(fmt, ##__VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define ARM_LOCAL_BASE 0x40000000 +#define ARM_LOCAL_SIZE 0x00001000 + +/* mailbox registers */ +#define MBOXINTRCTRL_CORE(n) (0x00000050 + (0x04 * (n))) +#define MBOX0SET_CORE(n) (0x00000080 + (0x10 * (n))) +#define MBOX1SET_CORE(n) (0x00000084 + (0x10 * (n))) +#define MBOX2SET_CORE(n) (0x00000088 + (0x10 * (n))) +#define MBOX3SET_CORE(n) (0x0000008C + (0x10 * (n))) +#define MBOX0CLR_CORE(n) (0x000000C0 + (0x10 * (n))) +#define MBOX1CLR_CORE(n) (0x000000C4 + (0x10 * (n))) +#define MBOX2CLR_CORE(n) (0x000000C8 + (0x10 * (n))) +#define MBOX3CLR_CORE(n) (0x000000CC + (0x10 * (n))) + +static bus_space_handle_t bs_periph; + +#define BSRD4(addr) \ + bus_space_read_4(fdtbus_bs_tag, bs_periph, (addr)) +#define BSWR4(addr, val) \ + bus_space_write_4(fdtbus_bs_tag, bs_periph, (addr), (val)) + +void +platform_mp_init_secondary(void) +{ + +} + +void +platform_mp_setmaxid(void) +{ + + DPRINTF("platform_mp_setmaxid\n"); + if (mp_ncpus != 0) + return; + + mp_ncpus = 4; + mp_maxid = mp_ncpus - 1; + DPRINTF("mp_maxid=%d\n", mp_maxid); +} + +int +platform_mp_probe(void) +{ + + DPRINTF("platform_mp_probe\n"); + CPU_SETOF(0, &all_cpus); + if (mp_ncpus == 0) + platform_mp_setmaxid(); + return (mp_ncpus > 1); +} + +void +platform_mp_start_ap(void) +{ + uint32_t val; + int i, retry; + + DPRINTF("platform_mp_start_ap\n"); + + /* initialize */ + if (bus_space_map(fdtbus_bs_tag, ARM_LOCAL_BASE, ARM_LOCAL_SIZE, + 0, &bs_periph) != 0) + panic("can't map local peripheral\n"); + for (i = 0; i < mp_ncpus; i++) { + /* clear mailbox 0/3 */ + BSWR4(MBOX0CLR_CORE(i), 0xffffffff); + BSWR4(MBOX3CLR_CORE(i), 0xffffffff); + } + wmb(); + + /* boot secondary CPUs */ + for (i = 1; i < mp_ncpus; i++) { + /* set entry point to mailbox 3 */ + BSWR4(MBOX3SET_CORE(i), + (uint32_t)pmap_kextract((vm_offset_t)mpentry)); + wmb(); + + /* wait for bootup */ + retry = 1000; + do { + /* check entry point */ + val = BSRD4(MBOX3CLR_CORE(i)); + if (val == 0) + break; + DELAY(100); + retry--; + if (retry <= 0) { + printf("can't start for CPU%d\n", i); + break; + } + } while (1); + + /* dsb and sev */ + armv7_sev(); + + /* recode AP in CPU map */ + CPU_SET(i, &all_cpus); + } + + cpu_idcache_wbinv_all(); + cpu_l2cache_wbinv_all(); +} + +void +pic_ipi_send(cpuset_t cpus, u_int ipi) +{ + int i; + + dsb(); + for (i = 0; i < mp_ncpus; i++) { + if (CPU_ISSET(i, &cpus)) + BSWR4(MBOX0SET_CORE(i), 1 << ipi); + } + wmb(); +} + +int +pic_ipi_read(int i) +{ + uint32_t val; + int cpu, ipi; + + cpu = PCPU_GET(cpuid); + dsb(); + if (i != -1) { + val = BSRD4(MBOX0CLR_CORE(cpu)); + if (val == 0) + return (0); + ipi = ffs(val) - 1; + return (ipi); + } + return (0x3ff); +} + +void +pic_ipi_clear(int ipi) +{ + int cpu; + + cpu = PCPU_GET(cpuid); + dsb(); + BSWR4(MBOX0CLR_CORE(cpu), 1 << ipi); + wmb(); +} + +void +platform_ipi_send(cpuset_t cpus, u_int ipi) +{ + + pic_ipi_send(cpus, ipi); +} diff --git a/sys/arm/broadcom/bcm2835/files.bcm2836 b/sys/arm/broadcom/bcm2835/files.bcm2836 index f797cf7..36f4d24 100644 --- a/sys/arm/broadcom/bcm2835/files.bcm2836 +++ b/sys/arm/broadcom/bcm2835/files.bcm2836 @@ -3,3 +3,4 @@ arm/arm/generic_timer.c standard arm/broadcom/bcm2835/bcm2836.c standard +arm/broadcom/bcm2835/bcm2836_mp.c optional smp diff --git a/sys/arm/broadcom/bcm2835/std.bcm2836 b/sys/arm/broadcom/bcm2835/std.bcm2836 index bb112be..862be75 100644 --- a/sys/arm/broadcom/bcm2835/std.bcm2836 +++ b/sys/arm/broadcom/bcm2835/std.bcm2836 @@ -6,6 +6,7 @@ makeoptions CONF_CFLAGS="-march=armv7a" options SOC_BCM2836 options ARM_L2_PIPT +options IPI_IRQ_START=76 files "../broadcom/bcm2835/files.bcm2836" files "../broadcom/bcm2835/files.bcm283x" diff --git a/sys/arm/conf/AML8726 b/sys/arm/conf/AML8726 index a6b4a8e..125a53d 100644 --- a/sys/arm/conf/AML8726 +++ b/sys/arm/conf/AML8726 @@ -20,7 +20,7 @@ ident AML8726 -include "std.armv6" +include "std.armv6" include "../amlogic/aml8726/std.aml8726" options HZ=100 diff --git a/sys/arm/conf/APALIS-IMX6 b/sys/arm/conf/APALIS-IMX6 index ceb21c7..ce8a0d5 100644 --- a/sys/arm/conf/APALIS-IMX6 +++ b/sys/arm/conf/APALIS-IMX6 @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "IMX6" +include "IMX6" ident APALIS-IMX6 makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP index ed4aa2d..6d51c16 100644 --- a/sys/arm/conf/ARMADAXP +++ b/sys/arm/conf/ARMADAXP @@ -20,8 +20,8 @@ ident MV-88F78XX0 -include "std.armv6" -include "../mv/armadaxp/std.mv78x60" +include "std.armv6" +include "../mv/armadaxp/std.mv78x60" options SOC_MV_ARMADAXP diff --git a/sys/arm/conf/ARNDALE b/sys/arm/conf/ARNDALE index 964f9e4..1c16d13 100644 --- a/sys/arm/conf/ARNDALE +++ b/sys/arm/conf/ARNDALE @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "EXYNOS5250" +include "EXYNOS5250" ident ARNDALE #FDT diff --git a/sys/arm/conf/ARNDALE-OCTA b/sys/arm/conf/ARNDALE-OCTA index ad937ee..a4faaa0 100644 --- a/sys/arm/conf/ARNDALE-OCTA +++ b/sys/arm/conf/ARNDALE-OCTA @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "EXYNOS5420" +include "EXYNOS5420" ident ARNDALE-OCTA #FDT diff --git a/sys/arm/conf/ATMEL b/sys/arm/conf/ATMEL index 2e8da7d..c3b6035 100644 --- a/sys/arm/conf/ATMEL +++ b/sys/arm/conf/ATMEL @@ -6,8 +6,8 @@ ident ATMEL -include "std.arm" -include "../at91/std.atmel" +include "std.arm" +include "../at91/std.atmel" # Typical values for most SoCs and board configurations. Will not work for # at91sam9g45 or on some boards with non u-boot boot loaders. diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA index b356b35..fd4d62a 100644 --- a/sys/arm/conf/AVILA +++ b/sys/arm/conf/AVILA @@ -20,10 +20,10 @@ ident AVILA -include "std.arm" -include "../xscale/ixp425/std.ixp425" +include "std.arm" +include "../xscale/ixp425/std.ixp425" # NB: memory mapping is defined in std.avila -include "../xscale/ixp425/std.avila" +include "../xscale/ixp425/std.avila" options XSCALE_CACHE_READ_WRITE_ALLOCATE #To statically compile in device wiring instead of /boot/device.hints hints "AVILA.hints" # Default places to look for devices. diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index 997a62e..97e2d3d 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -23,8 +23,8 @@ ident BEAGLEBONE -include "std.armv6" -include "../ti/am335x/std.am335x" +include "std.armv6" +include "../ti/am335x/std.am335x" makeoptions MODULES_EXTRA="dtb/am335x" diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT index d483a00..a6f8e49 100644 --- a/sys/arm/conf/BWCT +++ b/sys/arm/conf/BWCT @@ -21,10 +21,10 @@ ident BWCT -include "std.arm" +include "std.arm" options VERBOSE_INIT_ARM -include "../at91/std.bwct" +include "../at91/std.bwct" #To statically compile in device wiring instead of /boot/device.hints hints "BWCT.hints" diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA index 1cf7fb9..c25521b 100644 --- a/sys/arm/conf/CAMBRIA +++ b/sys/arm/conf/CAMBRIA @@ -20,10 +20,10 @@ ident CAMBRIA -include "std.arm" -include "../xscale/ixp425/std.ixp435" +include "std.arm" +include "../xscale/ixp425/std.ixp435" # NB: memory mapping is defined in std.avila -include "../xscale/ixp425/std.avila" +include "../xscale/ixp425/std.avila" options XSCALE_CACHE_READ_WRITE_ALLOCATE #To statically compile in device wiring instead of /boot/device.hints hints "CAMBRIA.hints" # Default places to look for devices. diff --git a/sys/arm/conf/CHROMEBOOK b/sys/arm/conf/CHROMEBOOK index 9459151..059f243 100644 --- a/sys/arm/conf/CHROMEBOOK +++ b/sys/arm/conf/CHROMEBOOK @@ -17,7 +17,7 @@ # # $FreeBSD$ -include "EXYNOS5250" +include "EXYNOS5250" ident CHROMEBOOK hints "CHROMEBOOK.hints" diff --git a/sys/arm/conf/CHROMEBOOK-PEACH-PIT b/sys/arm/conf/CHROMEBOOK-PEACH-PIT index e01128c..87284c2 100644 --- a/sys/arm/conf/CHROMEBOOK-PEACH-PIT +++ b/sys/arm/conf/CHROMEBOOK-PEACH-PIT @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "EXYNOS5420" +include "EXYNOS5420" ident CHROMEBOOK-PEACH-PIT hints "CHROMEBOOK-PEACH-PIT.hints" diff --git a/sys/arm/conf/CHROMEBOOK-SNOW b/sys/arm/conf/CHROMEBOOK-SNOW index e9242d1..aee3dc0 100644 --- a/sys/arm/conf/CHROMEBOOK-SNOW +++ b/sys/arm/conf/CHROMEBOOK-SNOW @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "CHROMEBOOK" +include "CHROMEBOOK" ident CHROMEBOOK-SNOW #FDT diff --git a/sys/arm/conf/CHROMEBOOK-SPRING b/sys/arm/conf/CHROMEBOOK-SPRING index 1b791ac..9714d34 100644 --- a/sys/arm/conf/CHROMEBOOK-SPRING +++ b/sys/arm/conf/CHROMEBOOK-SPRING @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "CHROMEBOOK" +include "CHROMEBOOK" ident CHROMEBOOK-SPRING #FDT diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS index d906a2b..710a471 100644 --- a/sys/arm/conf/CNS11XXNAS +++ b/sys/arm/conf/CNS11XXNAS @@ -20,14 +20,14 @@ ident CNS11XXNAS -include "std.arm" +include "std.arm" #options PHYSADDR=0x10000000 #options KERNPHYSADDR=0x10200000 #options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm #options FLASHADDR=0x50000000 #options LOADERRAMADDR=0x00000000 -include "../cavium/cns11xx/std.econa" +include "../cavium/cns11xx/std.econa" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/COLIBRI-VF50 b/sys/arm/conf/COLIBRI-VF50 index 9f73f69..81581f6 100644 --- a/sys/arm/conf/COLIBRI-VF50 +++ b/sys/arm/conf/COLIBRI-VF50 @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "VYBRID" +include "VYBRID" ident COLIBRI-VF50 #FDT diff --git a/sys/arm/conf/COSMIC b/sys/arm/conf/COSMIC index 72ae5c2..61b99a7 100644 --- a/sys/arm/conf/COSMIC +++ b/sys/arm/conf/COSMIC @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "VYBRID" +include "VYBRID" ident COSMIC #FDT diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB index f5cc932..69b0ebd 100644 --- a/sys/arm/conf/CRB +++ b/sys/arm/conf/CRB @@ -19,13 +19,13 @@ ident CRB -include "std.arm" +include "std.arm" options PHYSADDR=0x00000000 options KERNPHYSADDR=0x00200000 options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm options COUNTS_PER_SEC=400000000 -include "../xscale/i8134x/std.crb" +include "../xscale/i8134x/std.crb" makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD index 8f856bd..26283d4 100644 --- a/sys/arm/conf/CUBIEBOARD +++ b/sys/arm/conf/CUBIEBOARD @@ -21,8 +21,8 @@ ident CUBIEBOARD -include "std.armv6" -include "../allwinner/std.a10" +include "std.armv6" +include "../allwinner/std.a10" options HZ=100 options SCHED_4BSD # 4BSD scheduler diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2 index 15d028f..45311c3 100644 --- a/sys/arm/conf/CUBIEBOARD2 +++ b/sys/arm/conf/CUBIEBOARD2 @@ -21,8 +21,8 @@ ident CUBIEBOARD2 -include "std.armv6" -include "../allwinner/a20/std.a20" +include "std.armv6" +include "../allwinner/a20/std.a20" options HZ=100 options SCHED_ULE # ULE scheduler diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX index 2e7fa36..e59e426 100644 --- a/sys/arm/conf/DB-78XXX +++ b/sys/arm/conf/DB-78XXX @@ -5,8 +5,8 @@ # ident DB-88F78XX -include "std.arm" -include "../mv/discovery/std.db78xxx" +include "std.arm" +include "../mv/discovery/std.db78xxx" options SOC_MV_DISCOVERY diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX index 7cc06a0..f1729f0 100644 --- a/sys/arm/conf/DB-88F5XXX +++ b/sys/arm/conf/DB-88F5XXX @@ -5,8 +5,8 @@ # ident DB-88F5XXX -include "std.arm" -include "../mv/orion/std.db88f5xxx" +include "std.arm" +include "../mv/orion/std.db88f5xxx" options SOC_MV_ORION diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX index afec0e7..4018bcd 100644 --- a/sys/arm/conf/DB-88F6XXX +++ b/sys/arm/conf/DB-88F6XXX @@ -5,8 +5,8 @@ # ident DB-88F6XXX -include "std.arm" -include "../mv/kirkwood/std.db88f6xxx" +include "std.arm" +include "../mv/kirkwood/std.db88f6xxx" options SOC_MV_KIRKWOOD diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53 index 20dec9c..65239c1 100644 --- a/sys/arm/conf/DIGI-CCWMX53 +++ b/sys/arm/conf/DIGI-CCWMX53 @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "IMX53" +include "IMX53" ident DIGI-CCWMX53 makeoptions WITHOUT_MODULES="ahc" diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index c6308cd..9e73980 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -21,8 +21,8 @@ ident DOCKSTAR -include "std.arm" -include "../mv/kirkwood/std.db88f6xxx" +include "std.arm" +include "../mv/kirkwood/std.db88f6xxx" makeoptions FDT_DTS_FILE=dockstar.dts diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index f97b564..f44599e 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -24,8 +24,8 @@ ident DREAMPLUG-1001 -include "std.arm" -include "../mv/kirkwood/std.db88f6xxx" +include "std.arm" +include "../mv/kirkwood/std.db88f6xxx" makeoptions FDT_DTS_FILE=dreamplug-1001.dts diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250 index bcb8276..8f13505 100644 --- a/sys/arm/conf/EA3250 +++ b/sys/arm/conf/EA3250 @@ -5,8 +5,8 @@ # ident EA3250 -include "std.arm" -include "../lpc/std.lpc" +include "std.arm" +include "../lpc/std.lpc" hints "EA3250.hints" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/EB9200 b/sys/arm/conf/EB9200 index bf0c41b..afcc530 100644 --- a/sys/arm/conf/EB9200 +++ b/sys/arm/conf/EB9200 @@ -16,8 +16,8 @@ ident EB9200 -include "std.arm" -include "../at91/std.eb9200" +include "std.arm" +include "../at91/std.eb9200" # The AT91 platform doesn't use /boot/loader, so we have to statically wire # hints. hints "EB9200.hints" diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index 81edae8..dc22943 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -20,7 +20,7 @@ ident EFIKA_MX -include "std.armv6" +include "std.armv6" include "../freescale/imx/std.imx51" makeoptions WITHOUT_MODULES="ahc" diff --git a/sys/arm/conf/EP80219 b/sys/arm/conf/EP80219 index 6f2bef8..301849c 100644 --- a/sys/arm/conf/EP80219 +++ b/sys/arm/conf/EP80219 @@ -19,13 +19,13 @@ ident EP80219 -include "std.arm" +include "std.arm" options PHYSADDR=0xa0000000 options KERNPHYSADDR=0xa0200000 options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm #options ARM32_NEW_VM_LAYOUT -include "../xscale/i80321/std.ep80219" +include "../xscale/i80321/std.ep80219" makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5 index f01ea0d..c91869a 100644 --- a/sys/arm/conf/ETHERNUT5 +++ b/sys/arm/conf/ETHERNUT5 @@ -21,8 +21,8 @@ ident ETHERNUT5 -include "std.arm" -include "../at91/std.ethernut5" +include "std.arm" +include "../at91/std.ethernut5" # To statically compile in device wiring instead of /boot/device.hints hints "ETHERNUT5.hints" diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index 2f96935..0bd6ad6 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -20,7 +20,7 @@ makeoptions WERROR="-Werror" -include "std.armv6" +include "std.armv6" options HZ=100 options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption diff --git a/sys/arm/conf/EXYNOS5250 b/sys/arm/conf/EXYNOS5250 index 156d856..e22239f 100644 --- a/sys/arm/conf/EXYNOS5250 +++ b/sys/arm/conf/EXYNOS5250 @@ -18,8 +18,8 @@ # $FreeBSD$ ident EXYNOS5250 -include "EXYNOS5.common" -include "../samsung/exynos/std.exynos5250" +include "EXYNOS5.common" +include "../samsung/exynos/std.exynos5250" #FDT options FDT diff --git a/sys/arm/conf/EXYNOS5420 b/sys/arm/conf/EXYNOS5420 index 0f2c2c7..b55151a 100644 --- a/sys/arm/conf/EXYNOS5420 +++ b/sys/arm/conf/EXYNOS5420 @@ -18,8 +18,8 @@ # $FreeBSD$ ident EXYNOS5420 -include "EXYNOS5.common" -include "../samsung/exynos/std.exynos5420" +include "EXYNOS5.common" +include "../samsung/exynos/std.exynos5420" #FDT options FDT diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX index 9ba6155..048bd3c 100644 --- a/sys/arm/conf/GUMSTIX +++ b/sys/arm/conf/GUMSTIX @@ -19,7 +19,7 @@ # $FreeBSD$ ident GUMSTIX -include "std.arm" +include "std.arm" cpu CPU_XSCALE_PXA2X0 # This probably wants to move somewhere else. Maybe we can create a basic @@ -31,7 +31,7 @@ options PHYSADDR=0xa0000000 options KERNPHYSADDR=0xa0200000 options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm -include "../xscale/pxa/std.pxa" +include "../xscale/pxa/std.pxa" makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200 index 8d22da5..43a8148 100644 --- a/sys/arm/conf/HL200 +++ b/sys/arm/conf/HL200 @@ -21,8 +21,8 @@ ident HL200 -include "std.arm" -include "../at91/std.hl200" +include "std.arm" +include "../at91/std.hl200" #To statically compile in device wiring instead of /boot/device.hints hints "KB920X.hints" diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201 index 4ec6da3..2eed9d5 100644 --- a/sys/arm/conf/HL201 +++ b/sys/arm/conf/HL201 @@ -21,8 +21,8 @@ ident HL201 -include "std.arm" -include "../at91/std.hl201" +include "std.arm" +include "../at91/std.hl201" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index 3275bfc..d07d6ad 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -20,7 +20,7 @@ ident IMX53 -include "std.armv6" +include "std.armv6" include "../freescale/imx/std.imx53" options SOC_IMX53 diff --git a/sys/arm/conf/IMX53-QSB b/sys/arm/conf/IMX53-QSB index fdde591..5fa907c 100644 --- a/sys/arm/conf/IMX53-QSB +++ b/sys/arm/conf/IMX53-QSB @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "IMX53" +include "IMX53" ident IMX53-QSB options HZ=250 # 4ms scheduling quantum diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 5ead99b..332681a 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -19,7 +19,7 @@ # $FreeBSD$ ident IMX6 -include "std.armv6" +include "std.armv6" include "../freescale/imx/std.imx6" options SOC_IMX6 diff --git a/sys/arm/conf/IQ31244 b/sys/arm/conf/IQ31244 index 403a0c2..ae8eae8 100644 --- a/sys/arm/conf/IQ31244 +++ b/sys/arm/conf/IQ31244 @@ -19,14 +19,14 @@ ident IQ31244 -include "std.arm" +include "std.arm" options PHYSADDR=0xa0000000 options KERNPHYSADDR=0xa0200000 options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm options FLASHADDR=0xf0000000 options LOADERRAMADDR=0x00000000 -include "../xscale/i80321/std.iq31244" +include "../xscale/i80321/std.iq31244" makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X index 6d91ad8..79be31a 100644 --- a/sys/arm/conf/KB920X +++ b/sys/arm/conf/KB920X @@ -22,8 +22,8 @@ ident KB920X -include "std.arm" -include "../at91/std.kb920x" +include "std.arm" +include "../at91/std.kb920x" # The AT91 platform doesn't use /boot/loader, so we have to statically wire # hints. hints "KB920X.hints" diff --git a/sys/arm/conf/LN2410SBC b/sys/arm/conf/LN2410SBC index ae3c62a..a154c32 100644 --- a/sys/arm/conf/LN2410SBC +++ b/sys/arm/conf/LN2410SBC @@ -19,7 +19,7 @@ ident LN2410SBC -include "std.arm" +include "std.arm" include "../samsung/s3c2xx0/std.ln2410sbc" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" # Default places to look for devices. diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU index 00a2902..665910a 100644 --- a/sys/arm/conf/NSLU +++ b/sys/arm/conf/NSLU @@ -21,7 +21,7 @@ ident NSLU -include "std.arm" +include "std.arm" # XXX What is defined in std.avila does not exactly match the following: #options PHYSADDR=0x10000000 #options KERNPHYSADDR=0x10200000 @@ -29,9 +29,9 @@ include "std.arm" #options FLASHADDR=0x50000000 #options LOADERRAMADDR=0x00000000 -include "../xscale/ixp425/std.ixp425" +include "../xscale/ixp425/std.ixp425" # NB: memory mapping is defined in std.avila (see also comment above) -include "../xscale/ixp425/std.avila" +include "../xscale/ixp425/std.avila" options XSCALE_CACHE_READ_WRITE_ALLOCATE #To statically compile in device wiring instead of /boot/device.hints hints "NSLU.hints" # Default places to look for devices. diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD index e58c953..41e2900 100644 --- a/sys/arm/conf/PANDABOARD +++ b/sys/arm/conf/PANDABOARD @@ -27,7 +27,7 @@ ident PANDABOARD hints "PANDABOARD.hints" -include "std.armv6" +include "std.armv6" include "../ti/omap4/pandaboard/std.pandaboard" options HZ=100 diff --git a/sys/arm/conf/QILA9G20 b/sys/arm/conf/QILA9G20 index 2f9b609..1d6bff9 100644 --- a/sys/arm/conf/QILA9G20 +++ b/sys/arm/conf/QILA9G20 @@ -22,8 +22,8 @@ ident QILA9G20 -include "std.arm" -include "../at91/std.qila9g20" +include "std.arm" +include "../at91/std.qila9g20" #To statically compile in device wiring instead of /boot/device.hints hints "QILA9G20.hints" diff --git a/sys/arm/conf/QUARTZ b/sys/arm/conf/QUARTZ index 04f1b5c..9c98185 100644 --- a/sys/arm/conf/QUARTZ +++ b/sys/arm/conf/QUARTZ @@ -19,7 +19,7 @@ #NO_UNIVERSE -include "VYBRID" +include "VYBRID" ident QUARTZ #FDT diff --git a/sys/arm/conf/RADXA b/sys/arm/conf/RADXA index ad5eadf..8801f67 100644 --- a/sys/arm/conf/RADXA +++ b/sys/arm/conf/RADXA @@ -20,7 +20,7 @@ #NO_UNIVERSE -include "RK3188" +include "RK3188" ident RADXA # Flattened Device Tree diff --git a/sys/arm/conf/RADXA-LITE b/sys/arm/conf/RADXA-LITE index c07462d..7252941 100644 --- a/sys/arm/conf/RADXA-LITE +++ b/sys/arm/conf/RADXA-LITE @@ -20,7 +20,7 @@ #NO_UNIVERSE -include "RK3188" +include "RK3188" ident RADXA-LITE # Flattened Device Tree diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index 46bc334..9afa7ab 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -20,8 +20,8 @@ ident RK3188 -include "std.armv6" -include "../rockchip/std.rk30xx" +include "std.armv6" +include "../rockchip/std.rk30xx" options HZ=100 options SCHED_ULE # ULE scheduler diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B index 309a499..9193bca 100644 --- a/sys/arm/conf/RPI-B +++ b/sys/arm/conf/RPI-B @@ -20,9 +20,9 @@ ident RPI-B -include "std.armv6" -include "../broadcom/bcm2835/std.rpi" -include "../broadcom/bcm2835/std.bcm2835" +include "std.armv6" +include "../broadcom/bcm2835/std.rpi" +include "../broadcom/bcm2835/std.bcm2835" options HZ=100 options SCHED_4BSD # 4BSD scheduler diff --git a/sys/arm/conf/RPI2 b/sys/arm/conf/RPI2 index dbb67d9..27caac9 100644 --- a/sys/arm/conf/RPI2 +++ b/sys/arm/conf/RPI2 @@ -20,12 +20,13 @@ ident RPI2 -include "std.armv6" -include "../broadcom/bcm2835/std.rpi" -include "../broadcom/bcm2835/std.bcm2836" +include "std.armv6" +include "../broadcom/bcm2835/std.rpi" +include "../broadcom/bcm2835/std.bcm2836" options HZ=100 -options SCHED_4BSD # 4BSD scheduler +options SCHED_ULE # ULE scheduler +options SMP # Enable multiple cores options PLATFORM # Debugging for use in -current diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK index 30680c5..a3c7759 100644 --- a/sys/arm/conf/SAM9260EK +++ b/sys/arm/conf/SAM9260EK @@ -21,8 +21,8 @@ ident SAM9260EK -include "std.arm" -include "../at91/std.sam9260ek" +include "std.arm" +include "../at91/std.sam9260ek" # To statically compile in device wiring instead of /boot/device.hints hints "SAM9260EK.hints" diff --git a/sys/arm/conf/SAM9G20EK b/sys/arm/conf/SAM9G20EK index 4d961c7..e12a143 100644 --- a/sys/arm/conf/SAM9G20EK +++ b/sys/arm/conf/SAM9G20EK @@ -19,8 +19,8 @@ ident SAM9G20EK -include "std.arm" -include "../at91/std.sam9g20ek" +include "std.arm" +include "../at91/std.sam9g20ek" #To statically compile in device wiring instead of /boot/device.hints hints "SAM9G20EK.hints" diff --git a/sys/arm/conf/SAM9X25EK b/sys/arm/conf/SAM9X25EK index 49afe99..08dc1f5 100644 --- a/sys/arm/conf/SAM9X25EK +++ b/sys/arm/conf/SAM9X25EK @@ -21,8 +21,8 @@ ident SAM9X25EK -include "std.arm" -include "../at91/std.sam9x25ek" +include "std.arm" +include "../at91/std.sam9x25ek" #To statically compile in device wiring instead of /boot/device.hints hints "SAM9G20EK.hints" diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG index e013e75..9797cc0 100644 --- a/sys/arm/conf/SHEEVAPLUG +++ b/sys/arm/conf/SHEEVAPLUG @@ -6,8 +6,8 @@ #NO_UNIVERSE ident SHEEVAPLUG -include "std.arm" -include "../mv/kirkwood/std.db88f6xxx" +include "std.arm" +include "../mv/kirkwood/std.db88f6xxx" options SOC_MV_KIRKWOOD diff --git a/sys/arm/conf/SN9G45 b/sys/arm/conf/SN9G45 index bf46503..e85d613 100644 --- a/sys/arm/conf/SN9G45 +++ b/sys/arm/conf/SN9G45 @@ -21,8 +21,8 @@ ident SN9G45 -include "std.arm" -include "../at91/std.sn9g45" +include "std.arm" +include "../at91/std.sn9g45" #To statically compile in device wiring instead of /boot/device.hints #hints "SN9G45.hints" diff --git a/sys/arm/conf/SOCKIT.common b/sys/arm/conf/SOCKIT.common index eb87fd6..ff817f8 100644 --- a/sys/arm/conf/SOCKIT.common +++ b/sys/arm/conf/SOCKIT.common @@ -18,7 +18,7 @@ # # $FreeBSD$ -include "std.armv6" +include "std.armv6" include "../altera/socfpga/std.socfpga" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/TS7800 b/sys/arm/conf/TS7800 index ab9fe5b..1a565c4 100644 --- a/sys/arm/conf/TS7800 +++ b/sys/arm/conf/TS7800 @@ -5,8 +5,8 @@ # ident TS7800 -include "std.arm" -include "../mv/orion/std.ts7800" +include "std.arm" +include "../mv/orion/std.ts7800" options SOC_MV_ORION diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB index 182e56c..d1fc77a 100644 --- a/sys/arm/conf/VERSATILEPB +++ b/sys/arm/conf/VERSATILEPB @@ -22,7 +22,7 @@ ident VERSATILEPB machine arm armv6 cpu CPU_ARM1176 -include "std.armv6" +include "std.armv6" files "../versatile/files.versatile" makeoptions MODULES_OVERRIDE="" diff --git a/sys/arm/conf/VIRT b/sys/arm/conf/VIRT index 0f67b84..58efec4 100644 --- a/sys/arm/conf/VIRT +++ b/sys/arm/conf/VIRT @@ -20,8 +20,8 @@ ident VIRT -include "std.armv6" -include "../qemu/std.virt" +include "std.armv6" +include "../qemu/std.virt" options HZ=100 options SCHED_4BSD # 4BSD scheduler diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID index 8fb0198..7e01756 100644 --- a/sys/arm/conf/VYBRID +++ b/sys/arm/conf/VYBRID @@ -19,8 +19,8 @@ # $FreeBSD$ ident VYBRID -include "std.armv6" -include "../freescale/vybrid/std.vybrid" +include "std.armv6" +include "../freescale/vybrid/std.vybrid" makeoptions WERROR="-Werror" diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index 7c108a1..3c31b74 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -21,7 +21,7 @@ ident ZEDBOARD -include "std.armv6" +include "std.armv6" include "../xilinx/zedboard/std.zedboard" options SCHED_ULE # ULE scheduler diff --git a/sys/arm/include/armreg.h b/sys/arm/include/armreg.h index 3163ba5..9358703 100644 --- a/sys/arm/include/armreg.h +++ b/sys/arm/include/armreg.h @@ -346,6 +346,9 @@ #define CPUV7_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x3ff) /* associativity */ #define CPUV7_CT_xSIZE_SET(x) (((x) >> 13) & 0x7fff) /* num sets */ +#define CPUV7_L2CTLR_NPROC_SHIFT 24 +#define CPUV7_L2CTLR_NPROC(r) ((((r) >> CPUV7_L2CTLR_NPROC_SHIFT) & 3) + 1) + #define CPU_CLIDR_CTYPE(reg,x) (((reg) >> ((x) * 3)) & 0x7) #define CPU_CLIDR_LOUIS(reg) (((reg) >> 21) & 0x7) #define CPU_CLIDR_LOC(reg) (((reg) >> 24) & 0x7) diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h index 6c226a3..b0d7a7f 100644 --- a/sys/arm/include/cpu-v6.h +++ b/sys/arm/include/cpu-v6.h @@ -143,6 +143,13 @@ _RF0(cp15_ttbr_get, CP15_TTBR0(%0)) _RF0(cp15_dfar_get, CP15_DFAR(%0)) #if __ARM_ARCH >= 7 _RF0(cp15_ifar_get, CP15_IFAR(%0)) +_RF0(cp15_l2ctlr_get, CP15_L2CTLR(%0)) +#endif +#if __ARM_ARCH >= 6 +_RF0(cp15_actlr_get, CP15_ACTLR(%0)) +_WF1(cp15_ats1cpr_set, CP15_ATS1CPR(%0)); +_RF0(cp15_par_get, CP15_PAR); +_RF0(cp15_sctlr_get, CP15_SCTLR(%0)) #endif /*CPU id registers */ diff --git a/sys/arm/include/pl310.h b/sys/arm/include/pl310.h index f7c75e9..fd75d44 100644 --- a/sys/arm/include/pl310.h +++ b/sys/arm/include/pl310.h @@ -133,7 +133,7 @@ #define PREFETCH_CTRL_DATA_PREFETCH (1 << 28) #define PREFETCH_CTRL_INSTR_PREFETCH (1 << 29) #define PREFETCH_CTRL_DL (1 << 30) -#define PL310_POWER_CTRL 0xF60 +#define PL310_POWER_CTRL 0xF80 #define POWER_CTRL_ENABLE_GATING (1 << 0) #define POWER_CTRL_ENABLE_STANDBY (1 << 1) diff --git a/sys/arm/include/sysreg.h b/sys/arm/include/sysreg.h index f29991a..fb13487 100644 --- a/sys/arm/include/sysreg.h +++ b/sys/arm/include/sysreg.h @@ -212,6 +212,7 @@ #if __ARM_ARCH == 6 && defined(CPU_ARM1176) #define CP15_PMCCNTR(rr) p15, 0, rr, c15, c12, 1 /* PM Cycle Count Register */ #elif __ARM_ARCH > 6 +#define CP15_L2CTLR(rr) p15, 1, rr, c9, c0, 2 /* L2 Control Register */ #define CP15_PMCR(rr) p15, 0, rr, c9, c12, 0 /* Performance Monitor Control Register */ #define CP15_PMCNTENSET(rr) p15, 0, rr, c9, c12, 1 /* PM Count Enable Set Register */ #define CP15_PMCNTENCLR(rr) p15, 0, rr, c9, c12, 2 /* PM Count Enable Clear Register */ diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c index ad688f3..3337032 100644 --- a/sys/arm/ti/ti_i2c.c +++ b/sys/arm/ti/ti_i2c.c @@ -953,6 +953,17 @@ static device_method_t ti_i2c_methods[] = { DEVMETHOD(device_attach, ti_i2c_attach), DEVMETHOD(device_detach, ti_i2c_detach), + /* 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, ti_i2c_get_node), diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c new file mode 100644 index 0000000..477c819 --- /dev/null +++ b/sys/arm64/arm64/busdma_bounce.c @@ -0,0 +1,1080 @@ +/*- + * Copyright (c) 1997, 1998 Justin T. Gibbs. + * Copyright (c) 2015 The FreeBSD Foundation + * All rights reserved. + * + * Portions of this software were developed by Semihalf + * under sponsorship of the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. 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 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/bus.h> +#include <sys/interrupt.h> +#include <sys/kernel.h> +#include <sys/ktr.h> +#include <sys/lock.h> +#include <sys/proc.h> +#include <sys/memdesc.h> +#include <sys/mutex.h> +#include <sys/sysctl.h> +#include <sys/uio.h> + +#include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> +#include <vm/vm_page.h> +#include <vm/vm_map.h> + +#include <machine/atomic.h> +#include <machine/bus.h> +#include <machine/md_var.h> +#include <arm64/include/bus_dma_impl.h> + +#define MAX_BPAGES 4096 + +enum { + BUS_DMA_COULD_BOUNCE = 0x01, + BUS_DMA_MIN_ALLOC_COMP = 0x02, + BUS_DMA_KMEM_ALLOC = 0x04, +}; + +struct bounce_zone; + +struct bus_dma_tag { + struct bus_dma_tag_common common; + int map_count; + int bounce_flags; + bus_dma_segment_t *segments; + struct bounce_zone *bounce_zone; +}; + +struct bounce_page { + vm_offset_t vaddr; /* kva of bounce buffer */ + bus_addr_t busaddr; /* Physical address */ + vm_offset_t datavaddr; /* kva of client data */ + bus_addr_t dataaddr; /* client physical address */ + bus_size_t datacount; /* client data count */ + STAILQ_ENTRY(bounce_page) links; +}; + +int busdma_swi_pending; + +struct bounce_zone { + STAILQ_ENTRY(bounce_zone) links; + STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; + int total_bpages; + int free_bpages; + int reserved_bpages; + int active_bpages; + int total_bounced; + int total_deferred; + int map_count; + bus_size_t alignment; + bus_addr_t lowaddr; + char zoneid[8]; + char lowaddrid[20]; + struct sysctl_ctx_list sysctl_tree; + struct sysctl_oid *sysctl_tree_top; +}; + +static struct mtx bounce_lock; +static int total_bpages; +static int busdma_zonecount; +static STAILQ_HEAD(, bounce_zone) bounce_zone_list; + +static SYSCTL_NODE(_hw, OID_AUTO, busdma, CTLFLAG_RD, 0, "Busdma parameters"); +SYSCTL_INT(_hw_busdma, OID_AUTO, total_bpages, CTLFLAG_RD, &total_bpages, 0, + "Total bounce pages"); + +struct bus_dmamap { + struct bp_list bpages; + int pagesneeded; + int pagesreserved; + bus_dma_tag_t dmat; + struct memdesc mem; + bus_dmamap_callback_t *callback; + void *callback_arg; + STAILQ_ENTRY(bus_dmamap) links; +}; + +static STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist; +static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist; +static struct bus_dmamap nobounce_dmamap; + +static void init_bounce_pages(void *dummy); +static int alloc_bounce_zone(bus_dma_tag_t dmat); +static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages); +static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, + int commit); +static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, + vm_offset_t vaddr, bus_addr_t addr, bus_size_t size); +static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage); +int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr); +static void _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, + pmap_t pmap, void *buf, bus_size_t buflen, int flags); +static void _bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, + vm_paddr_t buf, bus_size_t buflen, int flags); +static int _bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map, + int flags); + +/* + * Allocate a device specific dma_tag. + */ +static int +bounce_bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, + bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, + int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, bus_dma_tag_t *dmat) +{ + bus_dma_tag_t newtag; + int error; + + *dmat = NULL; + error = common_bus_dma_tag_create(parent != NULL ? &parent->common : + NULL, alignment, boundary, lowaddr, highaddr, filter, filterarg, + maxsize, nsegments, maxsegsz, flags, lockfunc, lockfuncarg, + sizeof (struct bus_dma_tag), (void **)&newtag); + if (error != 0) + return (error); + + newtag->common.impl = &bus_dma_bounce_impl; + newtag->map_count = 0; + newtag->segments = NULL; + + if (parent != NULL && ((newtag->common.filter != NULL) || + ((parent->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0))) + newtag->bounce_flags |= BUS_DMA_COULD_BOUNCE; + + if (newtag->common.lowaddr < ptoa((vm_paddr_t)Maxmem) || + newtag->common.alignment > 1) + newtag->bounce_flags |= BUS_DMA_COULD_BOUNCE; + + if (((newtag->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) && + (flags & BUS_DMA_ALLOCNOW) != 0) { + struct bounce_zone *bz; + + /* Must bounce */ + if ((error = alloc_bounce_zone(newtag)) != 0) { + free(newtag, M_DEVBUF); + return (error); + } + bz = newtag->bounce_zone; + + if (ptoa(bz->total_bpages) < maxsize) { + int pages; + + pages = atop(maxsize) - bz->total_bpages; + + /* Add pages to our bounce pool */ + if (alloc_bounce_pages(newtag, pages) < pages) + error = ENOMEM; + } + /* Performed initial allocation */ + newtag->bounce_flags |= BUS_DMA_MIN_ALLOC_COMP; + } else + error = 0; + + if (error != 0) + free(newtag, M_DEVBUF); + else + *dmat = newtag; + CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", + __func__, newtag, (newtag != NULL ? newtag->common.flags : 0), + error); + return (error); +} + +static int +bounce_bus_dma_tag_destroy(bus_dma_tag_t dmat) +{ + bus_dma_tag_t dmat_copy, parent; + int error; + + error = 0; + dmat_copy = dmat; + + if (dmat != NULL) { + if (dmat->map_count != 0) { + error = EBUSY; + goto out; + } + while (dmat != NULL) { + parent = (bus_dma_tag_t)dmat->common.parent; + atomic_subtract_int(&dmat->common.ref_count, 1); + if (dmat->common.ref_count == 0) { + if (dmat->segments != NULL) + free(dmat->segments, M_DEVBUF); + free(dmat, M_DEVBUF); + /* + * Last reference count, so + * release our reference + * count on our parent. + */ + dmat = parent; + } else + dmat = NULL; + } + } +out: + CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error); + return (error); +} + +/* + * Allocate a handle for mapping from kva/uva/physical + * address space into bus device space. + */ +static int +bounce_bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) +{ + struct bounce_zone *bz; + int error, maxpages, pages; + + error = 0; + + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->common.nsegments, + M_DEVBUF, M_NOWAIT); + if (dmat->segments == NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, ENOMEM); + return (ENOMEM); + } + } + + /* + * Bouncing might be required if the driver asks for an active + * exclusion region, a data alignment that is stricter than 1, and/or + * an active address boundary. + */ + if (dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) { + /* Must bounce */ + if (dmat->bounce_zone == NULL) { + if ((error = alloc_bounce_zone(dmat)) != 0) + return (error); + } + bz = dmat->bounce_zone; + + *mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF, + M_NOWAIT | M_ZERO); + if (*mapp == NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, ENOMEM); + return (ENOMEM); + } + + /* Initialize the new map */ + STAILQ_INIT(&((*mapp)->bpages)); + + /* + * Attempt to add pages to our pool on a per-instance + * basis up to a sane limit. + */ + if (dmat->common.alignment > 1) + maxpages = MAX_BPAGES; + else + maxpages = MIN(MAX_BPAGES, Maxmem - + atop(dmat->common.lowaddr)); + if ((dmat->bounce_flags & BUS_DMA_MIN_ALLOC_COMP) == 0 || + (bz->map_count > 0 && bz->total_bpages < maxpages)) { + pages = MAX(atop(dmat->common.maxsize), 1); + pages = MIN(maxpages - bz->total_bpages, pages); + pages = MAX(pages, 1); + if (alloc_bounce_pages(dmat, pages) < pages) + error = ENOMEM; + if ((dmat->bounce_flags & BUS_DMA_MIN_ALLOC_COMP) + == 0) { + if (error == 0) { + dmat->bounce_flags |= + BUS_DMA_MIN_ALLOC_COMP; + } + } else + error = 0; + } + bz->map_count++; + } else { + *mapp = NULL; + } + if (error == 0) + dmat->map_count++; + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->common.flags, error); + return (error); +} + +/* + * Destroy a handle for mapping from kva/uva/physical + * address space into bus device space. + */ +static int +bounce_bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) +{ + + if (map != NULL && map != &nobounce_dmamap) { + if (STAILQ_FIRST(&map->bpages) != NULL) { + CTR3(KTR_BUSDMA, "%s: tag %p error %d", + __func__, dmat, EBUSY); + return (EBUSY); + } + if (dmat->bounce_zone) + dmat->bounce_zone->map_count--; + free(map, M_DEVBUF); + } + dmat->map_count--; + CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat); + return (0); +} + + +/* + * Allocate a piece of memory that can be efficiently mapped into + * bus device space based on the constraints lited in the dma tag. + * A dmamap to for use with dmamap_load is also allocated. + */ +static int +bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp) +{ + /* + * XXX ARM64TODO: + * This bus_dma implementation requires IO-Coherent architecutre. + * If IO-Coherency is not guaranteed, the BUS_DMA_COHERENT flag has + * to be implented using non-cacheable memory. + */ + + vm_memattr_t attr; + int mflags; + + if (flags & BUS_DMA_NOWAIT) + mflags = M_NOWAIT; + else + mflags = M_WAITOK; + + /* If we succeed, no mapping/bouncing will be required */ + *mapp = NULL; + + if (dmat->segments == NULL) { + dmat->segments = (bus_dma_segment_t *)malloc( + sizeof(bus_dma_segment_t) * dmat->common.nsegments, + M_DEVBUF, mflags); + if (dmat->segments == NULL) { + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->common.flags, ENOMEM); + return (ENOMEM); + } + } + if (flags & BUS_DMA_ZERO) + mflags |= M_ZERO; + if (flags & BUS_DMA_NOCACHE) + attr = VM_MEMATTR_UNCACHEABLE; + else + attr = VM_MEMATTR_DEFAULT; + + /* + * XXX: + * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact + * alignment guarantees of malloc need to be nailed down, and the + * code below should be rewritten to take that into account. + * + * In the meantime, we'll warn the user if malloc gets it wrong. + */ + if ((dmat->common.maxsize <= PAGE_SIZE) && + (dmat->common.alignment < dmat->common.maxsize) && + dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) && + attr == VM_MEMATTR_DEFAULT) { + *vaddr = malloc(dmat->common.maxsize, M_DEVBUF, mflags); + } else if (dmat->common.nsegments >= btoc(dmat->common.maxsize) && + dmat->common.alignment <= PAGE_SIZE && + (dmat->common.boundary == 0 || + dmat->common.boundary >= dmat->common.lowaddr)) { + /* Page-based multi-segment allocations allowed */ + *vaddr = (void *)kmem_alloc_attr(kernel_arena, + dmat->common.maxsize, mflags, 0ul, dmat->common.lowaddr, + attr); + dmat->bounce_flags |= BUS_DMA_KMEM_ALLOC; + } else { + *vaddr = (void *)kmem_alloc_contig(kernel_arena, + dmat->common.maxsize, mflags, 0ul, dmat->common.lowaddr, + dmat->common.alignment != 0 ? dmat->common.alignment : 1ul, + dmat->common.boundary, attr); + dmat->bounce_flags |= BUS_DMA_KMEM_ALLOC; + } + if (*vaddr == NULL) { + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->common.flags, ENOMEM); + return (ENOMEM); + } else if (vtophys(*vaddr) & (dmat->common.alignment - 1)) { + printf("bus_dmamem_alloc failed to align memory properly.\n"); + } + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", + __func__, dmat, dmat->common.flags, 0); + return (0); +} + +/* + * Free a piece of memory and it's allociated dmamap, that was allocated + * via bus_dmamem_alloc. Make the same choice for free/contigfree. + */ +static void +bounce_bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) +{ + /* + * dmamem does not need to be bounced, so the map should be + * NULL and the BUS_DMA_KMEM_ALLOC flag cleared if malloc() + * was used and set if kmem_alloc_contig() was used. + */ + if (map != NULL) + panic("bus_dmamem_free: Invalid map freed\n"); + if ((dmat->bounce_flags & BUS_DMA_KMEM_ALLOC) == 0) + free(vaddr, M_DEVBUF); + else + kmem_free(kernel_arena, (vm_offset_t)vaddr, + dmat->common.maxsize); + CTR3(KTR_BUSDMA, "%s: tag %p flags 0x%x", __func__, dmat, + dmat->bounce_flags); +} + +static void +_bus_dmamap_count_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, + bus_size_t buflen, int flags) +{ + bus_addr_t curaddr; + bus_size_t sgsize; + + if ((map != &nobounce_dmamap && map->pagesneeded == 0)) { + /* + * Count the number of bounce pages + * needed in order to complete this transfer + */ + curaddr = buf; + while (buflen != 0) { + sgsize = MIN(buflen, dmat->common.maxsegsz); + if (bus_dma_run_filter(&dmat->common, curaddr)) { + sgsize = MIN(sgsize, PAGE_SIZE); + map->pagesneeded++; + } + curaddr += sgsize; + buflen -= sgsize; + } + CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); + } +} + +static void +_bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, + void *buf, bus_size_t buflen, int flags) +{ + vm_offset_t vaddr; + vm_offset_t vendaddr; + bus_addr_t paddr; + bus_size_t sg_len; + + if ((map != &nobounce_dmamap && map->pagesneeded == 0)) { + CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, " + "alignment= %d", dmat->common.lowaddr, + ptoa((vm_paddr_t)Maxmem), + dmat->common.boundary, dmat->common.alignment); + CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d", + map, &nobounce_dmamap, map->pagesneeded); + /* + * Count the number of bounce pages + * needed in order to complete this transfer + */ + vaddr = (vm_offset_t)buf; + vendaddr = (vm_offset_t)buf + buflen; + + while (vaddr < vendaddr) { + sg_len = PAGE_SIZE - ((vm_offset_t)vaddr & PAGE_MASK); + if (pmap == kernel_pmap) + paddr = pmap_kextract(vaddr); + else + paddr = pmap_extract(pmap, vaddr); + if (bus_dma_run_filter(&dmat->common, paddr) != 0) { + sg_len = roundup2(sg_len, + dmat->common.alignment); + map->pagesneeded++; + } + vaddr += sg_len; + } + CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded); + } +} + +static int +_bus_dmamap_reserve_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int flags) +{ + + /* Reserve Necessary Bounce Pages */ + mtx_lock(&bounce_lock); + if (flags & BUS_DMA_NOWAIT) { + if (reserve_bounce_pages(dmat, map, 0) != 0) { + mtx_unlock(&bounce_lock); + return (ENOMEM); + } + } else { + if (reserve_bounce_pages(dmat, map, 1) != 0) { + /* Queue us for resources */ + STAILQ_INSERT_TAIL(&bounce_map_waitinglist, map, links); + mtx_unlock(&bounce_lock); + return (EINPROGRESS); + } + } + mtx_unlock(&bounce_lock); + + return (0); +} + +/* + * Add a single contiguous physical range to the segment list. + */ +static int +_bus_dmamap_addseg(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t curaddr, + bus_size_t sgsize, bus_dma_segment_t *segs, int *segp) +{ + bus_addr_t baddr, bmask; + int seg; + + /* + * Make sure we don't cross any boundaries. + */ + bmask = ~(dmat->common.boundary - 1); + if (dmat->common.boundary > 0) { + baddr = (curaddr + dmat->common.boundary) & bmask; + if (sgsize > (baddr - curaddr)) + sgsize = (baddr - curaddr); + } + + /* + * Insert chunk into a segment, coalescing with + * previous segment if possible. + */ + seg = *segp; + if (seg == -1) { + seg = 0; + segs[seg].ds_addr = curaddr; + segs[seg].ds_len = sgsize; + } else { + if (curaddr == segs[seg].ds_addr + segs[seg].ds_len && + (segs[seg].ds_len + sgsize) <= dmat->common.maxsegsz && + (dmat->common.boundary == 0 || + (segs[seg].ds_addr & bmask) == (curaddr & bmask))) + segs[seg].ds_len += sgsize; + else { + if (++seg >= dmat->common.nsegments) + return (0); + segs[seg].ds_addr = curaddr; + segs[seg].ds_len = sgsize; + } + } + *segp = seg; + return (sgsize); +} + +/* + * Utility function to load a physical buffer. segp contains + * the starting segment on entrace, and the ending segment on exit. + */ +static int +bounce_bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, + vm_paddr_t buf, bus_size_t buflen, int flags, bus_dma_segment_t *segs, + int *segp) +{ + bus_size_t sgsize; + bus_addr_t curaddr; + int error; + + if (map == NULL) + map = &nobounce_dmamap; + + if (segs == NULL) + segs = dmat->segments; + + if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) { + _bus_dmamap_count_phys(dmat, map, buf, buflen, flags); + if (map->pagesneeded != 0) { + error = _bus_dmamap_reserve_pages(dmat, map, flags); + if (error) + return (error); + } + } + + while (buflen > 0) { + curaddr = buf; + sgsize = MIN(buflen, dmat->common.maxsegsz); + if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) && + map->pagesneeded != 0 && + bus_dma_run_filter(&dmat->common, curaddr)) { + sgsize = MIN(sgsize, PAGE_SIZE); + curaddr = add_bounce_page(dmat, map, 0, curaddr, + sgsize); + } + sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs, + segp); + if (sgsize == 0) + break; + buf += sgsize; + buflen -= sgsize; + } + + /* + * Did we fit? + */ + return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */ +} + +/* + * Utility function to load a linear buffer. segp contains + * the starting segment on entrace, and the ending segment on exit. + */ +static int +bounce_bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, + bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs, + int *segp) +{ + bus_size_t sgsize, max_sgsize; + bus_addr_t curaddr; + vm_offset_t vaddr; + int error; + + if (map == NULL) + map = &nobounce_dmamap; + + if (segs == NULL) + segs = dmat->segments; + + if ((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) { + _bus_dmamap_count_pages(dmat, map, pmap, buf, buflen, flags); + if (map->pagesneeded != 0) { + error = _bus_dmamap_reserve_pages(dmat, map, flags); + if (error) + return (error); + } + } + + vaddr = (vm_offset_t)buf; + while (buflen > 0) { + /* + * Get the physical address for this segment. + */ + if (pmap == kernel_pmap) + curaddr = pmap_kextract(vaddr); + else + curaddr = pmap_extract(pmap, vaddr); + + /* + * Compute the segment size, and adjust counts. + */ + max_sgsize = MIN(buflen, dmat->common.maxsegsz); + sgsize = PAGE_SIZE - ((vm_offset_t)curaddr & PAGE_MASK); + if (((dmat->bounce_flags & BUS_DMA_COULD_BOUNCE) != 0) && + map->pagesneeded != 0 && + bus_dma_run_filter(&dmat->common, curaddr)) { + sgsize = roundup2(sgsize, dmat->common.alignment); + sgsize = MIN(sgsize, max_sgsize); + curaddr = add_bounce_page(dmat, map, vaddr, curaddr, + sgsize); + } else { + sgsize = MIN(sgsize, max_sgsize); + } + sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs, + segp); + if (sgsize == 0) + break; + vaddr += sgsize; + buflen -= sgsize; + } + + /* + * Did we fit? + */ + return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */ +} + +static void +bounce_bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map, + struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg) +{ + + if (map == NULL) + return; + map->mem = *mem; + map->dmat = dmat; + map->callback = callback; + map->callback_arg = callback_arg; +} + +static bus_dma_segment_t * +bounce_bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map, + bus_dma_segment_t *segs, int nsegs, int error) +{ + + if (segs == NULL) + segs = dmat->segments; + return (segs); +} + +/* + * Release the mapping held by map. + */ +static void +bounce_bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) +{ + struct bounce_page *bpage; + + while ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { + STAILQ_REMOVE_HEAD(&map->bpages, links); + free_bounce_page(dmat, bpage); + } +} + +static void +bounce_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, + bus_dmasync_op_t op) +{ + struct bounce_page *bpage; + + /* + * XXX ARM64TODO: + * This bus_dma implementation requires IO-Coherent architecutre. + * If IO-Coherency is not guaranteed, cache operations have to be + * added to this function. + */ + + if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { + /* + * Handle data bouncing. We might also + * want to add support for invalidating + * the caches on broken hardware + */ + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " + "performing bounce", __func__, dmat, + dmat->common.flags, op); + + if ((op & BUS_DMASYNC_PREWRITE) != 0) { + while (bpage != NULL) { + if (bpage->datavaddr != 0) { + bcopy((void *)bpage->datavaddr, + (void *)bpage->vaddr, + bpage->datacount); + } else { + physcopyout(bpage->dataaddr, + (void *)bpage->vaddr, + bpage->datacount); + } + bpage = STAILQ_NEXT(bpage, links); + } + dmat->bounce_zone->total_bounced++; + } + + if ((op & BUS_DMASYNC_POSTREAD) != 0) { + while (bpage != NULL) { + if (bpage->datavaddr != 0) { + bcopy((void *)bpage->vaddr, + (void *)bpage->datavaddr, + bpage->datacount); + } else { + physcopyin((void *)bpage->vaddr, + bpage->dataaddr, + bpage->datacount); + } + bpage = STAILQ_NEXT(bpage, links); + } + dmat->bounce_zone->total_bounced++; + } + } +} + +static void +init_bounce_pages(void *dummy __unused) +{ + + total_bpages = 0; + STAILQ_INIT(&bounce_zone_list); + STAILQ_INIT(&bounce_map_waitinglist); + STAILQ_INIT(&bounce_map_callbacklist); + mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); +} +SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); + +static struct sysctl_ctx_list * +busdma_sysctl_tree(struct bounce_zone *bz) +{ + return (&bz->sysctl_tree); +} + +static struct sysctl_oid * +busdma_sysctl_tree_top(struct bounce_zone *bz) +{ + return (bz->sysctl_tree_top); +} + +static int +alloc_bounce_zone(bus_dma_tag_t dmat) +{ + struct bounce_zone *bz; + + /* Check to see if we already have a suitable zone */ + STAILQ_FOREACH(bz, &bounce_zone_list, links) { + if ((dmat->common.alignment <= bz->alignment) && + (dmat->common.lowaddr >= bz->lowaddr)) { + dmat->bounce_zone = bz; + return (0); + } + } + + if ((bz = (struct bounce_zone *)malloc(sizeof(*bz), M_DEVBUF, + M_NOWAIT | M_ZERO)) == NULL) + return (ENOMEM); + + STAILQ_INIT(&bz->bounce_page_list); + bz->free_bpages = 0; + bz->reserved_bpages = 0; + bz->active_bpages = 0; + bz->lowaddr = dmat->common.lowaddr; + bz->alignment = MAX(dmat->common.alignment, PAGE_SIZE); + bz->map_count = 0; + snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); + busdma_zonecount++; + snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); + STAILQ_INSERT_TAIL(&bounce_zone_list, bz, links); + dmat->bounce_zone = bz; + + sysctl_ctx_init(&bz->sysctl_tree); + bz->sysctl_tree_top = SYSCTL_ADD_NODE(&bz->sysctl_tree, + SYSCTL_STATIC_CHILDREN(_hw_busdma), OID_AUTO, bz->zoneid, + CTLFLAG_RD, 0, ""); + if (bz->sysctl_tree_top == NULL) { + sysctl_ctx_free(&bz->sysctl_tree); + return (0); /* XXX error code? */ + } + + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_bpages", CTLFLAG_RD, &bz->total_bpages, 0, + "Total bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "free_bpages", CTLFLAG_RD, &bz->free_bpages, 0, + "Free bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "reserved_bpages", CTLFLAG_RD, &bz->reserved_bpages, 0, + "Reserved bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "active_bpages", CTLFLAG_RD, &bz->active_bpages, 0, + "Active bounce pages"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_bounced", CTLFLAG_RD, &bz->total_bounced, 0, + "Total bounce requests"); + SYSCTL_ADD_INT(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "total_deferred", CTLFLAG_RD, &bz->total_deferred, 0, + "Total bounce requests that were deferred"); + SYSCTL_ADD_STRING(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "lowaddr", CTLFLAG_RD, bz->lowaddrid, 0, ""); + SYSCTL_ADD_UAUTO(busdma_sysctl_tree(bz), + SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, + "alignment", CTLFLAG_RD, &bz->alignment, ""); + + return (0); +} + +static int +alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) +{ + struct bounce_zone *bz; + int count; + + bz = dmat->bounce_zone; + count = 0; + while (numpages > 0) { + struct bounce_page *bpage; + + bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF, + M_NOWAIT | M_ZERO); + + if (bpage == NULL) + break; + bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF, + M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, 0); + if (bpage->vaddr == 0) { + free(bpage, M_DEVBUF); + break; + } + bpage->busaddr = pmap_kextract(bpage->vaddr); + mtx_lock(&bounce_lock); + STAILQ_INSERT_TAIL(&bz->bounce_page_list, bpage, links); + total_bpages++; + bz->total_bpages++; + bz->free_bpages++; + mtx_unlock(&bounce_lock); + count++; + numpages--; + } + return (count); +} + +static int +reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map, int commit) +{ + struct bounce_zone *bz; + int pages; + + mtx_assert(&bounce_lock, MA_OWNED); + bz = dmat->bounce_zone; + pages = MIN(bz->free_bpages, map->pagesneeded - map->pagesreserved); + if (commit == 0 && map->pagesneeded > (map->pagesreserved + pages)) + return (map->pagesneeded - (map->pagesreserved + pages)); + bz->free_bpages -= pages; + bz->reserved_bpages += pages; + map->pagesreserved += pages; + pages = map->pagesneeded - map->pagesreserved; + + return (pages); +} + +static bus_addr_t +add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr, + bus_addr_t addr, bus_size_t size) +{ + struct bounce_zone *bz; + struct bounce_page *bpage; + + KASSERT(dmat->bounce_zone != NULL, ("no bounce zone in dma tag")); + KASSERT(map != NULL && map != &nobounce_dmamap, + ("add_bounce_page: bad map %p", map)); + + bz = dmat->bounce_zone; + if (map->pagesneeded == 0) + panic("add_bounce_page: map doesn't need any pages"); + map->pagesneeded--; + + if (map->pagesreserved == 0) + panic("add_bounce_page: map doesn't need any pages"); + map->pagesreserved--; + + mtx_lock(&bounce_lock); + bpage = STAILQ_FIRST(&bz->bounce_page_list); + if (bpage == NULL) + panic("add_bounce_page: free page list is empty"); + + STAILQ_REMOVE_HEAD(&bz->bounce_page_list, links); + bz->reserved_bpages--; + bz->active_bpages++; + mtx_unlock(&bounce_lock); + + if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) { + /* Page offset needs to be preserved. */ + bpage->vaddr |= addr & PAGE_MASK; + bpage->busaddr |= addr & PAGE_MASK; + } + bpage->datavaddr = vaddr; + bpage->dataaddr = addr; + bpage->datacount = size; + STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); + return (bpage->busaddr); +} + +static void +free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage) +{ + struct bus_dmamap *map; + struct bounce_zone *bz; + + bz = dmat->bounce_zone; + bpage->datavaddr = 0; + bpage->datacount = 0; + if (dmat->common.flags & BUS_DMA_KEEP_PG_OFFSET) { + /* + * Reset the bounce page to start at offset 0. Other uses + * of this bounce page may need to store a full page of + * data and/or assume it starts on a page boundary. + */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + } + + mtx_lock(&bounce_lock); + STAILQ_INSERT_HEAD(&bz->bounce_page_list, bpage, links); + bz->free_bpages++; + bz->active_bpages--; + if ((map = STAILQ_FIRST(&bounce_map_waitinglist)) != NULL) { + if (reserve_bounce_pages(map->dmat, map, 1) == 0) { + STAILQ_REMOVE_HEAD(&bounce_map_waitinglist, links); + STAILQ_INSERT_TAIL(&bounce_map_callbacklist, + map, links); + busdma_swi_pending = 1; + bz->total_deferred++; + swi_sched(vm_ih, 0); + } + } + mtx_unlock(&bounce_lock); +} + +void +busdma_swi(void) +{ + bus_dma_tag_t dmat; + struct bus_dmamap *map; + + mtx_lock(&bounce_lock); + while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) { + STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links); + mtx_unlock(&bounce_lock); + dmat = map->dmat; + (dmat->common.lockfunc)(dmat->common.lockfuncarg, BUS_DMA_LOCK); + bus_dmamap_load_mem(map->dmat, map, &map->mem, + map->callback, map->callback_arg, BUS_DMA_WAITOK); + (dmat->common.lockfunc)(dmat->common.lockfuncarg, + BUS_DMA_UNLOCK); + mtx_lock(&bounce_lock); + } + mtx_unlock(&bounce_lock); +} + +struct bus_dma_impl bus_dma_bounce_impl = { + .tag_create = bounce_bus_dma_tag_create, + .tag_destroy = bounce_bus_dma_tag_destroy, + .map_create = bounce_bus_dmamap_create, + .map_destroy = bounce_bus_dmamap_destroy, + .mem_alloc = bounce_bus_dmamem_alloc, + .mem_free = bounce_bus_dmamem_free, + .load_phys = bounce_bus_dmamap_load_phys, + .load_buffer = bounce_bus_dmamap_load_buffer, + .load_ma = bus_dmamap_load_ma_triv, + .map_waitok = bounce_bus_dmamap_waitok, + .map_complete = bounce_bus_dmamap_complete, + .map_unload = bounce_bus_dmamap_unload, + .map_sync = bounce_bus_dmamap_sync +}; diff --git a/sys/arm64/arm64/busdma_machdep.c b/sys/arm64/arm64/busdma_machdep.c index 4a89b1f..df7a8be 100644 --- a/sys/arm64/arm64/busdma_machdep.c +++ b/sys/arm64/arm64/busdma_machdep.c @@ -1,22 +1,292 @@ -/* $FreeBSD$ */ +/*- + * Copyright (c) 1997, 1998 Justin T. Gibbs. + * Copyright (c) 2013, 2015 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Portions of this software were developed by Semihalf + * under sponsorship of the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. 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 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 <sys/cdefs.h> __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> - +#include <sys/malloc.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/ktr.h> +#include <sys/lock.h> +#include <sys/memdesc.h> +#include <sys/mutex.h> +#include <sys/uio.h> #include <vm/vm.h> +#include <vm/vm_extern.h> #include <vm/pmap.h> #include <machine/bus.h> +#include <arm64/include/bus_dma_impl.h> + +/* + * Convenience function for manipulating driver locks from busdma (during + * busdma_swi, for example). Drivers that don't provide their own locks + * should specify &Giant to dmat->lockfuncarg. Drivers that use their own + * non-mutex locking scheme don't have to use this at all. + */ +void +busdma_lock_mutex(void *arg, bus_dma_lock_op_t op) +{ + struct mtx *dmtx; + + dmtx = (struct mtx *)arg; + switch (op) { + case BUS_DMA_LOCK: + mtx_lock(dmtx); + break; + case BUS_DMA_UNLOCK: + mtx_unlock(dmtx); + break; + default: + panic("Unknown operation 0x%x for busdma_lock_mutex!", op); + } +} + +/* + * dflt_lock should never get called. It gets put into the dma tag when + * lockfunc == NULL, which is only valid if the maps that are associated + * with the tag are meant to never be defered. + * XXX Should have a way to identify which driver is responsible here. + */ +void +bus_dma_dflt_lock(void *arg, bus_dma_lock_op_t op) +{ + + panic("driver error: busdma dflt_lock called"); +} + +/* + * Return true if a match is made. + * + * To find a match walk the chain of bus_dma_tag_t's looking for 'paddr'. + * + * If paddr is within the bounds of the dma tag then call the filter callback + * to check for a match, if there is no filter callback then assume a match. + */ +int +bus_dma_run_filter(struct bus_dma_tag_common *tc, bus_addr_t paddr) +{ + int retval; + + retval = 0; + do { + if (((paddr > tc->lowaddr && paddr <= tc->highaddr) || + ((paddr & (tc->alignment - 1)) != 0)) && + (tc->filter == NULL || + (*tc->filter)(tc->filterarg, paddr) != 0)) + retval = 1; + + tc = tc->parent; + } while (retval == 0 && tc != NULL); + return (retval); +} + +int +common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg, + bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, + bus_dma_lock_t *lockfunc, void *lockfuncarg, size_t sz, void **dmat) +{ + void *newtag; + struct bus_dma_tag_common *common; + + KASSERT(sz >= sizeof(struct bus_dma_tag_common), ("sz")); + /* Return a NULL tag on failure */ + *dmat = NULL; + /* Basic sanity checking */ + if (boundary != 0 && boundary < maxsegsz) + maxsegsz = boundary; + if (maxsegsz == 0) + return (EINVAL); + + newtag = malloc(sz, M_DEVBUF, M_ZERO | M_NOWAIT); + if (newtag == NULL) { + CTR4(KTR_BUSDMA, "%s returned tag %p tag flags 0x%x error %d", + __func__, newtag, 0, ENOMEM); + return (ENOMEM); + } + + common = newtag; + common->impl = &bus_dma_bounce_impl; + common->parent = parent; + common->alignment = alignment; + common->boundary = boundary; + common->lowaddr = trunc_page((vm_paddr_t)lowaddr) + (PAGE_SIZE - 1); + common->highaddr = trunc_page((vm_paddr_t)highaddr) + (PAGE_SIZE - 1); + common->filter = filter; + common->filterarg = filterarg; + common->maxsize = maxsize; + common->nsegments = nsegments; + common->maxsegsz = maxsegsz; + common->flags = flags; + common->ref_count = 1; /* Count ourself */ + if (lockfunc != NULL) { + common->lockfunc = lockfunc; + common->lockfuncarg = lockfuncarg; + } else { + common->lockfunc = bus_dma_dflt_lock; + common->lockfuncarg = NULL; + } + + /* Take into account any restrictions imposed by our parent tag */ + if (parent != NULL) { + common->impl = parent->impl; + common->lowaddr = MIN(parent->lowaddr, common->lowaddr); + common->highaddr = MAX(parent->highaddr, common->highaddr); + if (common->boundary == 0) + common->boundary = parent->boundary; + else if (parent->boundary != 0) { + common->boundary = MIN(parent->boundary, + common->boundary); + } + if (common->filter == NULL) { + /* + * Short circuit looking at our parent directly + * since we have encapsulated all of its information + */ + common->filter = parent->filter; + common->filterarg = parent->filterarg; + common->parent = parent->parent; + } + atomic_add_int(&parent->ref_count, 1); + } + *dmat = common; + return (0); +} + +/* + * Allocate a device specific dma_tag. + */ +int +bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, + bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, + int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, bus_dma_tag_t *dmat) +{ + struct bus_dma_tag_common *tc; + int error; + + if (parent == NULL) { + error = bus_dma_bounce_impl.tag_create(parent, alignment, + boundary, lowaddr, highaddr, filter, filterarg, maxsize, + nsegments, maxsegsz, flags, lockfunc, lockfuncarg, dmat); + } else { + tc = (struct bus_dma_tag_common *)parent; + error = tc->impl->tag_create(parent, alignment, + boundary, lowaddr, highaddr, filter, filterarg, maxsize, + nsegments, maxsegsz, flags, lockfunc, lockfuncarg, dmat); + } + return (error); +} + +int +bus_dma_tag_destroy(bus_dma_tag_t dmat) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->tag_destroy(dmat)); +} + +/* + * Allocate a handle for mapping from kva/uva/physical + * address space into bus device space. + */ +int +bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->map_create(dmat, flags, mapp)); +} + +/* + * Destroy a handle for mapping from kva/uva/physical + * address space into bus device space. + */ +int +bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->map_destroy(dmat, map)); +} + + +/* + * Allocate a piece of memory that can be efficiently mapped into + * bus device space based on the constraints listed in the dma tag. + * A dmamap to for use with dmamap_load is also allocated. + */ +int +bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->mem_alloc(dmat, vaddr, flags, mapp)); +} + +/* + * Free a piece of memory and it's allociated dmamap, that was allocated + * via bus_dmamem_alloc. Make the same choice for free/contigfree. + */ +void +bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) +{ + struct bus_dma_tag_common *tc; + + tc = (struct bus_dma_tag_common *)dmat; + tc->impl->mem_free(dmat, vaddr, map); +} int _bus_dmamap_load_phys(bus_dma_tag_t dmat, bus_dmamap_t map, vm_paddr_t buf, bus_size_t buflen, int flags, bus_dma_segment_t *segs, int *segp) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_load_phys"); + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->load_phys(dmat, map, buf, buflen, flags, segs, + segp)); } int @@ -24,8 +294,11 @@ _bus_dmamap_load_ma(bus_dma_tag_t dmat, bus_dmamap_t map, struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags, bus_dma_segment_t *segs, int *segp) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_load_ma"); + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->load_ma(dmat, map, ma, tlen, ma_offs, flags, + segs, segp)); } int @@ -33,36 +306,50 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, bus_size_t buflen, pmap_t pmap, int flags, bus_dma_segment_t *segs, int *segp) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_load_buffer"); + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->load_buffer(dmat, map, buf, buflen, pmap, flags, segs, + segp)); } void __bus_dmamap_waitok(bus_dma_tag_t dmat, bus_dmamap_t map, struct memdesc *mem, bus_dmamap_callback_t *callback, void *callback_arg) { + struct bus_dma_tag_common *tc; - panic("__bus_dmamap_waitok"); + tc = (struct bus_dma_tag_common *)dmat; + tc->impl->map_waitok(dmat, map, mem, callback, callback_arg); } bus_dma_segment_t * _bus_dmamap_complete(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dma_segment_t *segs, int nsegs, int error) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_complete"); + tc = (struct bus_dma_tag_common *)dmat; + return (tc->impl->map_complete(dmat, map, segs, nsegs, error)); } +/* + * Release the mapping held by map. + */ void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_unload"); + tc = (struct bus_dma_tag_common *)dmat; + tc->impl->map_unload(dmat, map); } void _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) { + struct bus_dma_tag_common *tc; - panic("_bus_dmamap_sync"); + tc = (struct bus_dma_tag_common *)dmat; + tc->impl->map_sync(dmat, map, op); } diff --git a/sys/arm64/include/bus_dma_impl.h b/sys/arm64/include/bus_dma_impl.h new file mode 100644 index 0000000..354290e --- /dev/null +++ b/sys/arm64/include/bus_dma_impl.h @@ -0,0 +1,96 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov <kib@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_BUS_DMA_IMPL_H_ +#define _MACHINE_BUS_DMA_IMPL_H_ + +struct bus_dma_tag_common { + struct bus_dma_impl *impl; + struct bus_dma_tag_common *parent; + bus_size_t alignment; + bus_addr_t boundary; + bus_addr_t lowaddr; + bus_addr_t highaddr; + bus_dma_filter_t *filter; + void *filterarg; + bus_size_t maxsize; + u_int nsegments; + bus_size_t maxsegsz; + int flags; + bus_dma_lock_t *lockfunc; + void *lockfuncarg; + int ref_count; +}; + +struct bus_dma_impl { + int (*tag_create)(bus_dma_tag_t parent, + bus_size_t alignment, bus_addr_t boundary, bus_addr_t lowaddr, + bus_addr_t highaddr, bus_dma_filter_t *filter, + void *filterarg, bus_size_t maxsize, int nsegments, + bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, bus_dma_tag_t *dmat); + int (*tag_destroy)(bus_dma_tag_t dmat); + int (*map_create)(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp); + int (*map_destroy)(bus_dma_tag_t dmat, bus_dmamap_t map); + int (*mem_alloc)(bus_dma_tag_t dmat, void** vaddr, int flags, + bus_dmamap_t *mapp); + void (*mem_free)(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map); + int (*load_ma)(bus_dma_tag_t dmat, bus_dmamap_t map, + struct vm_page **ma, bus_size_t tlen, int ma_offs, int flags, + bus_dma_segment_t *segs, int *segp); + int (*load_phys)(bus_dma_tag_t dmat, bus_dmamap_t map, + vm_paddr_t buf, bus_size_t buflen, int flags, + bus_dma_segment_t *segs, int *segp); + int (*load_buffer)(bus_dma_tag_t dmat, bus_dmamap_t map, + void *buf, bus_size_t buflen, pmap_t pmap, int flags, + bus_dma_segment_t *segs, int *segp); + void (*map_waitok)(bus_dma_tag_t dmat, bus_dmamap_t map, + struct memdesc *mem, bus_dmamap_callback_t *callback, + void *callback_arg); + bus_dma_segment_t *(*map_complete)(bus_dma_tag_t dmat, bus_dmamap_t map, + bus_dma_segment_t *segs, int nsegs, int error); + void (*map_unload)(bus_dma_tag_t dmat, bus_dmamap_t map); + void (*map_sync)(bus_dma_tag_t dmat, bus_dmamap_t map, + bus_dmasync_op_t op); +}; + +void bus_dma_dflt_lock(void *arg, bus_dma_lock_op_t op); +int bus_dma_run_filter(struct bus_dma_tag_common *dmat, bus_addr_t paddr); +int common_bus_dma_tag_create(struct bus_dma_tag_common *parent, + bus_size_t alignment, + bus_addr_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, + int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, size_t sz, void **dmat); + +extern struct bus_dma_impl bus_dma_bounce_impl; + +#endif diff --git a/sys/boot/arm/uboot/ldscript.arm b/sys/boot/arm/uboot/ldscript.arm index b3be119..1eb10a8 100644 --- a/sys/boot/arm/uboot/ldscript.arm +++ b/sys/boot/arm/uboot/ldscript.arm @@ -6,6 +6,15 @@ SECTIONS { /* Read-only sections, merged into text segment: */ . = UBLDR_LOADADDR + SIZEOF_HEADERS; + .text : + { + *(.text) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + _etext = .; + PROVIDE (etext = .); .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } @@ -32,15 +41,6 @@ SECTIONS .rela.sbss : { *(.rela.sbss) } .rela.sdata2 : { *(.rela.sdata2) } .rela.sbss2 : { *(.rela.sbss2) } - .text : - { - *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - } =0 - _etext = .; - PROVIDE (etext = .); .init : { *(.init) } =0 .fini : { *(.fini) } =0 .rodata : { *(.rodata) *(.gnu.linkonce.r*) } diff --git a/sys/boot/fdt/dts/arm/odroidc1.dts b/sys/boot/fdt/dts/arm/odroidc1.dts index c65344b..3079a9f 100644 --- a/sys/boot/fdt/dts/arm/odroidc1.dts +++ b/sys/boot/fdt/dts/arm/odroidc1.dts @@ -194,7 +194,6 @@ compatible = "amlogic,aml8726-rtc"; reg = <0xc8100740 20>; /* aobus 0x1d0 */ interrupts = <0 72 1>; - interrupt-parent = <&gic>; init-always = "false"; xo-init = <0x180a>; @@ -246,7 +245,6 @@ compatible = "amlogic,aml8726-mmc"; reg = <0xc1108c20 32>; /* cbus 0x2308 */ interrupts = <0 28 1>; - interrupt-parent = <&gic>; clocks = <&clk81>; @@ -274,7 +272,6 @@ clock-frequency = <1275000000>; reg = <0xc1108e00 60>; /* cbus 0x2380 */ interrupts = <0 78 1>; - interrupt-parent = <&gic>; pinctrl-names = "default"; pinctrl-0 = <&pins_sdxc_c>; @@ -311,7 +308,6 @@ compatible = "synopsys,designware-hs-otg2"; reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/ interrupts = <0 30 4>; - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; @@ -323,7 +319,6 @@ compatible = "synopsys,designware-hs-otg2"; reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */ interrupts = <0 31 4>; - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; @@ -335,7 +330,6 @@ compatible = "snps,dwmac"; reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */ interrupts = <0 8 1>; - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; @@ -352,7 +346,6 @@ <0 3 1>, <0 12 1>, <0 13 1>; - interrupt-parent = <&gic>; address = <0x7900000>; /* match memreserve */ width = <720>; diff --git a/sys/boot/fdt/dts/arm/rpi2.dts b/sys/boot/fdt/dts/arm/rpi2.dts index 1c8c559..e32cfb0 100644 --- a/sys/boot/fdt/dts/arm/rpi2.dts +++ b/sys/boot/fdt/dts/arm/rpi2.dts @@ -43,6 +43,24 @@ reg = <0xf00>; /* CPU ID=0xf00 */ clock-frequency = <800000000>; /* 800MHz */ }; + cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf01>; /* CPU ID=0xf01 */ + clock-frequency = <800000000>; /* 800MHz */ + }; + cpu@2 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf02>; /* CPU ID=0xf02 */ + clock-frequency = <800000000>; /* 800MHz */ + }; + cpu@3 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0xf03>; /* CPU ID=0xf03 */ + clock-frequency = <800000000>; /* 800MHz */ + }; }; memory { diff --git a/sys/boot/fdt/dts/arm/vsatv102-m6.dts b/sys/boot/fdt/dts/arm/vsatv102-m6.dts index ad3b5a1..3ca8fc9 100644 --- a/sys/boot/fdt/dts/arm/vsatv102-m6.dts +++ b/sys/boot/fdt/dts/arm/vsatv102-m6.dts @@ -153,7 +153,6 @@ compatible = "amlogic,aml8726-rtc"; reg = <0xda004340 20>; /* secbus2 0xd0 */ interrupts = <0 72 1>; /* AM_IRQ2(8) */ - interrupt-parent = <&gic>; init-always = "false"; xo-init = <0x180a>; @@ -205,7 +204,6 @@ compatible = "amlogic,aml8726-mmc"; reg = <0xc1108c20 32>; /* cbus 0x2308 */ interrupts = <0 28 1>; /* AM_IRQ0(28) */ - interrupt-parent = <&gic>; clocks = <&clk81>; @@ -243,7 +241,6 @@ compatible = "synopsys,designware-hs-otg2"; reg = <0xc9040000 0x40000>; /* ahbbus 0x40000*/ interrupts = <0 30 4>; /* AM_IRQ0(30) */ - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; }; @@ -253,7 +250,6 @@ compatible = "synopsys,designware-hs-otg2"; reg = <0xc90c0000 0x40000>; /* ahbbus 0xc0000 */ interrupts = <0 31 4>; /* AM_IRQ0(31) */ - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; @@ -265,7 +261,6 @@ compatible = "snps,dwmac"; reg = <0xc9410000 0x2000>; /* ahbbus 0x410000 */ interrupts = <0 8 1>; /* AM_IRQ0(8) */ - interrupt-parent = <&gic>; #address-cells = <1>; #size-cells = <0>; @@ -282,7 +277,6 @@ <0 3 1>, /* AM_IRQ0(3) */ <0 12 1>, /* AM_IRQ0(12) */ <0 13 1>; /* AM_IRQ0(13) */ - interrupt-parent = <&gic>; address = <0x84900000>; /* match memreserve */ width = <720>; diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index a922967..b5582e9 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -521,7 +521,7 @@ ctl_be_block_biodone(struct bio *bio) if (beio->num_errors > 0) { if (error == EOPNOTSUPP) { ctl_set_invalid_opcode(&io->scsiio); - } else if (error == ENOSPC) { + } else if (error == ENOSPC || error == EDQUOT) { ctl_set_space_alloc_fail(&io->scsiio); } else if (beio->bio_cmd == BIO_FLUSH) { /* XXX KDM is there is a better error here? */ @@ -738,7 +738,7 @@ ctl_be_block_dispatch_file(struct ctl_be_block_lun *be_lun, ctl_scsi_path_string(io, path_str, sizeof(path_str)); printf("%s%s command returned errno %d\n", path_str, (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE", error); - if (error == ENOSPC) { + if (error == ENOSPC || error == EDQUOT) { ctl_set_space_alloc_fail(&io->scsiio); } else ctl_set_medium_error(&io->scsiio); @@ -895,7 +895,7 @@ ctl_be_block_dispatch_zvol(struct ctl_be_block_lun *be_lun, * return the I/O to the user. */ if (error != 0) { - if (error == ENOSPC) { + if (error == ENOSPC || error == EDQUOT) { ctl_set_space_alloc_fail(&io->scsiio); } else ctl_set_medium_error(&io->scsiio); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c index cbccad3..a0c1377 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c @@ -1142,7 +1142,8 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx) } dsobj = dsl_dataset_create_sync(ds->ds_dir, recv_clone_name, snap, crflags, drba->drba_cred, tx); - dsl_dataset_rele(snap, FTAG); + if (drba->drba_snapobj != 0) + dsl_dataset_rele(snap, FTAG); dsl_dataset_rele(ds, FTAG); } else { dsl_dir_t *dd; diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 06c8549..8f00f59 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -576,6 +576,7 @@ options STACK # please see hwpmc(4). device hwpmc # Driver (also a loadable module) +options HWPMC_DEBUG options HWPMC_HOOKS # Other necessary kernel hooks diff --git a/sys/conf/files b/sys/conf/files index caaed94..8d51fe5 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4052,6 +4052,7 @@ xen/xenbus/xenbusb_if.m optional xenhvm xen/xenbus/xenbusb.c optional xenhvm xen/xenbus/xenbusb_front.c optional xenhvm xen/xenbus/xenbusb_back.c optional xenhvm +xen/xenmem/xenmem_if.m optional xenhvm xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index f80fecd..9b1ff0d 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -5,6 +5,7 @@ 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 arm64/arm64/busdma_machdep.c standard arm64/arm64/clock.c standard arm64/arm64/copyinout.S standard diff --git a/sys/conf/options b/sys/conf/options index 6d2a0fa..d7b937d 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -861,6 +861,7 @@ DCONS_FORCE_CONSOLE opt_dcons.h DCONS_FORCE_GDB opt_dcons.h # HWPMC options +HWPMC_DEBUG opt_global.h HWPMC_HOOKS HWPMC_MIPS_BACKTRACE opt_hwpmc_hooks.h diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 7796fbe..2176191 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -605,9 +605,11 @@ acpi_attach(device_t dev) if (AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) sc->acpi_handle_reboot = 1; +#if !ACPI_REDUCED_HARDWARE /* Only enable S4BIOS by default if the FACS says it is available. */ if (AcpiGbl_FACS != NULL && AcpiGbl_FACS->Flags & ACPI_FACS_S4_BIOS_PRESENT) sc->acpi_s4bios = 1; +#endif /* Probe all supported sleep states. */ acpi_sleep_states[ACPI_STATE_S0] = TRUE; diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 8df2782..a24ba4e 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #if defined(__amd64__) || defined(__i386__) #include <machine/clock.h> +#include <machine/specialreg.h> +#include <machine/md_var.h> #endif #include <sys/rman.h> @@ -70,6 +72,10 @@ struct acpi_cx { uint32_t power; /* Power consumed (mW). */ int res_type; /* Resource type for p_lvlx. */ int res_rid; /* Resource ID for p_lvlx. */ + bool do_mwait; + uint32_t mwait_hint; + bool mwait_hw_coord; + bool mwait_bm_avoidance; }; #define MAX_CX_STATES 8 @@ -128,6 +134,12 @@ struct acpi_cpu_device { #define PIIX4_STOP_BREAK_MASK (PIIX4_BRLD_EN_IRQ0 | PIIX4_BRLD_EN_IRQ | PIIX4_BRLD_EN_IRQ8) #define PIIX4_PCNTRL_BST_EN (1<<10) +#define CST_FFH_VENDOR_INTEL 1 +#define CST_FFH_INTEL_CL_C1IO 1 +#define CST_FFH_INTEL_CL_MWAIT 2 +#define CST_FFH_MWAIT_HW_COORD 0x0001 +#define CST_FFH_MWAIT_BM_AVOID 0x0002 + /* Allow users to ignore processor orders in MADT. */ static int cpu_unordered; SYSCTL_INT(_debug_acpi, OID_AUTO, cpu_unordered, CTLFLAG_RDTUN, @@ -179,6 +191,9 @@ static int acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc); static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); +#if defined(__i386__) || defined(__amd64__) +static int acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS); +#endif static device_method_t acpi_cpu_methods[] = { /* Device interface */ @@ -348,7 +363,18 @@ acpi_cpu_attach(device_t dev) * so advertise this ourselves. Note this is not the same as independent * SMP control where each CPU can have different settings. */ - sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3; + sc->cpu_features = ACPI_CAP_SMP_SAME | ACPI_CAP_SMP_SAME_C3 | + ACPI_CAP_C1_IO_HALT; + +#if defined(__i386__) || defined(__amd64__) + /* + * Ask for MWAIT modes if not disabled and interrupts work + * reasonable with MWAIT. + */ + if (!acpi_disabled("mwait") && cpu_mwait_usable()) + sc->cpu_features |= ACPI_CAP_SMP_C1_NATIVE | ACPI_CAP_SMP_C3_NATIVE; +#endif + if (devclass_get_drivers(acpi_cpu_devclass, &drivers, &drv_count) == 0) { for (i = 0; i < drv_count; i++) { if (ACPI_GET_FEATURES(drivers[i], &features) == 0) @@ -720,6 +746,27 @@ acpi_cpu_generic_cx_probe(struct acpi_cpu_softc *sc) } } +static void +acpi_cpu_cx_cst_mwait(struct acpi_cx *cx_ptr, uint64_t address, int accsize) +{ + + cx_ptr->do_mwait = true; + cx_ptr->mwait_hint = address & 0xffffffff; + cx_ptr->mwait_hw_coord = (accsize & CST_FFH_MWAIT_HW_COORD) != 0; + cx_ptr->mwait_bm_avoidance = (accsize & CST_FFH_MWAIT_BM_AVOID) != 0; +} + +static void +acpi_cpu_cx_cst_free_plvlx(device_t cpu_dev, struct acpi_cx *cx_ptr) +{ + + if (cx_ptr->p_lvlx == NULL) + return; + bus_release_resource(cpu_dev, cx_ptr->res_type, cx_ptr->res_rid, + cx_ptr->p_lvlx); + cx_ptr->p_lvlx = NULL; +} + /* * Parse a _CST package and set up its Cx states. Since the _CST object * can change dynamically, our notify handler may call this function @@ -734,7 +781,8 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) ACPI_OBJECT *top; ACPI_OBJECT *pkg; uint32_t count; - int i; + uint64_t address; + int i, vendor, class, accsize; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -790,6 +838,30 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) /* Validate the state to see if we should use it. */ switch (cx_ptr->type) { case ACPI_STATE_C1: + acpi_cpu_cx_cst_free_plvlx(sc->cpu_dev, cx_ptr); +#if defined(__i386__) || defined(__amd64__) + if (acpi_PkgFFH_IntelCpu(pkg, 0, &vendor, &class, &address, + &accsize) == 0 && vendor == CST_FFH_VENDOR_INTEL) { + if (class == CST_FFH_INTEL_CL_C1IO) { + /* C1 I/O then Halt */ + cx_ptr->res_rid = sc->cpu_cx_count; + bus_set_resource(sc->cpu_dev, SYS_RES_IOPORT, + cx_ptr->res_rid, address, 1); + cx_ptr->p_lvlx = bus_alloc_resource_any(sc->cpu_dev, + SYS_RES_IOPORT, &cx_ptr->res_rid, RF_ACTIVE | + RF_SHAREABLE); + if (cx_ptr->p_lvlx == NULL) { + bus_delete_resource(sc->cpu_dev, SYS_RES_IOPORT, + cx_ptr->res_rid); + device_printf(sc->cpu_dev, + "C1 I/O failed to allocate port %d, " + "degrading to C1 Halt", (int)address); + } + } else if (class == CST_FFH_INTEL_CL_MWAIT) { + acpi_cpu_cx_cst_mwait(cx_ptr, address, accsize); + } + } +#endif if (sc->cpu_cx_states[0].type == ACPI_STATE_C0) { /* This is the first C1 state. Use the reserved slot. */ sc->cpu_cx_states[0] = *cx_ptr; @@ -818,23 +890,34 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) } /* Free up any previous register. */ - if (cx_ptr->p_lvlx != NULL) { - bus_release_resource(sc->cpu_dev, cx_ptr->res_type, cx_ptr->res_rid, - cx_ptr->p_lvlx); - cx_ptr->p_lvlx = NULL; - } + acpi_cpu_cx_cst_free_plvlx(sc->cpu_dev, cx_ptr); /* Allocate the control register for C2 or C3. */ - cx_ptr->res_rid = sc->cpu_cx_count; - acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type, &cx_ptr->res_rid, - &cx_ptr->p_lvlx, RF_SHAREABLE); - if (cx_ptr->p_lvlx) { +#if defined(__i386__) || defined(__amd64__) + if (acpi_PkgFFH_IntelCpu(pkg, 0, &vendor, &class, &address, + &accsize) == 0 && vendor == CST_FFH_VENDOR_INTEL && + class == CST_FFH_INTEL_CL_MWAIT) { + /* Native C State Instruction use (mwait) */ + acpi_cpu_cx_cst_mwait(cx_ptr, address, accsize); ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "acpi_cpu%d: Got C%d - %d latency\n", - device_get_unit(sc->cpu_dev), cx_ptr->type, - cx_ptr->trans_lat)); + "acpi_cpu%d: Got C%d/mwait - %d latency\n", + device_get_unit(sc->cpu_dev), cx_ptr->type, cx_ptr->trans_lat)); cx_ptr++; sc->cpu_cx_count++; + } else +#endif + { + cx_ptr->res_rid = sc->cpu_cx_count; + acpi_PkgGas(sc->cpu_dev, pkg, 0, &cx_ptr->res_type, + &cx_ptr->res_rid, &cx_ptr->p_lvlx, RF_SHAREABLE); + if (cx_ptr->p_lvlx) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "acpi_cpu%d: Got C%d - %d latency\n", + device_get_unit(sc->cpu_dev), cx_ptr->type, + cx_ptr->trans_lat)); + cx_ptr++; + sc->cpu_cx_count++; + } } } AcpiOsFree(buf.Pointer); @@ -956,6 +1039,13 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc) OID_AUTO, "cx_usage_counters", CTLTYPE_STRING | CTLFLAG_RD, (void *)sc, 0, acpi_cpu_usage_counters_sysctl, "A", "Cx sleep state counters"); +#if defined(__i386__) || defined(__amd64__) + SYSCTL_ADD_PROC(&sc->cpu_sysctl_ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(sc->cpu_dev)), + OID_AUTO, "cx_method", CTLTYPE_STRING | CTLFLAG_RD, + (void *)sc, 0, acpi_cpu_method_sysctl, "A", + "Cx entrance methods"); +#endif /* Signal platform that we can handle _CST notification. */ if (!cpu_cx_generic && cpu_cst_cnt != 0) { @@ -1043,7 +1133,14 @@ acpi_cpu_idle(sbintime_t sbt) */ if (cx_next->type == ACPI_STATE_C1) { cputicks = cpu_ticks(); - acpi_cpu_c1(); + if (cx_next->p_lvlx != NULL) { + /* C1 I/O then Halt */ + CPU_GET_REG(cx_next->p_lvlx, 1); + } + if (cx_next->do_mwait) + acpi_cpu_idle_mwait(cx_next->mwait_hint); + else + acpi_cpu_c1(); end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate(); if (curthread->td_critnest == 0) end_time = min(end_time, 500000 / hz); @@ -1055,7 +1152,7 @@ acpi_cpu_idle(sbintime_t sbt) * For C3, disable bus master arbitration and enable bus master wake * if BM control is available, otherwise flush the CPU cache. */ - if (cx_next->type == ACPI_STATE_C3) { + if (cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) { if ((cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) { AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 1); AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 1); @@ -1076,7 +1173,10 @@ acpi_cpu_idle(sbintime_t sbt) start_time = 0; cputicks = cpu_ticks(); } - CPU_GET_REG(cx_next->p_lvlx, 1); + if (cx_next->do_mwait) + acpi_cpu_idle_mwait(cx_next->mwait_hint); + else + CPU_GET_REG(cx_next->p_lvlx, 1); /* * Read the end time twice. Since it may take an arbitrary time @@ -1092,8 +1192,8 @@ acpi_cpu_idle(sbintime_t sbt) end_time = ((cpu_ticks() - cputicks) << 20) / cpu_tickrate(); /* Enable bus master arbitration and disable bus master wakeup. */ - if (cx_next->type == ACPI_STATE_C3 && - (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) { + if ((cx_next->type == ACPI_STATE_C3 || cx_next->mwait_bm_avoidance) && + (cpu_quirks & CPU_QUIRK_NO_BM_CTRL) == 0) { AcpiWriteBitRegister(ACPI_BITREG_ARB_DISABLE, 0); AcpiWriteBitRegister(ACPI_BITREG_BUS_MASTER_RLD, 0); } @@ -1286,6 +1386,44 @@ acpi_cpu_usage_counters_sysctl(SYSCTL_HANDLER_ARGS) return (0); } +#if defined(__i386__) || defined(__amd64__) +static int +acpi_cpu_method_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct acpi_cpu_softc *sc; + struct acpi_cx *cx; + struct sbuf sb; + char buf[128]; + int i; + + sc = (struct acpi_cpu_softc *)arg1; + sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN); + for (i = 0; i < sc->cpu_cx_count; i++) { + cx = &sc->cpu_cx_states[i]; + sbuf_printf(&sb, "C%d/", i + 1); + if (cx->do_mwait) { + sbuf_cat(&sb, "mwait"); + if (cx->mwait_hw_coord) + sbuf_cat(&sb, "/hwc"); + if (cx->mwait_bm_avoidance) + sbuf_cat(&sb, "/bma"); + } else if (cx->type == ACPI_STATE_C1) { + sbuf_cat(&sb, "hlt"); + } else { + sbuf_cat(&sb, "io"); + } + if (cx->type == ACPI_STATE_C1 && cx->p_lvlx != NULL) + sbuf_cat(&sb, "/iohlt"); + sbuf_putc(&sb, ' '); + } + sbuf_trim(&sb); + sbuf_finish(&sb); + sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); + sbuf_delete(&sb); + return (0); +} +#endif + static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc) { diff --git a/sys/dev/acpica/acpi_package.c b/sys/dev/acpica/acpi_package.c index e38fea5..c1070cb 100644 --- a/sys/dev/acpica/acpi_package.c +++ b/sys/dev/acpica/acpi_package.c @@ -120,6 +120,28 @@ acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid, return (acpi_bus_alloc_gas(dev, type, rid, &gas, dst, flags)); } +int +acpi_PkgFFH_IntelCpu(ACPI_OBJECT *res, int idx, int *vendor, int *class, + uint64_t *address, int *accsize) +{ + ACPI_GENERIC_ADDRESS gas; + ACPI_OBJECT *obj; + + obj = &res->Package.Elements[idx]; + if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER || + obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3) + return (EINVAL); + + memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas)); + if (gas.SpaceId != ACPI_ADR_SPACE_FIXED_HARDWARE) + return (ERESTART); + *vendor = gas.BitWidth; + *class = gas.BitOffset; + *address = gas.Address; + *accsize = gas.AccessWidth; + return (0); +} + ACPI_HANDLE acpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj) { diff --git a/sys/dev/acpica/acpi_timer.c b/sys/dev/acpica/acpi_timer.c index 03ef686..296e38f 100644 --- a/sys/dev/acpica/acpi_timer.c +++ b/sys/dev/acpica/acpi_timer.c @@ -128,7 +128,8 @@ acpi_timer_identify(driver_t *driver, device_t parent) ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); if (acpi_disabled("timer") || (acpi_quirks & ACPI_Q_TIMER) || - acpi_timer_dev || acpi_timer_disabled) + acpi_timer_dev || acpi_timer_disabled || + AcpiGbl_FADT.PmTimerLength == 0) return_VOID; if ((dev = BUS_ADD_CHILD(parent, 2, "acpi_timer", 0)) == NULL) { diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 2e2b96d..cbd4bd9 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -467,6 +467,8 @@ int acpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst); int acpi_PkgStr(ACPI_OBJECT *res, int idx, void *dst, size_t size); int acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid, struct resource **dst, u_int flags); +int acpi_PkgFFH_IntelCpu(ACPI_OBJECT *res, int idx, int *vendor, + int *class, uint64_t *address, int *accsize); ACPI_HANDLE acpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj); /* diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 1a8398c..0bee138 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -47,7 +47,7 @@ __FBSDID("$FreeBSD$"); #include <machine/md_var.h> #include <machine/specialreg.h> -#ifdef DEBUG +#ifdef HWPMC_DEBUG enum pmc_class amd_pmc_class; #endif @@ -282,16 +282,16 @@ amd_read_pmc(int cpu, int ri, pmc_value_t *v) mode = PMC_TO_MODE(pm); - PMCDBG(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class); + PMCDBG2(MDP,REA,1,"amd-read id=%d class=%d", ri, pd->pm_descr.pd_class); -#ifdef DEBUG +#ifdef HWPMC_DEBUG KASSERT(pd->pm_descr.pd_class == amd_pmc_class, ("[amd,%d] unknown PMC class (%d)", __LINE__, pd->pm_descr.pd_class)); #endif tmp = rdmsr(pd->pm_perfctr); /* RDMSR serializes */ - PMCDBG(MDP,REA,2,"amd-read (pre-munge) id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"amd-read (pre-munge) id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(mode)) { /* Sign extend 48 bit value to 64 bits. */ tmp = (pmc_value_t) (((int64_t) tmp << 16) >> 16); @@ -299,7 +299,7 @@ amd_read_pmc(int cpu, int ri, pmc_value_t *v) } *v = tmp; - PMCDBG(MDP,REA,2,"amd-read (post-munge) id=%d -> %jd", ri, *v); + PMCDBG2(MDP,REA,2,"amd-read (post-munge) id=%d -> %jd", ri, *v); return 0; } @@ -329,7 +329,7 @@ amd_write_pmc(int cpu, int ri, pmc_value_t v) mode = PMC_TO_MODE(pm); -#ifdef DEBUG +#ifdef HWPMC_DEBUG KASSERT(pd->pm_descr.pd_class == amd_pmc_class, ("[amd,%d] unknown PMC class (%d)", __LINE__, pd->pm_descr.pd_class)); @@ -339,7 +339,7 @@ amd_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(mode)) v = AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"amd-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"amd-write cpu=%d ri=%d v=%jx", cpu, ri, v); /* write the PMC value */ wrmsr(pd->pm_perfctr, v); @@ -356,7 +356,7 @@ amd_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[amd,%d] illegal CPU value %d", __LINE__, cpu)); @@ -395,7 +395,7 @@ amd_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) { (void) pc; - PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, + PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0); /* enable the RDPMC instruction if needed */ @@ -416,7 +416,7 @@ amd_switch_out(struct pmc_cpu *pc, struct pmc_process *pp) (void) pc; (void) pp; /* can be NULL */ - PMCDBG(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ? + PMCDBG3(MDP,SWO,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp ? (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) == 1 : 0); /* always turn off the RDPMC instruction */ @@ -453,7 +453,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm, caps = pm->pm_caps; - PMCDBG(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps); + PMCDBG2(MDP,ALL,1,"amd-allocate ri=%d caps=0x%x", ri, caps); if ((pd->pd_caps & caps) != caps) return EPERM; @@ -500,7 +500,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_amd.pm_amd_evsel = config; /* save config value */ - PMCDBG(MDP,ALL,2,"amd-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"amd-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -515,7 +515,7 @@ amd_allocate_pmc(int cpu, int ri, struct pmc *pm, static int amd_release_pmc(int cpu, int ri, struct pmc *pmc) { -#ifdef DEBUG +#ifdef HWPMC_DEBUG const struct amd_descr *pd; #endif struct pmc_hw *phw; @@ -532,7 +532,7 @@ amd_release_pmc(int cpu, int ri, struct pmc *pmc) KASSERT(phw->phw_pmc == NULL, ("[amd,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); -#ifdef DEBUG +#ifdef HWPMC_DEBUG pd = &amd_pmcdesc[ri]; if (pd->pm_descr.pd_class == amd_pmc_class) KASSERT(AMD_PMC_IS_STOPPED(pd->pm_evsel), @@ -567,7 +567,7 @@ amd_start_pmc(int cpu, int ri) ("[amd,%d] starting cpu%d,pmc%d with null pmc record", __LINE__, cpu, ri)); - PMCDBG(MDP,STA,1,"amd-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1,"amd-start cpu=%d ri=%d", cpu, ri); KASSERT(AMD_PMC_IS_STOPPED(pd->pm_evsel), ("[amd,%d] pmc%d,cpu%d: Starting active PMC \"%s\"", __LINE__, @@ -576,7 +576,7 @@ amd_start_pmc(int cpu, int ri) /* turn on the PMC ENABLE bit */ config = pm->pm_md.pm_amd.pm_amd_evsel | AMD_PMC_ENABLE; - PMCDBG(MDP,STA,2,"amd-start config=0x%x", config); + PMCDBG1(MDP,STA,2,"amd-start config=0x%x", config); wrmsr(pd->pm_evsel, config); return 0; @@ -610,7 +610,7 @@ amd_stop_pmc(int cpu, int ri) ("[amd,%d] PMC%d, CPU%d \"%s\" already stopped", __LINE__, ri, cpu, pd->pm_descr.pd_name)); - PMCDBG(MDP,STO,1,"amd-stop ri=%d", ri); + PMCDBG1(MDP,STO,1,"amd-stop ri=%d", ri); /* turn off the PMC ENABLE bit */ config = pm->pm_md.pm_amd.pm_amd_evsel & ~AMD_PMC_ENABLE; @@ -637,7 +637,7 @@ amd_intr(int cpu, struct trapframe *tf) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[amd,%d] out of range CPU %d", __LINE__, cpu)); - PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); retval = 0; @@ -769,7 +769,7 @@ amd_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[amd,%d] insane cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"amd-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"amd-init cpu=%d", cpu); amd_pcpu[cpu] = pac = malloc(sizeof(struct amd_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -816,7 +816,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[amd,%d] insane cpu number (%d)", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"amd-cleanup cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"amd-cleanup cpu=%d", cpu); /* * First, turn off all PMCs on this CPU. @@ -835,7 +835,7 @@ amd_pcpu_fini(struct pmc_mdep *md, int cpu) amd_pcpu[cpu] = NULL; -#ifdef DEBUG +#ifdef HWPMC_DEBUG for (i = 0; i < AMD_NPMCS; i++) { KASSERT(pac->pc_amdpmcs[i].phw_pmc == NULL, ("[amd,%d] CPU%d/PMC%d in use", __LINE__, cpu, i)); @@ -912,7 +912,7 @@ pmc_amd_initialize(void) return NULL; } -#ifdef DEBUG +#ifdef HWPMC_DEBUG amd_pmc_class = class; #endif @@ -976,7 +976,7 @@ pmc_amd_initialize(void) pmc_mdep->pmd_npmc += AMD_NPMCS; - PMCDBG(MDP,INI,0,"%s","amd-initialize"); + PMCDBG0(MDP,INI,0,"amd-initialize"); return (pmc_mdep); diff --git a/sys/dev/hwpmc/hwpmc_armv7.c b/sys/dev/hwpmc/hwpmc_armv7.c index 13fdc76..66d4971 100644 --- a/sys/dev/hwpmc/hwpmc_armv7.c +++ b/sys/dev/hwpmc/hwpmc_armv7.c @@ -201,7 +201,7 @@ armv7_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_armv7.pm_armv7_evsel = config; - PMCDBG(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"armv7-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -225,7 +225,7 @@ armv7_read_pmc(int cpu, int ri, pmc_value_t *v) else tmp = armv7_pmcn_read(ri); - PMCDBG(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"armv7-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = ARMV7_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); else @@ -249,7 +249,7 @@ armv7_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = ARMV7_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"armv7-write cpu=%d ri=%d v=%jx", cpu, ri, v); if (pm->pm_md.pm_armv7.pm_armv7_evsel == 0xFF) cp15_pmccntr_set(v); @@ -264,7 +264,7 @@ armv7_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[armv7,%d] illegal CPU value %d", __LINE__, cpu)); @@ -462,7 +462,7 @@ armv7_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[armv7,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"armv7-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"armv7-init cpu=%d", cpu); armv7_pcpu[cpu] = pac = malloc(sizeof(struct armv7_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -516,7 +516,7 @@ pmc_armv7_initialize() armv7_npmcs = (reg >> ARMV7_PMNC_N_SHIFT) & \ ARMV7_PMNC_N_MASK; - PMCDBG(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs); + PMCDBG1(MDP,INI,1,"armv7-init npmcs=%d", armv7_npmcs); /* * Allocate space for pointers to PMC HW descriptors and for diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index f50dfb6c..afa5def 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -123,7 +123,7 @@ core_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[iaf,%d] insane cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"core-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"core-init cpu=%d", cpu); core_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_ri; npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAP].pcd_num; @@ -162,7 +162,7 @@ core_pcpu_fini(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[core,%d] insane cpu number (%d)", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"core-pcpu-fini cpu=%d", cpu); if ((cc = core_pcpu[cpu]) == NULL) return (0); @@ -223,7 +223,7 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm, KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[core,%d] illegal CPU %d", __LINE__, cpu)); - PMCDBG(MDP,ALL,1, "iaf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps); + PMCDBG2(MDP,ALL,1, "iaf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps); if (ri < 0 || ri > core_iaf_npmc) return (EINVAL); @@ -267,7 +267,7 @@ iaf_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_iaf.pm_iaf_ctrl = (flags << (ri * 4)); - PMCDBG(MDP,ALL,2, "iaf-allocate config=0x%jx", + PMCDBG1(MDP,ALL,2, "iaf-allocate config=0x%jx", (uintmax_t) pm->pm_md.pm_iaf.pm_iaf_ctrl); return (0); @@ -282,7 +282,7 @@ iaf_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < core_iaf_npmc, ("[core,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "iaf-config cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "iaf-config cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__, cpu)); @@ -362,7 +362,7 @@ iaf_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp; - PMCDBG(MDP,REA,1, "iaf-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, + PMCDBG4(MDP,REA,1, "iaf-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, IAF_RI_TO_MSR(ri), *v); return (0); @@ -371,7 +371,7 @@ iaf_read_pmc(int cpu, int ri, pmc_value_t *v) static int iaf_release_pmc(int cpu, int ri, struct pmc *pmc) { - PMCDBG(MDP,REL,1, "iaf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc); + PMCDBG3(MDP,REL,1, "iaf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[core,%d] illegal CPU value %d", __LINE__, cpu)); @@ -396,7 +396,7 @@ iaf_start_pmc(int cpu, int ri) KASSERT(ri >= 0 && ri < core_iaf_npmc, ("[core,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1,"iaf-start cpu=%d ri=%d", cpu, ri); iafc = core_pcpu[cpu]; pm = iafc->pc_corepmcs[ri + core_iaf_ri].phw_pmc; @@ -414,7 +414,7 @@ iaf_start_pmc(int cpu, int ri) IAF_GLOBAL_CTRL_MASK)); } while (iafc->pc_resync != 0); - PMCDBG(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", + PMCDBG4(MDP,STA,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); @@ -428,7 +428,7 @@ iaf_stop_pmc(int cpu, int ri) struct core_cpu *iafc; uint64_t msr = 0; - PMCDBG(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1,"iaf-stop cpu=%d ri=%d", cpu, ri); iafc = core_pcpu[cpu]; @@ -445,7 +445,7 @@ iaf_stop_pmc(int cpu, int ri) iafc->pc_iafctrl &= ~fc; - PMCDBG(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl); + PMCDBG1(MDP,STO,1,"iaf-stop iafctrl=%x", iafc->pc_iafctrl); msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; wrmsr(IAF_CTRL, msr | (iafc->pc_iafctrl & IAF_CTRL_MASK)); @@ -457,7 +457,7 @@ iaf_stop_pmc(int cpu, int ri) IAF_GLOBAL_CTRL_MASK)); } while (iafc->pc_resync != 0); - PMCDBG(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", + PMCDBG4(MDP,STO,1,"iafctrl=%x(%x) globalctrl=%jx(%jx)", iafc->pc_iafctrl, (uint32_t) rdmsr(IAF_CTRL), iafc->pc_globalctrl, rdmsr(IA_GLOBAL_CTRL)); @@ -495,7 +495,7 @@ iaf_write_pmc(int cpu, int ri, pmc_value_t v) msr = rdmsr(IAF_CTRL) & ~IAF_CTRL_MASK; wrmsr(IAF_CTRL, msr | (cc->pc_iafctrl & IAF_CTRL_MASK)); - PMCDBG(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx " + PMCDBG6(MDP,WRI,1, "iaf-write cpu=%d ri=%d msr=0x%x v=%jx iafctrl=%jx " "pmc=%jx", cpu, ri, IAF_RI_TO_MSR(ri), v, (uintmax_t) rdmsr(IAF_CTRL), (uintmax_t) rdpmc(IAF_RI_TO_MSR(ri))); @@ -511,7 +511,7 @@ iaf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth) KASSERT(md != NULL, ("[iaf,%d] md is NULL", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "iaf-initialize"); + PMCDBG0(MDP,INI,1, "iaf-initialize"); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_IAF]; @@ -2289,7 +2289,7 @@ iap_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < core_iap_npmc, ("[core,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "iap-config cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "iap-config cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(core_pcpu[cpu] != NULL, ("[core,%d] null per-cpu %d", __LINE__, cpu)); @@ -2368,7 +2368,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp & ((1ULL << core_iap_width) - 1); - PMCDBG(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, + PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, ri, *v); return (0); @@ -2379,7 +2379,7 @@ iap_release_pmc(int cpu, int ri, struct pmc *pm) { (void) pm; - PMCDBG(MDP,REL,1, "iap-release cpu=%d ri=%d pm=%p", cpu, ri, + PMCDBG3(MDP,REL,1, "iap-release cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), @@ -2412,11 +2412,11 @@ iap_start_pmc(int cpu, int ri) ("[core,%d] starting cpu%d,ri%d with no pmc configured", __LINE__, cpu, ri)); - PMCDBG(MDP,STA,1, "iap-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1, "iap-start cpu=%d ri=%d", cpu, ri); evsel = pm->pm_md.pm_iap.pm_iap_evsel; - PMCDBG(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x", + PMCDBG4(MDP,STA,2, "iap-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x", cpu, ri, IAP_EVSEL0 + ri, evsel); /* Event specific configuration. */ @@ -2464,7 +2464,7 @@ iap_stop_pmc(int cpu, int ri) ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1, "iap-stop cpu=%d ri=%d", cpu, ri); msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK; wrmsr(IAP_EVSEL0 + ri, msr); /* stop hw */ @@ -2501,7 +2501,7 @@ iap_write_pmc(int cpu, int ri, pmc_value_t v) ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, + PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, IAP_PMC0 + ri, v); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) @@ -2526,7 +2526,7 @@ iap_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth, KASSERT(md != NULL, ("[iap,%d] md is NULL", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "iap-initialize"); + PMCDBG0(MDP,INI,1, "iap-initialize"); /* Remember the set of architectural events supported. */ core_architectural_events = ~flags; @@ -2564,7 +2564,7 @@ core_intr(int cpu, struct trapframe *tf) int error, found_interrupt, ri; uint64_t msr; - PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); found_interrupt = 0; @@ -2623,7 +2623,7 @@ core2_intr(int cpu, struct trapframe *tf) struct core_cpu *cc; pmc_value_t v; - PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); /* @@ -2635,7 +2635,7 @@ core2_intr(int cpu, struct trapframe *tf) intrstatus = rdmsr(IA_GLOBAL_STATUS); intrenable = intrstatus & core_pmcmask; - PMCDBG(MDP,INT, 1, "cpu=%d intrstatus=%jx", cpu, + PMCDBG2(MDP,INT, 1, "cpu=%d intrstatus=%jx", cpu, (uintmax_t) intrstatus); found_interrupt = 0; @@ -2681,7 +2681,7 @@ core2_intr(int cpu, struct trapframe *tf) /* Reload sampling count. */ wrmsr(IAF_CTR0 + n, v); - PMCDBG(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu, + PMCDBG4(MDP,INT, 1, "iaf-intr cpu=%d error=%d v=%jx(%jx)", cpu, error, (uintmax_t) v, (uintmax_t) rdpmc(IAF_RI_TO_MSR(n))); } @@ -2706,7 +2706,7 @@ core2_intr(int cpu, struct trapframe *tf) v = iap_reload_count_to_perfctr_value(pm->pm_sc.pm_reloadcount); - PMCDBG(MDP,INT, 1, "iap-intr cpu=%d error=%d v=%jx", cpu, error, + PMCDBG3(MDP,INT, 1, "iap-intr cpu=%d error=%d v=%jx", cpu, error, (uintmax_t) v); /* Reload sampling count. */ @@ -2716,14 +2716,14 @@ core2_intr(int cpu, struct trapframe *tf) /* * Reenable all non-stalled PMCs. */ - PMCDBG(MDP,INT, 1, "cpu=%d intrenable=%jx", cpu, + PMCDBG2(MDP,INT, 1, "cpu=%d intrenable=%jx", cpu, (uintmax_t) intrenable); cc->pc_globalctrl |= intrenable; wrmsr(IA_GLOBAL_CTRL, cc->pc_globalctrl & IA_GLOBAL_CTRL_MASK); - PMCDBG(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx " + PMCDBG5(MDP,INT, 1, "cpu=%d fixedctrl=%jx globalctrl=%jx status=%jx " "ovf=%jx", cpu, (uintmax_t) rdmsr(IAF_CTRL), (uintmax_t) rdmsr(IA_GLOBAL_CTRL), (uintmax_t) rdmsr(IA_GLOBAL_STATUS), @@ -2750,7 +2750,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override) cpuid[CORE_CPUID_EAX] & 0xFF; core_cputype = md->pmd_cputype; - PMCDBG(MDP,INI,1,"core-init cputype=%d ncpu=%d ipa-version=%d", + PMCDBG3(MDP,INI,1,"core-init cputype=%d ncpu=%d ipa-version=%d", core_cputype, maxcpu, ipa_version); if (ipa_version < 1 || ipa_version > 3 || @@ -2788,7 +2788,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override) core_pmcmask |= ((1ULL << core_iaf_npmc) - 1) << IAF_OFFSET; } - PMCDBG(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask, + PMCDBG2(MDP,INI,1,"core-init pmcmask=0x%jx iafri=%d", core_pmcmask, core_iaf_ri); core_pcpu = malloc(sizeof(*core_pcpu) * maxcpu, M_PMC, @@ -2811,7 +2811,7 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override) void pmc_core_finalize(struct pmc_mdep *md) { - PMCDBG(MDP,INI,1, "%s", "core-finalize"); + PMCDBG0(MDP,INI,1, "core-finalize"); free(core_pcpu, M_PMC); core_pcpu = NULL; diff --git a/sys/dev/hwpmc/hwpmc_e500.c b/sys/dev/hwpmc/hwpmc_e500.c index d81b333..d963e73 100644 --- a/sys/dev/hwpmc/hwpmc_e500.c +++ b/sys/dev/hwpmc/hwpmc_e500.c @@ -304,7 +304,7 @@ e500_read_pmc(int cpu, int ri, pmc_value_t *v) ri)); tmp = e500_pmcn_read(ri); - PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); else @@ -328,7 +328,7 @@ e500_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); e500_pmcn_write(ri, v); @@ -340,7 +340,7 @@ e500_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); @@ -443,7 +443,7 @@ e500_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu); /* Freeze all counters. */ mtpmr(PMR_PMGC0, PMGC_FAC | PMGC_PMIE | PMGC_FCECE); @@ -543,7 +543,7 @@ e500_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; - PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -576,7 +576,7 @@ e500_intr(int cpu, struct trapframe *tf) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); - PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); retval = 0; diff --git a/sys/dev/hwpmc/hwpmc_intel.c b/sys/dev/hwpmc/hwpmc_intel.c index 486dfa0..ce49f54 100644 --- a/sys/dev/hwpmc/hwpmc_intel.c +++ b/sys/dev/hwpmc/hwpmc_intel.c @@ -46,14 +46,14 @@ intel_switch_in(struct pmc_cpu *pc, struct pmc_process *pp) { (void) pc; - PMCDBG(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, + PMCDBG3(MDP,SWI,1, "pc=%p pp=%p enable-msr=%d", pc, pp, pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS); /* allow the RDPMC instruction if needed */ if (pp->pp_flags & PMC_PP_ENABLE_MSR_ACCESS) load_cr4(rcr4() | CR4_PCE); - PMCDBG(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4()); + PMCDBG1(MDP,SWI,1, "cr4=0x%jx", (uintmax_t) rcr4()); return 0; } @@ -64,7 +64,7 @@ intel_switch_out(struct pmc_cpu *pc, struct pmc_process *pp) (void) pc; (void) pp; /* can be NULL */ - PMCDBG(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp, + PMCDBG3(MDP,SWO,1, "pc=%p pp=%p cr4=0x%jx", pc, pp, (uintmax_t) rcr4()); /* always turn off the RDPMC instruction */ @@ -83,7 +83,7 @@ pmc_intel_initialize(void) KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL, ("[intel,%d] Initializing non-intel processor", __LINE__)); - PMCDBG(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id); + PMCDBG1(MDP,INI,0, "intel-initialize cpuid=0x%x", cpu_id); cputype = -1; nclasses = 2; diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c index 4d14011..cc85481 100644 --- a/sys/dev/hwpmc/hwpmc_logging.c +++ b/sys/dev/hwpmc/hwpmc_logging.c @@ -211,9 +211,9 @@ pmclog_get_buffer(struct pmc_owner *po) TAILQ_REMOVE(&pmc_bufferlist, plb, plb_next); mtx_unlock_spin(&pmc_bufferlist_mtx); - PMCDBG(LOG,GTB,1, "po=%p plb=%p", po, plb); + PMCDBG2(LOG,GTB,1, "po=%p plb=%p", po, plb); -#ifdef DEBUG +#ifdef HWPMC_DEBUG if (plb) KASSERT(plb->plb_ptr == plb->plb_base && plb->plb_base < plb->plb_fence, @@ -261,7 +261,7 @@ pmclog_loop(void *arg) ownercred = crhold(p->p_ucred); PROC_UNLOCK(p); - PMCDBG(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread); + PMCDBG2(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread); KASSERT(po->po_kthread == curthread->td_proc, ("[pmclog,%d] proc mismatch po=%p po/kt=%p curproc=%p", __LINE__, po, po->po_kthread, curthread->td_proc)); @@ -312,7 +312,7 @@ pmclog_loop(void *arg) mtx_unlock(&pmc_kthread_mtx); /* process the request */ - PMCDBG(LOG,WRI,2, "po=%p base=%p ptr=%p", po, + PMCDBG3(LOG,WRI,2, "po=%p base=%p ptr=%p", po, lb->plb_base, lb->plb_ptr); /* change our thread's credentials before issuing the I/O */ @@ -343,7 +343,7 @@ pmclog_loop(void *arg) po->po_error = error; /* save for flush log */ - PMCDBG(LOG,WRI,2, "po=%p error=%d", po, error); + PMCDBG2(LOG,WRI,2, "po=%p error=%d", po, error); break; } @@ -403,7 +403,7 @@ pmclog_release(struct pmc_owner *po) mtx_unlock_spin(&po->po_mtx); - PMCDBG(LOG,REL,1, "po=%p", po); + PMCDBG1(LOG,REL,1, "po=%p", po); } @@ -423,7 +423,7 @@ pmclog_reserve(struct pmc_owner *po, int length) uint32_t *lh; struct timespec ts; - PMCDBG(LOG,ALL,1, "po=%p len=%d", po, length); + PMCDBG2(LOG,ALL,1, "po=%p len=%d", po, length); KASSERT(length % sizeof(uint32_t) == 0, ("[pmclog,%d] length not a multiple of word size", __LINE__)); @@ -519,7 +519,7 @@ pmclog_schedule_io(struct pmc_owner *po) ("[pmclog,%d] buffer invariants po=%p ptr=%p fenc=%p", __LINE__, po, po->po_curbuf->plb_ptr, po->po_curbuf->plb_fence)); - PMCDBG(LOG,SIO, 1, "po=%p", po); + PMCDBG1(LOG,SIO, 1, "po=%p", po); mtx_assert(&po->po_mtx, MA_OWNED); @@ -579,7 +579,7 @@ pmclog_configure_log(struct pmc_mdep *md, struct pmc_owner *po, int logfd) * the former is not held here. */ sx_assert(&pmc_sx, SA_UNLOCKED); - PMCDBG(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); + PMCDBG2(LOG,CFG,1, "config po=%p logfd=%d", po, logfd); p = po->po_owner; @@ -649,7 +649,7 @@ pmclog_deconfigure_log(struct pmc_owner *po) int error; struct pmclog_buffer *lb; - PMCDBG(LOG,CFG,1, "de-config po=%p", po); + PMCDBG1(LOG,CFG,1, "de-config po=%p", po); if ((po->po_flags & PMC_PO_OWNS_LOGFILE) == 0) return (EINVAL); @@ -700,7 +700,7 @@ pmclog_flush(struct pmc_owner *po) int error; struct pmclog_buffer *lb; - PMCDBG(LOG,FLS,1, "po=%p", po); + PMCDBG1(LOG,FLS,1, "po=%p", po); /* * If there is a pending error recorded by the logger thread, @@ -741,7 +741,7 @@ int pmclog_close(struct pmc_owner *po) { - PMCDBG(LOG,CLO,1, "po=%p", po); + PMCDBG1(LOG,CLO,1, "po=%p", po); mtx_lock(&pmc_kthread_mtx); @@ -773,7 +773,7 @@ pmclog_process_callchain(struct pmc *pm, struct pmc_sample *ps) uint32_t flags; struct pmc_owner *po; - PMCDBG(LOG,SAM,1,"pm=%p pid=%d n=%d", pm, ps->ps_pid, + PMCDBG3(LOG,SAM,1,"pm=%p pid=%d n=%d", pm, ps->ps_pid, ps->ps_nsamples); recordlen = offsetof(struct pmclog_callchain, pl_pc) + @@ -843,7 +843,7 @@ pmclog_process_pmcallocate(struct pmc *pm) po = pm->pm_owner; - PMCDBG(LOG,ALL,1, "pm=%p", pm); + PMCDBG1(LOG,ALL,1, "pm=%p", pm); if (PMC_TO_CLASS(pm) == PMC_CLASS_SOFT) { PMCLOG_RESERVE(po, PMCALLOCATEDYN, @@ -874,7 +874,7 @@ pmclog_process_pmcattach(struct pmc *pm, pid_t pid, char *path) int pathlen, recordlen; struct pmc_owner *po; - PMCDBG(LOG,ATT,1,"pm=%p pid=%d", pm, pid); + PMCDBG2(LOG,ATT,1,"pm=%p pid=%d", pm, pid); po = pm->pm_owner; @@ -893,7 +893,7 @@ pmclog_process_pmcdetach(struct pmc *pm, pid_t pid) { struct pmc_owner *po; - PMCDBG(LOG,ATT,1,"!pm=%p pid=%d", pm, pid); + PMCDBG2(LOG,ATT,1,"!pm=%p pid=%d", pm, pid); po = pm->pm_owner; @@ -915,7 +915,7 @@ pmclog_process_proccsw(struct pmc *pm, struct pmc_process *pp, pmc_value_t v) KASSERT(pm->pm_flags & PMC_F_LOG_PROCCSW, ("[pmclog,%d] log-process-csw called gratuitously", __LINE__)); - PMCDBG(LOG,SWO,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid, + PMCDBG3(LOG,SWO,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid, v); po = pm->pm_owner; @@ -933,7 +933,7 @@ pmclog_process_procexec(struct pmc_owner *po, pmc_id_t pmid, pid_t pid, { int pathlen, recordlen; - PMCDBG(LOG,EXC,1,"po=%p pid=%d path=\"%s\"", po, pid, path); + PMCDBG3(LOG,EXC,1,"po=%p pid=%d path=\"%s\"", po, pid, path); pathlen = strlen(path) + 1; /* #bytes for the path */ recordlen = offsetof(struct pmclog_procexec, pl_pathname) + pathlen; @@ -957,7 +957,7 @@ pmclog_process_procexit(struct pmc *pm, struct pmc_process *pp) struct pmc_owner *po; ri = PMC_TO_ROWINDEX(pm); - PMCDBG(LOG,EXT,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid, + PMCDBG3(LOG,EXT,1,"pm=%p pid=%d v=%jx", pm, pp->pp_proc->p_pid, pp->pp_pmcs[ri].pp_pmcval); po = pm->pm_owner; @@ -1003,7 +1003,7 @@ pmclog_process_userlog(struct pmc_owner *po, struct pmc_op_writelog *wl) { int error; - PMCDBG(LOG,WRI,1, "writelog po=%p ud=0x%x", po, wl->pm_userdata); + PMCDBG2(LOG,WRI,1, "writelog po=%p ud=0x%x", po, wl->pm_userdata); error = 0; diff --git a/sys/dev/hwpmc/hwpmc_mips.c b/sys/dev/hwpmc/hwpmc_mips.c index 68a81e0..72f8e89 100644 --- a/sys/dev/hwpmc/hwpmc_mips.c +++ b/sys/dev/hwpmc/hwpmc_mips.c @@ -104,7 +104,7 @@ mips_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_mips_evsel = config; - PMCDBG(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -123,7 +123,7 @@ mips_read_pmc(int cpu, int ri, pmc_value_t *v) pm = mips_pcpu[cpu]->pc_mipspmcs[ri].phw_pmc; tmp = mips_pmcn_read(ri); - PMCDBG(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"mips-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = tmp - (1UL << (mips_pmc_spec.ps_counter_width - 1)); @@ -148,7 +148,7 @@ mips_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = (1UL << (mips_pmc_spec.ps_counter_width - 1)) - v; - PMCDBG(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"mips-write cpu=%d ri=%d v=%jx", cpu, ri, v); mips_pmcn_write(ri, v); @@ -160,7 +160,7 @@ mips_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[mips,%d] illegal CPU value %d", __LINE__, cpu)); @@ -376,7 +376,7 @@ mips_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[mips,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"mips-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"mips-init cpu=%d", cpu); mips_pcpu[cpu] = pac = malloc(sizeof(struct mips_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -421,7 +421,7 @@ pmc_mips_initialize() */ mips_npmcs = 2; - PMCDBG(MDP,INI,1,"mips-init npmcs=%d", mips_npmcs); + PMCDBG1(MDP,INI,1,"mips-init npmcs=%d", mips_npmcs); /* * Allocate space for pointers to PMC HW descriptors and for diff --git a/sys/dev/hwpmc/hwpmc_mips24k.c b/sys/dev/hwpmc/hwpmc_mips24k.c index 18d7f6c..7841555 100644 --- a/sys/dev/hwpmc/hwpmc_mips24k.c +++ b/sys/dev/hwpmc/hwpmc_mips24k.c @@ -223,7 +223,7 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps) if (caps & PMC_CAP_INTERRUPT) config |= MIPS24K_PMC_INTERRUPT_ENABLE; - PMCDBG(MDP,ALL,2,"mips24k-get_perfctl ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"mips24k-get_perfctl ri=%d -> config=0x%x", ri, config); return (config); } diff --git a/sys/dev/hwpmc/hwpmc_mips74k.c b/sys/dev/hwpmc/hwpmc_mips74k.c index 3a5ff33..59f677d 100644 --- a/sys/dev/hwpmc/hwpmc_mips74k.c +++ b/sys/dev/hwpmc/hwpmc_mips74k.c @@ -255,7 +255,7 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps) if (caps & PMC_CAP_INTERRUPT) config |= MIPS74K_PMC_INTERRUPT_ENABLE; - PMCDBG(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"mips74k-get_perfctl ri=%d -> config=0x%x", ri, config); return (config); } diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index cb8ed37..3793aa2 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -173,7 +173,7 @@ static struct pmc_classdep **pmc_rowindex_to_classdep; * Prototypes */ -#ifdef DEBUG +#ifdef HWPMC_DEBUG static int pmc_debugflags_sysctl_handler(SYSCTL_HANDLER_ARGS); static int pmc_debugflags_parse(char *newstr, char *fence); #endif @@ -238,7 +238,7 @@ static int pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; SYSCTL_INT(_kern_hwpmc, OID_AUTO, callchaindepth, CTLFLAG_RDTUN, &pmc_callchaindepth, 0, "depth of call chain records"); -#ifdef DEBUG +#ifdef HWPMC_DEBUG struct pmc_debugflags pmc_debugflags = PMC_DEBUG_DEFAULT_FLAGS; char pmc_debugstr[PMC_DEBUG_STRSIZE]; TUNABLE_STR(PMC_SYSCTL_NAME_PREFIX "debugflags", pmc_debugstr, @@ -337,7 +337,7 @@ static moduledata_t pmc_mod = { DECLARE_MODULE(pmc, pmc_mod, SI_SUB_SMP, SI_ORDER_ANY); MODULE_VERSION(pmc, PMC_VERSION); -#ifdef DEBUG +#ifdef HWPMC_DEBUG enum pmc_dbgparse_state { PMCDS_WS, /* in whitespace */ PMCDS_MAJOR, /* seen a major keyword */ @@ -651,12 +651,12 @@ pmc_ri_to_classdep(struct pmc_mdep *md, int ri, int *adjri) static void pmc_save_cpu_binding(struct pmc_binding *pb) { - PMCDBG(CPU,BND,2, "%s", "save-cpu"); + PMCDBG0(CPU,BND,2, "save-cpu"); thread_lock(curthread); pb->pb_bound = sched_is_bound(curthread); pb->pb_cpu = curthread->td_oncpu; thread_unlock(curthread); - PMCDBG(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu); + PMCDBG1(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu); } /* @@ -666,7 +666,7 @@ pmc_save_cpu_binding(struct pmc_binding *pb) static void pmc_restore_cpu_binding(struct pmc_binding *pb) { - PMCDBG(CPU,BND,2, "restore-cpu curcpu=%d restore=%d", + PMCDBG2(CPU,BND,2, "restore-cpu curcpu=%d restore=%d", curthread->td_oncpu, pb->pb_cpu); thread_lock(curthread); if (pb->pb_bound) @@ -674,7 +674,7 @@ pmc_restore_cpu_binding(struct pmc_binding *pb) else sched_unbind(curthread); thread_unlock(curthread); - PMCDBG(CPU,BND,2, "%s", "restore-cpu done"); + PMCDBG0(CPU,BND,2, "restore-cpu done"); } /* @@ -691,7 +691,7 @@ pmc_select_cpu(int cpu) KASSERT(pmc_cpu_is_active(cpu), ("[pmc,%d] selecting inactive " "CPU %d", __LINE__, cpu)); - PMCDBG(CPU,SEL,2, "select-cpu cpu=%d", cpu); + PMCDBG1(CPU,SEL,2, "select-cpu cpu=%d", cpu); thread_lock(curthread); sched_bind(curthread, cpu); thread_unlock(curthread); @@ -700,7 +700,7 @@ pmc_select_cpu(int cpu) ("[pmc,%d] CPU not bound [cpu=%d, curr=%d]", __LINE__, cpu, curthread->td_oncpu)); - PMCDBG(CPU,SEL,2, "select-cpu cpu=%d ok", cpu); + PMCDBG1(CPU,SEL,2, "select-cpu cpu=%d ok", cpu); } /* @@ -742,14 +742,14 @@ pmc_remove_owner(struct pmc_owner *po) sx_assert(&pmc_sx, SX_XLOCKED); - PMCDBG(OWN,ORM,1, "remove-owner po=%p", po); + PMCDBG1(OWN,ORM,1, "remove-owner po=%p", po); /* Remove descriptor from the owner hash table */ LIST_REMOVE(po, po_next); /* release all owned PMC descriptors */ LIST_FOREACH_SAFE(pm, &po->po_pmcs, pm_next, tmp) { - PMCDBG(OWN,ORM,2, "pmc=%p", pm); + PMCDBG1(OWN,ORM,2, "pmc=%p", pm); KASSERT(pm->pm_owner == po, ("[pmc,%d] owner %p != po %p", __LINE__, pm->pm_owner, po)); @@ -775,7 +775,7 @@ static void pmc_maybe_remove_owner(struct pmc_owner *po) { - PMCDBG(OWN,OMR,1, "maybe-remove-owner po=%p", po); + PMCDBG1(OWN,OMR,1, "maybe-remove-owner po=%p", po); /* * Remove owner record if @@ -813,10 +813,10 @@ pmc_link_target_process(struct pmc *pm, struct pmc_process *pp) ri = PMC_TO_ROWINDEX(pm); - PMCDBG(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p", + PMCDBG3(PRC,TLK,1, "link-target pmc=%p ri=%d pmc-process=%p", pm, ri, pp); -#ifdef DEBUG +#ifdef HWPMC_DEBUG LIST_FOREACH(pt, &pm->pm_targets, pt_next) if (pt->pt_process == pp) KASSERT(0, ("[pmc,%d] pp %p already in pmc %p targets", @@ -866,7 +866,7 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp) ri = PMC_TO_ROWINDEX(pm); - PMCDBG(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p", + PMCDBG3(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p", pm, ri, pp); KASSERT(pp->pp_pmcs[ri].pp_pmc == pm, @@ -902,7 +902,7 @@ pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp) kern_psignal(p, SIGIO); PROC_UNLOCK(p); - PMCDBG(PRC,SIG,2, "signalling proc=%p signal=%d", p, + PMCDBG2(PRC,SIG,2, "signalling proc=%p signal=%d", p, SIGIO); } } @@ -975,7 +975,7 @@ pmc_attach_one_process(struct proc *p, struct pmc *pm) sx_assert(&pmc_sx, SX_XLOCKED); - PMCDBG(PRC,ATT,2, "attach-one pm=%p ri=%d proc=%p (%d, %s)", pm, + PMCDBG5(PRC,ATT,2, "attach-one pm=%p ri=%d proc=%p (%d, %s)", pm, PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm); /* @@ -1040,7 +1040,7 @@ pmc_attach_process(struct proc *p, struct pmc *pm) sx_assert(&pmc_sx, SX_XLOCKED); - PMCDBG(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm, + PMCDBG5(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm, PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm); @@ -1107,7 +1107,7 @@ pmc_detach_one_process(struct proc *p, struct pmc *pm, int flags) ri = PMC_TO_ROWINDEX(pm); - PMCDBG(PRC,ATT,2, "detach-one pm=%p ri=%d proc=%p (%d, %s) flags=0x%x", + PMCDBG6(PRC,ATT,2, "detach-one pm=%p ri=%d proc=%p (%d, %s) flags=0x%x", pm, ri, p, p->p_pid, p->p_comm, flags); if ((pp = pmc_find_process_descriptor(p, 0)) == NULL) @@ -1157,7 +1157,7 @@ pmc_detach_process(struct proc *p, struct pmc *pm) sx_assert(&pmc_sx, SX_XLOCKED); - PMCDBG(PRC,ATT,1, "detach pm=%p ri=%d proc=%p (%d, %s)", pm, + PMCDBG5(PRC,ATT,1, "detach pm=%p ri=%d proc=%p (%d, %s)", pm, PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm); if ((pm->pm_flags & PMC_F_DESCENDANTS) == 0) @@ -1228,7 +1228,7 @@ pmc_process_csw_in(struct thread *td) cpu = PCPU_GET(cpuid); /* td->td_oncpu is invalid */ - PMCDBG(CSW,SWI,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p, + PMCDBG5(CSW,SWI,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p, p->p_pid, p->p_comm, pp); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), @@ -1295,7 +1295,7 @@ pmc_process_csw_in(struct thread *td) mtx_pool_unlock_spin(pmc_mtxpool, pm); } - PMCDBG(CSW,SWI,1,"cpu=%d ri=%d new=%jd", cpu, ri, newvalue); + PMCDBG3(CSW,SWI,1,"cpu=%d ri=%d new=%jd", cpu, ri, newvalue); pcd->pcd_write_pmc(cpu, adjri, newvalue); pcd->pcd_start_pmc(cpu, adjri); @@ -1356,7 +1356,7 @@ pmc_process_csw_out(struct thread *td) cpu = PCPU_GET(cpuid); /* td->td_oncpu is invalid */ - PMCDBG(CSW,SWO,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p, + PMCDBG5(CSW,SWO,1, "cpu=%d proc=%p (%d, %s) pp=%p", cpu, p, p->p_pid, p->p_comm, pp); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), @@ -1418,7 +1418,7 @@ pmc_process_csw_out(struct thread *td) tmp = newvalue - PMC_PCPU_SAVED(cpu,ri); - PMCDBG(CSW,SWO,1,"cpu=%d ri=%d tmp=%jd", cpu, ri, + PMCDBG3(CSW,SWO,1,"cpu=%d ri=%d tmp=%jd", cpu, ri, tmp); if (mode == PMC_MODE_TS) { @@ -1575,7 +1575,7 @@ pmc_log_kernel_mappings(struct pmc *pm) */ kmbase = linker_hwpmc_list_objects(); for (km = kmbase; km->pm_file != NULL; km++) { - PMCDBG(LOG,REG,1,"%s %p", (char *) km->pm_file, + PMCDBG2(LOG,REG,1,"%s %p", (char *) km->pm_file, (void *) km->pm_address); pmclog_process_map_in(po, (pid_t) -1, km->pm_address, km->pm_file); @@ -1616,7 +1616,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p) for (entry = map->header.next; entry != &map->header; entry = entry->next) { if (entry == NULL) { - PMCDBG(LOG,OPS,2, "hwpmc: vm_map entry unexpectedly " + PMCDBG2(LOG,OPS,2, "hwpmc: vm_map entry unexpectedly " "NULL! pid=%d vm_map=%p\n", p->p_pid, map); break; } @@ -1649,7 +1649,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p) * At this point lobj is the base vm_object and it is locked. */ if (lobj == NULL) { - PMCDBG(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d " + PMCDBG3(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d " "vm_map=%p vm_obj=%p\n", p->p_pid, map, obj); VM_OBJECT_RUNLOCK(obj); continue; @@ -1784,7 +1784,7 @@ pmc_log_all_process_mappings(struct pmc_owner *po) */ -#ifdef DEBUG +#ifdef HWPMC_DEBUG const char *pmc_hooknames[] = { /* these strings correspond to PMC_FN_* in <sys/pmckern.h> */ "", @@ -1806,7 +1806,7 @@ static int pmc_hook_handler(struct thread *td, int function, void *arg) { - PMCDBG(MOD,PMH,1, "hook td=%p func=%d \"%s\" arg=%p", td, function, + PMCDBG4(MOD,PMH,1, "hook td=%p func=%d \"%s\" arg=%p", td, function, pmc_hooknames[function], arg); switch (function) @@ -1889,7 +1889,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg) free(freepath, M_TEMP); - PMCDBG(PRC,EXC,1, "exec proc=%p (%d, %s) cred-changed=%d", + PMCDBG4(PRC,EXC,1, "exec proc=%p (%d, %s) cred-changed=%d", p, p->p_pid, p->p_comm, pk->pm_credentialschanged); if (pk->pm_credentialschanged == 0) /* no change */ @@ -2002,7 +2002,7 @@ pmc_hook_handler(struct thread *td, int function, void *arg) break; default: -#ifdef DEBUG +#ifdef HWPMC_DEBUG KASSERT(0, ("[pmc,%d] unknown hook %d\n", __LINE__, function)); #endif break; @@ -2034,7 +2034,7 @@ pmc_allocate_owner_descriptor(struct proc *p) TAILQ_INIT(&po->po_logbuffers); mtx_init(&po->po_mtx, "pmc-owner-mtx", "pmc-per-proc", MTX_SPIN); - PMCDBG(OWN,ALL,1, "allocate-owner proc=%p (%d, %s) pmc-owner=%p", + PMCDBG4(OWN,ALL,1, "allocate-owner proc=%p (%d, %s) pmc-owner=%p", p, p->p_pid, p->p_comm, po); return po; @@ -2044,7 +2044,7 @@ static void pmc_destroy_owner_descriptor(struct pmc_owner *po) { - PMCDBG(OWN,REL,1, "destroy-owner po=%p proc=%p (%d, %s)", + PMCDBG4(OWN,REL,1, "destroy-owner po=%p proc=%p (%d, %s)", po, po->po_owner, po->po_owner->p_pid, po->po_owner->p_comm); mtx_destroy(&po->po_mtx); @@ -2135,7 +2135,7 @@ pmc_find_owner_descriptor(struct proc *p) if (po->po_owner == p) break; - PMCDBG(OWN,FND,1, "find-owner proc=%p (%d, %s) hindex=0x%x -> " + PMCDBG5(OWN,FND,1, "find-owner proc=%p (%d, %s) hindex=0x%x -> " "pmc-owner=%p", p, p->p_pid, p->p_comm, hindex, po); return po; @@ -2155,7 +2155,7 @@ pmc_allocate_pmc_descriptor(void) pmc = malloc(sizeof(struct pmc), M_PMC, M_WAITOK|M_ZERO); - PMCDBG(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc); + PMCDBG1(PMC,ALL,1, "allocate-pmc -> pmc=%p", pmc); return pmc; } @@ -2185,7 +2185,7 @@ pmc_destroy_pmc_descriptor(struct pmc *pm) static void pmc_wait_for_pmc_idle(struct pmc *pm) { -#ifdef DEBUG +#ifdef HWPMC_DEBUG volatile int maxloop; maxloop = 100 * pmc_cpu_max(); @@ -2195,7 +2195,7 @@ pmc_wait_for_pmc_idle(struct pmc *pm) * comes down to zero. */ while (atomic_load_acq_32(&pm->pm_runcount) > 0) { -#ifdef DEBUG +#ifdef HWPMC_DEBUG maxloop--; KASSERT(maxloop > 0, ("[pmc,%d] (ri%d, rc%d) waiting too long for " @@ -2238,7 +2238,7 @@ pmc_release_pmc_descriptor(struct pmc *pm) pcd = pmc_ri_to_classdep(md, ri, &adjri); mode = PMC_TO_MODE(pm); - PMCDBG(PMC,REL,1, "release-pmc pmc=%p ri=%d mode=%d", pm, ri, + PMCDBG3(PMC,REL,1, "release-pmc pmc=%p ri=%d mode=%d", pm, ri, mode); /* @@ -2266,14 +2266,14 @@ pmc_release_pmc_descriptor(struct pmc *pm) KASSERT(phw->phw_pmc == pm, ("[pmc, %d] pmc ptr ri(%d) hw(%p) pm(%p)", __LINE__, ri, phw->phw_pmc, pm)); - PMCDBG(PMC,REL,2, "stopping cpu=%d ri=%d", cpu, ri); + PMCDBG2(PMC,REL,2, "stopping cpu=%d ri=%d", cpu, ri); critical_enter(); pcd->pcd_stop_pmc(cpu, adjri); critical_exit(); } - PMCDBG(PMC,REL,2, "decfg cpu=%d ri=%d", cpu, ri); + PMCDBG2(PMC,REL,2, "decfg cpu=%d ri=%d", cpu, ri); critical_enter(); pcd->pcd_config_pmc(cpu, adjri, NULL); @@ -2329,7 +2329,7 @@ pmc_release_pmc_descriptor(struct pmc *pm) pp = ptgt->pt_process; pmc_unlink_target_process(pm, pp); /* frees 'ptgt' */ - PMCDBG(PMC,REL,3, "pp->refcnt=%d", pp->pp_refcnt); + PMCDBG1(PMC,REL,3, "pp->refcnt=%d", pp->pp_refcnt); /* * If the target process record shows that no @@ -2395,7 +2395,7 @@ pmc_register_owner(struct proc *p, struct pmc *pmc) if (po->po_flags & PMC_PO_OWNS_LOGFILE) pmclog_process_pmcallocate(pmc); - PMCDBG(PMC,REG,1, "register-owner pmc-owner=%p pmc=%p", + PMCDBG2(PMC,REG,1, "register-owner pmc-owner=%p pmc=%p", po, pmc); return 0; @@ -2433,7 +2433,7 @@ pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, int cpu) struct pmc_owner *po; struct pmc_process *pp; - PMCDBG(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d " + PMCDBG5(PMC,ALR,1, "can-allocate-rowindex proc=%p (%d, %s) ri=%d " "cpu=%d", p, p->p_pid, p->p_comm, ri, cpu); /* @@ -2463,7 +2463,7 @@ pmc_can_allocate_rowindex(struct proc *p, unsigned int ri, int cpu) if (pp->pp_pmcs[ri].pp_pmc) return EEXIST; - PMCDBG(PMC,ALR,2, "can-allocate-rowindex proc=%p (%d, %s) ri=%d ok", + PMCDBG4(PMC,ALR,2, "can-allocate-rowindex proc=%p (%d, %s) ri=%d ok", p, p->p_pid, p->p_comm, ri); return 0; @@ -2481,7 +2481,7 @@ pmc_can_allocate_row(int ri, enum pmc_mode mode) sx_assert(&pmc_sx, SX_XLOCKED); - PMCDBG(PMC,ALR,1, "can-allocate-row ri=%d mode=%d", ri, mode); + PMCDBG2(PMC,ALR,1, "can-allocate-row ri=%d mode=%d", ri, mode); if (PMC_IS_SYSTEM_MODE(mode)) disp = PMC_DISP_STANDALONE; @@ -2508,7 +2508,7 @@ pmc_can_allocate_row(int ri, enum pmc_mode mode) * All OK */ - PMCDBG(PMC,ALR,2, "can-allocate-row ri=%d mode=%d ok", ri, mode); + PMCDBG2(PMC,ALR,2, "can-allocate-row ri=%d mode=%d ok", ri, mode); return 0; @@ -2541,7 +2541,7 @@ pmc_find_pmc(pmc_id_t pmcid, struct pmc **pmc) struct pmc *pm; struct pmc_owner *po; - PMCDBG(PMC,FND,1, "find-pmc id=%d", pmcid); + PMCDBG1(PMC,FND,1, "find-pmc id=%d", pmcid); if ((po = pmc_find_owner_descriptor(curthread->td_proc)) == NULL) return ESRCH; @@ -2549,7 +2549,7 @@ pmc_find_pmc(pmc_id_t pmcid, struct pmc **pmc) if ((pm = pmc_find_pmc_descriptor_in_process(po, pmcid)) == NULL) return EINVAL; - PMCDBG(PMC,FND,2, "find-pmc id=%d -> pmc=%p", pmcid, pm); + PMCDBG2(PMC,FND,2, "find-pmc id=%d -> pmc=%p", pmcid, pm); *pmc = pm; return 0; @@ -2577,7 +2577,7 @@ pmc_start(struct pmc *pm) error = 0; - PMCDBG(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, mode, ri); + PMCDBG3(PMC,OPS,1, "start pmc=%p mode=%d ri=%d", pm, mode, ri); po = pm->pm_owner; @@ -2633,7 +2633,7 @@ pmc_start(struct pmc *pm) if (po->po_sscount == 0) { LIST_INSERT_HEAD(&pmc_ss_owners, po, po_ssnext); atomic_add_rel_int(&pmc_ss_count, 1); - PMCDBG(PMC,OPS,1, "po=%p in global list", po); + PMCDBG1(PMC,OPS,1, "po=%p in global list", po); } po->po_sscount++; @@ -2696,7 +2696,7 @@ pmc_stop(struct pmc *pm) KASSERT(pm != NULL, ("[pmc,%d] null pmc", __LINE__)); - PMCDBG(PMC,OPS,1, "stop pmc=%p mode=%d ri=%d", pm, + PMCDBG3(PMC,OPS,1, "stop pmc=%p mode=%d ri=%d", pm, PMC_TO_MODE(pm), PMC_TO_ROWINDEX(pm)); pm->pm_state = PMC_STATE_STOPPED; @@ -2751,7 +2751,7 @@ pmc_stop(struct pmc *pm) if (po->po_sscount == 0) { atomic_subtract_rel_int(&pmc_ss_count, 1); LIST_REMOVE(po, po_ssnext); - PMCDBG(PMC,OPS,2,"po=%p removed from global list", po); + PMCDBG1(PMC,OPS,2,"po=%p removed from global list", po); } } @@ -2759,7 +2759,7 @@ pmc_stop(struct pmc *pm) } -#ifdef DEBUG +#ifdef HWPMC_DEBUG static const char *pmc_op_to_name[] = { #undef __PMC_OP #define __PMC_OP(N, D) #N , @@ -2804,7 +2804,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) op = c->pmop_code; arg = c->pmop_data; - PMCDBG(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op, + PMCDBG3(MOD,PMS,1, "syscall op=%d \"%s\" arg=%p", op, pmc_op_to_name[op], arg); error = 0; @@ -3317,7 +3317,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) break; } - PMCDBG(PMC,ALL,2, "event=%d caps=0x%x mode=%d cpu=%d", + PMCDBG4(PMC,ALL,2, "event=%d caps=0x%x mode=%d cpu=%d", pa.pm_ev, caps, mode, cpu); pmc = pmc_allocate_pmc_descriptor(); @@ -3379,7 +3379,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) /* Fill in the correct value in the ID field */ pmc->pm_id = PMC_ID_MAKE_ID(cpu,mode,pa.pm_class,n); - PMCDBG(PMC,ALL,2, "ev=%d class=%d mode=%d n=%d -> pmcid=%x", + PMCDBG5(PMC,ALL,2, "ev=%d class=%d mode=%d n=%d -> pmcid=%x", pmc->pm_event, pa.pm_class, mode, n, pmc->pm_id); /* Process mode PMCs with logging enabled need log files */ @@ -3702,7 +3702,7 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) break; ri = 0; - PMCDBG(PMC,OPS,1, "rw id=%d flags=0x%x", prw.pm_pmcid, + PMCDBG2(PMC,OPS,1, "rw id=%d flags=0x%x", prw.pm_pmcid, prw.pm_flags); /* must have at least one flag set */ @@ -3798,12 +3798,12 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) pprw = (struct pmc_op_pmcrw *) arg; -#ifdef DEBUG +#ifdef HWPMC_DEBUG if (prw.pm_flags & PMC_F_NEWVALUE) - PMCDBG(PMC,OPS,2, "rw id=%d new %jx -> old %jx", + PMCDBG3(PMC,OPS,2, "rw id=%d new %jx -> old %jx", ri, prw.pm_value, oldvalue); else if (prw.pm_flags & PMC_F_OLDVALUE) - PMCDBG(PMC,OPS,2, "rw id=%d -> old %jx", ri, oldvalue); + PMCDBG2(PMC,OPS,2, "rw id=%d -> old %jx", ri, oldvalue); #endif /* return old value if requested */ @@ -4046,7 +4046,7 @@ pmc_process_interrupt(int cpu, int ring, struct pmc *pm, struct trapframe *tf, if (ps->ps_nsamples) { /* in use, reader hasn't caught up */ pm->pm_stalled = 1; atomic_add_int(&pmc_stats.pm_intr_bufferfull, 1); - PMCDBG(SAM,INT,1,"(spc) cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", + PMCDBG6(SAM,INT,1,"(spc) cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm, (void *) tf, inuserspace, (int) (psb->ps_write - psb->ps_samples), (int) (psb->ps_read - psb->ps_samples)); @@ -4056,7 +4056,7 @@ pmc_process_interrupt(int cpu, int ring, struct pmc *pm, struct trapframe *tf, /* Fill in entry. */ - PMCDBG(SAM,INT,1,"cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm, + PMCDBG6(SAM,INT,1,"cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm, (void *) tf, inuserspace, (int) (psb->ps_write - psb->ps_samples), (int) (psb->ps_read - psb->ps_samples)); @@ -4239,7 +4239,7 @@ pmc_process_samples(int cpu, int ring) break; } - PMCDBG(SAM,OPS,1,"cpu=%d pm=%p n=%d fl=%x wr=%d rd=%d", cpu, + PMCDBG6(SAM,OPS,1,"cpu=%d pm=%p n=%d fl=%x wr=%d rd=%d", cpu, pm, ps->ps_nsamples, ps->ps_flags, (int) (psb->ps_write - psb->ps_samples), (int) (psb->ps_read - psb->ps_samples)); @@ -4355,7 +4355,7 @@ pmc_process_exit(void *arg __unused, struct proc *p) return; PMC_GET_SX_XLOCK(); - PMCDBG(PRC,EXT,1,"process-exit proc=%p (%d, %s)", p, p->p_pid, + PMCDBG3(PRC,EXT,1,"process-exit proc=%p (%d, %s)", p, p->p_pid, p->p_comm); /* @@ -4370,7 +4370,7 @@ pmc_process_exit(void *arg __unused, struct proc *p) * entry from our target process hash table, using * PMC_FLAG_REMOVE. */ - PMCDBG(PRC,EXT,1, "process-exit proc=%p (%d, %s)", p, p->p_pid, + PMCDBG3(PRC,EXT,1, "process-exit proc=%p (%d, %s)", p, p->p_pid, p->p_comm); critical_enter(); /* no preemption */ @@ -4380,7 +4380,7 @@ pmc_process_exit(void *arg __unused, struct proc *p) if ((pp = pmc_find_process_descriptor(p, PMC_FLAG_REMOVE)) != NULL) { - PMCDBG(PRC,EXT,2, + PMCDBG2(PRC,EXT,2, "process-exit proc=%p pmc-process=%p", p, pp); /* @@ -4403,13 +4403,13 @@ pmc_process_exit(void *arg __unused, struct proc *p) (void) (*pcd->pcd_get_config)(cpu, adjri, &pm); - PMCDBG(PRC,EXT,2, "ri=%d pm=%p", ri, pm); + PMCDBG2(PRC,EXT,2, "ri=%d pm=%p", ri, pm); if (pm == NULL || !PMC_IS_VIRTUAL_MODE(PMC_TO_MODE(pm))) continue; - PMCDBG(PRC,EXT,2, "ppmcs[%d]=%p pm=%p " + PMCDBG4(PRC,EXT,2, "ppmcs[%d]=%p pm=%p " "state=%d", ri, pp->pp_pmcs[ri].pp_pmc, pm, pm->pm_state); @@ -4525,7 +4525,7 @@ pmc_process_fork(void *arg __unused, struct proc *p1, struct proc *newproc, return; PMC_GET_SX_XLOCK(); - PMCDBG(PMC,FRK,1, "process-fork proc=%p (%d, %s) -> %p", p1, + PMCDBG4(PMC,FRK,1, "process-fork proc=%p (%d, %s) -> %p", p1, p1->p_pid, p1->p_comm, newproc); /* @@ -4712,7 +4712,7 @@ pmc_initialize(void) md = NULL; error = 0; -#ifdef DEBUG +#ifdef HWPMC_DEBUG /* parse debug flags first */ if (TUNABLE_STR_FETCH(PMC_SYSCTL_NAME_PREFIX "debugflags", pmc_debugstr, sizeof(pmc_debugstr))) @@ -4720,7 +4720,7 @@ pmc_initialize(void) pmc_debugstr+strlen(pmc_debugstr)); #endif - PMCDBG(MOD,INI,0, "PMC Initialize (version %x)", PMC_VERSION); + PMCDBG1(MOD,INI,0, "PMC Initialize (version %x)", PMC_VERSION); /* check kernel version */ if (pmc_kernel_version != PMC_VERSION) { @@ -4881,7 +4881,7 @@ pmc_initialize(void) pmc_mtxpool = mtx_pool_create("pmc-leaf", pmc_mtxpool_size, MTX_SPIN); - PMCDBG(MOD,INI,1, "pmc_ownerhash=%p, mask=0x%lx " + PMCDBG4(MOD,INI,1, "pmc_ownerhash=%p, mask=0x%lx " "targethash=%p mask=0x%lx", pmc_ownerhash, pmc_ownerhashmask, pmc_processhash, pmc_processhashmask); @@ -4933,11 +4933,11 @@ pmc_cleanup(void) struct pmc_ownerhash *ph; struct pmc_owner *po, *tmp; struct pmc_binding pb; -#ifdef DEBUG +#ifdef HWPMC_DEBUG struct pmc_processhash *prh; #endif - PMCDBG(MOD,INI,0, "%s", "cleanup"); + PMCDBG0(MOD,INI,0, "cleanup"); /* switch off sampling */ CPU_ZERO(&pmc_cpumask); @@ -4966,7 +4966,7 @@ pmc_cleanup(void) pmc_remove_owner(po); /* send SIGBUS to owner processes */ - PMCDBG(MOD,INI,2, "cleanup signal proc=%p " + PMCDBG3(MOD,INI,2, "cleanup signal proc=%p " "(%d, %s)", po->po_owner, po->po_owner->p_pid, po->po_owner->p_comm); @@ -4985,15 +4985,15 @@ pmc_cleanup(void) mtx_destroy(&pmc_processhash_mtx); if (pmc_processhash) { -#ifdef DEBUG +#ifdef HWPMC_DEBUG struct pmc_process *pp; - PMCDBG(MOD,INI,3, "%s", "destroy process hash"); + PMCDBG0(MOD,INI,3, "destroy process hash"); for (prh = pmc_processhash; prh <= &pmc_processhash[pmc_processhashmask]; prh++) LIST_FOREACH(pp, prh, pp_next) - PMCDBG(MOD,INI,3, "pid=%d", pp->pp_proc->p_pid); + PMCDBG1(MOD,INI,3, "pid=%d", pp->pp_proc->p_pid); #endif hashdestroy(pmc_processhash, M_PMC, pmc_processhashmask); @@ -5001,7 +5001,7 @@ pmc_cleanup(void) } if (pmc_ownerhash) { - PMCDBG(MOD,INI,3, "%s", "destroy owner hash"); + PMCDBG0(MOD,INI,3, "destroy owner hash"); hashdestroy(pmc_ownerhash, M_PMC, pmc_ownerhashmask); pmc_ownerhash = NULL; } @@ -5014,11 +5014,11 @@ pmc_cleanup(void) /* do processor and pmc-class dependent cleanup */ maxcpu = pmc_cpu_max(); - PMCDBG(MOD,INI,3, "%s", "md cleanup"); + PMCDBG0(MOD,INI,3, "md cleanup"); if (md) { pmc_save_cpu_binding(&pb); for (cpu = 0; cpu < maxcpu; cpu++) { - PMCDBG(MOD,INI,1,"pmc-cleanup cpu=%d pcs=%p", + PMCDBG2(MOD,INI,1,"pmc-cleanup cpu=%d pcs=%p", cpu, pmc_pcpu[cpu]); if (!pmc_cpu_is_active(cpu) || pmc_pcpu[cpu] == NULL) continue; @@ -5094,7 +5094,7 @@ load (struct module *module __unused, int cmd, void *arg __unused) error = pmc_initialize(); if (error != 0) break; - PMCDBG(MOD,INI,1, "syscall=%d maxcpu=%d", + PMCDBG2(MOD,INI,1, "syscall=%d maxcpu=%d", pmc_syscall_num, pmc_cpu_max()); break; @@ -5102,7 +5102,7 @@ load (struct module *module __unused, int cmd, void *arg __unused) case MOD_UNLOAD : case MOD_SHUTDOWN: pmc_cleanup(); - PMCDBG(MOD,INI,1, "%s", "unloaded"); + PMCDBG0(MOD,INI,1, "unloaded"); break; default : diff --git a/sys/dev/hwpmc/hwpmc_mpc7xxx.c b/sys/dev/hwpmc/hwpmc_mpc7xxx.c index eaa440e..296bd37 100644 --- a/sys/dev/hwpmc/hwpmc_mpc7xxx.c +++ b/sys/dev/hwpmc/hwpmc_mpc7xxx.c @@ -384,7 +384,7 @@ mpc7xxx_read_pmc(int cpu, int ri, pmc_value_t *v) ri)); tmp = mpc7xxx_pmcn_read(ri); - PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); else @@ -408,7 +408,7 @@ mpc7xxx_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); mpc7xxx_pmcn_write(ri, v); @@ -420,7 +420,7 @@ mpc7xxx_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); @@ -559,7 +559,7 @@ mpc7xxx_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu); powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -638,7 +638,7 @@ mpc7xxx_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; - PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -671,7 +671,7 @@ mpc7xxx_intr(int cpu, struct trapframe *tf) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); - PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); retval = 0; diff --git a/sys/dev/hwpmc/hwpmc_octeon.c b/sys/dev/hwpmc/hwpmc_octeon.c index 824a7b0..b614573 100644 --- a/sys/dev/hwpmc/hwpmc_octeon.c +++ b/sys/dev/hwpmc/hwpmc_octeon.c @@ -189,7 +189,8 @@ mips_get_perfctl(int cpu, int ri, uint32_t event, uint32_t caps) if (caps & PMC_CAP_INTERRUPT) control.s.ie = 1; - PMCDBG(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, control.u32); + PMCDBG2(MDP,ALL,2,"mips-allocate ri=%d -> config=0x%x", ri, + control.u32); return (control.u32); } diff --git a/sys/dev/hwpmc/hwpmc_piv.c b/sys/dev/hwpmc/hwpmc_piv.c index ff47cb8..872ad89 100644 --- a/sys/dev/hwpmc/hwpmc_piv.c +++ b/sys/dev/hwpmc/hwpmc_piv.c @@ -563,7 +563,7 @@ p4_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[p4,%d] insane cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,0, "p4-init cpu=%d is-primary=%d", cpu, + PMCDBG2(MDP,INI,0, "p4-init cpu=%d is-primary=%d", cpu, pmc_cpu_is_primary(cpu) != 0); first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri; @@ -590,7 +590,7 @@ p4_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(plc != pc, ("[p4,%d] per-cpu config error", __LINE__)); - PMCDBG(MDP,INI,1, "p4-init cpu=%d phycpu=%d pc=%p", cpu, + PMCDBG3(MDP,INI,1, "p4-init cpu=%d phycpu=%d pc=%p", cpu, phycpu, pc); KASSERT(pc, ("[p4,%d] Null Per-Cpu state cpu=%d phycpu=%d", __LINE__, cpu, phycpu)); @@ -642,7 +642,7 @@ p4_pcpu_fini(struct pmc_mdep *md, int cpu) struct p4_cpu *p4c; struct pmc_cpu *pc; - PMCDBG(MDP,INI,0, "p4-cleanup cpu=%d", cpu); + PMCDBG1(MDP,INI,0, "p4-cleanup cpu=%d", cpu); pc = pmc_pcpu[cpu]; first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_P4].pcd_ri; @@ -702,7 +702,7 @@ p4_read_pmc(int cpu, int ri, pmc_value_t *v) mode = PMC_TO_MODE(pm); - PMCDBG(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode); + PMCDBG3(MDP,REA,1, "p4-read cpu=%d ri=%d mode=%d", cpu, ri, mode); KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, ("[p4,%d] unknown PMC class %d", __LINE__, pd->pm_descr.pd_class)); @@ -723,7 +723,7 @@ p4_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp; - PMCDBG(MDP,REA,2, "p4-read -> %jx", *v); + PMCDBG1(MDP,REA,2, "p4-read -> %jx", *v); return (0); } @@ -757,7 +757,7 @@ p4_write_pmc(int cpu, int ri, pmc_value_t v) mode = PMC_TO_MODE(pm); - PMCDBG(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri, + PMCDBG4(MDP,WRI,1, "p4-write cpu=%d ri=%d mode=%d v=%jx", cpu, ri, mode, v); /* @@ -800,7 +800,7 @@ p4_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < P4_NPMCS, ("[p4,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)]; phw = &pc->pc_p4pmcs[ri]; @@ -930,7 +930,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm, pd = &p4_pmcdesc[ri]; - PMCDBG(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x " + PMCDBG4(MDP,ALL,1, "p4-allocate ri=%d class=%d pmccaps=0x%x " "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, pm->pm_caps); @@ -965,7 +965,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm, if ((pevent = p4_find_event(pm->pm_event)) == NULL) return (ESRCH); - PMCDBG(MDP,ALL,2, "pevent={ev=%d,escrsel=0x%x,cccrsel=0x%x,isti=%d}", + PMCDBG4(MDP,ALL,2, "pevent={ev=%d,escrsel=0x%x,cccrsel=0x%x,isti=%d}", pevent->pm_event, pevent->pm_escr_eventselect, pevent->pm_cccr_select, pevent->pm_is_ti_event); @@ -1105,7 +1105,7 @@ p4_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_p4.pm_p4_cccrvalue = cccrvalue; pm->pm_md.pm_p4.pm_p4_escrvalue = escrvalue; - PMCDBG(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x " + PMCDBG5(MDP,ALL,2, "p4-allocate cccrsel=0x%x cccrval=0x%x " "escr=%d escrmsr=0x%x escrval=0x%x", pevent->pm_cccr_select, cccrvalue, escr, pm->pm_md.pm_p4.pm_p4_escrmsr, escrvalue); @@ -1127,7 +1127,7 @@ p4_release_pmc(int cpu, int ri, struct pmc *pm) escr = pm->pm_md.pm_p4.pm_p4_escr; - PMCDBG(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr); + PMCDBG3(MDP,REL,1, "p4-release cpu=%d ri=%d escr=%d", cpu, ri, escr); if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)]; @@ -1171,7 +1171,7 @@ p4_start_pmc(int cpu, int ri) KASSERT(pm != NULL, ("[p4,%d] starting cpu%d,pmc%d with null pmc", __LINE__, cpu, ri)); - PMCDBG(MDP,STA,1, "p4-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1, "p4-start cpu=%d ri=%d", cpu, ri); KASSERT(pd->pm_descr.pd_class == PMC_CLASS_P4, ("[p4,%d] wrong PMC class %d", __LINE__, @@ -1283,9 +1283,10 @@ p4_start_pmc(int cpu, int ri) mtx_unlock_spin(&pc->pc_mtx); - PMCDBG(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d " - "escrmsr=0x%x escrvalue=0x%x cccr_config=0x%x v=%jx", cpu, rc, - ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue, + PMCDBG6(MDP,STA,2,"p4-start cpu=%d rc=%d ri=%d escr=%d " + "escrmsr=0x%x escrvalue=0x%x", cpu, rc, + ri, pm->pm_md.pm_p4.pm_p4_escr, escrmsr, escrvalue); + PMCDBG2(MDP,STA,2,"cccr_config=0x%x v=%jx", cccrvalue, P4_PCPU_HW_VALUE(pc,ri,cpu)); return (0); @@ -1317,7 +1318,7 @@ p4_stop_pmc(int cpu, int ri) KASSERT(pm != NULL, ("[p4,%d] null pmc for cpu%d, ri%d", __LINE__, cpu, ri)); - PMCDBG(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1, "p4-stop cpu=%d ri=%d", cpu, ri); if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) { wrmsr(pd->pm_cccr_msr, @@ -1385,9 +1386,9 @@ p4_stop_pmc(int cpu, int ri) mtx_unlock_spin(&pc->pc_mtx); - PMCDBG(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x " - "escrval=0x%x cccrval=0x%x v=%jx", cpu, rc, ri, escrmsr, - escrvalue, cccrvalue, tmp); + PMCDBG5(MDP,STO,2, "p4-stop cpu=%d rc=%d ri=%d escrmsr=0x%x " + "escrval=0x%x", cpu, rc, ri, escrmsr, escrvalue); + PMCDBG2(MDP,STO,2, "cccrval=0x%x v=%jx", cccrvalue, tmp); if (tmp < P4_PCPU_HW_VALUE(pc,ri,cpu)) /* 40 bit counter overflow */ tmp += (P4_PERFCTR_MASK + 1) - P4_PCPU_HW_VALUE(pc,ri,cpu); @@ -1422,7 +1423,7 @@ p4_intr(int cpu, struct trapframe *tf) struct pmc *pm; pmc_value_t v; - PMCDBG(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT, 1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); pc = p4_pcpu[P4_TO_HTT_PRIMARY(cpu)]; @@ -1492,7 +1493,7 @@ p4_intr(int cpu, struct trapframe *tf) v = rdmsr(P4_PERFCTR_MSR_FIRST + ri); - PMCDBG(MDP,INT, 2, "ri=%d v=%jx", ri, v); + PMCDBG2(MDP,INT, 2, "ri=%d v=%jx", ri, v); /* Stop the counter, and reset the overflow bit */ cccrval &= ~(P4_CCCR_OVF | P4_CCCR_ENABLE); @@ -1568,7 +1569,7 @@ p4_describe(int cpu, int ri, struct pmc_info *pi, KASSERT(ri >= 0 && ri < P4_NPMCS, ("[p4,%d] row-index %d out of range", __LINE__, ri)); - PMCDBG(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,OPS,1,"p4-describe cpu=%d ri=%d", cpu, ri); if (P4_CPU_IS_HTT_SECONDARY(cpu)) return (EINVAL); @@ -1604,7 +1605,7 @@ p4_get_msr(int ri, uint32_t *msr) *msr = p4_pmcdesc[ri].pm_pmc_msr - P4_PERFCTR_MSR_FIRST; - PMCDBG(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr); + PMCDBG2(MDP,OPS, 1, "ri=%d getmsr=0x%x", ri, *msr); return 0; } @@ -1620,7 +1621,7 @@ pmc_p4_initialize(struct pmc_mdep *md, int ncpus) KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL, ("[p4,%d] Initializing non-intel processor", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "p4-initialize"); + PMCDBG0(MDP,INI,1, "p4-initialize"); /* Allocate space for pointers to per-cpu descriptors. */ p4_pcpu = malloc(sizeof(*p4_pcpu) * ncpus, M_PMC, M_ZERO | M_WAITOK); diff --git a/sys/dev/hwpmc/hwpmc_ppc970.c b/sys/dev/hwpmc/hwpmc_ppc970.c index f477be3..1a263f3 100644 --- a/sys/dev/hwpmc/hwpmc_ppc970.c +++ b/sys/dev/hwpmc/hwpmc_ppc970.c @@ -342,7 +342,7 @@ ppc970_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] illegal CPU value %d", __LINE__, cpu)); @@ -445,7 +445,7 @@ ppc970_read_pmc(int cpu, int ri, pmc_value_t *v) ri)); tmp = ppc970_pmcn_read(ri); - PMCDBG(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"ppc-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = POWERPC_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); else @@ -469,7 +469,7 @@ ppc970_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = POWERPC_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"powerpc-write cpu=%d ri=%d v=%jx", cpu, ri, v); ppc970_pmcn_write(ri, v); @@ -487,7 +487,7 @@ ppc970_intr(int cpu, struct trapframe *tf) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] out of range CPU %d", __LINE__, cpu)); - PMCDBG(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, + PMCDBG3(MDP,INT,1, "cpu=%d tf=%p um=%d", cpu, (void *) tf, TRAPF_USERMODE(tf)); retval = 0; @@ -546,7 +546,7 @@ ppc970_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[powerpc,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"powerpc-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"powerpc-init cpu=%d", cpu); powerpc_pcpu[cpu] = pac = malloc(sizeof(struct powerpc_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -632,7 +632,7 @@ ppc970_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_powerpc.pm_powerpc_evsel = config; - PMCDBG(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"powerpc-allocate ri=%d -> config=0x%x", ri, config); return 0; } diff --git a/sys/dev/hwpmc/hwpmc_ppro.c b/sys/dev/hwpmc/hwpmc_ppro.c index e99bb30..9d983fa 100644 --- a/sys/dev/hwpmc/hwpmc_ppro.c +++ b/sys/dev/hwpmc/hwpmc_ppro.c @@ -339,7 +339,7 @@ p6_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[p6,%d] bad cpu %d", __LINE__, cpu)); - PMCDBG(MDP,INI,0,"p6-init cpu=%d", cpu); + PMCDBG1(MDP,INI,0,"p6-init cpu=%d", cpu); p6c = malloc(sizeof (struct p6_cpu), M_PMC, M_WAITOK|M_ZERO); pc = pmc_pcpu[cpu]; @@ -371,7 +371,7 @@ p6_pcpu_fini(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[p6,%d] bad cpu %d", __LINE__, cpu)); - PMCDBG(MDP,INI,0,"p6-cleanup cpu=%d", cpu); + PMCDBG1(MDP,INI,0,"p6-cleanup cpu=%d", cpu); p6c = p6_pcpu[cpu]; p6_pcpu[cpu] = NULL; @@ -412,7 +412,7 @@ p6_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp; - PMCDBG(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, + PMCDBG4(MDP,REA,1, "p6-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, pd->pm_pmc_msr, *v); return (0); @@ -435,7 +435,7 @@ p6_write_pmc(int cpu, int ri, pmc_value_t v) KASSERT(pm, ("[p6,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); - PMCDBG(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, + PMCDBG4(MDP,WRI,1, "p6-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, pd->pm_pmc_msr, v); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) @@ -455,7 +455,7 @@ p6_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < P6_NPMCS, ("[p6,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "p6-config cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "p6-config cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(p6_pcpu[cpu] != NULL, ("[p6,%d] null per-cpu %d", __LINE__, cpu)); @@ -508,7 +508,7 @@ p6_allocate_pmc(int cpu, int ri, struct pmc *pm, pd = &p6_pmcdesc[ri]; - PMCDBG(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x " + PMCDBG4(MDP,ALL,1, "p6-allocate ri=%d class=%d pmccaps=0x%x " "reqcaps=0x%x", ri, pd->pm_descr.pd_class, pd->pm_descr.pd_caps, pm->pm_caps); @@ -579,7 +579,7 @@ p6_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_ppro.pm_ppro_evsel = config; - PMCDBG(MDP,ALL,2, "p6-allocate config=0x%x", config); + PMCDBG1(MDP,ALL,2, "p6-allocate config=0x%x", config); return (0); } @@ -589,7 +589,7 @@ p6_release_pmc(int cpu, int ri, struct pmc *pm) { (void) pm; - PMCDBG(MDP,REL,1, "p6-release cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,REL,1, "p6-release cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[p6,%d] illegal CPU value %d", __LINE__, cpu)); @@ -623,11 +623,11 @@ p6_start_pmc(int cpu, int ri) ("[p6,%d] starting cpu%d,ri%d with no pmc configured", __LINE__, cpu, ri)); - PMCDBG(MDP,STA,1, "p6-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1, "p6-start cpu=%d ri=%d", cpu, ri); config = pm->pm_md.pm_ppro.pm_ppro_evsel; - PMCDBG(MDP,STA,2, "p6-start/2 cpu=%d ri=%d evselmsr=0x%x config=0x%x", + PMCDBG4(MDP,STA,2, "p6-start/2 cpu=%d ri=%d evselmsr=0x%x config=0x%x", cpu, ri, pd->pm_evsel_msr, config); P6_MARK_STARTED(pc, ri); @@ -658,14 +658,14 @@ p6_stop_pmc(int cpu, int ri) ("[p6,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG(MDP,STO,1, "p6-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1, "p6-stop cpu=%d ri=%d", cpu, ri); wrmsr(pd->pm_evsel_msr, 0); /* stop hw */ P6_MARK_STOPPED(pc, ri); /* update software state */ P6_SYNC_CTR_STATE(pc); /* restart CTR1 if need be */ - PMCDBG(MDP,STO,2, "p6-stop/2 cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,2, "p6-stop/2 cpu=%d ri=%d", cpu, ri); return (0); } @@ -788,7 +788,7 @@ pmc_p6_initialize(struct pmc_mdep *md, int ncpus) KASSERT(cpu_vendor_id == CPU_VENDOR_INTEL, ("[p6,%d] Initializing non-intel processor", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "p6-initialize"); + PMCDBG0(MDP,INI,1, "p6-initialize"); /* Allocate space for pointers to per-cpu descriptors. */ p6_pcpu = malloc(sizeof(struct p6_cpu **) * ncpus, M_PMC, diff --git a/sys/dev/hwpmc/hwpmc_soft.c b/sys/dev/hwpmc/hwpmc_soft.c index 7a585eb..fe143ad 100644 --- a/sys/dev/hwpmc/hwpmc_soft.c +++ b/sys/dev/hwpmc/hwpmc_soft.c @@ -136,7 +136,7 @@ soft_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[soft,%d] illegal CPU value %d", __LINE__, cpu)); @@ -276,7 +276,7 @@ soft_read_pmc(int cpu, int ri, pmc_value_t *v) KASSERT(pm != NULL, ("[soft,%d] no owner for PHW [cpu%d,pmc%d]", __LINE__, cpu, ri)); - PMCDBG(MDP,REA,1,"soft-read id=%d", ri); + PMCDBG1(MDP,REA,1,"soft-read id=%d", ri); *v = soft_pcpu[cpu]->soft_values[ri]; @@ -300,7 +300,7 @@ soft_write_pmc(int cpu, int ri, pmc_value_t v) KASSERT(pm, ("[soft,%d] cpu %d ri %d pmc not configured", __LINE__, cpu, ri)); - PMCDBG(MDP,WRI,1, "soft-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1, "soft-write cpu=%d ri=%d v=%jx", cpu, ri, v); soft_pcpu[cpu]->soft_values[ri] = v; diff --git a/sys/dev/hwpmc/hwpmc_tsc.c b/sys/dev/hwpmc/hwpmc_tsc.c index 237b7a1..5eb6907 100644 --- a/sys/dev/hwpmc/hwpmc_tsc.c +++ b/sys/dev/hwpmc/hwpmc_tsc.c @@ -99,7 +99,7 @@ tsc_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[tsc,%d] illegal CPU value %d", __LINE__, cpu)); @@ -253,7 +253,7 @@ tsc_read_pmc(int cpu, int ri, pmc_value_t *v) KASSERT(mode == PMC_MODE_SC, ("[tsc,%d] illegal pmc mode %d", __LINE__, mode)); - PMCDBG(MDP,REA,1,"tsc-read id=%d", ri); + PMCDBG1(MDP,REA,1,"tsc-read id=%d", ri); *v = rdtsc(); diff --git a/sys/dev/hwpmc/hwpmc_uncore.c b/sys/dev/hwpmc/hwpmc_uncore.c index 6a30eb0..2b24b33e 100644 --- a/sys/dev/hwpmc/hwpmc_uncore.c +++ b/sys/dev/hwpmc/hwpmc_uncore.c @@ -101,7 +101,7 @@ uncore_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[ucf,%d] insane cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"uncore-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"uncore-init cpu=%d", cpu); uncore_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_ri; npmc = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP].pcd_num; @@ -137,7 +137,7 @@ uncore_pcpu_fini(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[uncore,%d] insane cpu number (%d)", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"uncore-pcpu-fini cpu=%d", cpu); if ((cc = uncore_pcpu[cpu]) == NULL) return (0); @@ -193,7 +193,7 @@ ucf_allocate_pmc(int cpu, int ri, struct pmc *pm, KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[uncore,%d] illegal CPU %d", __LINE__, cpu)); - PMCDBG(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps); + PMCDBG2(MDP,ALL,1, "ucf-allocate ri=%d reqcaps=0x%x", ri, pm->pm_caps); if (ri < 0 || ri > uncore_ucf_npmc) return (EINVAL); @@ -212,7 +212,7 @@ ucf_allocate_pmc(int cpu, int ri, struct pmc *pm, pm->pm_md.pm_ucf.pm_ucf_ctrl = (flags << (ri * 4)); - PMCDBG(MDP,ALL,2, "ucf-allocate config=0x%jx", + PMCDBG1(MDP,ALL,2, "ucf-allocate config=0x%jx", (uintmax_t) pm->pm_md.pm_ucf.pm_ucf_ctrl); return (0); @@ -227,7 +227,7 @@ ucf_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < uncore_ucf_npmc, ("[uncore,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "ucf-config cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__, cpu)); @@ -296,7 +296,7 @@ ucf_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp; - PMCDBG(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v); + PMCDBG3(MDP,REA,1, "ucf-read cpu=%d ri=%d -> v=%jx", cpu, ri, *v); return (0); } @@ -304,7 +304,7 @@ ucf_read_pmc(int cpu, int ri, pmc_value_t *v) static int ucf_release_pmc(int cpu, int ri, struct pmc *pmc) { - PMCDBG(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc); + PMCDBG3(MDP,REL,1, "ucf-release cpu=%d ri=%d pm=%p", cpu, ri, pmc); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[uncore,%d] illegal CPU value %d", __LINE__, cpu)); @@ -328,7 +328,7 @@ ucf_start_pmc(int cpu, int ri) KASSERT(ri >= 0 && ri < uncore_ucf_npmc, ("[uncore,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1,"ucf-start cpu=%d ri=%d", cpu, ri); ucfc = uncore_pcpu[cpu]; pm = ucfc->pc_uncorepmcs[ri + uncore_ucf_ri].phw_pmc; @@ -343,7 +343,7 @@ ucf_start_pmc(int cpu, int ri) wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl); } while (ucfc->pc_resync != 0); - PMCDBG(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", + PMCDBG4(MDP,STA,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL), ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL)); @@ -356,7 +356,7 @@ ucf_stop_pmc(int cpu, int ri) uint32_t fc; struct uncore_cpu *ucfc; - PMCDBG(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1,"ucf-stop cpu=%d ri=%d", cpu, ri); ucfc = uncore_pcpu[cpu]; @@ -369,7 +369,7 @@ ucf_stop_pmc(int cpu, int ri) ucfc->pc_ucfctrl &= ~fc; - PMCDBG(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl); + PMCDBG1(MDP,STO,1,"ucf-stop ucfctrl=%x", ucfc->pc_ucfctrl); wrmsr(UCF_CTRL, ucfc->pc_ucfctrl); do { @@ -378,7 +378,7 @@ ucf_stop_pmc(int cpu, int ri) wrmsr(UC_GLOBAL_CTRL, ucfc->pc_globalctrl); } while (ucfc->pc_resync != 0); - PMCDBG(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", + PMCDBG4(MDP,STO,1,"ucfctrl=%x(%x) globalctrl=%jx(%jx)", ucfc->pc_ucfctrl, (uint32_t) rdmsr(UCF_CTRL), ucfc->pc_globalctrl, rdmsr(UC_GLOBAL_CTRL)); @@ -409,7 +409,7 @@ ucf_write_pmc(int cpu, int ri, pmc_value_t v) wrmsr(UCF_CTR0 + ri, v); wrmsr(UCF_CTRL, cc->pc_ucfctrl); - PMCDBG(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ", + PMCDBG4(MDP,WRI,1, "ucf-write cpu=%d ri=%d v=%jx ucfctrl=%jx ", cpu, ri, v, (uintmax_t) rdmsr(UCF_CTRL)); return (0); @@ -423,7 +423,7 @@ ucf_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth) KASSERT(md != NULL, ("[ucf,%d] md is NULL", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "ucf-initialize"); + PMCDBG0(MDP,INI,1, "ucf-initialize"); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCF]; @@ -933,7 +933,7 @@ ucp_config_pmc(int cpu, int ri, struct pmc *pm) KASSERT(ri >= 0 && ri < uncore_ucp_npmc, ("[uncore,%d] illegal row-index %d", __LINE__, ri)); - PMCDBG(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "ucp-config cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(uncore_pcpu[cpu] != NULL, ("[uncore,%d] null per-cpu %d", __LINE__, cpu)); @@ -1001,7 +1001,7 @@ ucp_read_pmc(int cpu, int ri, pmc_value_t *v) else *v = tmp; - PMCDBG(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, + PMCDBG4(MDP,REA,1, "ucp-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, ri, *v); return (0); @@ -1012,7 +1012,7 @@ ucp_release_pmc(int cpu, int ri, struct pmc *pm) { (void) pm; - PMCDBG(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri, + PMCDBG3(MDP,REL,1, "ucp-release cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), @@ -1045,11 +1045,11 @@ ucp_start_pmc(int cpu, int ri) ("[uncore,%d] starting cpu%d,ri%d with no pmc configured", __LINE__, cpu, ri)); - PMCDBG(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STA,1, "ucp-start cpu=%d ri=%d", cpu, ri); evsel = pm->pm_md.pm_ucp.pm_ucp_evsel; - PMCDBG(MDP,STA,2, + PMCDBG4(MDP,STA,2, "ucp-start/2 cpu=%d ri=%d evselmsr=0x%x evsel=0x%x", cpu, ri, SELECTSEL(uncore_cputype) + ri, evsel); @@ -1104,7 +1104,7 @@ ucp_stop_pmc(int cpu, int ri) ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri); + PMCDBG2(MDP,STO,1, "ucp-stop cpu=%d ri=%d", cpu, ri); /* stop hw. */ wrmsr(SELECTSEL(uncore_cputype) + ri, 0); @@ -1136,7 +1136,7 @@ ucp_write_pmc(int cpu, int ri, pmc_value_t v) ("[uncore,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, + PMCDBG4(MDP,WRI,1, "ucp-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, UCP_PMC0 + ri, v); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) @@ -1160,7 +1160,7 @@ ucp_initialize(struct pmc_mdep *md, int maxcpu, int npmc, int pmcwidth) KASSERT(md != NULL, ("[ucp,%d] md is NULL", __LINE__)); - PMCDBG(MDP,INI,1, "%s", "ucp-initialize"); + PMCDBG0(MDP,INI,1, "ucp-initialize"); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_UCP]; @@ -1213,7 +1213,7 @@ pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu) ucf_initialize(md, maxcpu, uncore_ucf_npmc, uncore_ucf_width); uncore_pmcmask |= ((1ULL << uncore_ucf_npmc) - 1) << SELECTOFF(uncore_cputype); - PMCDBG(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask, + PMCDBG2(MDP,INI,1,"uncore-init pmcmask=0x%jx ucfri=%d", uncore_pmcmask, uncore_ucf_ri); uncore_pcpu = malloc(sizeof(*uncore_pcpu) * maxcpu, M_PMC, @@ -1225,7 +1225,7 @@ pmc_uncore_initialize(struct pmc_mdep *md, int maxcpu) void pmc_uncore_finalize(struct pmc_mdep *md) { - PMCDBG(MDP,INI,1, "%s", "uncore-finalize"); + PMCDBG0(MDP,INI,1, "uncore-finalize"); free(uncore_pcpu, M_PMC); uncore_pcpu = NULL; diff --git a/sys/dev/hwpmc/hwpmc_xscale.c b/sys/dev/hwpmc/hwpmc_xscale.c index 9b73337..e5df8d0 100644 --- a/sys/dev/hwpmc/hwpmc_xscale.c +++ b/sys/dev/hwpmc/hwpmc_xscale.c @@ -277,7 +277,7 @@ xscale_allocate_pmc(int cpu, int ri, struct pmc *pm, return EINVAL; pm->pm_md.pm_xscale.pm_xscale_evsel = config; - PMCDBG(MDP,ALL,2,"xscale-allocate ri=%d -> config=0x%x", ri, config); + PMCDBG2(MDP,ALL,2,"xscale-allocate ri=%d -> config=0x%x", ri, config); return 0; } @@ -296,7 +296,7 @@ xscale_read_pmc(int cpu, int ri, pmc_value_t *v) pm = xscale_pcpu[cpu]->pc_xscalepmcs[ri].phw_pmc; tmp = xscale_pmcn_read(ri); - PMCDBG(MDP,REA,2,"xscale-read id=%d -> %jd", ri, tmp); + PMCDBG2(MDP,REA,2,"xscale-read id=%d -> %jd", ri, tmp); if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) *v = XSCALE_PERFCTR_VALUE_TO_RELOAD_COUNT(tmp); else @@ -320,7 +320,7 @@ xscale_write_pmc(int cpu, int ri, pmc_value_t v) if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = XSCALE_RELOAD_COUNT_TO_PERFCTR_VALUE(v); - PMCDBG(MDP,WRI,1,"xscale-write cpu=%d ri=%d v=%jx", cpu, ri, v); + PMCDBG3(MDP,WRI,1,"xscale-write cpu=%d ri=%d v=%jx", cpu, ri, v); xscale_pmcn_write(ri, v); @@ -332,7 +332,7 @@ xscale_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; - PMCDBG(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); + PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[xscale,%d] illegal CPU value %d", __LINE__, cpu)); @@ -568,7 +568,7 @@ xscale_pcpu_init(struct pmc_mdep *md, int cpu) KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[xscale,%d] wrong cpu number %d", __LINE__, cpu)); - PMCDBG(MDP,INI,1,"xscale-init cpu=%d", cpu); + PMCDBG1(MDP,INI,1,"xscale-init cpu=%d", cpu); xscale_pcpu[cpu] = pac = malloc(sizeof(struct xscale_cpu), M_PMC, M_WAITOK|M_ZERO); @@ -628,7 +628,7 @@ pmc_xscale_initialize() printf("%s: unknown XScale core generation\n", __func__); return (NULL); } - PMCDBG(MDP,INI,1,"xscale-init npmcs=%d", xscale_npmcs); + PMCDBG1(MDP,INI,1,"xscale-init npmcs=%d", xscale_npmcs); /* * Allocate space for pointers to PMC HW descriptors and for diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c index dc56760..150eecd 100644 --- a/sys/dev/iicbus/iicbus.c +++ b/sys/dev/iicbus/iicbus.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include <sys/malloc.h> #include <sys/module.h> #include <sys/mutex.h> +#include <sys/rman.h> #include <sys/sysctl.h> #include <sys/bus.h> @@ -147,6 +148,7 @@ iicbus_print_child(device_t dev, device_t child) retval += bus_print_child_header(dev, child); if (devi->addr != 0) retval += printf(" at addr %#x", devi->addr); + resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld"); retval += bus_print_child_footer(dev, child); return (retval); @@ -157,9 +159,9 @@ iicbus_probe_nomatch(device_t bus, device_t child) { struct iicbus_ivar *devi = IICBUS_IVAR(child); - device_printf(bus, "<unknown card>"); - printf(" at addr %#x\n", devi->addr); - return; + device_printf(bus, "<unknown card> at addr %#x", devi->addr); + resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld"); + printf("\n"); } static int @@ -209,6 +211,7 @@ iicbus_add_child(device_t dev, u_int order, const char *name, int unit) device_delete_child(dev, child); return (0); } + resource_list_init(&devi->rl); device_set_ivars(child, devi); return (child); } @@ -217,11 +220,77 @@ static void iicbus_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; + int irq; struct iicbus_ivar *devi; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = IICBUS_IVAR(child); resource_int_value(dname, dunit, "addr", &devi->addr); + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static int +iicbus_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct iicbus_ivar *devi; + struct resource_list_entry *rle; + + devi = IICBUS_IVAR(child); + rle = resource_list_add(&devi->rl, type, rid, start, + start + count - 1, count); + if (rle == NULL) + return (ENXIO); + + return (0); +} + +static struct resource * +iicbus_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + /* Only IRQ resources are supported. */ + if (type != SYS_RES_IRQ) + return (NULL); + + /* + * Request for the default allocation with a given rid: use resource + * list stored in the local device info. + */ + if ((start == 0UL) && (end == ~0UL)) { + rl = BUS_GET_RESOURCE_LIST(bus, child); + if (rl == NULL) + return (NULL); + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) { + if (bootverbose) + device_printf(bus, "no default resources for " + "rid = %d, type = %d\n", *rid, type); + return (NULL); + } + start = rle->start; + end = rle->end; + count = rle->count; + } + + return (bus_generic_alloc_resource(bus, child, type, rid, start, end, + count, flags)); +} + +static struct resource_list * +iicbus_get_resource_list(device_t bus __unused, device_t child) +{ + struct iicbus_ivar *devi; + + devi = IICBUS_IVAR(child); + return (&devi->rl); } int @@ -291,14 +360,24 @@ iicbus_get_frequency(device_t dev, u_char speed) } static device_method_t iicbus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, iicbus_probe), - DEVMETHOD(device_attach, iicbus_attach), - DEVMETHOD(device_detach, iicbus_detach), - - /* bus interface */ - DEVMETHOD(bus_add_child, iicbus_add_child), - DEVMETHOD(bus_print_child, iicbus_print_child), + /* device interface */ + DEVMETHOD(device_probe, iicbus_probe), + DEVMETHOD(device_attach, iicbus_attach), + DEVMETHOD(device_detach, iicbus_detach), + + /* bus interface */ + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + 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_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_alloc_resource, iicbus_alloc_resource), + DEVMETHOD(bus_get_resource_list, iicbus_get_resource_list), + DEVMETHOD(bus_set_resource, iicbus_set_resource), + DEVMETHOD(bus_add_child, iicbus_add_child), + DEVMETHOD(bus_print_child, iicbus_print_child), DEVMETHOD(bus_probe_nomatch, iicbus_probe_nomatch), DEVMETHOD(bus_read_ivar, iicbus_read_ivar), DEVMETHOD(bus_child_pnpinfo_str, iicbus_child_pnpinfo_str), @@ -322,4 +401,3 @@ devclass_t iicbus_devclass; MODULE_VERSION(iicbus, IICBUS_MODVER); DRIVER_MODULE(iicbus, iichb, iicbus_driver, iicbus_devclass, 0, 0); - diff --git a/sys/dev/iicbus/iicbus.h b/sys/dev/iicbus/iicbus.h index b5905ad..1085319 100644 --- a/sys/dev/iicbus/iicbus.h +++ b/sys/dev/iicbus/iicbus.h @@ -50,6 +50,7 @@ struct iicbus_softc struct iicbus_ivar { uint32_t addr; + struct resource_list rl; bool nostop; }; diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c index f6d1be5..e51aef1 100644 --- a/sys/dev/ofw/ofw_iicbus.c +++ b/sys/dev/ofw/ofw_iicbus.c @@ -50,6 +50,8 @@ static device_t ofw_iicbus_add_child(device_t dev, u_int order, const char *name, int unit); static const struct ofw_bus_devinfo *ofw_iicbus_get_devinfo(device_t bus, device_t dev); +static struct resource_list *ofw_iicbus_get_resource_list(device_t bus, + device_t child); static device_method_t ofw_iicbus_methods[] = { /* Device interface */ @@ -57,6 +59,7 @@ static device_method_t ofw_iicbus_methods[] = { DEVMETHOD(device_attach, ofw_iicbus_attach), /* Bus interface */ + DEVMETHOD(bus_get_resource_list, ofw_iicbus_get_resource_list), DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), DEVMETHOD(bus_add_child, ofw_iicbus_add_child), @@ -72,7 +75,7 @@ static device_method_t ofw_iicbus_methods[] = { }; struct ofw_iicbus_devinfo { - struct iicbus_ivar opd_dinfo; + struct iicbus_ivar opd_dinfo; /* Must be the first. */ struct ofw_bus_devinfo opd_obdinfo; }; @@ -153,7 +156,10 @@ ofw_iicbus_attach(device_t dev) free(dinfo, M_DEVBUF); continue; } + childdev = device_add_child(dev, NULL, -1); + resource_list_init(&dinfo->opd_dinfo.rl); + ofw_bus_intr_to_rl(childdev, child, &dinfo->opd_dinfo.rl); device_set_ivars(childdev, dinfo); } @@ -199,3 +205,12 @@ ofw_iicbus_get_devinfo(device_t bus, device_t dev) dinfo = device_get_ivars(dev); return (&dinfo->opd_obdinfo); } + +static struct resource_list * +ofw_iicbus_get_resource_list(device_t bus __unused, device_t child) +{ + struct ofw_iicbus_devinfo *devi; + + devi = device_get_ivars(child); + return (&devi->opd_dinfo.rl); +} diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index fbf49f6..83ec6c1 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1020,32 +1020,17 @@ static const struct { { NULL, NULL, NULL, 0 } }; -static const struct { - char *name, *alias1, *alias2; - int matrix_id; -} matrix_id_tab[] = { - { "1.0", "1", "mono", SND_CHN_MATRIX_1_0 }, - { "2.0", "2", "stereo", SND_CHN_MATRIX_2_0 }, - { "2.1", NULL, NULL, SND_CHN_MATRIX_2_1 }, - { "3.0", "3", NULL, SND_CHN_MATRIX_3_0 }, - { "3.1", NULL, NULL, SND_CHN_MATRIX_3_1 }, - { "4.0", "4", "quad", SND_CHN_MATRIX_4_0 }, - { "4.1", NULL, NULL, SND_CHN_MATRIX_4_1 }, - { "5.0", "5", NULL, SND_CHN_MATRIX_5_0 }, - { "5.1", "6", NULL, SND_CHN_MATRIX_5_1 }, - { "6.0", NULL, NULL, SND_CHN_MATRIX_6_0 }, - { "6.1", "7", NULL, SND_CHN_MATRIX_6_1 }, - { "7.0", NULL, NULL, SND_CHN_MATRIX_7_0 }, - { "7.1", "8", NULL, SND_CHN_MATRIX_7_1 }, - { NULL, NULL, NULL, SND_CHN_MATRIX_UNKNOWN } -}; - uint32_t snd_str2afmt(const char *req) { - uint32_t i, afmt; - int matrix_id; - char b1[8], b2[8]; + int ext; + int ch; + int i; + char b1[8]; + char b2[8]; + + memset(b1, 0, sizeof(b1)); + memset(b2, 0, sizeof(b2)); i = sscanf(req, "%5[^:]:%6s", b1, b2); @@ -1059,88 +1044,78 @@ snd_str2afmt(const char *req) } else return (0); - afmt = 0; - matrix_id = SND_CHN_MATRIX_UNKNOWN; - - for (i = 0; afmt == 0 && afmt_tab[i].name != NULL; i++) { - if (strcasecmp(afmt_tab[i].name, b1) == 0 || - (afmt_tab[i].alias1 != NULL && - strcasecmp(afmt_tab[i].alias1, b1) == 0) || - (afmt_tab[i].alias2 != NULL && - strcasecmp(afmt_tab[i].alias2, b1) == 0)) { - afmt = afmt_tab[i].afmt; - strlcpy(b1, afmt_tab[i].name, sizeof(b1)); - } - } - - if (afmt == 0) + i = sscanf(b2, "%d.%d", &ch, &ext); + + if (i == 0) { + if (strcasecmp(b2, "mono") == 0) { + ch = 1; + ext = 0; + } else if (strcasecmp(b2, "stereo") == 0) { + ch = 2; + ext = 0; + } else if (strcasecmp(b2, "quad") == 0) { + ch = 4; + ext = 0; + } else + return (0); + } else if (i == 1) { + if (ch < 1 || ch > AFMT_CHANNEL_MAX) + return (0); + ext = 0; + } else if (i == 2) { + if (ext < 0 || ext > AFMT_EXTCHANNEL_MAX) + return (0); + if (ch < 1 || (ch + ext) > AFMT_CHANNEL_MAX) + return (0); + } else return (0); - for (i = 0; matrix_id == SND_CHN_MATRIX_UNKNOWN && - matrix_id_tab[i].name != NULL; i++) { - if (strcmp(matrix_id_tab[i].name, b2) == 0 || - (matrix_id_tab[i].alias1 != NULL && - strcmp(matrix_id_tab[i].alias1, b2) == 0) || - (matrix_id_tab[i].alias2 != NULL && - strcasecmp(matrix_id_tab[i].alias2, b2) == 0)) { - matrix_id = matrix_id_tab[i].matrix_id; - strlcpy(b2, matrix_id_tab[i].name, sizeof(b2)); + for (i = 0; afmt_tab[i].name != NULL; i++) { + if (strcasecmp(afmt_tab[i].name, b1) != 0) { + if (afmt_tab[i].alias1 == NULL) + continue; + if (strcasecmp(afmt_tab[i].alias1, b1) != 0) { + if (afmt_tab[i].alias2 == NULL) + continue; + if (strcasecmp(afmt_tab[i].alias2, b1) != 0) + continue; + } } + /* found a match */ + return (SND_FORMAT(afmt_tab[i].afmt, ch + ext, ext)); } - - if (matrix_id == SND_CHN_MATRIX_UNKNOWN) - return (0); - -#ifndef _KERNEL - printf("Parse OK: '%s' -> '%s:%s' %d\n", req, b1, b2, - (int)(b2[0]) - '0' + (int)(b2[2]) - '0'); -#endif - - return (SND_FORMAT(afmt, b2[0] - '0' + b2[2] - '0', b2[2] - '0')); + /* not a valid format */ + return (0); } uint32_t snd_afmt2str(uint32_t afmt, char *buf, size_t len) { - uint32_t i, enc, ch, ext; - char tmp[AFMTSTR_LEN]; + uint32_t enc; + uint32_t ext; + uint32_t ch; + int i; if (buf == NULL || len < AFMTSTR_LEN) return (0); - - bzero(tmp, sizeof(tmp)); + memset(buf, 0, len); enc = AFMT_ENCODING(afmt); ch = AFMT_CHANNEL(afmt); ext = AFMT_EXTCHANNEL(afmt); - - for (i = 0; afmt_tab[i].name != NULL; i++) { - if (enc == afmt_tab[i].afmt) { - strlcpy(tmp, afmt_tab[i].name, sizeof(tmp)); - strlcat(tmp, ":", sizeof(tmp)); - break; - } - } - - if (strlen(tmp) == 0) + /* check there is at least one channel */ + if (ch <= ext) return (0); - - for (i = 0; matrix_id_tab[i].name != NULL; i++) { - if (ch == (matrix_id_tab[i].name[0] - '0' + - matrix_id_tab[i].name[2] - '0') && - ext == (matrix_id_tab[i].name[2] - '0')) { - strlcat(tmp, matrix_id_tab[i].name, sizeof(tmp)); - break; - } + for (i = 0; afmt_tab[i].name != NULL; i++) { + if (enc != afmt_tab[i].afmt) + continue; + /* found a match */ + snprintf(buf, len, "%s:%d.%d", + afmt_tab[i].name, ch - ext, ext); + return (SND_FORMAT(enc, ch, ext)); } - - if (strlen(tmp) == 0) - return (0); - - strlcpy(buf, tmp, len); - - return (snd_str2afmt(buf)); + return (0); } int diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index 6601b54..45f43b5 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -162,6 +162,7 @@ struct pcm_channel { } channels; struct pcmchan_matrix matrix; + struct pcmchan_matrix matrix_scratch; int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX]; diff --git a/sys/dev/sound/pcm/feeder_chain.c b/sys/dev/sound/pcm/feeder_chain.c index a647269..308d5f2 100644 --- a/sys/dev/sound/pcm/feeder_chain.c +++ b/sys/dev/sound/pcm/feeder_chain.c @@ -561,6 +561,20 @@ feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc) ((c)->mode == FEEDER_CHAIN_LEAN && \ !((c)->current.afmt & (AFMT_S16_NE | AFMT_S32_NE))))) +static void +feeder_default_matrix(struct pcmchan_matrix *m, uint32_t fmt, int id) +{ + int x; + + memset(m, 0, sizeof(*m)); + + m->id = id; + m->channels = AFMT_CHANNEL(fmt); + m->ext = AFMT_EXTCHANNEL(fmt); + for (x = 0; x != SND_CHN_T_MAX; x++) + m->offset[x] = -1; +} + int feeder_chain(struct pcm_channel *c) { @@ -641,10 +655,10 @@ feeder_chain(struct pcm_channel *c) */ hwmatrix = CHANNEL_GETMATRIX(c->methods, c->devinfo, hwfmt); if (hwmatrix == NULL) { - device_printf(c->dev, - "%s(): failed to acquire hw matrix [0x%08x]\n", - __func__, hwfmt); - return (ENODEV); + /* setup a default matrix */ + hwmatrix = &c->matrix_scratch; + feeder_default_matrix(hwmatrix, hwfmt, + SND_CHN_MATRIX_UNKNOWN); } /* ..... and rebuild hwfmt. */ hwfmt = SND_FORMAT(hwfmt, hwmatrix->channels, hwmatrix->ext); @@ -656,13 +670,14 @@ feeder_chain(struct pcm_channel *c) softmatrix->ext != AFMT_EXTCHANNEL(softfmt)) { softmatrix = feeder_matrix_format_map(softfmt); if (softmatrix == NULL) { - device_printf(c->dev, - "%s(): failed to acquire soft matrix [0x%08x]\n", - __func__, softfmt); - return (ENODEV); + /* setup a default matrix */ + softmatrix = &c->matrix; + feeder_default_matrix(softmatrix, softfmt, + SND_CHN_MATRIX_PCMCHANNEL); + } else { + c->matrix = *softmatrix; + c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; } - c->matrix = *softmatrix; - c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL; } softfmt = SND_FORMAT(softfmt, softmatrix->channels, softmatrix->ext); if (softfmt != c->format) diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h index 3565ca5..32e0343 100644 --- a/sys/dev/sound/pcm/sound.h +++ b/sys/dev/sound/pcm/sound.h @@ -213,10 +213,12 @@ struct snd_mixer; * ~(0xb00ff7ff) */ #define AFMT_ENCODING_MASK 0xf00fffff -#define AFMT_CHANNEL_MASK 0x01f00000 +#define AFMT_CHANNEL_MASK 0x07f00000 #define AFMT_CHANNEL_SHIFT 20 -#define AFMT_EXTCHANNEL_MASK 0x0e000000 -#define AFMT_EXTCHANNEL_SHIFT 25 +#define AFMT_CHANNEL_MAX 0x7f +#define AFMT_EXTCHANNEL_MASK 0x08000000 +#define AFMT_EXTCHANNEL_SHIFT 27 +#define AFMT_EXTCHANNEL_MAX 1 #define AFMT_ENCODING(v) ((v) & AFMT_ENCODING_MASK) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 8822bf0..063d8ce 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -115,6 +115,8 @@ SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RWTUN, #define UAUDIO_NFRAMES 64 /* must be factor of 8 due HS-USB */ #define UAUDIO_NCHANBUFS 2 /* number of outstanding request */ #define UAUDIO_RECURSE_LIMIT 255 /* rounds */ +#define UAUDIO_CHANNELS_MAX MIN(64, AFMT_CHANNEL_MAX) +#define UAUDIO_MATRIX_MAX 8 /* channels */ #define MAKE_WORD(h,l) (((h) << 8) | (l)) #define BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1) @@ -346,6 +348,7 @@ struct uaudio_softc { uint8_t sc_uq_au_no_xu:1; uint8_t sc_uq_bad_adc:1; uint8_t sc_uq_au_vendor_class:1; + uint8_t sc_pcm_bitperfect:1; }; struct uaudio_terminal_node { @@ -1062,6 +1065,10 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_clas */ uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL); } + if (sc->sc_pcm_bitperfect) { + DPRINTF("device needs bitperfect by default\n"); + uaudio_pcm_setflags(dev, SD_F_BITPERFECT); + } if (mixer_init(dev, mixer_class, sc)) goto detach; sc->sc_mixer_init = 1; @@ -1568,6 +1575,19 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, asf1d.v1 = NULL; ed1 = NULL; sed.v1 = NULL; + + /* + * There can only be one USB audio instance + * per USB device. Grab all USB audio + * interfaces on this USB device so that we + * don't attach USB audio twice: + */ + if (alt_index == 0 && curidx != sc->sc_mixer_iface_index && + (id->bInterfaceClass == UICLASS_AUDIO || audio_if != 0 || + midi_if != 0)) { + usbd_set_parent_iface(sc->sc_udev, curidx, + sc->sc_mixer_iface_index); + } } if (audio_if == 0) { @@ -1803,9 +1823,6 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, chan_alt->iface_index = curidx; chan_alt->iface_alt_index = alt_index; - usbd_set_parent_iface(sc->sc_udev, curidx, - sc->sc_mixer_iface_index); - if (ep_dir == UE_DIR_IN) chan_alt->usb_cfg = uaudio_cfg_record; else @@ -1826,19 +1843,21 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, format = chan_alt->p_fmt->freebsd_fmt; + /* get default SND_FORMAT() */ + format = SND_FORMAT(format, chan_alt->channels, 0); + switch (chan_alt->channels) { - case 2: - /* stereo */ - format = SND_FORMAT(format, 2, 0); - break; + uint32_t temp_fmt; case 1: - /* mono */ - format = SND_FORMAT(format, 1, 0); + case 2: + /* mono and stereo */ break; default: /* surround and more */ - format = feeder_matrix_default_format( - SND_FORMAT(format, chan_alt->channels, 0)); + temp_fmt = feeder_matrix_default_format(format); + /* if multichannel, then format can be zero */ + if (temp_fmt != 0) + format = temp_fmt; break; } @@ -1865,6 +1884,10 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev, chan->pcm_cap.fmtlist = chan->pcm_format; chan->pcm_cap.fmtlist[0] = format; + /* check if device needs bitperfect */ + if (chan_alt->channels > UAUDIO_MATRIX_MAX) + sc->sc_pcm_bitperfect = 1; + if (rate < chan->pcm_cap.minspeed || chan->pcm_cap.minspeed == 0) chan->pcm_cap.minspeed = rate; if (rate > chan->pcm_cap.maxspeed || chan->pcm_cap.maxspeed == 0) @@ -1939,15 +1962,15 @@ uaudio_chan_fill_info(struct uaudio_softc *sc, struct usb_device *udev) channels = 4; break; default: - channels = 16; + channels = UAUDIO_CHANNELS_MAX; break; } - } else if (channels > 16) { - channels = 16; - } - if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) { + } else if (channels > UAUDIO_CHANNELS_MAX) + channels = UAUDIO_CHANNELS_MAX; + + if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) sc->sc_sndstat_valid = 1; - } + /* try to search for a valid config */ for (x = channels; x; x--) { diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c index e0c5db7..3cfaef0 100644 --- a/sys/dev/usb/quirk/usb_quirk.c +++ b/sys/dev/usb/quirk/usb_quirk.c @@ -523,6 +523,9 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(FEIYA, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), USB_QUIRK(REALTEK, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), USB_QUIRK(INITIO, DUMMY, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE, UQ_MATCH_VENDOR_ONLY), + + /* DYMO LabelManager Pnp */ + USB_QUIRK(DYMO, LABELMANAGERPNP, 0x0000, 0xffff, UQ_MSC_DYMO_EJECT), }; #undef USB_QUIRK_VP #undef USB_QUIRK @@ -592,6 +595,7 @@ static const char *usb_quirk_str[USB_QUIRK_MAX] = { [UQ_BAD_MIDI] = "UQ_BAD_MIDI", [UQ_AU_VENDOR_CLASS] = "UQ_AU_VENDOR_CLASS", [UQ_SINGLE_CMD_MIDI] = "UQ_SINGLE_CMD_MIDI", + [UQ_MSC_DYMO_EJECT] = "UQ_MSC_DYMO_EJECT", }; /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/quirk/usb_quirk.h b/sys/dev/usb/quirk/usb_quirk.h index c2e9501..7010916 100644 --- a/sys/dev/usb/quirk/usb_quirk.h +++ b/sys/dev/usb/quirk/usb_quirk.h @@ -108,6 +108,7 @@ enum { UQ_BAD_MIDI, /* device claims MIDI class, but isn't */ UQ_AU_VENDOR_CLASS, /* audio device uses vendor and not audio class */ UQ_SINGLE_CMD_MIDI, /* at most one command per USB packet */ + UQ_MSC_DYMO_EJECT, /* ejects Dymo MSC device */ USB_QUIRK_MAX }; diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index b3b46b3..5ffc07f 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -1343,6 +1343,12 @@ usb_probe_and_attach(struct usb_device *udev, uint8_t iface_index) */ if (iface_index == USB_IFACE_INDEX_ANY) { + if (usb_test_quirk(&uaa, UQ_MSC_DYMO_EJECT) != 0 && + usb_dymo_eject(udev, 0) == 0) { + /* success, mark the udev as disappearing */ + uaa.dev_state = UAA_DEV_EJECTING; + } + EVENTHANDLER_INVOKE(usb_dev_configured, udev, &uaa); if (uaa.dev_state != UAA_DEV_READY) { diff --git a/sys/dev/usb/usb_msctest.c b/sys/dev/usb/usb_msctest.c index c77afd0..b99fd29 100644 --- a/sys/dev/usb/usb_msctest.c +++ b/sys/dev/usb/usb_msctest.c @@ -181,6 +181,7 @@ static usb_callback_t bbb_data_rd_cs_callback; static usb_callback_t bbb_data_write_callback; static usb_callback_t bbb_data_wr_cs_callback; static usb_callback_t bbb_status_callback; +static usb_callback_t bbb_raw_write_callback; static void bbb_done(struct bbb_transfer *, int); static void bbb_transfer_start(struct bbb_transfer *, uint8_t); @@ -188,7 +189,7 @@ static void bbb_data_clear_stall_callback(struct usb_xfer *, uint8_t, uint8_t); static int bbb_command_start(struct bbb_transfer *, uint8_t, uint8_t, void *, size_t, void *, size_t, usb_timeout_t); -static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t); +static struct bbb_transfer *bbb_attach(struct usb_device *, uint8_t, uint8_t); static void bbb_detach(struct bbb_transfer *); static const struct usb_config bbb_config[ST_MAX] = { @@ -251,6 +252,19 @@ static const struct usb_config bbb_config[ST_MAX] = { }, }; +static const struct usb_config bbb_raw_config[1] = { + + [0] = { + .type = UE_BULK_INTR, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = SCSI_MAX_LEN, + .flags = {.ext_buffer = 1,.proxy_buffer = 1,}, + .callback = &bbb_raw_write_callback, + .timeout = 1 * USB_MS_HZ, /* 1 second */ + }, +}; + static void bbb_done(struct bbb_transfer *sc, int error) { @@ -471,6 +485,47 @@ bbb_status_callback(struct usb_xfer *xfer, usb_error_t error) } } +static void +bbb_raw_write_callback(struct usb_xfer *xfer, usb_error_t error) +{ + struct bbb_transfer *sc = usbd_xfer_softc(xfer); + usb_frlength_t max_bulk = usbd_xfer_max_len(xfer); + int actlen, sumlen; + + usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + sc->data_rem -= actlen; + sc->data_ptr += actlen; + sc->actlen += actlen; + + if (actlen < sumlen) { + /* short transfer */ + sc->data_rem = 0; + } + case USB_ST_SETUP: + DPRINTF("max_bulk=%d, data_rem=%d\n", + max_bulk, sc->data_rem); + + if (sc->data_rem == 0) { + bbb_done(sc, 0); + break; + } + if (max_bulk > sc->data_rem) { + max_bulk = sc->data_rem; + } + usbd_xfer_set_timeout(xfer, sc->data_timeout); + usbd_xfer_set_frame_data(xfer, 0, sc->data_ptr, max_bulk); + usbd_transfer_submit(xfer); + break; + + default: /* Error */ + bbb_done(sc, error); + break; + } +} + /*------------------------------------------------------------------------* * bbb_command_start - execute a SCSI command synchronously * @@ -506,13 +561,45 @@ bbb_command_start(struct bbb_transfer *sc, uint8_t dir, uint8_t lun, return (sc->error); } +/*------------------------------------------------------------------------* + * bbb_raw_write - write a raw BULK message synchronously + * + * Return values + * 0: Success + * Else: Failure + *------------------------------------------------------------------------*/ +static int +bbb_raw_write(struct bbb_transfer *sc, const void *data_ptr, size_t data_len, + usb_timeout_t data_timeout) +{ + sc->data_ptr = __DECONST(void *, data_ptr); + sc->data_len = data_len; + sc->data_rem = data_len; + sc->data_timeout = (data_timeout + USB_MS_HZ); + sc->actlen = 0; + sc->error = 0; + + DPRINTFN(1, "BULK DATA = %*D\n", (int)data_len, + (const char *)data_ptr, ":"); + + mtx_lock(&sc->mtx); + usbd_transfer_start(sc->xfer[0]); + while (usbd_transfer_pending(sc->xfer[0])) + cv_wait(&sc->cv, &sc->mtx); + mtx_unlock(&sc->mtx); + return (sc->error); +} + static struct bbb_transfer * -bbb_attach(struct usb_device *udev, uint8_t iface_index) +bbb_attach(struct usb_device *udev, uint8_t iface_index, + uint8_t bInterfaceClass) { struct usb_interface *iface; struct usb_interface_descriptor *id; + const struct usb_config *pconfig; struct bbb_transfer *sc; usb_error_t err; + int nconfig; #if USB_HAVE_MSCTEST_DETACH uint8_t do_unlock; @@ -535,22 +622,39 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index) return (NULL); id = iface->idesc; - if (id == NULL || id->bInterfaceClass != UICLASS_MASS) + if (id == NULL || id->bInterfaceClass != bInterfaceClass) return (NULL); - switch (id->bInterfaceSubClass) { - case UISUBCLASS_SCSI: - case UISUBCLASS_UFI: - case UISUBCLASS_SFF8020I: - case UISUBCLASS_SFF8070I: + switch (id->bInterfaceClass) { + case UICLASS_MASS: + switch (id->bInterfaceSubClass) { + case UISUBCLASS_SCSI: + case UISUBCLASS_UFI: + case UISUBCLASS_SFF8020I: + case UISUBCLASS_SFF8070I: + break; + default: + return (NULL); + } + switch (id->bInterfaceProtocol) { + case UIPROTO_MASS_BBB_OLD: + case UIPROTO_MASS_BBB: + break; + default: + return (NULL); + } + pconfig = bbb_config; + nconfig = ST_MAX; break; - default: - return (NULL); - } - - switch (id->bInterfaceProtocol) { - case UIPROTO_MASS_BBB_OLD: - case UIPROTO_MASS_BBB: + case UICLASS_HID: + switch (id->bInterfaceSubClass) { + case 0: + break; + default: + return (NULL); + } + pconfig = bbb_raw_config; + nconfig = 1; break; default: return (NULL); @@ -560,22 +664,27 @@ bbb_attach(struct usb_device *udev, uint8_t iface_index) mtx_init(&sc->mtx, "USB autoinstall", NULL, MTX_DEF); cv_init(&sc->cv, "WBBB"); - err = usbd_transfer_setup(udev, &iface_index, sc->xfer, bbb_config, - ST_MAX, sc, &sc->mtx); + err = usbd_transfer_setup(udev, &iface_index, sc->xfer, pconfig, + nconfig, sc, &sc->mtx); if (err) { bbb_detach(sc); return (NULL); } - /* store pointer to DMA buffers */ - sc->buffer = usbd_xfer_get_frame_buffer( - sc->xfer[ST_DATA_RD], 0); - sc->buffer_size = - usbd_xfer_max_len(sc->xfer[ST_DATA_RD]); - sc->cbw = usbd_xfer_get_frame_buffer( - sc->xfer[ST_COMMAND], 0); - sc->csw = usbd_xfer_get_frame_buffer( - sc->xfer[ST_STATUS], 0); - + switch (id->bInterfaceClass) { + case UICLASS_MASS: + /* store pointer to DMA buffers */ + sc->buffer = usbd_xfer_get_frame_buffer( + sc->xfer[ST_DATA_RD], 0); + sc->buffer_size = + usbd_xfer_max_len(sc->xfer[ST_DATA_RD]); + sc->cbw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_COMMAND], 0); + sc->csw = usbd_xfer_get_frame_buffer( + sc->xfer[ST_STATUS], 0); + break; + default: + break; + } return (sc); } @@ -604,7 +713,7 @@ usb_iface_is_cdrom(struct usb_device *udev, uint8_t iface_index) uint8_t sid_type; int err; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (0); @@ -660,7 +769,7 @@ usb_msc_auto_quirk(struct usb_device *udev, uint8_t iface_index) uint8_t sid_type; int err; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (0); @@ -829,7 +938,7 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) struct bbb_transfer *sc; usb_error_t err; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (USB_ERR_INVAL); @@ -890,6 +999,21 @@ usb_msc_eject(struct usb_device *udev, uint8_t iface_index, int method) } usb_error_t +usb_dymo_eject(struct usb_device *udev, uint8_t iface_index) +{ + static const uint8_t data[3] = { 0x1b, 0x5a, 0x01 }; + struct bbb_transfer *sc; + usb_error_t err; + + sc = bbb_attach(udev, iface_index, UICLASS_HID); + if (sc == NULL) + return (USB_ERR_INVAL); + err = bbb_raw_write(sc, data, sizeof(data), USB_MS_HZ); + bbb_detach(sc); + return (err); +} + +usb_error_t usb_msc_read_10(struct usb_device *udev, uint8_t iface_index, uint32_t lba, uint32_t blocks, void *buffer) { @@ -908,7 +1032,7 @@ usb_msc_read_10(struct usb_device *udev, uint8_t iface_index, cmd[8] = blocks; cmd[9] = 0; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (USB_ERR_INVAL); @@ -939,7 +1063,7 @@ usb_msc_write_10(struct usb_device *udev, uint8_t iface_index, cmd[8] = blocks; cmd[9] = 0; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (USB_ERR_INVAL); @@ -958,7 +1082,7 @@ usb_msc_read_capacity(struct usb_device *udev, uint8_t iface_index, struct bbb_transfer *sc; usb_error_t err; - sc = bbb_attach(udev, iface_index); + sc = bbb_attach(udev, iface_index, UICLASS_MASS); if (sc == NULL) return (USB_ERR_INVAL); diff --git a/sys/dev/usb/usb_msctest.h b/sys/dev/usb/usb_msctest.h index dcc3cf7..d3f26c2 100644 --- a/sys/dev/usb/usb_msctest.h +++ b/sys/dev/usb/usb_msctest.h @@ -52,5 +52,7 @@ usb_error_t usb_msc_write_10(struct usb_device *udev, usb_error_t usb_msc_read_capacity(struct usb_device *udev, uint8_t iface_index, uint32_t *lba_last, uint32_t *block_size); +usb_error_t usb_dymo_eject(struct usb_device *udev, + uint8_t iface_index); #endif /* _USB_MSCTEST_H_ */ diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index abe2e6f..f8ba5b5 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -452,6 +452,7 @@ vendor GLOBESPAN 0x0915 Globespan vendor CONCORDCAMERA 0x0919 Concord Camera vendor GARMIN 0x091e Garmin International vendor GOHUBS 0x0921 GoHubs +vendor DYMO 0x0922 DYMO vendor XEROX 0x0924 Xerox vendor BIOMETRIC 0x0929 American Biometric Company vendor TOSHIBA 0x0930 Toshiba @@ -1694,6 +1695,9 @@ product DRESDENELEKTRONIK WIRELESSHANDHELDTERMINAL 0x0004 Wireless Handheld Ter product DRESDENELEKTRONIK DE_RFNODE 0x001c deRFnode product DRESDENELEKTRONIK LEVELSHIFTERSTICKLOWCOST 0x0022 Levelshifter Stick Low Cost +/* DYMO */ +product DYMO LABELMANAGERPNP 0x1001 DYMO LabelManager PnP + /* Dynastream Innovations */ product DYNASTREAM ANTDEVBOARD 0x1003 ANT dev board product DYNASTREAM ANT2USB 0x1004 ANT2USB diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c index 72004d9..331f782 100644 --- a/sys/dev/usb/wlan/if_urtwn.c +++ b/sys/dev/usb/wlan/if_urtwn.c @@ -1195,7 +1195,7 @@ urtwn_efuse_read(struct urtwn_softc *sc) uint8_t *rom = (uint8_t *)&sc->rom; uint16_t addr = 0; uint32_t reg; - uint8_t off, msk, vol; + uint8_t off, msk; int i; urtwn_efuse_switch_power(sc); @@ -1228,18 +1228,15 @@ urtwn_efuse_read(struct urtwn_softc *sc) printf("\n"); } #endif - /* Disable LDO 2.5V. */ - vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3); - urtwn_write_1(sc, R92C_EFUSE_TEST + 3, vol & ~(0x80)); - + urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF); } + static void urtwn_efuse_switch_power(struct urtwn_softc *sc) { uint32_t reg; - if (sc->chip & URTWN_CHIP_88E) - urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON); + urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON); reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL); if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) { @@ -1257,16 +1254,6 @@ urtwn_efuse_switch_power(struct urtwn_softc *sc) urtwn_write_2(sc, R92C_SYS_CLKR, reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M); } - - if (!(sc->chip & URTWN_CHIP_88E)) { - uint8_t vol; - - /* Enable LDO 2.5V. */ - vol = urtwn_read_1(sc, R92C_EFUSE_TEST + 3); - vol &= 0x0f; - vol |= 0x30; - urtwn_write_1(sc, R92C_EFUSE_TEST + 3, (vol | 0x80)); - } } static int @@ -1905,10 +1892,7 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni, txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8)); txd->txdw5 |= htole32(0x0001ff00); /* Send data at OFDM54. */ - if (sc->chip & URTWN_CHIP_88E) - txd->txdw5 |= htole32(0x13 & 0x3f); - else - txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); + txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11)); } else { txd->txdw1 |= htole32( SM(R92C_TXDW1_MACID, 0) | @@ -3364,6 +3348,7 @@ urtwn_init_locked(void *arg) urtwn_rxfilter_init(sc); + /* Set response rate. */ reg = urtwn_read_4(sc, R92C_RRSR); reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M); urtwn_write_4(sc, R92C_RRSR, reg); diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h index 4eef029..2bbec7a 100644 --- a/sys/dev/usb/wlan/if_urtwnreg.h +++ b/sys/dev/usb/wlan/if_urtwnreg.h @@ -177,13 +177,13 @@ #define R92C_RD_NAV_NXT 0x544 #define R92C_NAV_PROT_LEN 0x546 #define R92C_BCN_CTRL 0x550 -#define R92C_USTIME_TSF 0x551 #define R92C_MBID_NUM 0x552 #define R92C_DUAL_TSF_RST 0x553 #define R92C_BCN_INTERVAL 0x554 #define R92C_DRVERLYINT 0x558 #define R92C_BCNDMATIM 0x559 #define R92C_ATIMWND 0x55a +#define R92C_USTIME_TSF 0x55c #define R92C_BCN_MAX_ERR 0x55d #define R92C_RXTSF_OFFSET_CCK 0x55e #define R92C_RXTSF_OFFSET_OFDM 0x55f diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h index 85c0345..bdfcf46 100644 --- a/sys/dev/vt/vt.h +++ b/sys/dev/vt/vt.h @@ -83,9 +83,8 @@ #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) #define VT_SYSCTL_INT(_name, _default, _descr) \ -static int vt_##_name = _default; \ -SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, _default,\ - _descr); +static int vt_##_name = (_default); \ +SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, 0, _descr) struct vt_driver; diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index a637055..e6603a9 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -451,12 +451,35 @@ vt_proc_window_switch(struct vt_window *vw) struct vt_device *vd; int ret; + /* Prevent switching to NULL */ + if (vw == NULL) { + DPRINTF(30, "%s: Cannot switch: vw is NULL.", __func__); + return (EINVAL); + } vd = vw->vw_device; curvw = vd->vd_curwindow; + /* Check if virtual terminal is locked */ if (curvw->vw_flags & VWF_VTYLOCK) return (EBUSY); + /* Check if switch already in progress */ + if (curvw->vw_flags & VWF_SWWAIT_REL) { + /* Check if switching to same window */ + if (curvw->vw_switch_to == vw) { + DPRINTF(30, "%s: Switch in progress to same vw.", __func__); + return (0); /* success */ + } + DPRINTF(30, "%s: Switch in progress to different vw.", __func__); + return (EBUSY); + } + + /* Avoid switching to already selected window */ + if (vw == curvw) { + DPRINTF(30, "%s: Cannot switch: vw == curvw.", __func__); + return (0); /* success */ + } + /* Ask current process permission to switch away. */ if (curvw->vw_smode.mode == VT_PROCESS) { DPRINTF(30, "%s: VT_PROCESS ", __func__); @@ -664,8 +687,7 @@ vt_scrollmode_kbdevent(struct vt_window *vw, int c, int console) if (console == 0) { if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) { vw = vd->vd_windows[c - F_SCR]; - if (vw != NULL) - vt_proc_window_switch(vw); + vt_proc_window_switch(vw); return; } VT_LOCK(vd); @@ -750,8 +772,7 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c) if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) { vw = vd->vd_windows[c - F_SCR]; - if (vw != NULL) - vt_proc_window_switch(vw); + vt_proc_window_switch(vw); return (0); } @@ -760,15 +781,13 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c) /* Switch to next VT. */ c = (vw->vw_number + 1) % VT_MAXWINDOWS; vw = vd->vd_windows[c]; - if (vw != NULL) - vt_proc_window_switch(vw); + vt_proc_window_switch(vw); return (0); case PREV: /* Switch to previous VT. */ c = (vw->vw_number - 1) % VT_MAXWINDOWS; vw = vd->vd_windows[c]; - if (vw != NULL) - vt_proc_window_switch(vw); + vt_proc_window_switch(vw); return (0); case SLK: { vt_save_kbd_state(vw, kbd); @@ -2774,8 +2793,7 @@ vt_resume(struct vt_device *vd) if (vt_suspendswitch == 0) return; - /* Switch back to saved window */ - if (vd->vd_savedwindow != NULL) - vt_proc_window_switch(vd->vd_savedwindow); + /* Switch back to saved window, if any */ + vt_proc_window_switch(vd->vd_savedwindow); vd->vd_savedwindow = NULL; } diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index b647fec..d352242 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -2817,9 +2817,8 @@ xbb_free_communication_mem(struct xbb_softc *xbb) { if (xbb->kva != 0) { if (xbb->pseudo_phys_res != NULL) { - bus_release_resource(xbb->dev, SYS_RES_MEMORY, - xbb->pseudo_phys_res_id, - xbb->pseudo_phys_res); + xenmem_free(xbb->dev, xbb->pseudo_phys_res_id, + xbb->pseudo_phys_res); xbb->pseudo_phys_res = NULL; } } @@ -3056,10 +3055,8 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb) * via grant table operations. */ xbb->pseudo_phys_res_id = 0; - xbb->pseudo_phys_res = bus_alloc_resource(xbb->dev, SYS_RES_MEMORY, - &xbb->pseudo_phys_res_id, - 0, ~0, xbb->kva_size, - RF_ACTIVE); + xbb->pseudo_phys_res = xenmem_alloc(xbb->dev, &xbb->pseudo_phys_res_id, + xbb->kva_size); if (xbb->pseudo_phys_res == NULL) { xbb->kva = 0; return (ENOMEM); diff --git a/sys/dev/xen/grant_table/grant_table.c b/sys/dev/xen/grant_table/grant_table.c index ad65fe0..728d64d 100644 --- a/sys/dev/xen/grant_table/grant_table.c +++ b/sys/dev/xen/grant_table/grant_table.c @@ -559,9 +559,8 @@ gnttab_resume(device_t dev) KASSERT(dev != NULL, ("No resume frames and no device provided")); - gnttab_pseudo_phys_res = bus_alloc_resource(dev, - SYS_RES_MEMORY, &gnttab_pseudo_phys_res_id, 0, ~0, - PAGE_SIZE * max_nr_gframes, RF_ACTIVE); + gnttab_pseudo_phys_res = xenmem_alloc(dev, + &gnttab_pseudo_phys_res_id, PAGE_SIZE * max_nr_gframes); if (gnttab_pseudo_phys_res == NULL) panic("Unable to reserve physical memory for gnttab"); resume_frames = rman_get_start(gnttab_pseudo_phys_res); diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index b5c1c13..2233084 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -625,8 +625,7 @@ xnb_free_communication_mem(struct xnb_softc *xnb) { if (xnb->kva != 0) { if (xnb->pseudo_phys_res != NULL) { - bus_release_resource(xnb->dev, SYS_RES_MEMORY, - xnb->pseudo_phys_res_id, + xenmem_free(xnb->dev, xnb->pseudo_phys_res_id, xnb->pseudo_phys_res); xnb->pseudo_phys_res = NULL; } @@ -819,10 +818,8 @@ xnb_alloc_communication_mem(struct xnb_softc *xnb) * into this space. */ xnb->pseudo_phys_res_id = 0; - xnb->pseudo_phys_res = bus_alloc_resource(xnb->dev, SYS_RES_MEMORY, - &xnb->pseudo_phys_res_id, - 0, ~0, xnb->kva_size, - RF_ACTIVE); + xnb->pseudo_phys_res = xenmem_alloc(xnb->dev, &xnb->pseudo_phys_res_id, + xnb->kva_size); if (xnb->pseudo_phys_res == NULL) { xnb->kva = 0; return (ENOMEM); diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c index 761fb03..0bf9585 100644 --- a/sys/dev/xen/privcmd/privcmd.c +++ b/sys/dev/xen/privcmd/privcmd.c @@ -141,11 +141,8 @@ retry: free(map->errs, M_PRIVCMD); } - vm_phys_fictitious_unreg_range(map->phys_base_addr, - map->phys_base_addr + map->size * PAGE_SIZE); - - error = bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); + error = xenmem_free(privcmd_dev, map->pseudo_phys_res_id, + map->pseudo_phys_res); KASSERT(error == 0, ("Unable to release memory resource: %d", error)); free(map, M_PRIVCMD); @@ -196,36 +193,25 @@ privcmd_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size, vm_object_t *object, int nprot) { struct privcmd_map *map; - int error; map = malloc(sizeof(*map), M_PRIVCMD, M_WAITOK | M_ZERO); map->size = OFF_TO_IDX(size); map->pseudo_phys_res_id = 0; - map->pseudo_phys_res = bus_alloc_resource(privcmd_dev, SYS_RES_MEMORY, - &map->pseudo_phys_res_id, 0, ~0, size, RF_ACTIVE); + map->pseudo_phys_res = xenmem_alloc(privcmd_dev, + &map->pseudo_phys_res_id, size); if (map->pseudo_phys_res == NULL) { free(map, M_PRIVCMD); return (ENOMEM); } map->phys_base_addr = rman_get_start(map->pseudo_phys_res); - - error = vm_phys_fictitious_reg_range(map->phys_base_addr, - map->phys_base_addr + size, VM_MEMATTR_DEFAULT); - if (error) { - bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); - free(map, M_PRIVCMD); - return (error); - } - map->mem = cdev_pager_allocate(map, OBJT_MGTDEVICE, &privcmd_pg_ops, size, nprot, *offset, NULL); if (map->mem == NULL) { - bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); + xenmem_free(privcmd_dev, map->pseudo_phys_res_id, + map->pseudo_phys_res); free(map, M_PRIVCMD); return (ENOMEM); } diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c index 049354b..4c79691 100644 --- a/sys/i386/acpica/acpi_machdep.c +++ b/sys/i386/acpica/acpi_machdep.c @@ -106,13 +106,6 @@ acpi_machdep_quirks(int *quirks) return (0); } -void -acpi_cpu_c1() -{ - - __asm __volatile("sti; hlt"); -} - /* * Support for mapping ACPI tables during early boot. This abuses the * crashdump map because the kernel cannot allocate KVA in diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h index bffdd57..b5bd35e 100644 --- a/sys/i386/include/md_var.h +++ b/sys/i386/include/md_var.h @@ -97,6 +97,7 @@ struct dumperinfo; void *alloc_fpusave(int flags); void bcopyb(const void *from, void *to, size_t len); void busdma_swi(void); +bool cpu_mwait_usable(void); void cpu_probe_amdc1e(void); void cpu_setregs(void); void cpu_switch_load_gs(void) __asm(__STRING(cpu_switch_load_gs)); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index c3dd792..2c7fe2e 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -943,7 +943,8 @@ fail: #endif racct_proc_exit(newproc); fail1: - crfree(proc_set_cred(newproc, NULL)); + crfree(newproc->p_ucred); + newproc->p_ucred = NULL; fail2: if (vm2 != NULL) vmspace_free(vm2); diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index aef1e4e..ff5b106 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -665,13 +665,15 @@ reallocf(void *addr, unsigned long size, struct malloc_type *mtp, int flags) } /* - * Wake the page daemon when we exhaust KVA. It will call the lowmem handler - * and uma_reclaim() callbacks in a context that is safe. + * Wake the uma reclamation pagedaemon thread when we exhaust KVA. It + * will call the lowmem handler and uma_reclaim() callbacks in a + * context that is safe. */ static void kmem_reclaim(vmem_t *vm, int flags) { + uma_reclaim_wakeup(); pagedaemon_wakeup(); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 1d5ba1a..154c250 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -3371,8 +3371,6 @@ coredump(struct thread *td) len = MAXPATHLEN * 2 + sizeof(comm_name) - 1 + sizeof(' ') + sizeof(core_name) - 1; data = malloc(len, M_TEMP, M_WAITOK); - if (data == NULL) - goto out; if (vn_fullpath_global(td, p->p_textvp, &fullpath, &freepath) != 0) goto out; if (!coredump_sanitise_path(fullpath)) diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 0a93dbd..c7c0ee4 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -759,6 +759,29 @@ stopme: PROC_LOCK(p); PROC_SLOCK(p); } + } else if (mode == SINGLE_BOUNDARY) { + /* + * Wait until all suspended threads are removed from + * the processors. The thread_suspend_check() + * increments p_boundary_count while it is still + * running, which makes it possible for the execve() + * to destroy vmspace while our other threads are + * still using the address space. + * + * We lock the thread, which is only allowed to + * succeed after context switch code finished using + * the address space. + */ + FOREACH_THREAD_IN_PROC(p, td2) { + if (td2 == td) + continue; + thread_lock(td2); + KASSERT((td2->td_flags & TDF_BOUNDARY) != 0, + ("td %p not on boundary", td2)); + KASSERT(TD_IS_SUSPENDED(td2), + ("td %p is not suspended", td2)); + thread_unlock(td2); + } } PROC_SUNLOCK(p); return (0); diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index a1a7915..b77d476 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -813,6 +813,7 @@ m_dup(struct mbuf *m, int how) } if ((n->m_flags & M_EXT) == 0) nsize = MHLEN; + n->m_flags &= ~M_RDONLY; } n->m_len = 0; diff --git a/sys/net/if_me.c b/sys/net/if_me.c index a00bdd2..56fe4d5 100644 --- a/sys/net/if_me.c +++ b/sys/net/if_me.c @@ -477,7 +477,7 @@ me_check_nesting(struct ifnet *ifp, struct mbuf *m) count = 1; mtag = NULL; - while ((mtag = m_tag_locate(m, MTAG_ME, 0, NULL)) != NULL) { + while ((mtag = m_tag_locate(m, MTAG_ME, 0, mtag)) != NULL) { if (*(struct ifnet **)(mtag + 1) == ifp) { log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname); return (EIO); diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 8ce2aab..7c2e194 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -576,13 +576,12 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked /* decrement the ref count */ if (skey) { - sctp_free_sharedkey(skey); SCTPDBG(SCTP_DEBUG_AUTH2, "%s: stcb %p key %u refcount release to %d\n", __FUNCTION__, (void *)stcb, key_id, skey->refcount); /* see if a notification should be generated */ - if ((skey->refcount <= 1) && (skey->deactivated)) { + if ((skey->refcount <= 2) && (skey->deactivated)) { /* notify ULP that key is no longer used */ sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb, key_id, 0, so_locked); @@ -590,6 +589,7 @@ sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked "%s: stcb %p key %u no longer used, %d\n", __FUNCTION__, (void *)stcb, key_id, skey->refcount); } + sctp_free_sharedkey(skey); } } diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index e6e16ed..d7f08e9 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" -#include "opt_inet6.h" +#include "opt_sctp.h" #include "opt_ipsec.h" #include <sys/param.h> @@ -58,10 +58,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_pcb.h> #include <netinet/ip_var.h> #include <netinet/ip_options.h> +#ifdef SCTP +#include <netinet/sctp_crc32.h> +#endif #include <machine/in_cksum.h> -#ifdef IPSEC #include <netipsec/ipsec.h> #include <netipsec/ipsec6.h> #include <netipsec/xform.h> @@ -71,16 +73,12 @@ __FBSDID("$FreeBSD$"); #else #define KEYDEBUG(lev,arg) #endif -#endif /*IPSEC*/ #include <netinet6/ip6_ipsec.h> #include <netinet6/ip6_var.h> extern struct protosw inet6sw[]; - -#ifdef INET6 -#ifdef IPSEC #ifdef IPSEC_FILTERTUNNEL static VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 1; #else @@ -92,8 +90,6 @@ SYSCTL_DECL(_net_inet6_ipsec6); SYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ipsec6_filtertunnel), 0, "If set filter packets from an IPsec tunnel."); -#endif /* IPSEC */ -#endif /* INET6 */ /* * Check if we have to jump over firewall processing for this packet. @@ -103,16 +99,14 @@ SYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel, int ip6_ipsec_filtertunnel(struct mbuf *m) { -#ifdef IPSEC /* * Bypass packet filtering for packets previously handled by IPsec. */ if (!V_ip6_ipsec6_filtertunnel && m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) - return 1; -#endif - return 0; + return (1); + return (0); } /* @@ -125,11 +119,7 @@ int ip6_ipsec_fwd(struct mbuf *m) { -#ifdef IPSEC return (ipsec6_in_reject(m, NULL)); -#else - return (0); -#endif /* !IPSEC */ } /* @@ -143,7 +133,6 @@ int ip6_ipsec_input(struct mbuf *m, int nxt) { -#ifdef IPSEC /* * enforce IPsec policy checking if we are seeing last header. * note that we do not visit this with protocols with pcb layer @@ -151,7 +140,6 @@ ip6_ipsec_input(struct mbuf *m, int nxt) */ if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0) return (ipsec6_in_reject(m, NULL)); -#endif /* IPSEC */ return (0); } @@ -164,7 +152,6 @@ ip6_ipsec_input(struct mbuf *m, int nxt) int ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *error) { -#ifdef IPSEC struct secpolicy *sp; /* @@ -257,9 +244,7 @@ reinjected: bad: if (sp != NULL) KEY_FREESP(&sp); - return 1; -#endif /* IPSEC */ - return 0; + return (1); } #if 0 diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index eda02d9..d667903 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2900,14 +2900,6 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst) if (copym == NULL) return; } - -#ifdef DIAGNOSTIC - if (copym->m_len < sizeof(*ip6)) { - m_freem(copym); - return; - } -#endif - ip6 = mtod(copym, struct ip6_hdr *); /* * clear embedded scope identifiers if necessary. @@ -2915,7 +2907,11 @@ ip6_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in6 *dst) */ in6_clearscope(&ip6->ip6_src); in6_clearscope(&ip6->ip6_dst); - + if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + copym->m_pkthdr.csum_flags |= CSUM_DATA_VALID_IPV6 | + CSUM_PSEUDO_HDR; + copym->m_pkthdr.csum_data = 0xffff; + } (void)if_simloop(ifp, copym, dst->sin6_family, 0); } diff --git a/sys/sys/param.h b/sys/sys/param.h index bc722df..cbc2901 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1100072 /* Master, propagated to newvers */ +#define __FreeBSD_version 1100073 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 34d9c34..cc67d37 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -998,7 +998,8 @@ extern struct pmc_cpu **pmc_pcpu; /* driver statistics */ extern struct pmc_op_getdriverstats pmc_stats; -#if defined(DEBUG) +#if defined(HWPMC_DEBUG) +#include <sys/ktr.h> /* debug flags, major flag groups */ struct pmc_debugflags { @@ -1015,14 +1016,42 @@ struct pmc_debugflags { extern struct pmc_debugflags pmc_debugflags; +#define KTR_PMC KTR_SUBSYS + #define PMC_DEBUG_STRSIZE 128 #define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0 } -#define PMCDBG(M,N,L,F,...) do { \ +#define PMCDBG0(M, N, L, F) do { \ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ - printf(#M ":" #N ":" #L ": " F "\n", __VA_ARGS__); \ + CTR0(KTR_PMC, #M ":" #N ":" #L ": " F); \ } while (0) - +#define PMCDBG1(M, N, L, F, p1) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR1(KTR_PMC, #M ":" #N ":" #L ": " F, p1); \ +} while (0) +#define PMCDBG2(M, N, L, F, p1, p2) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR2(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2); \ +} while (0) +#define PMCDBG3(M, N, L, F, p1, p2, p3) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR3(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3); \ +} while (0) +#define PMCDBG4(M, N, L, F, p1, p2, p3, p4) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR4(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4);\ +} while (0) +#define PMCDBG5(M, N, L, F, p1, p2, p3, p4, p5) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR5(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4, \ + p5); \ +} while (0) +#define PMCDBG6(M, N, L, F, p1, p2, p3, p4, p5, p6) do { \ + if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \ + CTR6(KTR_PMC, #M ":" #N ":" #L ": " F, p1, p2, p3, p4, \ + p5, p6); \ +} while (0) + /* Major numbers */ #define PMC_DEBUG_MAJ_CPU 0 /* cpu switches */ #define PMC_DEBUG_MAJ_CSW 1 /* context switches */ @@ -1088,7 +1117,13 @@ extern struct pmc_debugflags pmc_debugflags; #define PMC_DEBUG_MIN_CLO 12 /* close */ #else -#define PMCDBG(M,N,L,F,...) /* nothing */ +#define PMCDBG0(M, N, L, F) /* nothing */ +#define PMCDBG1(M, N, L, F, p1) +#define PMCDBG2(M, N, L, F, p1, p2) +#define PMCDBG3(M, N, L, F, p1, p2, p3) +#define PMCDBG4(M, N, L, F, p1, p2, p3, p4) +#define PMCDBG5(M, N, L, F, p1, p2, p3, p4, p5) +#define PMCDBG6(M, N, L, F, p1, p2, p3, p4, p5, p6) #endif /* declare a dedicated memory pool */ diff --git a/sys/vm/default_pager.c b/sys/vm/default_pager.c index 26326a5..98dee45 100644 --- a/sys/vm/default_pager.c +++ b/sys/vm/default_pager.c @@ -113,6 +113,7 @@ default_pager_dealloc(object) /* * OBJT_DEFAULT objects have no special resources allocated to them. */ + object->type = OBJT_DEAD; } /* diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index d05ea33..33fba4e 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -254,6 +254,8 @@ dev_pager_dealloc(object) != NULL) dev_pager_free_page(object, m); } + object->handle = NULL; + object->type = OBJT_DEAD; } static int diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c index 9e98006..885a451 100644 --- a/sys/vm/phys_pager.c +++ b/sys/vm/phys_pager.c @@ -131,6 +131,8 @@ phys_pager_dealloc(vm_object_t object) mtx_unlock(&phys_pager_mtx); VM_OBJECT_WLOCK(object); } + object->handle = NULL; + object->type = OBJT_DEAD; } /* diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c index e35741e..23ebd3a 100644 --- a/sys/vm/sg_pager.c +++ b/sys/vm/sg_pager.c @@ -130,6 +130,8 @@ sg_pager_dealloc(vm_object_t object) sg = object->handle; sglist_free(sg); + object->handle = NULL; + object->type = OBJT_DEAD; } static int diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 9a83989..3005491 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -697,6 +697,8 @@ swap_pager_dealloc(vm_object_t object) * if paging is still in progress on some objects. */ swp_pager_meta_free_all(object); + object->handle = NULL; + object->type = OBJT_DEAD; } /************************************************************************ diff --git a/sys/vm/uma.h b/sys/vm/uma.h index df6cc5c..d3e0658 100644 --- a/sys/vm/uma.h +++ b/sys/vm/uma.h @@ -690,4 +690,7 @@ struct uma_percpu_stat { uint64_t _ups_reserved[5]; /* Reserved. */ }; +void uma_reclaim_wakeup(void); +void uma_reclaim_worker(void *); + #endif /* _VM_UMA_H_ */ diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 4ff177f..d1573e6 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -3222,16 +3222,17 @@ uma_find_refcnt(uma_zone_t zone, void *item) } /* See uma.h */ -void -uma_reclaim(void) +static void +uma_reclaim_locked(bool kmem_danger) { + #ifdef UMA_DEBUG printf("UMA: vm asked us to release pages!\n"); #endif - sx_xlock(&uma_drain_lock); + sx_assert(&uma_drain_lock, SA_XLOCKED); bucket_enable(); zone_foreach(zone_drain); - if (vm_page_count_min()) { + if (vm_page_count_min() || kmem_danger) { cache_drain_safe(NULL); zone_foreach(zone_drain); } @@ -3243,9 +3244,42 @@ uma_reclaim(void) zone_drain(slabzone); zone_drain(slabrefzone); bucket_zone_drain(); +} + +void +uma_reclaim(void) +{ + + sx_xlock(&uma_drain_lock); + uma_reclaim_locked(false); sx_xunlock(&uma_drain_lock); } +static int uma_reclaim_needed; + +void +uma_reclaim_wakeup(void) +{ + + uma_reclaim_needed = 1; + wakeup(&uma_reclaim_needed); +} + +void +uma_reclaim_worker(void *arg __unused) +{ + + sx_xlock(&uma_drain_lock); + for (;;) { + sx_sleep(&uma_reclaim_needed, &uma_drain_lock, PVM, + "umarcl", 0); + if (uma_reclaim_needed) { + uma_reclaim_needed = 0; + uma_reclaim_locked(true); + } + } +} + /* See uma.h */ int uma_zone_exhausted(uma_zone_t zone) diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c index 4ec2613..865be71 100644 --- a/sys/vm/vm_meter.c +++ b/sys/vm/vm_meter.c @@ -111,14 +111,7 @@ vmtotal(SYSCTL_HANDLER_ARGS) */ mtx_lock(&vm_object_list_mtx); TAILQ_FOREACH(object, &vm_object_list, object_list) { - if (!VM_OBJECT_TRYWLOCK(object)) { - /* - * Avoid a lock-order reversal. Consequently, - * the reported number of active pages may be - * greater than the actual number. - */ - continue; - } + VM_OBJECT_WLOCK(object); vm_object_clear_flag(object, OBJ_ACTIVE); VM_OBJECT_WUNLOCK(object); } @@ -196,10 +189,9 @@ vmtotal(SYSCTL_HANDLER_ARGS) mtx_lock(&vm_object_list_mtx); TAILQ_FOREACH(object, &vm_object_list, object_list) { /* - * Perform unsynchronized reads on the object to avoid - * a lock-order reversal. In this case, the lack of - * synchronization should not impair the accuracy of - * the reported statistics. + * Perform unsynchronized reads on the object. In + * this case, the lack of synchronization should not + * impair the accuracy of the reported statistics. */ if ((object->flags & OBJ_FICTITIOUS) != 0) { /* diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index a1d6701..78cea70 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -166,6 +166,8 @@ vm_object_zdtor(void *mem, int size, void *arg) vm_object_t object; object = (vm_object_t)mem; + KASSERT(object->ref_count == 0, + ("object %p ref_count = %d", object, object->ref_count)); KASSERT(TAILQ_EMPTY(&object->memq), ("object %p has resident pages in its memq", object)); KASSERT(vm_radix_is_empty(&object->rtree), @@ -187,6 +189,9 @@ vm_object_zdtor(void *mem, int size, void *arg) KASSERT(object->shadow_count == 0, ("object %p shadow_count = %d", object, object->shadow_count)); + KASSERT(object->type == OBJT_DEAD, + ("object %p has non-dead type %d", + object, object->type)); } #endif @@ -199,6 +204,8 @@ vm_object_zinit(void *mem, int size, int flags) rw_init_flags(&object->lock, "vm object", RW_DUPOK | RW_NEW); /* These are true for any object that has been freed */ + object->type = OBJT_DEAD; + object->ref_count = 0; object->rtree.rt_root = 0; object->rtree.rt_flags = 0; object->paging_in_progress = 0; @@ -206,6 +213,10 @@ vm_object_zinit(void *mem, int size, int flags) object->shadow_count = 0; object->cache.rt_root = 0; object->cache.rt_flags = 0; + + mtx_lock(&vm_object_list_mtx); + TAILQ_INSERT_TAIL(&vm_object_list, object, object_list); + mtx_unlock(&vm_object_list_mtx); return (0); } @@ -252,10 +263,6 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, vm_object_t object) #if VM_NRESERVLEVEL > 0 LIST_INIT(&object->rvq); #endif - - mtx_lock(&vm_object_list_mtx); - TAILQ_INSERT_TAIL(&vm_object_list, object, object_list); - mtx_unlock(&vm_object_list_mtx); } /* @@ -671,19 +678,9 @@ vm_object_destroy(vm_object_t object) { /* - * Remove the object from the global object list. - */ - mtx_lock(&vm_object_list_mtx); - TAILQ_REMOVE(&vm_object_list, object, object_list); - mtx_unlock(&vm_object_list_mtx); - - /* * Release the allocation charge. */ if (object->cred != NULL) { - KASSERT(object->type == OBJT_DEFAULT || - object->type == OBJT_SWAP, - ("%s: non-swap obj %p has cred", __func__, object)); swap_release_by_cred(object->charge, object->cred); object->charge = 0; crfree(object->cred); @@ -788,6 +785,10 @@ vm_object_terminate(vm_object_t object) if (__predict_false(!vm_object_cache_is_empty(object))) vm_page_cache_free(object, 0, 0); + KASSERT(object->cred == NULL || object->type == OBJT_DEFAULT || + object->type == OBJT_SWAP, + ("%s: non-swap obj %p has cred", __func__, object)); + /* * Let the pager know object is dead. */ @@ -1803,6 +1804,8 @@ vm_object_collapse(vm_object_t object) KASSERT(backing_object->ref_count == 1, ( "backing_object %p was somehow re-referenced during collapse!", backing_object)); + backing_object->type = OBJT_DEAD; + backing_object->ref_count = 0; VM_OBJECT_WUNLOCK(backing_object); vm_object_destroy(backing_object); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 872ffd8..2f57579 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -1724,8 +1724,9 @@ vm_pageout_init(void) static void vm_pageout(void) { + int error; #if MAXMEMDOM > 1 - int error, i; + int i; #endif swap_pager_swap_init(); @@ -1739,6 +1740,10 @@ vm_pageout(void) } } #endif + error = kthread_add(uma_reclaim_worker, NULL, curproc, NULL, + 0, 0, "uma"); + if (error != 0) + panic("starting uma_reclaim helper, error %d\n", error); vm_pageout_worker((void *)(uintptr_t)0); } diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index 5c33be4..71fadd7 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -71,6 +71,7 @@ _Static_assert(sizeof(long) * NBBY >= VM_PHYSSEG_MAX, "Too many physsegs."); struct mem_affinity *mem_affinity; +int *mem_locality; int vm_ndomains = 1; @@ -140,6 +141,10 @@ static int sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS); SYSCTL_OID(_vm, OID_AUTO, phys_segs, CTLTYPE_STRING | CTLFLAG_RD, NULL, 0, sysctl_vm_phys_segs, "A", "Phys Seg Info"); +static int sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS); +SYSCTL_OID(_vm, OID_AUTO, phys_locality, CTLTYPE_STRING | CTLFLAG_RD, + NULL, 0, sysctl_vm_phys_locality, "A", "Phys Locality Info"); + SYSCTL_INT(_vm, OID_AUTO, ndomains, CTLFLAG_RD, &vm_ndomains, 0, "Number of physical memory domains available."); @@ -297,6 +302,48 @@ sysctl_vm_phys_segs(SYSCTL_HANDLER_ARGS) return (error); } +/* + * Return affinity, or -1 if there's no affinity information. + */ +static int +vm_phys_mem_affinity(int f, int t) +{ + + if (mem_locality == NULL) + return (-1); + if (f >= vm_ndomains || t >= vm_ndomains) + return (-1); + return (mem_locality[f * vm_ndomains + t]); +} + +/* + * Outputs the VM locality table. + */ +static int +sysctl_vm_phys_locality(SYSCTL_HANDLER_ARGS) +{ + struct sbuf sbuf; + int error, i, j; + + error = sysctl_wire_old_buffer(req, 0); + if (error != 0) + return (error); + sbuf_new_for_sysctl(&sbuf, NULL, 128, req); + + sbuf_printf(&sbuf, "\n"); + + for (i = 0; i < vm_ndomains; i++) { + sbuf_printf(&sbuf, "%d: ", i); + for (j = 0; j < vm_ndomains; j++) { + sbuf_printf(&sbuf, "%d ", vm_phys_mem_affinity(i, j)); + } + sbuf_printf(&sbuf, "\n"); + } + error = sbuf_finish(&sbuf); + sbuf_delete(&sbuf); + return (error); +} + static void vm_freelist_add(struct vm_freelist *fl, vm_page_t m, int order, int tail) { diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h index 8f3e847..575b93c 100644 --- a/sys/vm/vm_phys.h +++ b/sys/vm/vm_phys.h @@ -61,6 +61,7 @@ struct vm_phys_seg { }; extern struct mem_affinity *mem_affinity; +extern int *mem_locality; extern int vm_ndomains; extern struct vm_phys_seg vm_phys_segs[]; extern int vm_phys_nsegs; diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c index 8d2a741..e908279 100644 --- a/sys/x86/acpica/srat.c +++ b/sys/x86/acpica/srat.c @@ -64,9 +64,97 @@ static vm_paddr_t srat_physaddr; static int vm_domains[VM_PHYSSEG_MAX]; +static ACPI_TABLE_SLIT *slit; +static vm_paddr_t slit_physaddr; +static int vm_locality_table[MAXMEMDOM * MAXMEMDOM]; + static void srat_walk_table(acpi_subtable_handler *handler, void *arg); /* + * SLIT parsing. + */ + +static void +slit_parse_table(ACPI_TABLE_SLIT *s) +{ + int i, j; + int i_domain, j_domain; + int offset = 0; + uint8_t e; + + /* + * This maps the SLIT data into the VM-domain centric view. + * There may be sparse entries in the PXM namespace, so + * remap them to a VM-domain ID and if it doesn't exist, + * skip it. + * + * It should result in a packed 2d array of VM-domain + * locality information entries. + */ + + if (bootverbose) + printf("SLIT.Localities: %d\n", (int) s->LocalityCount); + for (i = 0; i < s->LocalityCount; i++) { + i_domain = acpi_map_pxm_to_vm_domainid(i); + if (i_domain < 0) + continue; + + if (bootverbose) + printf("%d: ", i); + for (j = 0; j < s->LocalityCount; j++) { + j_domain = acpi_map_pxm_to_vm_domainid(j); + if (j_domain < 0) + continue; + e = s->Entry[i * s->LocalityCount + j]; + if (bootverbose) + printf("%d ", (int) e); + /* 255 == "no locality information" */ + if (e == 255) + vm_locality_table[offset] = -1; + else + vm_locality_table[offset] = e; + offset++; + } + if (bootverbose) + printf("\n"); + } +} + +/* + * Look for an ACPI System Locality Distance Information Table ("SLIT") + */ +static int +parse_slit(void) +{ + + if (resource_disabled("slit", 0)) { + return (-1); + } + + slit_physaddr = acpi_find_table(ACPI_SIG_SLIT); + if (slit_physaddr == 0) { + return (-1); + } + + /* + * Make a pass over the table to populate the cpus[] and + * mem_info[] tables. + */ + slit = acpi_map_table(slit_physaddr, ACPI_SIG_SLIT); + slit_parse_table(slit); + acpi_unmap_table(slit); + slit = NULL; + + /* Tell the VM about it! */ + mem_locality = vm_locality_table; + return (0); +} + +/* + * SRAT parsing. + */ + +/* * Returns true if a memory range overlaps with at least one range in * phys_avail[]. */ @@ -301,17 +389,17 @@ renumber_domains(void) /* * Look for an ACPI System Resource Affinity Table ("SRAT") */ -static void -parse_srat(void *dummy) +static int +parse_srat(void) { int error; if (resource_disabled("srat", 0)) - return; + return (-1); srat_physaddr = acpi_find_table(ACPI_SIG_SRAT); if (srat_physaddr == 0) - return; + return (-1); /* * Make a pass over the table to populate the cpus[] and @@ -325,13 +413,39 @@ parse_srat(void *dummy) if (error || check_domains() != 0 || check_phys_avail() != 0 || renumber_domains() != 0) { srat_physaddr = 0; - return; + return (-1); } /* Point vm_phys at our memory affinity table. */ mem_affinity = mem_info; + + return (0); +} + +static void +init_mem_locality(void) +{ + int i; + + /* + * For now, assume 255 == "no locality information for + * this pairing. + */ + for (i = 0; i < MAXMEMDOM * MAXMEMDOM; i++) + vm_locality_table[i] = -1; +} + +static void +parse_acpi_tables(void *dummy) +{ + + if (parse_srat() < 0) + return; + init_mem_locality(); + (void) parse_slit(); } -SYSINIT(parse_srat, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_srat, NULL); +SYSINIT(parse_acpi_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_acpi_tables, + NULL); static void srat_walk_table(acpi_subtable_handler *handler, void *arg) diff --git a/sys/x86/include/acpica_machdep.h b/sys/x86/include/acpica_machdep.h index 46080c0..136285c 100644 --- a/sys/x86/include/acpica_machdep.h +++ b/sys/x86/include/acpica_machdep.h @@ -74,6 +74,7 @@ enum intr_polarity; void acpi_SetDefaultIntrModel(int model); void acpi_cpu_c1(void); +void acpi_cpu_idle_mwait(uint32_t mwait_hint); void *acpi_map_table(vm_paddr_t pa, const char *sig); void acpi_unmap_table(void *table); vm_paddr_t acpi_find_table(const char *sig); diff --git a/sys/x86/include/specialreg.h b/sys/x86/include/specialreg.h index a771fff..6c849ff 100644 --- a/sys/x86/include/specialreg.h +++ b/sys/x86/include/specialreg.h @@ -53,6 +53,7 @@ #define CR0_CD 0x40000000 /* Cache Disable */ #define CR3_PCID_SAVE 0x8000000000000000 +#define CR3_PCID_MASK 0xfff /* * Bits in PPro special registers diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index f8d1f08..7925713 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$"); #ifdef SMP #include <machine/smp.h> #endif +#include <x86/acpica_machdep.h> #include <vm/vm.h> #include <vm/vm_extern.h> @@ -121,6 +122,27 @@ cpu_flush_dcache(void *ptr, size_t len) /* Not applicable */ } +void +acpi_cpu_c1(void) +{ + + __asm __volatile("sti; hlt"); +} + +void +acpi_cpu_idle_mwait(uint32_t mwait_hint) +{ + int *state; + + state = (int *)PCPU_PTR(monitorbuf); + /* + * XXXKIB. Software coordination mode should be supported, + * but all Intel CPUs provide hardware coordination. + */ + cpu_monitor(state, 0, 0); + cpu_mwait(MWAIT_INTRBREAK, mwait_hint); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) @@ -194,6 +216,15 @@ cpu_halt(void) halt(); } +bool +cpu_mwait_usable(void) +{ + + return ((cpu_feature2 & CPUID2_MON) != 0 && ((cpu_mon_mwait_flags & + (CPUID5_MON_MWAIT_EXT | CPUID5_MWAIT_INTRBREAK)) == + (CPUID5_MON_MWAIT_EXT | CPUID5_MWAIT_INTRBREAK))); +} + void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */ static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */ static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */ @@ -220,7 +251,7 @@ cpu_idle_acpi(sbintime_t sbt) else if (cpu_idle_hook) cpu_idle_hook(sbt); else - __asm __volatile("sti; hlt"); + acpi_cpu_c1(); *state = STATE_RUNNING; } #endif /* !PC98 */ @@ -253,7 +284,7 @@ cpu_idle_hlt(sbintime_t sbt) if (sched_runnable()) enable_intr(); else - __asm __volatile("sti; hlt"); + acpi_cpu_c1(); *state = STATE_RUNNING; } diff --git a/sys/x86/xen/xen_apic.c b/sys/x86/xen/xen_apic.c index c742920..a65f3b5 100644 --- a/sys/x86/xen/xen_apic.c +++ b/sys/x86/xen/xen_apic.c @@ -423,31 +423,29 @@ xen_invltlb(void *arg) #ifdef __amd64__ static int -xen_invltlb_pcid(void *arg) +xen_invltlb_invpcid(void *arg) { - invltlb_pcid_handler(); + invltlb_invpcid_handler(); return (FILTER_HANDLED); } -#endif static int -xen_invlpg(void *arg) +xen_invltlb_pcid(void *arg) { - invlpg_handler(); + invltlb_pcid_handler(); return (FILTER_HANDLED); } +#endif -#ifdef __amd64__ static int -xen_invlpg_pcid(void *arg) +xen_invlpg(void *arg) { - invlpg_pcid_handler(); + invlpg_handler(); return (FILTER_HANDLED); } -#endif static int xen_invlrng(void *arg) @@ -532,8 +530,8 @@ xen_setup_cpus(void) #ifdef __amd64__ if (pmap_pcid_enabled) { - xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = xen_invltlb_pcid; - xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = xen_invlpg_pcid; + xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = invpcid_works ? + xen_invltlb_invpcid : xen_invltlb_pcid; } #endif CPU_FOREACH(i) diff --git a/sys/x86/xen/xenpv.c b/sys/x86/xen/xenpv.c index bdda883..2e4a9fe 100644 --- a/sys/x86/xen/xenpv.c +++ b/sys/x86/xen/xenpv.c @@ -33,11 +33,33 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/module.h> #include <sys/pcpu.h> +#include <sys/rman.h> #include <sys/smp.h> +#include <vm/vm.h> +#include <vm/vm_page.h> +#include <vm/vm_param.h> +#include <vm/vm_phys.h> + #include <xen/xen-os.h> #include <xen/gnttab.h> +#include "xenmem_if.h" + +/* + * Allocate unused physical memory above 4GB in order to map memory + * from foreign domains. We use memory starting at 4GB in order to + * prevent clashes with MMIO/ACPI regions. + * + * Since this is not possible on i386 just use any available memory + * chunk and hope we don't clash with anything else. + */ +#ifdef __amd64__ +#define LOW_MEM_LIMIT 0x100000000ul +#else +#define LOW_MEM_LIMIT 0 +#endif + static devclass_t xenpv_devclass; static void @@ -85,6 +107,42 @@ xenpv_attach(device_t dev) return (0); } +static struct resource * +xenpv_alloc_physmem(device_t dev, device_t child, int *res_id, size_t size) +{ + struct resource *res; + vm_paddr_t phys_addr; + int error; + + res = bus_alloc_resource(child, SYS_RES_MEMORY, res_id, LOW_MEM_LIMIT, + ~0ul, size, RF_ACTIVE); + if (res == NULL) + return (NULL); + + phys_addr = rman_get_start(res); + error = vm_phys_fictitious_reg_range(phys_addr, phys_addr + size, + VM_MEMATTR_DEFAULT); + if (error) { + bus_release_resource(child, SYS_RES_MEMORY, *res_id, res); + return (NULL); + } + + return (res); +} + +static int +xenpv_free_physmem(device_t dev, device_t child, int res_id, struct resource *res) +{ + vm_paddr_t phys_addr; + size_t size; + + phys_addr = rman_get_start(res); + size = rman_get_size(res); + + vm_phys_fictitious_unreg_range(phys_addr, phys_addr + size); + return (bus_release_resource(child, SYS_RES_MEMORY, res_id, res)); +} + static device_method_t xenpv_methods[] = { /* Device interface */ DEVMETHOD(device_identify, xenpv_identify), @@ -100,6 +158,10 @@ static device_method_t xenpv_methods[] = { DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + /* Interface to allocate memory for foreign mappings */ + DEVMETHOD(xenmem_alloc, xenpv_alloc_physmem), + DEVMETHOD(xenmem_free, xenpv_free_physmem), + DEVMETHOD_END }; @@ -110,3 +172,25 @@ static driver_t xenpv_driver = { }; DRIVER_MODULE(xenpv, nexus, xenpv_driver, xenpv_devclass, 0, 0); + +struct resource * +xenmem_alloc(device_t dev, int *res_id, size_t size) +{ + device_t parent; + + parent = device_get_parent(dev); + if (parent == NULL) + return (NULL); + return (XENMEM_ALLOC(parent, dev, res_id, size)); +} + +int +xenmem_free(device_t dev, int res_id, struct resource *res) +{ + device_t parent; + + parent = device_get_parent(dev); + if (parent == NULL) + return (ENXIO); + return (XENMEM_FREE(parent, dev, res_id, res)); +} diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h index c982d55..7ceef4f 100644 --- a/sys/xen/xen-os.h +++ b/sys/xen/xen-os.h @@ -89,6 +89,13 @@ xen_initial_domain(void) (HYPERVISOR_start_info->flags & SIF_INITDOMAIN) != 0); } +/* + * Functions to allocate/free unused memory in order + * to map memory from other domains. + */ +struct resource *xenmem_alloc(device_t dev, int *res_id, size_t size); +int xenmem_free(device_t dev, int res_id, struct resource *res); + /* Debug/emergency function, prints directly to hypervisor console */ void xc_printf(const char *, ...) __printflike(1, 2); diff --git a/sys/xen/xenmem/xenmem_if.m b/sys/xen/xenmem/xenmem_if.m new file mode 100644 index 0000000..5cc2171 --- /dev/null +++ b/sys/xen/xenmem/xenmem_if.m @@ -0,0 +1,95 @@ +#- +# Copyright (c) 2015 Roger Pau Monné <royger@FreeBSD.org> +# 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 <sys/bus.h> + +INTERFACE xenmem; + +# +# Default implementations of some methods. +# +CODE { + static struct resource * + xenmem_generic_alloc(device_t dev, device_t child, int *res_id, + size_t size) + { + device_t parent; + + parent = device_get_parent(dev); + if (parent == NULL) + return (NULL); + return (XENMEM_ALLOC(parent, child, res_id, size)); + } + + static int + xenmem_generic_free(device_t dev, device_t child, int res_id, + struct resource *res) + { + device_t parent; + + parent = device_get_parent(dev); + if (parent == NULL) + return (ENXIO); + return (XENMEM_FREE(parent, child, res_id, res)); + } +}; + +/** + * @brief Request for unused physical memory regions. + * + * @param _dev the device whose child was being probed. + * @param _child the child device which failed to probe. + * @param _res_id a pointer to the resource identifier. + * @param _size size of the required memory region. + * + * @returns the resource which was allocated or @c NULL if no + * resource could be allocated. + */ +METHOD struct resource * alloc { + device_t _dev; + device_t _child; + int *_res_id; + size_t _size; +} DEFAULT xenmem_generic_alloc; + +/** + * @brief Free physical memory regions. + * + * @param _dev the device whose child was being probed. + * @param _child the child device which failed to probe. + * @param _res_id the resource identifier. + * @param _res the resource. + * + * @returns 0 on success, otherwise an error code. + */ +METHOD int free { + device_t _dev; + device_t _child; + int _res_id; + struct resource *_res; +} DEFAULT xenmem_generic_free; diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index a519580..4a2ba751 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1009,12 +1009,6 @@ OLD_FILES+=usr/bin/c++filt .endif OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/libexec/cc1plus -.if ${MK_GCC} == no -OLD_FILES+=usr/bin/gperf -OLD_FILES+=usr/share/info/gperf.info.gz -OLD_FILES+=usr/share/man/man1/gperf.1.gz -OLD_FILES+=usr/share/man/man1/gperf.7.gz -.endif .endif .if ${MK_FMTREE} == no @@ -1729,6 +1723,7 @@ OLD_FILES+=usr/bin/g++ OLD_FILES+=usr/bin/gcc OLD_FILES+=usr/bin/gcov OLD_FILES+=usr/bin/gcpp +OLD_FILES+=usr/bin/gperf .if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386" OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_aes.h OLD_FILES+=usr/include/gcc/4.2/__wmmintrin_pclmul.h @@ -1754,10 +1749,13 @@ OLD_FILES+=usr/share/info/cpp.info.gz OLD_FILES+=usr/share/info/cppinternals.info.gz OLD_FILES+=usr/share/info/gcc.info.gz OLD_FILES+=usr/share/info/gccint.info.gz +OLD_FILES+=usr/share/info/gperf.info.gz OLD_FILES+=usr/share/man/man1/g++.1.gz OLD_FILES+=usr/share/man/man1/gcc.1.gz OLD_FILES+=usr/share/man/man1/gcov.1.gz OLD_FILES+=usr/share/man/man1/gcpp.1.gz +OLD_FILES+=usr/share/man/man1/gperf.1.gz +OLD_FILES+=usr/share/man/man1/gperf.7.gz .endif .if ${MK_GCOV} == no diff --git a/usr.bin/checknr/checknr.c b/usr.bin/checknr/checknr.c index 235ec33..06395b0 100644 --- a/usr.bin/checknr/checknr.c +++ b/usr.bin/checknr/checknr.c @@ -313,7 +313,7 @@ static void process(FILE *f) { int i, n; - char mac[512]; /* The current macro or nroff command */ + char mac[64]; /* The current macro or nroff command */ char *line; size_t linecap; int pl; diff --git a/usr.bin/col/col.c b/usr.bin/col/col.c index 74c59b6..c620bcb 100644 --- a/usr.bin/col/col.c +++ b/usr.bin/col/col.c @@ -96,6 +96,7 @@ struct line_str { int l_max_col; /* max column in the line */ }; +static void addto_lineno(int *, int); static LINE *alloc_line(void); static void dowarn(int); static void flush_line(LINE *); @@ -108,7 +109,7 @@ static CSET last_set; /* char_set of last char printed */ static LINE *lines; static int compress_spaces; /* if doing space -> tab conversion */ static int fine; /* if `fine' resolution (half lines) */ -static int max_bufd_lines; /* max # lines to keep in memory */ +static int max_bufd_lines; /* max # of half lines to keep in memory */ static int nblank_lines; /* # blanks after last flushed line */ static int no_backspaces; /* if not to output any backspaces */ static int pass_unknown_seqs; /* pass unknown control sequences */ @@ -133,6 +134,7 @@ main(int argc, char **argv) int this_line; /* line l points to */ int nflushd_lines; /* number of lines that were flushed */ int adjust, opt, warned, width; + const char *errstr; cap_rights_t rights; unsigned long cmd; @@ -151,7 +153,7 @@ main(int argc, char **argv) if (cap_enter() < 0 && errno != ENOSYS) err(1, "unable to enter capability mode"); - max_bufd_lines = 128; + max_bufd_lines = 256; compress_spaces = 1; /* compress spaces into tabs */ while ((opt = getopt(argc, argv, "bfhl:px")) != -1) switch (opt) { @@ -165,8 +167,11 @@ main(int argc, char **argv) compress_spaces = 1; break; case 'l': /* buffered line count */ - if ((max_bufd_lines = atoi(optarg)) <= 0) - errx(1, "bad -l argument %s", optarg); + max_bufd_lines = strtonum(optarg, 1, + (INT_MAX - BUFFER_MARGIN) / 2, &errstr) * 2; + if (errstr != NULL) + errx(1, "bad -l argument, %s: %s", errstr, + optarg); break; case 'p': /* pass unknown control sequences */ pass_unknown_seqs = 1; @@ -182,9 +187,6 @@ main(int argc, char **argv) if (optind != argc) usage(); - /* this value is in half lines */ - max_bufd_lines *= 2; - adjust = cur_col = extra_lines = warned = 0; cur_line = max_line = nflushd_lines = this_line = 0; cur_set = last_set = CS_NORMAL; @@ -204,19 +206,19 @@ main(int argc, char **argv) case ESC: /* just ignore EOF */ switch(getwchar()) { case RLF: - cur_line -= 2; + addto_lineno(&cur_line, -2); break; case RHLF: - cur_line--; + addto_lineno(&cur_line, -1); break; case FHLF: - cur_line++; + addto_lineno(&cur_line, 1); if (cur_line > max_line) max_line = cur_line; } continue; case NL: - cur_line += 2; + addto_lineno(&cur_line, 2); if (cur_line > max_line) max_line = cur_line; cur_col = 0; @@ -235,7 +237,7 @@ main(int argc, char **argv) ++cur_col; continue; case VT: - cur_line -= 2; + addto_lineno(&cur_line, -2); continue; } if (iswspace(ch)) { @@ -248,58 +250,61 @@ main(int argc, char **argv) } /* Must stuff ch in a line - are we at the right one? */ - if (cur_line != this_line - adjust) { + if (cur_line + adjust != this_line) { LINE *lnew; - int nmove; - - adjust = 0; - nmove = cur_line - this_line; - if (!fine) { - /* round up to next line */ - if (cur_line & 1) { - adjust = 1; - nmove++; - } - } - if (nmove < 0) { - for (; nmove < 0 && l->l_prev; nmove++) + + /* round up to next line */ + adjust = !fine && (cur_line & 1); + + if (cur_line + adjust < this_line) { + while (cur_line + adjust < this_line && + l->l_prev != NULL) { l = l->l_prev; - if (nmove) { + this_line--; + } + if (cur_line + adjust < this_line) { if (nflushd_lines == 0) { /* * Allow backup past first * line if nothing has been * flushed yet. */ - for (; nmove < 0; nmove++) { + while (cur_line + adjust + < this_line) { lnew = alloc_line(); l->l_prev = lnew; lnew->l_next = l; l = lines = lnew; extra_lines++; + this_line--; } } else { if (!warned++) dowarn(cur_line); - cur_line -= nmove; + cur_line = this_line - adjust; } } } else { /* may need to allocate here */ - for (; nmove > 0 && l->l_next; nmove--) + while (cur_line + adjust > this_line) { + if (l->l_next == NULL) { + l->l_next = alloc_line(); + l->l_next->l_prev = l; + } l = l->l_next; - for (; nmove > 0; nmove--) { - lnew = alloc_line(); - lnew->l_prev = l; - l->l_next = lnew; - l = lnew; + this_line++; } } - this_line = cur_line + adjust; - nmove = this_line - nflushd_lines; - if (nmove >= max_bufd_lines + BUFFER_MARGIN) { - nflushd_lines += nmove - max_bufd_lines; - flush_lines(nmove - max_bufd_lines); + if (this_line > nflushd_lines && + this_line - nflushd_lines >= + max_bufd_lines + BUFFER_MARGIN) { + if (extra_lines) { + flush_lines(extra_lines); + extra_lines = 0; + } + flush_lines(this_line - nflushd_lines - + max_bufd_lines); + nflushd_lines = this_line - max_bufd_lines; } } /* grow line's buffer? */ @@ -330,25 +335,23 @@ main(int argc, char **argv) } if (ferror(stdin)) err(1, NULL); - if (max_line == 0) - exit(0); /* no lines, so just exit */ + if (extra_lines) + flush_lines(extra_lines); /* goto the last line that had a character on it */ for (; l->l_next; l = l->l_next) this_line++; - flush_lines(this_line - nflushd_lines + extra_lines + 1); + flush_lines(this_line - nflushd_lines + 1); /* make sure we leave things in a sane state */ if (last_set != CS_NORMAL) PUTC(SI); /* flush out the last few blank lines */ - nblank_lines = max_line - this_line; + if (max_line > this_line) + nblank_lines = max_line - this_line; if (max_line & 1) nblank_lines++; - else if (!nblank_lines) - /* missing a \n on the last line? */ - nblank_lines = 2; flush_blanks(); exit(0); } @@ -365,7 +368,8 @@ flush_lines(int nflush) flush_blanks(); flush_line(l); } - nblank_lines++; + if (l->l_line || l->l_next) + nblank_lines++; if (l->l_line) (void)free(l->l_line); free_line(l); @@ -517,6 +521,23 @@ flush_line(LINE *l) } } +/* + * Increment or decrement a line number, checking for overflow. + * Stop one below INT_MAX such that the adjust variable is safe. + */ +void +addto_lineno(int *lno, int offset) +{ + if (offset > 0) { + if (*lno >= INT_MAX - offset) + errx(1, "too many lines"); + } else { + if (*lno < INT_MIN - offset) + errx(1, "too many reverse line feeds"); + } + *lno += offset; +} + #define NALLOC 64 static LINE *line_freelist; diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index f04c531..109ef2d 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -315,7 +315,7 @@ intpr(int interval, void (*pfunc)(char *), int af) for (ifa = ifap; ifa; ifa = ifa->ifa_next) { bool network = false, link = false; - char *name; + char *name, *xname, buf[IFNAMSIZ+1]; if (interface != NULL && strcmp(ifa->ifa_name, interface) != 0) continue; @@ -341,10 +341,20 @@ intpr(int interval, void (*pfunc)(char *), int af) xo_open_instance("interface"); + if ((ifa->ifa_flags & IFF_UP) == 0) { + xname = stpcpy(buf, name); + *xname++ = '*'; + *xname = '\0'; + xname = buf; + } else + xname = name; + if (Wflag) - xo_emit("{tk:name/%-7.7s}", name); + xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%7.7s}", + name, ifa->ifa_flags, xname); else - xo_emit("{tk:name/%-5.5s}", name); + xo_emit("{etk:name/%s}{e:flags/0x%x}{d:/%5.5s}", + name, ifa->ifa_flags, xname); #define IFA_MTU(ifa) (((struct if_data *)(ifa)->ifa_data)->ifi_mtu) show_stat("lu", 6, "mtu", IFA_MTU(ifa), IFA_MTU(ifa)); diff --git a/usr.sbin/bhyve/inout.c b/usr.sbin/bhyve/inout.c index 402b953..929bb3c 100644 --- a/usr.sbin/bhyve/inout.c +++ b/usr.sbin/bhyve/inout.c @@ -107,7 +107,7 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) uint32_t eax, val; inout_func_t handler; void *arg; - int error, retval; + int error, fault, retval; enum vm_reg_name idxreg; uint64_t gla, index, iterations, count; struct vm_inout_str *vis; @@ -163,11 +163,11 @@ emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) } error = vm_copy_setup(ctx, vcpu, &vis->paging, gla, - bytes, prot, iov, nitems(iov)); - if (error == -1) { + bytes, prot, iov, nitems(iov), &fault); + if (error) { retval = -1; /* Unrecoverable error */ break; - } else if (error == 1) { + } else if (fault) { retval = 0; /* Resume guest to handle fault */ break; } diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c index 31e02f8..35a0859 100644 --- a/usr.sbin/bhyve/pci_ahci.c +++ b/usr.sbin/bhyve/pci_ahci.c @@ -2093,7 +2093,7 @@ pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, struct pci_ahci_softc *sc = pi->pi_arg; assert(baridx == 5); - assert(size == 4); + assert((offset % 4) == 0 && size == 4); pthread_mutex_lock(&sc->mtx); @@ -2182,24 +2182,29 @@ pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset) static uint64_t pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, - uint64_t offset, int size) + uint64_t regoff, int size) { struct pci_ahci_softc *sc = pi->pi_arg; + uint64_t offset; uint32_t value; assert(baridx == 5); - assert(size == 4); + assert(size == 1 || size == 2 || size == 4); + assert((regoff & (size - 1)) == 0); pthread_mutex_lock(&sc->mtx); + offset = regoff & ~0x3; /* round down to a multiple of 4 bytes */ if (offset < AHCI_OFFSET) value = pci_ahci_host_read(sc, offset); else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) value = pci_ahci_port_read(sc, offset); else { value = 0; - WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", offset); + WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", + regoff); } + value >>= 8 * (regoff & 0x3); pthread_mutex_unlock(&sc->mtx); diff --git a/usr.sbin/bhyve/pci_virtio_net.c b/usr.sbin/bhyve/pci_virtio_net.c index 7227488..1a029d5 100644 --- a/usr.sbin/bhyve/pci_virtio_net.c +++ b/usr.sbin/bhyve/pci_virtio_net.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include <sys/select.h> #include <sys/uio.h> #include <sys/ioctl.h> +#include <machine/atomic.h> #include <net/ethernet.h> #include <errno.h> @@ -453,7 +454,7 @@ pci_vtnet_tx_thread(void *param) { struct pci_vtnet_softc *sc = param; struct vqueue_info *vq; - int have_work, error; + int error; vq = &sc->vsc_queues[VTNET_TXQ]; @@ -467,20 +468,16 @@ pci_vtnet_tx_thread(void *param) for (;;) { /* note - tx mutex is locked here */ - do { + while (sc->resetting || !vq_has_descs(vq)) { vq->vq_used->vu_flags &= ~VRING_USED_F_NO_NOTIFY; - if (sc->resetting) - have_work = 0; - else - have_work = vq_has_descs(vq); - - if (!have_work) { - sc->tx_in_progress = 0; - error = pthread_cond_wait(&sc->tx_cond, - &sc->tx_mtx); - assert(error == 0); - } - } while (!have_work); + mb(); + if (!sc->resetting && vq_has_descs(vq)) + break; + + sc->tx_in_progress = 0; + error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); + assert(error == 0); + } vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; sc->tx_in_progress = 1; pthread_mutex_unlock(&sc->tx_mtx); diff --git a/usr.sbin/bhyve/task_switch.c b/usr.sbin/bhyve/task_switch.c index ba6a9d2..69dfaae 100644 --- a/usr.sbin/bhyve/task_switch.c +++ b/usr.sbin/bhyve/task_switch.c @@ -202,7 +202,8 @@ desc_table_limit_check(struct vmctx *ctx, int vcpu, uint16_t sel) */ static int desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc, bool doread) + uint16_t sel, struct user_segment_descriptor *desc, bool doread, + int *faultptr) { struct iovec iov[2]; uint64_t base; @@ -215,28 +216,30 @@ desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, assert(limit >= SEL_LIMIT(sel)); error = vm_copy_setup(ctx, vcpu, paging, base + SEL_START(sel), - sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov)); - if (error == 0) { - if (doread) - vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc)); - else - vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc)); - } - return (error); + sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov), + faultptr); + if (error || *faultptr) + return (error); + + if (doread) + vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc)); + else + vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc)); + return (0); } static int desc_table_read(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { - return (desc_table_rw(ctx, vcpu, paging, sel, desc, true)); + return (desc_table_rw(ctx, vcpu, paging, sel, desc, true, faultptr)); } static int desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { - return (desc_table_rw(ctx, vcpu, paging, sel, desc, false)); + return (desc_table_rw(ctx, vcpu, paging, sel, desc, false, faultptr)); } /* @@ -248,7 +251,7 @@ desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, */ static int read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - uint16_t sel, struct user_segment_descriptor *desc) + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) { struct vm_guest_paging sup_paging; int error; @@ -267,7 +270,7 @@ read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, sup_paging = ts->paging; sup_paging.cpl = 0; /* implicit supervisor mode */ - error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc); + error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc, faultptr); return (error); } @@ -301,14 +304,10 @@ ldt_desc(int sd_type) /* * Validate the descriptor 'seg_desc' associated with 'segment'. - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - int segment, struct seg_desc *seg_desc) + int segment, struct seg_desc *seg_desc, int *faultptr) { struct vm_guest_paging sup_paging; struct user_segment_descriptor usd; @@ -369,8 +368,8 @@ validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, /* Read the descriptor from the GDT/LDT */ sup_paging = ts->paging; sup_paging.cpl = 0; /* implicit supervisor mode */ - error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd); - if (error) + error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd, faultptr); + if (error || *faultptr) return (error); /* Verify that the descriptor type is compatible with the segment */ @@ -476,14 +475,10 @@ update_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *sd) /* * Update the vcpu registers to reflect the state of the new task. - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, - uint16_t ot_sel, struct tss32 *tss, struct iovec *iov) + uint16_t ot_sel, struct tss32 *tss, struct iovec *iov, int *faultptr) { struct seg_desc seg_desc, seg_desc2; uint64_t *pdpte, maxphyaddr, reserved; @@ -565,8 +560,9 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, vm_copyout(ctx, vcpu, tss, iov, sizeof(*tss)); /* Validate segment descriptors */ - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_LDTR, &seg_desc); @@ -579,33 +575,40 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, * VM-entry checks so the guest can handle any exception injected * during task switch emulation. */ - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2); - if (error) + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_CS, &seg_desc); update_seg_desc(ctx, vcpu, VM_REG_GUEST_SS, &seg_desc2); ts->paging.cpl = tss->tss_cs & SEL_RPL_MASK; - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_DS, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_ES, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_FS, &seg_desc); - error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc); - if (error) + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc, + faultptr); + if (error || *faultptr) return (error); update_seg_desc(ctx, vcpu, VM_REG_GUEST_GS, &seg_desc); @@ -616,14 +619,10 @@ tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, * Push an error code on the stack of the new task. This is needed if the * task switch was triggered by a hardware exception that causes an error * code to be saved (e.g. #PF). - * - * Returns 0 on success. - * Returns 1 if an exception was injected into the guest. - * Returns -1 otherwise. */ static int push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, - int task_type, uint32_t errcode) + int task_type, uint32_t errcode, int *faultptr) { struct iovec iov[2]; struct seg_desc seg_desc; @@ -632,6 +631,8 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, uint32_t esp; uint16_t stacksel; + *faultptr = 0; + cr0 = GETREG(ctx, vcpu, VM_REG_GUEST_CR0); rflags = GETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS); stacksel = GETREG(ctx, vcpu, VM_REG_GUEST_SS); @@ -666,17 +667,19 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, if (vie_calculate_gla(paging->cpu_mode, VM_REG_GUEST_SS, &seg_desc, esp, bytes, stacksize, PROT_WRITE, &gla)) { sel_exception(ctx, vcpu, IDT_SS, stacksel, 1); - return (1); + *faultptr = 1; + return (0); } if (vie_alignment_check(paging->cpl, bytes, cr0, rflags, gla)) { vm_inject_ac(ctx, vcpu, 1); - return (1); + *faultptr = 1; + return (0); } error = vm_copy_setup(ctx, vcpu, paging, gla, bytes, PROT_WRITE, - iov, nitems(iov)); - if (error) + iov, nitems(iov), faultptr); + if (error || *faultptr) return (error); vm_copyout(ctx, vcpu, &errcode, iov, bytes); @@ -687,16 +690,13 @@ push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, /* * Evaluate return value from helper functions and potentially return to * the VM run loop. - * 0: success - * +1: an exception was injected into the guest vcpu - * -1: unrecoverable/programming error */ -#define CHKERR(x) \ +#define CHKERR(error,fault) \ do { \ - assert(((x) == 0) || ((x) == 1) || ((x) == -1)); \ - if ((x) == -1) \ + assert((error == 0) || (error == EFAULT)); \ + if (error) \ return (VMEXIT_ABORT); \ - else if ((x) == 1) \ + else if (fault) \ return (VMEXIT_CONTINUE); \ } while (0) @@ -711,7 +711,7 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) struct iovec nt_iov[2], ot_iov[2]; uint64_t cr0, ot_base; uint32_t eip, ot_lim, access; - int error, ext, minlimit, nt_type, ot_type, vcpu; + int error, ext, fault, minlimit, nt_type, ot_type, vcpu; enum task_switch_reason reason; uint16_t nt_sel, ot_sel; @@ -739,8 +739,9 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) sup_paging.cpl = 0; /* implicit supervisor mode */ /* Fetch the new TSS descriptor */ - error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc); - CHKERR(error); + error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc, + &fault); + CHKERR(error, fault); nt = usd_to_seg_desc(&nt_desc); @@ -792,8 +793,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) /* Fetch the new TSS */ error = vm_copy_setup(ctx, vcpu, &sup_paging, nt.base, minlimit + 1, - PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov)); - CHKERR(error); + PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov), &fault); + CHKERR(error, fault); vm_copyin(ctx, vcpu, nt_iov, &newtss, minlimit + 1); /* Get the old TSS selector from the guest's task register */ @@ -818,13 +819,14 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(ot_type == SDT_SYS386BSY || ot_type == SDT_SYS286BSY); /* Fetch the old TSS descriptor */ - error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc); - CHKERR(error); + error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc, + &fault); + CHKERR(error, fault); /* Get the old TSS */ error = vm_copy_setup(ctx, vcpu, &sup_paging, ot_base, minlimit + 1, - PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov)); - CHKERR(error); + PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov), &fault); + CHKERR(error, fault); vm_copyin(ctx, vcpu, ot_iov, &oldtss, minlimit + 1); /* @@ -834,8 +836,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) if (reason == TSR_IRET || reason == TSR_JMP) { ot_desc.sd_type &= ~0x2; error = desc_table_write(ctx, vcpu, &sup_paging, ot_sel, - &ot_desc); - CHKERR(error); + &ot_desc, &fault); + CHKERR(error, fault); } if (nt_type == SDT_SYS286BSY || nt_type == SDT_SYS286TSS) { @@ -853,8 +855,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) if (reason != TSR_IRET) { nt_desc.sd_type |= 0x2; error = desc_table_write(ctx, vcpu, &sup_paging, nt_sel, - &nt_desc); - CHKERR(error); + &nt_desc, &fault); + CHKERR(error, fault); } /* Update task register to point at the new TSS */ @@ -877,8 +879,9 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(error == 0); /* Load processor state from new TSS */ - error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov); - CHKERR(error); + error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov, + &fault); + CHKERR(error, fault); /* * Section "Interrupt Tasks" in Intel SDM, Vol 3: if an exception @@ -889,8 +892,8 @@ vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) assert(task_switch->ext); assert(task_switch->reason == TSR_IDT_GATE); error = push_errcode(ctx, vcpu, &task_switch->paging, nt_type, - task_switch->errcode); - CHKERR(error); + task_switch->errcode, &fault); + CHKERR(error, fault); } /* diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8 index 9a204a4..6478241 100644 --- a/usr.sbin/pmcstat/pmcstat.8 +++ b/usr.sbin/pmcstat/pmcstat.8 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 27, 2015 +.Dd May 8, 2015 .Dt PMCSTAT 8 .Os .Sh NAME @@ -279,8 +279,9 @@ Set the pathname of the kernel directory to argument This directory specifies where .Nm should look for the kernel and its modules. -The default is -.Pa /boot/kernel . +The default is to use the path of the running kernel obtained from the +.Va kern.bootfile +sysctl. .It Fl l Ar secs Set system-wide performance measurement duration for .Ar secs diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c index 77613b4..c7f36bc 100644 --- a/usr.sbin/pmcstat/pmcstat.c +++ b/usr.sbin/pmcstat/pmcstat.c @@ -557,7 +557,7 @@ main(int argc, char **argv) int c, check_driver_stats, current_sampling_count; int do_callchain, do_descendants, do_logproccsw, do_logprocexit; int do_print, do_read; - size_t dummy; + size_t len; int graphdepth; int pipefd[2], rfd; int use_cumulative_counts; @@ -586,7 +586,6 @@ main(int argc, char **argv) args.pa_verbosity = 1; args.pa_logfd = -1; args.pa_fsroot = ""; - args.pa_kernel = strdup("/boot/kernel"); args.pa_samplesdir = "."; args.pa_printfile = stderr; args.pa_graphdepth = DEFAULT_CALLGRAPH_DEPTH; @@ -610,12 +609,20 @@ main(int argc, char **argv) ev = NULL; CPU_ZERO(&cpumask); + /* Default to using the running system kernel. */ + len = 0; + if (sysctlbyname("kern.bootfile", NULL, &len, NULL, 0) == -1) + err(EX_OSERR, "ERROR: Cannot determine path of running kernel"); + args.pa_kernel = malloc(len + 1); + if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1) + err(EX_OSERR, "ERROR: Cannot determine path of running kernel"); + /* * The initial CPU mask specifies all non-halted CPUS in the * system. */ - dummy = sizeof(int); - if (sysctlbyname("hw.ncpu", &ncpu, &dummy, NULL, 0) < 0) + len = sizeof(int); + if (sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0) < 0) err(EX_OSERR, "ERROR: Cannot determine the number of CPUs"); for (hcpu = 0; hcpu < ncpu; hcpu++) CPU_SET(hcpu, &cpumask); @@ -1061,33 +1068,31 @@ main(int argc, char **argv) ); /* - * Check if "-k kerneldir" was specified, and if whether - * 'kerneldir' actually refers to a file. If so, use - * `dirname path` to determine the kernel directory. + * Check if 'kerneldir' refers to a file rather than a + * directory. If so, use `dirname path` to determine the + * kernel directory. */ - if (args.pa_flags & FLAG_HAS_KERNELPATH) { - (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, - args.pa_kernel); + (void) snprintf(buffer, sizeof(buffer), "%s%s", args.pa_fsroot, + args.pa_kernel); + if (stat(buffer, &sb) < 0) + err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", + buffer); + if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) + errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.", + buffer); + if (!S_ISDIR(sb.st_mode)) { + tmp = args.pa_kernel; + args.pa_kernel = strdup(dirname(args.pa_kernel)); + free(tmp); + (void) snprintf(buffer, sizeof(buffer), "%s%s", + args.pa_fsroot, args.pa_kernel); if (stat(buffer, &sb) < 0) - err(EX_OSERR, "ERROR: Cannot locate kernel \"%s\"", + err(EX_OSERR, "ERROR: Cannot stat \"%s\"", buffer); - if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) - errx(EX_USAGE, "ERROR: \"%s\": Unsupported file type.", + if (!S_ISDIR(sb.st_mode)) + errx(EX_USAGE, + "ERROR: \"%s\" is not a directory.", buffer); - if (!S_ISDIR(sb.st_mode)) { - tmp = args.pa_kernel; - args.pa_kernel = strdup(dirname(args.pa_kernel)); - free(tmp); - (void) snprintf(buffer, sizeof(buffer), "%s%s", - args.pa_fsroot, args.pa_kernel); - if (stat(buffer, &sb) < 0) - err(EX_OSERR, "ERROR: Cannot stat \"%s\"", - buffer); - if (!S_ISDIR(sb.st_mode)) - errx(EX_USAGE, - "ERROR: \"%s\" is not a directory.", - buffer); - } } /* diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index 40de320..8190b28 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -1531,7 +1531,9 @@ pmcstat_analyze_log(void) free(ppm); } - /* associate this process image */ + /* + * Associate this process image. + */ image_path = pmcstat_string_intern( ev.pl_u.pl_x.pl_pathname); assert(image_path != NULL); diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile index 269b145..69953da 100644 --- a/usr.sbin/pw/Makefile +++ b/usr.sbin/pw/Makefile @@ -8,7 +8,7 @@ SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \ WARNS?= 2 -LIBADD= crypt util +LIBADD= crypt util sbuf .include <src.opts.mk> diff --git a/usr.sbin/pw/fileupd.c b/usr.sbin/pw/fileupd.c index 7df4bb1..dc32712 100644 --- a/usr.sbin/pw/fileupd.c +++ b/usr.sbin/pw/fileupd.c @@ -29,32 +29,11 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <stdio.h> -#include <fcntl.h> #include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/param.h> -#include <errno.h> -#include <unistd.h> #include "pwupd.h" int -extendline(char **buf, int * buflen, int needed) -{ - if (needed > *buflen) { - char *tmp = realloc(*buf, needed); - if (tmp == NULL) - return -1; - *buf = tmp; - *buflen = needed; - } - return *buflen; -} - -int extendarray(char ***buf, int * buflen, int needed) { if (needed > *buflen) { diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c index 3f78e95..74cc390 100644 --- a/usr.sbin/pw/grupd.c +++ b/usr.sbin/pw/grupd.c @@ -35,10 +35,6 @@ static const char rcsid[] = #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> #include <sys/param.h> #include "pwupd.h" diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c index 1289b3e..9dce918 100644 --- a/usr.sbin/pw/pw_conf.c +++ b/usr.sbin/pw/pw_conf.c @@ -29,6 +29,8 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include <sys/types.h> +#include <sys/sbuf.h> #include <string.h> #include <ctype.h> #include <fcntl.h> @@ -366,6 +368,7 @@ int write_userconfig(char const * file) { int fd; + struct sbuf *buf; if (file == NULL) file = _PATH_PW_CONF; @@ -376,126 +379,121 @@ write_userconfig(char const * file) if ((fp = fdopen(fd, "w")) == NULL) close(fd); else { - int i, j, k; - int len = LNBUFSZ; - char *buf = malloc(len); - + int i, j; + + buf = sbuf_new_auto(); for (i = _UC_NONE; i < _UC_FIELDS; i++) { int quote = 1; - char const *val = buf; - *buf = '\0'; + sbuf_clear(buf); switch (i) { case _UC_DEFAULTPWD: - val = boolean_str(config.default_password); + sbuf_cat(buf, boolean_str(config.default_password)); break; case _UC_REUSEUID: - val = boolean_str(config.reuse_uids); + sbuf_cat(buf, boolean_str(config.reuse_uids)); break; case _UC_REUSEGID: - val = boolean_str(config.reuse_gids); + sbuf_cat(buf, boolean_str(config.reuse_gids)); break; case _UC_NISPASSWD: - val = config.nispasswd ? config.nispasswd : ""; + sbuf_cat(buf, config.nispasswd ? + config.nispasswd : ""); quote = 0; break; case _UC_DOTDIR: - val = config.dotdir ? config.dotdir : boolean_str(0); + sbuf_cat(buf, config.dotdir ? + config.dotdir : boolean_str(0)); break; case _UC_NEWMAIL: - val = config.newmail ? config.newmail : boolean_str(0); + sbuf_cat(buf, config.newmail ? + config.newmail : boolean_str(0)); break; case _UC_LOGFILE: - val = config.logfile ? config.logfile : boolean_str(0); + sbuf_cat(buf, config.logfile ? + config.logfile : boolean_str(0)); break; case _UC_HOMEROOT: - val = config.home; + sbuf_cat(buf, config.home); break; case _UC_HOMEMODE: - sprintf(buf, "%04o", config.homemode); + sbuf_printf(buf, "%04o", config.homemode); quote = 0; break; case _UC_SHELLPATH: - val = config.shelldir; + sbuf_cat(buf, config.shelldir); break; case _UC_SHELLS: - for (j = k = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) { - char lbuf[64]; - int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", system_shells[j]); - if (l < 0) - l = 0; - if (l + k + 1 < len || extendline(&buf, &len, len + LNBUFSZ) != -1) { - strcpy(buf + k, lbuf); - k += l; - } + for (j = 0; j < _UC_MAXSHELLS && + system_shells[j] != NULL; j++) { + sbuf_printf(buf, "%s\"%s\"", j ? + "," : "", system_shells[j]); } quote = 0; break; case _UC_DEFAULTSHELL: - val = config.shell_default ? config.shell_default : bourne_shell; + sbuf_cat(buf, config.shell_default ? + config.shell_default : bourne_shell); break; case _UC_DEFAULTGROUP: - val = config.default_group ? config.default_group : ""; + sbuf_cat(buf, config.default_group ? + config.default_group : ""); break; case _UC_EXTRAGROUPS: extendarray(&config.groups, &config.numgroups, 200); - for (j = k = 0; j < config.numgroups && config.groups[j] != NULL; j++) { - char lbuf[64]; - int l = snprintf(lbuf, sizeof lbuf, "%s\"%s\"", k ? "," : "", config.groups[j]); - if (l < 0) - l = 0; - if (l + k + 1 < len || extendline(&buf, &len, len + 1024) != -1) { - strcpy(buf + k, lbuf); - k += l; - } - } + for (j = 0; j < config.numgroups && + config.groups[j] != NULL; j++) + sbuf_printf(buf, "%s\"%s\"", j ? + "," : "", config.groups[j]); quote = 0; break; case _UC_DEFAULTCLASS: - val = config.default_class ? config.default_class : ""; + sbuf_cat(buf, config.default_class ? + config.default_class : ""); break; case _UC_MINUID: - sprintf(buf, "%lu", (unsigned long) config.min_uid); + sbuf_printf(buf, "%lu", (unsigned long) config.min_uid); quote = 0; break; case _UC_MAXUID: - sprintf(buf, "%lu", (unsigned long) config.max_uid); + sbuf_printf(buf, "%lu", (unsigned long) config.max_uid); quote = 0; break; case _UC_MINGID: - sprintf(buf, "%lu", (unsigned long) config.min_gid); + sbuf_printf(buf, "%lu", (unsigned long) config.min_gid); quote = 0; break; case _UC_MAXGID: - sprintf(buf, "%lu", (unsigned long) config.max_gid); + sbuf_printf(buf, "%lu", (unsigned long) config.max_gid); quote = 0; break; case _UC_EXPIRE: - sprintf(buf, "%d", config.expire_days); + sbuf_printf(buf, "%d", config.expire_days); quote = 0; break; case _UC_PASSWORD: - sprintf(buf, "%d", config.password_days); + sbuf_printf(buf, "%d", config.password_days); quote = 0; break; case _UC_NONE: break; } + sbuf_finish(buf); if (comments[i]) fputs(comments[i], fp); if (*kwds[i]) { if (quote) - fprintf(fp, "%s = \"%s\"\n", kwds[i], val); + fprintf(fp, "%s = \"%s\"\n", kwds[i], sbuf_data(buf)); else - fprintf(fp, "%s = %s\n", kwds[i], val); + fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf)); #if debugging - printf("WROTE: %s = %s\n", kwds[i], val); + printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf)); #endif } } - free(buf); + sbuf_delete(buf); return fclose(fp) != EOF; } } diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c index 918fc30..c786cc7 100644 --- a/usr.sbin/pw/pw_nis.c +++ b/usr.sbin/pw/pw_nis.c @@ -29,9 +29,6 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <sys/types.h> #include <err.h> #include <pwd.h> diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 483148a..bdb3cd6 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -40,7 +40,6 @@ static const char rcsid[] = #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> -#include <unistd.h> #include <login_cap.h> #include <pwd.h> #include <grp.h> @@ -185,8 +184,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * But we create a symlink from cnf->home -> "/usr" -> cnf->home */ if (strchr(cnf->home+1, '/') == NULL) { - strcpy(dbuf, "/usr"); - strncat(dbuf, cnf->home, MAXPATHLEN-5); + snprintf(dbuf, MAXPATHLEN, "/usr%s", cnf->home); if (mkdir(dbuf, _DEF_DIRMODE) != -1 || errno == EEXIST) { chown(dbuf, 0, 0); /* @@ -364,11 +362,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_LOCK) { if (strncmp(pwd->pw_passwd, locked_str, sizeof(locked_str)-1) == 0) errx(EX_DATAERR, "user '%s' is already locked", pwd->pw_name); - passtmp = malloc(strlen(pwd->pw_passwd) + sizeof(locked_str)); + asprintf(&passtmp, "%s%s", locked_str, pwd->pw_passwd); if (passtmp == NULL) /* disaster */ errx(EX_UNAVAILABLE, "out of memory"); - strcpy(passtmp, locked_str); - strcat(passtmp, pwd->pw_passwd); pwd->pw_passwd = passtmp; edited = 1; } else if (mode == M_UNLOCK) { |