diff --git a/patch/kernel/rockchip64-default/04-patch-4.4.167-168.patch b/patch/kernel/rockchip64-default/04-patch-4.4.167-168.patch new file mode 100644 index 0000000000..32bb254ac6 --- /dev/null +++ b/patch/kernel/rockchip64-default/04-patch-4.4.167-168.patch @@ -0,0 +1,7597 @@ +diff --git a/Documentation/Makefile b/Documentation/Makefile +index fc759598c4c9..59d516b7afcb 100644 +--- a/Documentation/Makefile ++++ b/Documentation/Makefile +@@ -1,4 +1,3 @@ + subdir-y := accounting auxdisplay blackfin connector \ + filesystems filesystems ia64 laptops misc-devices \ +- networking pcmcia prctl ptp spi timers vDSO video4linux \ +- watchdog ++ pcmcia prctl ptp spi timers vDSO video4linux watchdog +diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile +deleted file mode 100644 +index 4c5d7c485439..000000000000 +--- a/Documentation/networking/Makefile ++++ /dev/null +@@ -1 +0,0 @@ +-subdir-y := timestamping +diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore +deleted file mode 100644 +index 9e69e982fb38..000000000000 +--- a/Documentation/networking/timestamping/.gitignore ++++ /dev/null +@@ -1,3 +0,0 @@ +-timestamping +-txtimestamp +-hwtstamp_config +diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile +deleted file mode 100644 +index 8c20dfaa4d6e..000000000000 +--- a/Documentation/networking/timestamping/Makefile ++++ /dev/null +@@ -1,14 +0,0 @@ +-# To compile, from the source root +-# +-# make headers_install +-# make M=documentation +- +-# List of programs to build +-hostprogs-y := hwtstamp_config timestamping txtimestamp +- +-# Tell kbuild to always build the programs +-always := $(hostprogs-y) +- +-HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include +-HOSTCFLAGS_txtimestamp.o += -I$(objtree)/usr/include +-HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include +diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c +deleted file mode 100644 +index e8b685a7f15f..000000000000 +--- a/Documentation/networking/timestamping/hwtstamp_config.c ++++ /dev/null +@@ -1,134 +0,0 @@ +-/* Test program for SIOC{G,S}HWTSTAMP +- * Copyright 2013 Solarflare Communications +- * Author: Ben Hutchings +- */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +-#include +- +-static int +-lookup_value(const char **names, int size, const char *name) +-{ +- int value; +- +- for (value = 0; value < size; value++) +- if (names[value] && strcasecmp(names[value], name) == 0) +- return value; +- +- return -1; +-} +- +-static const char * +-lookup_name(const char **names, int size, int value) +-{ +- return (value >= 0 && value < size) ? names[value] : NULL; +-} +- +-static void list_names(FILE *f, const char **names, int size) +-{ +- int value; +- +- for (value = 0; value < size; value++) +- if (names[value]) +- fprintf(f, " %s\n", names[value]); +-} +- +-static const char *tx_types[] = { +-#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name +- TX_TYPE(OFF), +- TX_TYPE(ON), +- TX_TYPE(ONESTEP_SYNC) +-#undef TX_TYPE +-}; +-#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0]))) +- +-static const char *rx_filters[] = { +-#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name +- RX_FILTER(NONE), +- RX_FILTER(ALL), +- RX_FILTER(SOME), +- RX_FILTER(PTP_V1_L4_EVENT), +- RX_FILTER(PTP_V1_L4_SYNC), +- RX_FILTER(PTP_V1_L4_DELAY_REQ), +- RX_FILTER(PTP_V2_L4_EVENT), +- RX_FILTER(PTP_V2_L4_SYNC), +- RX_FILTER(PTP_V2_L4_DELAY_REQ), +- RX_FILTER(PTP_V2_L2_EVENT), +- RX_FILTER(PTP_V2_L2_SYNC), +- RX_FILTER(PTP_V2_L2_DELAY_REQ), +- RX_FILTER(PTP_V2_EVENT), +- RX_FILTER(PTP_V2_SYNC), +- RX_FILTER(PTP_V2_DELAY_REQ), +-#undef RX_FILTER +-}; +-#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0]))) +- +-static void usage(void) +-{ +- fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n" +- "tx_type is any of (case-insensitive):\n", +- stderr); +- list_names(stderr, tx_types, N_TX_TYPES); +- fputs("rx_filter is any of (case-insensitive):\n", stderr); +- list_names(stderr, rx_filters, N_RX_FILTERS); +-} +- +-int main(int argc, char **argv) +-{ +- struct ifreq ifr; +- struct hwtstamp_config config; +- const char *name; +- int sock; +- +- if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) { +- usage(); +- return 2; +- } +- +- if (argc == 4) { +- config.flags = 0; +- config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]); +- config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]); +- if (config.tx_type < 0 || config.rx_filter < 0) { +- usage(); +- return 2; +- } +- } +- +- sock = socket(AF_INET, SOCK_DGRAM, 0); +- if (sock < 0) { +- perror("socket"); +- return 1; +- } +- +- strcpy(ifr.ifr_name, argv[1]); +- ifr.ifr_data = (caddr_t)&config; +- +- if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) { +- perror("ioctl"); +- return 1; +- } +- +- printf("flags = %#x\n", config.flags); +- name = lookup_name(tx_types, N_TX_TYPES, config.tx_type); +- if (name) +- printf("tx_type = %s\n", name); +- else +- printf("tx_type = %d\n", config.tx_type); +- name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter); +- if (name) +- printf("rx_filter = %s\n", name); +- else +- printf("rx_filter = %d\n", config.rx_filter); +- +- return 0; +-} +diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c +deleted file mode 100644 +index 5cdfd743447b..000000000000 +--- a/Documentation/networking/timestamping/timestamping.c ++++ /dev/null +@@ -1,528 +0,0 @@ +-/* +- * This program demonstrates how the various time stamping features in +- * the Linux kernel work. It emulates the behavior of a PTP +- * implementation in stand-alone master mode by sending PTPv1 Sync +- * multicasts once every second. It looks for similar packets, but +- * beyond that doesn't actually implement PTP. +- * +- * Outgoing packets are time stamped with SO_TIMESTAMPING with or +- * without hardware support. +- * +- * Incoming packets are time stamped with SO_TIMESTAMPING with or +- * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and +- * SO_TIMESTAMP[NS]. +- * +- * Copyright (C) 2009 Intel Corporation. +- * Author: Patrick Ohly +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms and conditions of the GNU General Public License, +- * version 2, as published by the Free Software Foundation. +- * +- * This program is distributed in the hope it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for +- * more details. +- * +- * You should have received a copy of the GNU General Public License along with +- * this program; if not, write to the Free Software Foundation, Inc., +- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +- */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#ifndef SO_TIMESTAMPING +-# define SO_TIMESTAMPING 37 +-# define SCM_TIMESTAMPING SO_TIMESTAMPING +-#endif +- +-#ifndef SO_TIMESTAMPNS +-# define SO_TIMESTAMPNS 35 +-#endif +- +-#ifndef SIOCGSTAMPNS +-# define SIOCGSTAMPNS 0x8907 +-#endif +- +-#ifndef SIOCSHWTSTAMP +-# define SIOCSHWTSTAMP 0x89b0 +-#endif +- +-static void usage(const char *error) +-{ +- if (error) +- printf("invalid option: %s\n", error); +- printf("timestamping interface option*\n\n" +- "Options:\n" +- " IP_MULTICAST_LOOP - looping outgoing multicasts\n" +- " SO_TIMESTAMP - normal software time stamping, ms resolution\n" +- " SO_TIMESTAMPNS - more accurate software time stamping\n" +- " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n" +- " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n" +- " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n" +- " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n" +- " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n" +- " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n" +- " SIOCGSTAMP - check last socket time stamp\n" +- " SIOCGSTAMPNS - more accurate socket time stamp\n"); +- exit(1); +-} +- +-static void bail(const char *error) +-{ +- printf("%s: %s\n", error, strerror(errno)); +- exit(1); +-} +- +-static const unsigned char sync[] = { +- 0x00, 0x01, 0x00, 0x01, +- 0x5f, 0x44, 0x46, 0x4c, +- 0x54, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x01, 0x01, +- +- /* fake uuid */ +- 0x00, 0x01, +- 0x02, 0x03, 0x04, 0x05, +- +- 0x00, 0x01, 0x00, 0x37, +- 0x00, 0x00, 0x00, 0x08, +- 0x00, 0x00, 0x00, 0x00, +- 0x49, 0x05, 0xcd, 0x01, +- 0x29, 0xb1, 0x8d, 0xb0, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x01, +- +- /* fake uuid */ +- 0x00, 0x01, +- 0x02, 0x03, 0x04, 0x05, +- +- 0x00, 0x00, 0x00, 0x37, +- 0x00, 0x00, 0x00, 0x04, +- 0x44, 0x46, 0x4c, 0x54, +- 0x00, 0x00, 0xf0, 0x60, +- 0x00, 0x01, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x01, +- 0x00, 0x00, 0xf0, 0x60, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x04, +- 0x44, 0x46, 0x4c, 0x54, +- 0x00, 0x01, +- +- /* fake uuid */ +- 0x00, 0x01, +- 0x02, 0x03, 0x04, 0x05, +- +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00, +- 0x00, 0x00, 0x00, 0x00 +-}; +- +-static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len) +-{ +- struct timeval now; +- int res; +- +- res = sendto(sock, sync, sizeof(sync), 0, +- addr, addr_len); +- gettimeofday(&now, 0); +- if (res < 0) +- printf("%s: %s\n", "send", strerror(errno)); +- else +- printf("%ld.%06ld: sent %d bytes\n", +- (long)now.tv_sec, (long)now.tv_usec, +- res); +-} +- +-static void printpacket(struct msghdr *msg, int res, +- char *data, +- int sock, int recvmsg_flags, +- int siocgstamp, int siocgstampns) +-{ +- struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name; +- struct cmsghdr *cmsg; +- struct timeval tv; +- struct timespec ts; +- struct timeval now; +- +- gettimeofday(&now, 0); +- +- printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n", +- (long)now.tv_sec, (long)now.tv_usec, +- (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", +- res, +- inet_ntoa(from_addr->sin_addr), +- msg->msg_controllen); +- for (cmsg = CMSG_FIRSTHDR(msg); +- cmsg; +- cmsg = CMSG_NXTHDR(msg, cmsg)) { +- printf(" cmsg len %zu: ", cmsg->cmsg_len); +- switch (cmsg->cmsg_level) { +- case SOL_SOCKET: +- printf("SOL_SOCKET "); +- switch (cmsg->cmsg_type) { +- case SO_TIMESTAMP: { +- struct timeval *stamp = +- (struct timeval *)CMSG_DATA(cmsg); +- printf("SO_TIMESTAMP %ld.%06ld", +- (long)stamp->tv_sec, +- (long)stamp->tv_usec); +- break; +- } +- case SO_TIMESTAMPNS: { +- struct timespec *stamp = +- (struct timespec *)CMSG_DATA(cmsg); +- printf("SO_TIMESTAMPNS %ld.%09ld", +- (long)stamp->tv_sec, +- (long)stamp->tv_nsec); +- break; +- } +- case SO_TIMESTAMPING: { +- struct timespec *stamp = +- (struct timespec *)CMSG_DATA(cmsg); +- printf("SO_TIMESTAMPING "); +- printf("SW %ld.%09ld ", +- (long)stamp->tv_sec, +- (long)stamp->tv_nsec); +- stamp++; +- /* skip deprecated HW transformed */ +- stamp++; +- printf("HW raw %ld.%09ld", +- (long)stamp->tv_sec, +- (long)stamp->tv_nsec); +- break; +- } +- default: +- printf("type %d", cmsg->cmsg_type); +- break; +- } +- break; +- case IPPROTO_IP: +- printf("IPPROTO_IP "); +- switch (cmsg->cmsg_type) { +- case IP_RECVERR: { +- struct sock_extended_err *err = +- (struct sock_extended_err *)CMSG_DATA(cmsg); +- printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s", +- strerror(err->ee_errno), +- err->ee_origin, +-#ifdef SO_EE_ORIGIN_TIMESTAMPING +- err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ? +- "bounced packet" : "unexpected origin" +-#else +- "probably SO_EE_ORIGIN_TIMESTAMPING" +-#endif +- ); +- if (res < sizeof(sync)) +- printf(" => truncated data?!"); +- else if (!memcmp(sync, data + res - sizeof(sync), +- sizeof(sync))) +- printf(" => GOT OUR DATA BACK (HURRAY!)"); +- break; +- } +- case IP_PKTINFO: { +- struct in_pktinfo *pktinfo = +- (struct in_pktinfo *)CMSG_DATA(cmsg); +- printf("IP_PKTINFO interface index %u", +- pktinfo->ipi_ifindex); +- break; +- } +- default: +- printf("type %d", cmsg->cmsg_type); +- break; +- } +- break; +- default: +- printf("level %d type %d", +- cmsg->cmsg_level, +- cmsg->cmsg_type); +- break; +- } +- printf("\n"); +- } +- +- if (siocgstamp) { +- if (ioctl(sock, SIOCGSTAMP, &tv)) +- printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno)); +- else +- printf("SIOCGSTAMP %ld.%06ld\n", +- (long)tv.tv_sec, +- (long)tv.tv_usec); +- } +- if (siocgstampns) { +- if (ioctl(sock, SIOCGSTAMPNS, &ts)) +- printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno)); +- else +- printf("SIOCGSTAMPNS %ld.%09ld\n", +- (long)ts.tv_sec, +- (long)ts.tv_nsec); +- } +-} +- +-static void recvpacket(int sock, int recvmsg_flags, +- int siocgstamp, int siocgstampns) +-{ +- char data[256]; +- struct msghdr msg; +- struct iovec entry; +- struct sockaddr_in from_addr; +- struct { +- struct cmsghdr cm; +- char control[512]; +- } control; +- int res; +- +- memset(&msg, 0, sizeof(msg)); +- msg.msg_iov = &entry; +- msg.msg_iovlen = 1; +- entry.iov_base = data; +- entry.iov_len = sizeof(data); +- msg.msg_name = (caddr_t)&from_addr; +- msg.msg_namelen = sizeof(from_addr); +- msg.msg_control = &control; +- msg.msg_controllen = sizeof(control); +- +- res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT); +- if (res < 0) { +- printf("%s %s: %s\n", +- "recvmsg", +- (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", +- strerror(errno)); +- } else { +- printpacket(&msg, res, data, +- sock, recvmsg_flags, +- siocgstamp, siocgstampns); +- } +-} +- +-int main(int argc, char **argv) +-{ +- int so_timestamping_flags = 0; +- int so_timestamp = 0; +- int so_timestampns = 0; +- int siocgstamp = 0; +- int siocgstampns = 0; +- int ip_multicast_loop = 0; +- char *interface; +- int i; +- int enabled = 1; +- int sock; +- struct ifreq device; +- struct ifreq hwtstamp; +- struct hwtstamp_config hwconfig, hwconfig_requested; +- struct sockaddr_in addr; +- struct ip_mreq imr; +- struct in_addr iaddr; +- int val; +- socklen_t len; +- struct timeval next; +- +- if (argc < 2) +- usage(0); +- interface = argv[1]; +- +- for (i = 2; i < argc; i++) { +- if (!strcasecmp(argv[i], "SO_TIMESTAMP")) +- so_timestamp = 1; +- else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS")) +- so_timestampns = 1; +- else if (!strcasecmp(argv[i], "SIOCGSTAMP")) +- siocgstamp = 1; +- else if (!strcasecmp(argv[i], "SIOCGSTAMPNS")) +- siocgstampns = 1; +- else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP")) +- ip_multicast_loop = 1; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE; +- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE")) +- so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE; +- else +- usage(argv[i]); +- } +- +- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +- if (sock < 0) +- bail("socket"); +- +- memset(&device, 0, sizeof(device)); +- strncpy(device.ifr_name, interface, sizeof(device.ifr_name)); +- if (ioctl(sock, SIOCGIFADDR, &device) < 0) +- bail("getting interface IP address"); +- +- memset(&hwtstamp, 0, sizeof(hwtstamp)); +- strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name)); +- hwtstamp.ifr_data = (void *)&hwconfig; +- memset(&hwconfig, 0, sizeof(hwconfig)); +- hwconfig.tx_type = +- (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ? +- HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; +- hwconfig.rx_filter = +- (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ? +- HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE; +- hwconfig_requested = hwconfig; +- if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) { +- if ((errno == EINVAL || errno == ENOTSUP) && +- hwconfig_requested.tx_type == HWTSTAMP_TX_OFF && +- hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE) +- printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n"); +- else +- bail("SIOCSHWTSTAMP"); +- } +- printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n", +- hwconfig_requested.tx_type, hwconfig.tx_type, +- hwconfig_requested.rx_filter, hwconfig.rx_filter); +- +- /* bind to PTP port */ +- addr.sin_family = AF_INET; +- addr.sin_addr.s_addr = htonl(INADDR_ANY); +- addr.sin_port = htons(319 /* PTP event port */); +- if (bind(sock, +- (struct sockaddr *)&addr, +- sizeof(struct sockaddr_in)) < 0) +- bail("bind"); +- +- /* set multicast group for outgoing packets */ +- inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */ +- addr.sin_addr = iaddr; +- imr.imr_multiaddr.s_addr = iaddr.s_addr; +- imr.imr_interface.s_addr = +- ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr; +- if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, +- &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0) +- bail("set multicast"); +- +- /* join multicast group, loop our own packet */ +- if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, +- &imr, sizeof(struct ip_mreq)) < 0) +- bail("join multicast group"); +- +- if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, +- &ip_multicast_loop, sizeof(enabled)) < 0) { +- bail("loop multicast"); +- } +- +- /* set socket options for time stamping */ +- if (so_timestamp && +- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, +- &enabled, sizeof(enabled)) < 0) +- bail("setsockopt SO_TIMESTAMP"); +- +- if (so_timestampns && +- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, +- &enabled, sizeof(enabled)) < 0) +- bail("setsockopt SO_TIMESTAMPNS"); +- +- if (so_timestamping_flags && +- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, +- &so_timestamping_flags, +- sizeof(so_timestamping_flags)) < 0) +- bail("setsockopt SO_TIMESTAMPING"); +- +- /* request IP_PKTINFO for debugging purposes */ +- if (setsockopt(sock, SOL_IP, IP_PKTINFO, +- &enabled, sizeof(enabled)) < 0) +- printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno)); +- +- /* verify socket options */ +- len = sizeof(val); +- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0) +- printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno)); +- else +- printf("SO_TIMESTAMP %d\n", val); +- +- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0) +- printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS", +- strerror(errno)); +- else +- printf("SO_TIMESTAMPNS %d\n", val); +- +- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) { +- printf("%s: %s\n", "getsockopt SO_TIMESTAMPING", +- strerror(errno)); +- } else { +- printf("SO_TIMESTAMPING %d\n", val); +- if (val != so_timestamping_flags) +- printf(" not the expected value %d\n", +- so_timestamping_flags); +- } +- +- /* send packets forever every five seconds */ +- gettimeofday(&next, 0); +- next.tv_sec = (next.tv_sec + 1) / 5 * 5; +- next.tv_usec = 0; +- while (1) { +- struct timeval now; +- struct timeval delta; +- long delta_us; +- int res; +- fd_set readfs, errorfs; +- +- gettimeofday(&now, 0); +- delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 + +- (long)(next.tv_usec - now.tv_usec); +- if (delta_us > 0) { +- /* continue waiting for timeout or data */ +- delta.tv_sec = delta_us / 1000000; +- delta.tv_usec = delta_us % 1000000; +- +- FD_ZERO(&readfs); +- FD_ZERO(&errorfs); +- FD_SET(sock, &readfs); +- FD_SET(sock, &errorfs); +- printf("%ld.%06ld: select %ldus\n", +- (long)now.tv_sec, (long)now.tv_usec, +- delta_us); +- res = select(sock + 1, &readfs, 0, &errorfs, &delta); +- gettimeofday(&now, 0); +- printf("%ld.%06ld: select returned: %d, %s\n", +- (long)now.tv_sec, (long)now.tv_usec, +- res, +- res < 0 ? strerror(errno) : "success"); +- if (res > 0) { +- if (FD_ISSET(sock, &readfs)) +- printf("ready for reading\n"); +- if (FD_ISSET(sock, &errorfs)) +- printf("has error\n"); +- recvpacket(sock, 0, +- siocgstamp, +- siocgstampns); +- recvpacket(sock, MSG_ERRQUEUE, +- siocgstamp, +- siocgstampns); +- } +- } else { +- /* write one packet */ +- sendpacket(sock, +- (struct sockaddr *)&addr, +- sizeof(addr)); +- next.tv_sec += 5; +- continue; +- } +- } +- +- return 0; +-} +diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c +deleted file mode 100644 +index 5df07047ca86..000000000000 +--- a/Documentation/networking/timestamping/txtimestamp.c ++++ /dev/null +@@ -1,549 +0,0 @@ +-/* +- * Copyright 2014 Google Inc. +- * Author: willemb@google.com (Willem de Bruijn) +- * +- * Test software tx timestamping, including +- * +- * - SCHED, SND and ACK timestamps +- * - RAW, UDP and TCP +- * - IPv4 and IPv6 +- * - various packet sizes (to test GSO and TSO) +- * +- * Consult the command line arguments for help on running +- * the various testcases. +- * +- * This test requires a dummy TCP server. +- * A simple `nc6 [-u] -l -p $DESTPORT` will do +- * +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms and conditions of the GNU General Public License, +- * version 2, as published by the Free Software Foundation. +- * +- * This program is distributed in the hope it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for +- * more details. +- * +- * You should have received a copy of the GNU General Public License along with +- * this program; if not, write to the Free Software Foundation, Inc., +- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +- */ +- +-#define _GNU_SOURCE +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* command line parameters */ +-static int cfg_proto = SOCK_STREAM; +-static int cfg_ipproto = IPPROTO_TCP; +-static int cfg_num_pkts = 4; +-static int do_ipv4 = 1; +-static int do_ipv6 = 1; +-static int cfg_payload_len = 10; +-static bool cfg_show_payload; +-static bool cfg_do_pktinfo; +-static bool cfg_loop_nodata; +-static uint16_t dest_port = 9000; +- +-static struct sockaddr_in daddr; +-static struct sockaddr_in6 daddr6; +-static struct timespec ts_prev; +- +-static void __print_timestamp(const char *name, struct timespec *cur, +- uint32_t key, int payload_len) +-{ +- if (!(cur->tv_sec | cur->tv_nsec)) +- return; +- +- fprintf(stderr, " %s: %lu s %lu us (seq=%u, len=%u)", +- name, cur->tv_sec, cur->tv_nsec / 1000, +- key, payload_len); +- +- if ((ts_prev.tv_sec | ts_prev.tv_nsec)) { +- int64_t cur_ms, prev_ms; +- +- cur_ms = (long) cur->tv_sec * 1000 * 1000; +- cur_ms += cur->tv_nsec / 1000; +- +- prev_ms = (long) ts_prev.tv_sec * 1000 * 1000; +- prev_ms += ts_prev.tv_nsec / 1000; +- +- fprintf(stderr, " (%+" PRId64 " us)", cur_ms - prev_ms); +- } +- +- ts_prev = *cur; +- fprintf(stderr, "\n"); +-} +- +-static void print_timestamp_usr(void) +-{ +- struct timespec ts; +- struct timeval tv; /* avoid dependency on -lrt */ +- +- gettimeofday(&tv, NULL); +- ts.tv_sec = tv.tv_sec; +- ts.tv_nsec = tv.tv_usec * 1000; +- +- __print_timestamp(" USR", &ts, 0, 0); +-} +- +-static void print_timestamp(struct scm_timestamping *tss, int tstype, +- int tskey, int payload_len) +-{ +- const char *tsname; +- +- switch (tstype) { +- case SCM_TSTAMP_SCHED: +- tsname = " ENQ"; +- break; +- case SCM_TSTAMP_SND: +- tsname = " SND"; +- break; +- case SCM_TSTAMP_ACK: +- tsname = " ACK"; +- break; +- default: +- error(1, 0, "unknown timestamp type: %u", +- tstype); +- } +- __print_timestamp(tsname, &tss->ts[0], tskey, payload_len); +-} +- +-/* TODO: convert to check_and_print payload once API is stable */ +-static void print_payload(char *data, int len) +-{ +- int i; +- +- if (!len) +- return; +- +- if (len > 70) +- len = 70; +- +- fprintf(stderr, "payload: "); +- for (i = 0; i < len; i++) +- fprintf(stderr, "%02hhx ", data[i]); +- fprintf(stderr, "\n"); +-} +- +-static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr) +-{ +- char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN]; +- +- fprintf(stderr, " pktinfo: ifindex=%u src=%s dst=%s\n", +- ifindex, +- saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown", +- daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown"); +-} +- +-static void __poll(int fd) +-{ +- struct pollfd pollfd; +- int ret; +- +- memset(&pollfd, 0, sizeof(pollfd)); +- pollfd.fd = fd; +- ret = poll(&pollfd, 1, 100); +- if (ret != 1) +- error(1, errno, "poll"); +-} +- +-static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len) +-{ +- struct sock_extended_err *serr = NULL; +- struct scm_timestamping *tss = NULL; +- struct cmsghdr *cm; +- int batch = 0; +- +- for (cm = CMSG_FIRSTHDR(msg); +- cm && cm->cmsg_len; +- cm = CMSG_NXTHDR(msg, cm)) { +- if (cm->cmsg_level == SOL_SOCKET && +- cm->cmsg_type == SCM_TIMESTAMPING) { +- tss = (void *) CMSG_DATA(cm); +- } else if ((cm->cmsg_level == SOL_IP && +- cm->cmsg_type == IP_RECVERR) || +- (cm->cmsg_level == SOL_IPV6 && +- cm->cmsg_type == IPV6_RECVERR)) { +- serr = (void *) CMSG_DATA(cm); +- if (serr->ee_errno != ENOMSG || +- serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { +- fprintf(stderr, "unknown ip error %d %d\n", +- serr->ee_errno, +- serr->ee_origin); +- serr = NULL; +- } +- } else if (cm->cmsg_level == SOL_IP && +- cm->cmsg_type == IP_PKTINFO) { +- struct in_pktinfo *info = (void *) CMSG_DATA(cm); +- print_pktinfo(AF_INET, info->ipi_ifindex, +- &info->ipi_spec_dst, &info->ipi_addr); +- } else if (cm->cmsg_level == SOL_IPV6 && +- cm->cmsg_type == IPV6_PKTINFO) { +- struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm); +- print_pktinfo(AF_INET6, info6->ipi6_ifindex, +- NULL, &info6->ipi6_addr); +- } else +- fprintf(stderr, "unknown cmsg %d,%d\n", +- cm->cmsg_level, cm->cmsg_type); +- +- if (serr && tss) { +- print_timestamp(tss, serr->ee_info, serr->ee_data, +- payload_len); +- serr = NULL; +- tss = NULL; +- batch++; +- } +- } +- +- if (batch > 1) +- fprintf(stderr, "batched %d timestamps\n", batch); +-} +- +-static int recv_errmsg(int fd) +-{ +- static char ctrl[1024 /* overprovision*/]; +- static struct msghdr msg; +- struct iovec entry; +- static char *data; +- int ret = 0; +- +- data = malloc(cfg_payload_len); +- if (!data) +- error(1, 0, "malloc"); +- +- memset(&msg, 0, sizeof(msg)); +- memset(&entry, 0, sizeof(entry)); +- memset(ctrl, 0, sizeof(ctrl)); +- +- entry.iov_base = data; +- entry.iov_len = cfg_payload_len; +- msg.msg_iov = &entry; +- msg.msg_iovlen = 1; +- msg.msg_name = NULL; +- msg.msg_namelen = 0; +- msg.msg_control = ctrl; +- msg.msg_controllen = sizeof(ctrl); +- +- ret = recvmsg(fd, &msg, MSG_ERRQUEUE); +- if (ret == -1 && errno != EAGAIN) +- error(1, errno, "recvmsg"); +- +- if (ret >= 0) { +- __recv_errmsg_cmsg(&msg, ret); +- if (cfg_show_payload) +- print_payload(data, cfg_payload_len); +- } +- +- free(data); +- return ret == -1; +-} +- +-static void do_test(int family, unsigned int opt) +-{ +- char *buf; +- int fd, i, val = 1, total_len; +- +- if (family == AF_INET6 && cfg_proto != SOCK_STREAM) { +- /* due to lack of checksum generation code */ +- fprintf(stderr, "test: skipping datagram over IPv6\n"); +- return; +- } +- +- total_len = cfg_payload_len; +- if (cfg_proto == SOCK_RAW) { +- total_len += sizeof(struct udphdr); +- if (cfg_ipproto == IPPROTO_RAW) +- total_len += sizeof(struct iphdr); +- } +- +- buf = malloc(total_len); +- if (!buf) +- error(1, 0, "malloc"); +- +- fd = socket(family, cfg_proto, cfg_ipproto); +- if (fd < 0) +- error(1, errno, "socket"); +- +- if (cfg_proto == SOCK_STREAM) { +- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, +- (char*) &val, sizeof(val))) +- error(1, 0, "setsockopt no nagle"); +- +- if (family == PF_INET) { +- if (connect(fd, (void *) &daddr, sizeof(daddr))) +- error(1, errno, "connect ipv4"); +- } else { +- if (connect(fd, (void *) &daddr6, sizeof(daddr6))) +- error(1, errno, "connect ipv6"); +- } +- } +- +- if (cfg_do_pktinfo) { +- if (family == AF_INET6) { +- if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO, +- &val, sizeof(val))) +- error(1, errno, "setsockopt pktinfo ipv6"); +- } else { +- if (setsockopt(fd, SOL_IP, IP_PKTINFO, +- &val, sizeof(val))) +- error(1, errno, "setsockopt pktinfo ipv4"); +- } +- } +- +- opt |= SOF_TIMESTAMPING_SOFTWARE | +- SOF_TIMESTAMPING_OPT_CMSG | +- SOF_TIMESTAMPING_OPT_ID; +- if (cfg_loop_nodata) +- opt |= SOF_TIMESTAMPING_OPT_TSONLY; +- +- if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, +- (char *) &opt, sizeof(opt))) +- error(1, 0, "setsockopt timestamping"); +- +- for (i = 0; i < cfg_num_pkts; i++) { +- memset(&ts_prev, 0, sizeof(ts_prev)); +- memset(buf, 'a' + i, total_len); +- +- if (cfg_proto == SOCK_RAW) { +- struct udphdr *udph; +- int off = 0; +- +- if (cfg_ipproto == IPPROTO_RAW) { +- struct iphdr *iph = (void *) buf; +- +- memset(iph, 0, sizeof(*iph)); +- iph->ihl = 5; +- iph->version = 4; +- iph->ttl = 2; +- iph->daddr = daddr.sin_addr.s_addr; +- iph->protocol = IPPROTO_UDP; +- /* kernel writes saddr, csum, len */ +- +- off = sizeof(*iph); +- } +- +- udph = (void *) buf + off; +- udph->source = ntohs(9000); /* random spoof */ +- udph->dest = ntohs(dest_port); +- udph->len = ntohs(sizeof(*udph) + cfg_payload_len); +- udph->check = 0; /* not allowed for IPv6 */ +- } +- +- print_timestamp_usr(); +- if (cfg_proto != SOCK_STREAM) { +- if (family == PF_INET) +- val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr)); +- else +- val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6)); +- } else { +- val = send(fd, buf, cfg_payload_len, 0); +- } +- if (val != total_len) +- error(1, errno, "send"); +- +- /* wait for all errors to be queued, else ACKs arrive OOO */ +- usleep(50 * 1000); +- +- __poll(fd); +- +- while (!recv_errmsg(fd)) {} +- } +- +- if (close(fd)) +- error(1, errno, "close"); +- +- free(buf); +- usleep(400 * 1000); +-} +- +-static void __attribute__((noreturn)) usage(const char *filepath) +-{ +- fprintf(stderr, "\nUsage: %s [options] hostname\n" +- "\nwhere options are:\n" +- " -4: only IPv4\n" +- " -6: only IPv6\n" +- " -h: show this message\n" +- " -I: request PKTINFO\n" +- " -l N: send N bytes at a time\n" +- " -n: set no-payload option\n" +- " -r: use raw\n" +- " -R: use raw (IP_HDRINCL)\n" +- " -p N: connect to port N\n" +- " -u: use udp\n" +- " -x: show payload (up to 70 bytes)\n", +- filepath); +- exit(1); +-} +- +-static void parse_opt(int argc, char **argv) +-{ +- int proto_count = 0; +- char c; +- +- while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) { +- switch (c) { +- case '4': +- do_ipv6 = 0; +- break; +- case '6': +- do_ipv4 = 0; +- break; +- case 'I': +- cfg_do_pktinfo = true; +- break; +- case 'n': +- cfg_loop_nodata = true; +- break; +- case 'r': +- proto_count++; +- cfg_proto = SOCK_RAW; +- cfg_ipproto = IPPROTO_UDP; +- break; +- case 'R': +- proto_count++; +- cfg_proto = SOCK_RAW; +- cfg_ipproto = IPPROTO_RAW; +- break; +- case 'u': +- proto_count++; +- cfg_proto = SOCK_DGRAM; +- cfg_ipproto = IPPROTO_UDP; +- break; +- case 'l': +- cfg_payload_len = strtoul(optarg, NULL, 10); +- break; +- case 'p': +- dest_port = strtoul(optarg, NULL, 10); +- break; +- case 'x': +- cfg_show_payload = true; +- break; +- case 'h': +- default: +- usage(argv[0]); +- } +- } +- +- if (!cfg_payload_len) +- error(1, 0, "payload may not be nonzero"); +- if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472) +- error(1, 0, "udp packet might exceed expected MTU"); +- if (!do_ipv4 && !do_ipv6) +- error(1, 0, "pass -4 or -6, not both"); +- if (proto_count > 1) +- error(1, 0, "pass -r, -R or -u, not multiple"); +- +- if (optind != argc - 1) +- error(1, 0, "missing required hostname argument"); +-} +- +-static void resolve_hostname(const char *hostname) +-{ +- struct addrinfo *addrs, *cur; +- int have_ipv4 = 0, have_ipv6 = 0; +- +- if (getaddrinfo(hostname, NULL, NULL, &addrs)) +- error(1, errno, "getaddrinfo"); +- +- cur = addrs; +- while (cur && !have_ipv4 && !have_ipv6) { +- if (!have_ipv4 && cur->ai_family == AF_INET) { +- memcpy(&daddr, cur->ai_addr, sizeof(daddr)); +- daddr.sin_port = htons(dest_port); +- have_ipv4 = 1; +- } +- else if (!have_ipv6 && cur->ai_family == AF_INET6) { +- memcpy(&daddr6, cur->ai_addr, sizeof(daddr6)); +- daddr6.sin6_port = htons(dest_port); +- have_ipv6 = 1; +- } +- cur = cur->ai_next; +- } +- if (addrs) +- freeaddrinfo(addrs); +- +- do_ipv4 &= have_ipv4; +- do_ipv6 &= have_ipv6; +-} +- +-static void do_main(int family) +-{ +- fprintf(stderr, "family: %s\n", +- family == PF_INET ? "INET" : "INET6"); +- +- fprintf(stderr, "test SND\n"); +- do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE); +- +- fprintf(stderr, "test ENQ\n"); +- do_test(family, SOF_TIMESTAMPING_TX_SCHED); +- +- fprintf(stderr, "test ENQ + SND\n"); +- do_test(family, SOF_TIMESTAMPING_TX_SCHED | +- SOF_TIMESTAMPING_TX_SOFTWARE); +- +- if (cfg_proto == SOCK_STREAM) { +- fprintf(stderr, "\ntest ACK\n"); +- do_test(family, SOF_TIMESTAMPING_TX_ACK); +- +- fprintf(stderr, "\ntest SND + ACK\n"); +- do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE | +- SOF_TIMESTAMPING_TX_ACK); +- +- fprintf(stderr, "\ntest ENQ + SND + ACK\n"); +- do_test(family, SOF_TIMESTAMPING_TX_SCHED | +- SOF_TIMESTAMPING_TX_SOFTWARE | +- SOF_TIMESTAMPING_TX_ACK); +- } +-} +- +-const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" }; +- +-int main(int argc, char **argv) +-{ +- if (argc == 1) +- usage(argv[0]); +- +- parse_opt(argc, argv); +- resolve_hostname(argv[argc - 1]); +- +- fprintf(stderr, "protocol: %s\n", sock_names[cfg_proto]); +- fprintf(stderr, "payload: %u\n", cfg_payload_len); +- fprintf(stderr, "server port: %u\n", dest_port); +- fprintf(stderr, "\n"); +- +- if (do_ipv4) +- do_main(PF_INET); +- if (do_ipv6) +- do_main(PF_INET6); +- +- return 0; +-} +diff --git a/Makefile b/Makefile +index 6b30551caee4..082f82471b51 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 167 ++SUBLEVEL = 168 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c +index a95499ea8706..fa1d41edce68 100644 +--- a/arch/arm/mach-omap1/board-ams-delta.c ++++ b/arch/arm/mach-omap1/board-ams-delta.c +@@ -511,6 +511,9 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old) + { + struct modem_private_data *priv = port->private_data; + ++ if (!priv) ++ return; ++ + if (IS_ERR(priv->regulator)) + return; + +diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c +index 30768003f854..8c505284bc0c 100644 +--- a/arch/arm/mach-omap2/prm44xx.c ++++ b/arch/arm/mach-omap2/prm44xx.c +@@ -344,7 +344,7 @@ static void omap44xx_prm_reconfigure_io_chain(void) + * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and + * omap44xx_prm_reconfigure_io_chain() must be called. No return value. + */ +-static void __init omap44xx_prm_enable_io_wakeup(void) ++static void omap44xx_prm_enable_io_wakeup(void) + { + s32 inst = omap4_prmst_get_prm_dev_inst(); + +diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c +index 877da1908234..98e2a5dbcfda 100644 +--- a/arch/cris/arch-v32/drivers/cryptocop.c ++++ b/arch/cris/arch-v32/drivers/cryptocop.c +@@ -2724,7 +2724,6 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig + (unsigned long int)(oper.indata + prev_ix), + noinpages, + 0, /* read access only for in data */ +- 0, /* no force */ + inpages, + NULL); + +@@ -2740,8 +2739,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig + current->mm, + (unsigned long int)oper.cipher_outdata, + nooutpages, +- 1, /* write access for out data */ +- 0, /* no force */ ++ FOLL_WRITE, /* write access for out data */ + outpages, + NULL); + up_read(¤t->mm->mmap_sem); +diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c +index 0c161ed6d18e..8205b456de7a 100644 +--- a/arch/ia64/kernel/err_inject.c ++++ b/arch/ia64/kernel/err_inject.c +@@ -143,7 +143,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr, + int ret; + + ret = get_user_pages(current, current->mm, virt_addr, +- 1, VM_READ, 0, NULL, NULL); ++ 1, FOLL_WRITE, NULL, NULL); + if (ret<=0) { + #ifdef ERR_INJ_DEBUG + printk("Virtual address %lx is not existing.\n",virt_addr); +diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c +index 349995d19c7f..e596e0a1cecc 100644 +--- a/arch/mips/mm/gup.c ++++ b/arch/mips/mm/gup.c +@@ -303,7 +303,7 @@ slow_irqon: + + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, +- write, 0, pages); ++ pages, write ? FOLL_WRITE : 0); + + /* Have to be a bit careful with return values */ + if (nr > 0) { +diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c +index 929c147e07b4..1b69bfdf59f9 100644 +--- a/arch/s390/kernel/perf_cpum_cf.c ++++ b/arch/s390/kernel/perf_cpum_cf.c +@@ -344,6 +344,8 @@ static int __hw_perf_event_init(struct perf_event *event) + break; + + case PERF_TYPE_HARDWARE: ++ if (is_sampling_event(event)) /* No sampling support */ ++ return -ENOENT; + ev = attr->config; + /* Count user space (problem-state) only */ + if (!attr->exclude_user && attr->exclude_kernel) { +diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c +index 12bbf0e8478f..7ad41be8b373 100644 +--- a/arch/s390/mm/gup.c ++++ b/arch/s390/mm/gup.c +@@ -242,7 +242,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, + start += nr << PAGE_SHIFT; + pages += nr; + ret = get_user_pages_unlocked(current, mm, start, +- nr_pages - nr, write, 0, pages); ++ nr_pages - nr, pages, write ? FOLL_WRITE : 0); + /* Have to be a bit careful with return values */ + if (nr > 0) + ret = (ret < 0) ? nr : ret + nr; +diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c +index e7af6a65baab..8c51a0e94854 100644 +--- a/arch/sh/mm/gup.c ++++ b/arch/sh/mm/gup.c +@@ -258,7 +258,8 @@ slow_irqon: + pages += nr; + + ret = get_user_pages_unlocked(current, mm, start, +- (end - start) >> PAGE_SHIFT, write, 0, pages); ++ (end - start) >> PAGE_SHIFT, pages, ++ write ? FOLL_WRITE : 0); + + /* Have to be a bit careful with return values */ + if (nr > 0) { +diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c +index 2e5c4fc2daa9..150f48303fb0 100644 +--- a/arch/sparc/mm/gup.c ++++ b/arch/sparc/mm/gup.c +@@ -250,7 +250,8 @@ slow: + pages += nr; + + ret = get_user_pages_unlocked(current, mm, start, +- (end - start) >> PAGE_SHIFT, write, 0, pages); ++ (end - start) >> PAGE_SHIFT, pages, ++ write ? FOLL_WRITE : 0); + + /* Have to be a bit careful with return values */ + if (nr > 0) { +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 3a37cdbdfbaa..c048d0d70cc4 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -765,7 +765,7 @@ struct kvm_x86_ops { + int (*hardware_setup)(void); /* __init */ + void (*hardware_unsetup)(void); /* __exit */ + bool (*cpu_has_accelerated_tpr)(void); +- bool (*cpu_has_high_real_mode_segbase)(void); ++ bool (*has_emulated_msr)(int index); + void (*cpuid_update)(struct kvm_vcpu *vcpu); + + /* Create, but do not attach this VCPU */ +diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h +index d788b0cdc0ad..6f8eadf0681f 100644 +--- a/arch/x86/include/asm/uaccess.h ++++ b/arch/x86/include/asm/uaccess.h +@@ -144,9 +144,14 @@ extern int __get_user_4(void); + extern int __get_user_8(void); + extern int __get_user_bad(void); + + #define __uaccess_begin() stac() + #define __uaccess_end() clac() ++#define __uaccess_begin_nospec() \ ++({ \ ++ stac(); \ ++ barrier_nospec(); \ ++}) + + /* + * This is a type: either unsigned long, if the argument fits into + * that type, or otherwise unsigned long long. +@@ -423,9 +428,9 @@ do { \ + ({ \ + int __gu_err; \ + unsigned long __gu_val; \ +- __uaccess_begin(); \ ++ __uaccess_begin_nospec(); \ + __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ + __uaccess_end(); \ + (x) = (__force __typeof__(*(ptr)))__gu_val; \ + __builtin_expect(__gu_err, 0); \ + }) +@@ -471,11 +476,15 @@ struct __large_struct { unsigned long buf[100]; }; + */ + #define uaccess_try do { \ + current_thread_info()->uaccess_err = 0; \ + __uaccess_begin(); \ + barrier(); + ++#define uaccess_try_nospec do { \ ++ current_thread_info()->uaccess_err = 0; \ ++ __uaccess_begin_nospec(); \ ++ + #define uaccess_catch(err) \ + __uaccess_end(); \ + (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \ + } while (0) + +@@ -537,7 +546,7 @@ struct __large_struct { unsigned long buf[100]; }; + * get_user_ex(...); + * } get_user_catch(err) + */ +-#define get_user_try uaccess_try ++#define get_user_try uaccess_try_nospec + #define get_user_catch(err) uaccess_catch(err) + + #define get_user_ex(x, ptr) do { \ +@@ -572,12 +581,12 @@ extern void __cmpxchg_wrong_size(void) + __typeof__(ptr) __uval = (uval); \ + __typeof__(*(ptr)) __old = (old); \ + __typeof__(*(ptr)) __new = (new); \ +- __uaccess_begin(); \ ++ __uaccess_begin_nospec(); \ + switch (size) { \ + case 1: \ + { \ + asm volatile("\n" \ + "1:\t" LOCK_PREFIX "cmpxchgb %4, %2\n" \ + "2:\n" \ + "\t.section .fixup, \"ax\"\n" \ + "3:\tmov %3, %0\n" \ + "\tjmp 2b\n" \ +diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h +index f5dcb5204dcd..f575ee3aea5c 100644 +--- a/arch/x86/include/asm/uaccess_32.h ++++ b/arch/x86/include/asm/uaccess_32.h +@@ -102,19 +102,19 @@ __copy_from_user(void *to, const void __user *from, unsigned long n) + + switch (n) { + case 1: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u8 *)to, from, 1, ret, 1); + __uaccess_end(); + return ret; + case 2: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u16 *)to, from, 2, ret, 2); + __uaccess_end(); + return ret; + case 4: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u32 *)to, from, 4, ret, 4); + __uaccess_end(); + return ret; + } + } +@@ -130,19 +130,19 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to, + + switch (n) { + case 1: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u8 *)to, from, 1, ret, 1); + __uaccess_end(); + return ret; + case 2: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u16 *)to, from, 2, ret, 2); + __uaccess_end(); + return ret; + case 4: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_size(*(u32 *)to, from, 4, ret, 4); + __uaccess_end(); + return ret; + } + } +diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h +index d83a55b95a48..dc2d00e7ced3 100644 +--- a/arch/x86/include/asm/uaccess_64.h ++++ b/arch/x86/include/asm/uaccess_64.h +@@ -57,49 +57,49 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size) + if (!__builtin_constant_p(size)) + return copy_user_generic(dst, (__force void *)src, size); + switch (size) { + case 1: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u8 *)dst, (u8 __user *)src, + ret, "b", "b", "=q", 1); + __uaccess_end(); + return ret; + case 2: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u16 *)dst, (u16 __user *)src, + ret, "w", "w", "=r", 2); + __uaccess_end(); + return ret; + case 4: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u32 *)dst, (u32 __user *)src, + ret, "l", "k", "=r", 4); + __uaccess_end(); + return ret; + case 8: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u64 *)dst, (u64 __user *)src, + ret, "q", "", "=r", 8); + __uaccess_end(); + return ret; + case 10: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u64 *)dst, (u64 __user *)src, + ret, "q", "", "=r", 10); + if (likely(!ret)) + __get_user_asm(*(u16 *)(8 + (char *)dst), + (u16 __user *)(8 + (char __user *)src), + ret, "w", "w", "=r", 2); + __uaccess_end(); + return ret; + case 16: +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(*(u64 *)dst, (u64 __user *)src, + ret, "q", "", "=r", 16); + if (likely(!ret)) + __get_user_asm(*(u64 *)(8 + (char *)dst), + (u64 __user *)(8 + (char __user *)src), + ret, "q", "", "=r", 8); + __uaccess_end(); + return ret; + default: + return copy_user_generic(dst, (__force void *)src, size); +@@ -192,47 +192,47 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) + switch (size) { + case 1: { + u8 tmp; +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(tmp, (u8 __user *)src, + ret, "b", "b", "=q", 1); + if (likely(!ret)) + __put_user_asm(tmp, (u8 __user *)dst, + ret, "b", "b", "iq", 1); + __uaccess_end(); + return ret; + } + case 2: { + u16 tmp; +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(tmp, (u16 __user *)src, + ret, "w", "w", "=r", 2); + if (likely(!ret)) + __put_user_asm(tmp, (u16 __user *)dst, + ret, "w", "w", "ir", 2); + __uaccess_end(); + return ret; + } + + case 4: { + u32 tmp; +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(tmp, (u32 __user *)src, + ret, "l", "k", "=r", 4); + if (likely(!ret)) + __put_user_asm(tmp, (u32 __user *)dst, + ret, "l", "k", "ir", 4); + __uaccess_end(); + return ret; + } + case 8: { + u64 tmp; +- __uaccess_begin(); ++ __uaccess_begin_nospec(); + __get_user_asm(tmp, (u64 __user *)src, + ret, "q", "", "=r", 8); + if (likely(!ret)) + __put_user_asm(tmp, (u64 __user *)dst, + ret, "q", "", "er", 8); + __uaccess_end(); + return ret; + } + default: +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c +index b12c0287d6cf..e8b46f575306 100644 +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -693,7 +693,8 @@ static void init_speculation_control(struct cpuinfo_x86 *c) + if (cpu_has(c, X86_FEATURE_INTEL_STIBP)) + set_cpu_cap(c, X86_FEATURE_STIBP); + +- if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD)) ++ if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) || ++ cpu_has(c, X86_FEATURE_VIRT_SSBD)) + set_cpu_cap(c, X86_FEATURE_SSBD); + + if (cpu_has(c, X86_FEATURE_AMD_IBRS)) { +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index 338d13d4fd2f..b857bb9f6f23 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -341,6 +341,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + F(3DNOWPREFETCH) | F(OSVW) | 0 /* IBS */ | F(XOP) | + 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM); + ++ /* cpuid 0x80000008.ebx */ ++ const u32 kvm_cpuid_8000_0008_ebx_x86_features = ++ F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD); ++ + /* cpuid 0xC0000001.edx */ + const u32 kvm_supported_word5_x86_features = + F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) | +@@ -358,6 +362,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + const u32 kvm_supported_word10_x86_features = + F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves; + ++ /* cpuid 7.0.edx*/ ++ const u32 kvm_cpuid_7_0_edx_x86_features = ++ F(SPEC_CTRL) | F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES); ++ + /* all calls to cpuid_count() should be made on the same cpu */ + get_cpu(); + +@@ -435,11 +443,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + cpuid_mask(&entry->ebx, 9); + // TSC_ADJUST is emulated + entry->ebx |= F(TSC_ADJUST); +- } else ++ entry->edx &= kvm_cpuid_7_0_edx_x86_features; ++ cpuid_mask(&entry->edx, CPUID_7_EDX); ++ } else { + entry->ebx = 0; ++ entry->edx = 0; ++ } + entry->eax = 0; + entry->ecx = 0; +- entry->edx = 0; + break; + } + case 9: +@@ -583,7 +594,21 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, + if (!g_phys_as) + g_phys_as = phys_as; + entry->eax = g_phys_as | (virt_as << 8); +- entry->ebx = entry->edx = 0; ++ entry->edx = 0; ++ /* ++ * IBRS, IBPB and VIRT_SSBD aren't necessarily present in ++ * hardware cpuid ++ */ ++ if (boot_cpu_has(X86_FEATURE_AMD_IBPB)) ++ entry->ebx |= F(AMD_IBPB); ++ if (boot_cpu_has(X86_FEATURE_AMD_IBRS)) ++ entry->ebx |= F(AMD_IBRS); ++ if (boot_cpu_has(X86_FEATURE_VIRT_SSBD)) ++ entry->ebx |= F(VIRT_SSBD); ++ entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features; ++ cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX); ++ if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD)) ++ entry->ebx |= F(VIRT_SSBD); + break; + } + case 0x80000019: +diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h +index d1534feefcfe..72f159f4d456 100644 +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -159,6 +159,46 @@ static inline bool guest_cpuid_has_rdtscp(struct kvm_vcpu *vcpu) + return best && (best->edx & bit(X86_FEATURE_RDTSCP)); + } + ++static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu) ++{ ++ struct kvm_cpuid_entry2 *best; ++ ++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); ++ if (best && (best->ebx & bit(X86_FEATURE_AMD_IBPB))) ++ return true; ++ best = kvm_find_cpuid_entry(vcpu, 7, 0); ++ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL)); ++} ++ ++static inline bool guest_cpuid_has_spec_ctrl(struct kvm_vcpu *vcpu) ++{ ++ struct kvm_cpuid_entry2 *best; ++ ++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); ++ if (best && (best->ebx & bit(X86_FEATURE_AMD_IBRS))) ++ return true; ++ best = kvm_find_cpuid_entry(vcpu, 7, 0); ++ return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SPEC_CTRL_SSBD))); ++} ++ ++static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu) ++{ ++ struct kvm_cpuid_entry2 *best; ++ ++ best = kvm_find_cpuid_entry(vcpu, 7, 0); ++ return best && (best->edx & bit(X86_FEATURE_ARCH_CAPABILITIES)); ++} ++ ++static inline bool guest_cpuid_has_virt_ssbd(struct kvm_vcpu *vcpu) ++{ ++ struct kvm_cpuid_entry2 *best; ++ ++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0); ++ return best && (best->ebx & bit(X86_FEATURE_VIRT_SSBD)); ++} ++ ++ ++ + /* + * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3 + */ +diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c +index a1afd80a68aa..3c70f6c76d3a 100644 +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -56,7 +56,7 @@ + #define APIC_BUS_CYCLE_NS 1 + + /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ +-#define apic_debug(fmt, arg...) ++#define apic_debug(fmt, arg...) do {} while (0) + + #define APIC_LVT_NUM 6 + /* 14 is the version for Xeon and Pentium 8.4.8*/ +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index df7827a981dd..ecdf724da371 100644 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -147,6 +148,14 @@ struct vcpu_svm { + u64 gs_base; + } host; + ++ u64 spec_ctrl; ++ /* ++ * Contains guest-controlled bits of VIRT_SPEC_CTRL, which will be ++ * translated into the appropriate L2_CFG bits on the host to ++ * perform speculative control. ++ */ ++ u64 virt_spec_ctrl; ++ + u32 *msrpm; + + ulong nmi_iret_rip; +@@ -182,6 +191,8 @@ static const struct svm_direct_access_msrs { + { .index = MSR_CSTAR, .always = true }, + { .index = MSR_SYSCALL_MASK, .always = true }, + #endif ++ { .index = MSR_IA32_SPEC_CTRL, .always = false }, ++ { .index = MSR_IA32_PRED_CMD, .always = false }, + { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false }, + { .index = MSR_IA32_LASTBRANCHTOIP, .always = false }, + { .index = MSR_IA32_LASTINTFROMIP, .always = false }, +@@ -411,6 +422,7 @@ struct svm_cpu_data { + struct kvm_ldttss_desc *tss_desc; + + struct page *save_area; ++ struct vmcb *current_vmcb; + }; + + static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); +@@ -762,6 +774,25 @@ static bool valid_msr_intercept(u32 index) + return false; + } + ++static bool msr_write_intercepted(struct kvm_vcpu *vcpu, unsigned msr) ++{ ++ u8 bit_write; ++ unsigned long tmp; ++ u32 offset; ++ u32 *msrpm; ++ ++ msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm: ++ to_svm(vcpu)->msrpm; ++ ++ offset = svm_msrpm_offset(msr); ++ bit_write = 2 * (msr & 0x0f) + 1; ++ tmp = msrpm[offset]; ++ ++ BUG_ON(offset == MSR_INVALID); ++ ++ return !!test_bit(bit_write, &tmp); ++} ++ + static void set_msr_interception(u32 *msrpm, unsigned msr, + int read, int write) + { +@@ -1120,6 +1151,9 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) + u32 dummy; + u32 eax = 1; + ++ svm->spec_ctrl = 0; ++ svm->virt_spec_ctrl = 0; ++ + if (!init_event) { + svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE | + MSR_IA32_APICBASE_ENABLE; +@@ -1210,11 +1244,17 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) + __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER); + kvm_vcpu_uninit(vcpu); + kmem_cache_free(kvm_vcpu_cache, svm); ++ /* ++ * The vmcb page can be recycled, causing a false negative in ++ * svm_vcpu_load(). So do a full IBPB now. ++ */ ++ indirect_branch_prediction_barrier(); + } + + static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + { + struct vcpu_svm *svm = to_svm(vcpu); ++ struct svm_cpu_data *sd = per_cpu(svm_data, cpu); + int i; + + if (unlikely(cpu != vcpu->cpu)) { +@@ -1239,6 +1279,10 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio); + } + } ++ if (sd->current_vmcb != svm->vmcb) { ++ sd->current_vmcb = svm->vmcb; ++ indirect_branch_prediction_barrier(); ++ } + } + + static void svm_vcpu_put(struct kvm_vcpu *vcpu) +@@ -3051,6 +3095,20 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + case MSR_VM_CR: + msr_info->data = svm->nested.vm_cr_msr; + break; ++ case MSR_IA32_SPEC_CTRL: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_spec_ctrl(vcpu)) ++ return 1; ++ ++ msr_info->data = svm->spec_ctrl; ++ break; ++ case MSR_AMD64_VIRT_SPEC_CTRL: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_virt_ssbd(vcpu)) ++ return 1; ++ ++ msr_info->data = svm->virt_spec_ctrl; ++ break; + case MSR_IA32_UCODE_REV: + msr_info->data = 0x01000065; + break; +@@ -3125,6 +3183,59 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) + case MSR_IA32_TSC: + kvm_write_tsc(vcpu, msr); + break; ++ case MSR_IA32_SPEC_CTRL: ++ if (!msr->host_initiated && ++ !guest_cpuid_has_spec_ctrl(vcpu)) ++ return 1; ++ ++ /* The STIBP bit doesn't fault even if it's not advertised */ ++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) ++ return 1; ++ ++ svm->spec_ctrl = data; ++ ++ if (!data) ++ break; ++ ++ /* ++ * For non-nested: ++ * When it's written (to non-zero) for the first time, pass ++ * it through. ++ * ++ * For nested: ++ * The handling of the MSR bitmap for L2 guests is done in ++ * nested_svm_vmrun_msrpm. ++ * We update the L1 MSR bit as well since it will end up ++ * touching the MSR anyway now. ++ */ ++ set_msr_interception(svm->msrpm, MSR_IA32_SPEC_CTRL, 1, 1); ++ break; ++ case MSR_IA32_PRED_CMD: ++ if (!msr->host_initiated && ++ !guest_cpuid_has_ibpb(vcpu)) ++ return 1; ++ ++ if (data & ~PRED_CMD_IBPB) ++ return 1; ++ ++ if (!data) ++ break; ++ ++ wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB); ++ if (is_guest_mode(vcpu)) ++ break; ++ set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1); ++ break; ++ case MSR_AMD64_VIRT_SPEC_CTRL: ++ if (!msr->host_initiated && ++ !guest_cpuid_has_virt_ssbd(vcpu)) ++ return 1; ++ ++ if (data & ~SPEC_CTRL_SSBD) ++ return 1; ++ ++ svm->virt_spec_ctrl = data; ++ break; + case MSR_STAR: + svm->vmcb->save.star = data; + break; +@@ -3811,6 +3922,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) + + local_irq_enable(); + ++ /* ++ * If this vCPU has touched SPEC_CTRL, restore the guest's value if ++ * it's non-zero. Since vmentry is serialising on affected CPUs, there ++ * is no need to worry about the conditional branch over the wrmsr ++ * being speculatively taken. ++ */ ++ x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); ++ + asm volatile ( + "push %%" _ASM_BP "; \n\t" + "mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t" +@@ -3915,6 +4034,26 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) + #endif + #endif + ++ /* ++ * We do not use IBRS in the kernel. If this vCPU has used the ++ * SPEC_CTRL MSR it may have left it on; save the value and ++ * turn it off. This is much more efficient than blindly adding ++ * it to the atomic save/restore list. Especially as the former ++ * (Saving guest MSRs on vmexit) doesn't even exist in KVM. ++ * ++ * For non-nested case: ++ * If the L01 MSR bitmap does not intercept the MSR, then we need to ++ * save it. ++ * ++ * For nested case: ++ * If the L02 MSR bitmap does not intercept the MSR, then we need to ++ * save it. ++ */ ++ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)) ++ svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); ++ ++ x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl); ++ + reload_tss(vcpu); + + local_irq_disable(); +@@ -4015,7 +4154,7 @@ static bool svm_cpu_has_accelerated_tpr(void) + return false; + } + +-static bool svm_has_high_real_mode_segbase(void) ++static bool svm_has_emulated_msr(int index) + { + return true; + } +@@ -4299,7 +4438,7 @@ static struct kvm_x86_ops svm_x86_ops = { + .hardware_enable = svm_hardware_enable, + .hardware_disable = svm_hardware_disable, + .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr, +- .cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase, ++ .has_emulated_msr = svm_has_emulated_msr, + + .vcpu_create = svm_create_vcpu, + .vcpu_free = svm_free_vcpu, +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index c5a4b1978cbf..e4b5fd72ca24 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + #include + + #include "trace.h" +@@ -109,6 +110,14 @@ static u64 __read_mostly host_xss; + static bool __read_mostly enable_pml = 1; + module_param_named(pml, enable_pml, bool, S_IRUGO); + ++#define MSR_TYPE_R 1 ++#define MSR_TYPE_W 2 ++#define MSR_TYPE_RW 3 ++ ++#define MSR_BITMAP_MODE_X2APIC 1 ++#define MSR_BITMAP_MODE_X2APIC_APICV 2 ++#define MSR_BITMAP_MODE_LM 4 ++ + #define KVM_VMX_TSC_MULTIPLIER_MAX 0xffffffffffffffffULL + + #define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD) +@@ -172,7 +181,6 @@ module_param(ple_window_max, int, S_IRUGO); + extern const ulong vmx_return; + + #define NR_AUTOLOAD_MSRS 8 +-#define VMCS02_POOL_SIZE 1 + + struct vmcs { + u32 revision_id; +@@ -189,6 +197,7 @@ struct loaded_vmcs { + struct vmcs *vmcs; + int cpu; + int launched; ++ unsigned long *msr_bitmap; + struct list_head loaded_vmcss_on_cpu_link; + }; + +@@ -205,7 +214,7 @@ struct shared_msr_entry { + * stored in guest memory specified by VMPTRLD, but is opaque to the guest, + * which must access it using VMREAD/VMWRITE/VMCLEAR instructions. + * More than one of these structures may exist, if L1 runs multiple L2 guests. +- * nested_vmx_run() will use the data here to build a vmcs02: a VMCS for the ++ * nested_vmx_run() will use the data here to build the vmcs02: a VMCS for the + * underlying hardware which will be used to run L2. + * This structure is packed to ensure that its layout is identical across + * machines (necessary for live migration). +@@ -384,13 +393,6 @@ struct __packed vmcs12 { + */ + #define VMCS12_SIZE 0x1000 + +-/* Used to remember the last vmcs02 used for some recently used vmcs12s */ +-struct vmcs02_list { +- struct list_head list; +- gpa_t vmptr; +- struct loaded_vmcs vmcs02; +-}; +- + /* + * The nested_vmx structure is part of vcpu_vmx, and holds information we need + * for correct emulation of VMX (i.e., nested VMX) on this vcpu. +@@ -412,16 +414,16 @@ struct nested_vmx { + */ + bool sync_shadow_vmcs; + +- /* vmcs02_list cache of VMCSs recently used to run L2 guests */ +- struct list_head vmcs02_pool; +- int vmcs02_num; + u64 vmcs01_tsc_offset; + bool change_vmcs01_virtual_x2apic_mode; + /* L2 must run next, and mustn't decide to exit to L1. */ + bool nested_run_pending; ++ ++ struct loaded_vmcs vmcs02; ++ + /* +- * Guest pages referred to in vmcs02 with host-physical pointers, so +- * we must keep them pinned while L2 runs. ++ * Guest pages referred to in the vmcs02 with host-physical ++ * pointers, so we must keep them pinned while L2 runs. + */ + struct page *apic_access_page; + struct page *virtual_apic_page; +@@ -531,6 +533,7 @@ struct vcpu_vmx { + unsigned long host_rsp; + u8 fail; + bool nmi_known_unmasked; ++ u8 msr_bitmap_mode; + u32 exit_intr_info; + u32 idt_vectoring_info; + ulong rflags; +@@ -542,6 +545,10 @@ struct vcpu_vmx { + u64 msr_host_kernel_gs_base; + u64 msr_guest_kernel_gs_base; + #endif ++ ++ u64 arch_capabilities; ++ u64 spec_ctrl; ++ + u32 vm_entry_controls_shadow; + u32 vm_exit_controls_shadow; + /* +@@ -889,6 +896,9 @@ static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu); + static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx); + static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx); + static int alloc_identity_pagetable(struct kvm *kvm); ++static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); ++static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, ++ u32 msr, int type); + + static DEFINE_PER_CPU(struct vmcs *, vmxarea); + static DEFINE_PER_CPU(struct vmcs *, current_vmcs); +@@ -908,11 +918,6 @@ static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock); + + static unsigned long *vmx_io_bitmap_a; + static unsigned long *vmx_io_bitmap_b; +-static unsigned long *vmx_msr_bitmap_legacy; +-static unsigned long *vmx_msr_bitmap_longmode; +-static unsigned long *vmx_msr_bitmap_legacy_x2apic; +-static unsigned long *vmx_msr_bitmap_longmode_x2apic; +-static unsigned long *vmx_msr_bitmap_nested; + static unsigned long *vmx_vmread_bitmap; + static unsigned long *vmx_vmwrite_bitmap; + +@@ -1689,6 +1694,52 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu) + vmcs_write32(EXCEPTION_BITMAP, eb); + } + ++/* ++ * Check if MSR is intercepted for currently loaded MSR bitmap. ++ */ ++static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) ++{ ++ unsigned long *msr_bitmap; ++ int f = sizeof(unsigned long); ++ ++ if (!cpu_has_vmx_msr_bitmap()) ++ return true; ++ ++ msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap; ++ ++ if (msr <= 0x1fff) { ++ return !!test_bit(msr, msr_bitmap + 0x800 / f); ++ } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { ++ msr &= 0x1fff; ++ return !!test_bit(msr, msr_bitmap + 0xc00 / f); ++ } ++ ++ return true; ++} ++ ++/* ++ * Check if MSR is intercepted for L01 MSR bitmap. ++ */ ++static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr) ++{ ++ unsigned long *msr_bitmap; ++ int f = sizeof(unsigned long); ++ ++ if (!cpu_has_vmx_msr_bitmap()) ++ return true; ++ ++ msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap; ++ ++ if (msr <= 0x1fff) { ++ return !!test_bit(msr, msr_bitmap + 0x800 / f); ++ } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { ++ msr &= 0x1fff; ++ return !!test_bit(msr, msr_bitmap + 0xc00 / f); ++ } ++ ++ return true; ++} ++ + static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx, + unsigned long entry, unsigned long exit) + { +@@ -2074,6 +2125,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + if (per_cpu(current_vmcs, cpu) != vmx->loaded_vmcs->vmcs) { + per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs; + vmcs_load(vmx->loaded_vmcs->vmcs); ++ indirect_branch_prediction_barrier(); + } + + if (vmx->loaded_vmcs->cpu != cpu) { +@@ -2353,27 +2405,6 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) + vmx->guest_msrs[from] = tmp; + } + +-static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) +-{ +- unsigned long *msr_bitmap; +- +- if (is_guest_mode(vcpu)) +- msr_bitmap = vmx_msr_bitmap_nested; +- else if (vcpu->arch.apic_base & X2APIC_ENABLE) { +- if (is_long_mode(vcpu)) +- msr_bitmap = vmx_msr_bitmap_longmode_x2apic; +- else +- msr_bitmap = vmx_msr_bitmap_legacy_x2apic; +- } else { +- if (is_long_mode(vcpu)) +- msr_bitmap = vmx_msr_bitmap_longmode; +- else +- msr_bitmap = vmx_msr_bitmap_legacy; +- } +- +- vmcs_write64(MSR_BITMAP, __pa(msr_bitmap)); +-} +- + /* + * Set up the vmcs to automatically save and restore system + * msrs. Don't touch the 64-bit msrs if the guest is in legacy +@@ -2414,7 +2445,7 @@ static void setup_msrs(struct vcpu_vmx *vmx) + vmx->save_nmsrs = save_nmsrs; + + if (cpu_has_vmx_msr_bitmap()) +- vmx_set_msr_bitmap(&vmx->vcpu); ++ vmx_update_msr_bitmap(&vmx->vcpu); + } + + /* +@@ -2828,6 +2859,19 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + case MSR_IA32_TSC: + msr_info->data = guest_read_tsc(vcpu); + break; ++ case MSR_IA32_SPEC_CTRL: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_spec_ctrl(vcpu)) ++ return 1; ++ ++ msr_info->data = to_vmx(vcpu)->spec_ctrl; ++ break; ++ case MSR_IA32_ARCH_CAPABILITIES: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_arch_capabilities(vcpu)) ++ return 1; ++ msr_info->data = to_vmx(vcpu)->arch_capabilities; ++ break; + case MSR_IA32_SYSENTER_CS: + msr_info->data = vmcs_read32(GUEST_SYSENTER_CS); + break; +@@ -2927,6 +2971,68 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) + case MSR_IA32_TSC: + kvm_write_tsc(vcpu, msr_info); + break; ++ case MSR_IA32_SPEC_CTRL: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_spec_ctrl(vcpu)) ++ return 1; ++ ++ /* The STIBP bit doesn't fault even if it's not advertised */ ++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD)) ++ return 1; ++ ++ vmx->spec_ctrl = data; ++ ++ if (!data) ++ break; ++ ++ /* ++ * For non-nested: ++ * When it's written (to non-zero) for the first time, pass ++ * it through. ++ * ++ * For nested: ++ * The handling of the MSR bitmap for L2 guests is done in ++ * nested_vmx_merge_msr_bitmap. We should not touch the ++ * vmcs02.msr_bitmap here since it gets completely overwritten ++ * in the merging. We update the vmcs01 here for L1 as well ++ * since it will end up touching the MSR anyway now. ++ */ ++ vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, ++ MSR_IA32_SPEC_CTRL, ++ MSR_TYPE_RW); ++ break; ++ case MSR_IA32_PRED_CMD: ++ if (!msr_info->host_initiated && ++ !guest_cpuid_has_ibpb(vcpu)) ++ return 1; ++ ++ if (data & ~PRED_CMD_IBPB) ++ return 1; ++ ++ if (!data) ++ break; ++ ++ wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB); ++ ++ /* ++ * For non-nested: ++ * When it's written (to non-zero) for the first time, pass ++ * it through. ++ * ++ * For nested: ++ * The handling of the MSR bitmap for L2 guests is done in ++ * nested_vmx_merge_msr_bitmap. We should not touch the ++ * vmcs02.msr_bitmap here since it gets completely overwritten ++ * in the merging. ++ */ ++ vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD, ++ MSR_TYPE_W); ++ break; ++ case MSR_IA32_ARCH_CAPABILITIES: ++ if (!msr_info->host_initiated) ++ return 1; ++ vmx->arch_capabilities = data; ++ break; + case MSR_IA32_CR_PAT: + if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { + if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data)) +@@ -3352,11 +3458,6 @@ static struct vmcs *alloc_vmcs_cpu(int cpu) + return vmcs; + } + +-static struct vmcs *alloc_vmcs(void) +-{ +- return alloc_vmcs_cpu(raw_smp_processor_id()); +-} +- + static void free_vmcs(struct vmcs *vmcs) + { + free_pages((unsigned long)vmcs, vmcs_config.order); +@@ -3372,6 +3473,34 @@ static void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) + loaded_vmcs_clear(loaded_vmcs); + free_vmcs(loaded_vmcs->vmcs); + loaded_vmcs->vmcs = NULL; ++ if (loaded_vmcs->msr_bitmap) ++ free_page((unsigned long)loaded_vmcs->msr_bitmap); ++} ++ ++static struct vmcs *alloc_vmcs(void) ++{ ++ return alloc_vmcs_cpu(raw_smp_processor_id()); ++} ++ ++static int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs) ++{ ++ loaded_vmcs->vmcs = alloc_vmcs(); ++ if (!loaded_vmcs->vmcs) ++ return -ENOMEM; ++ ++ loaded_vmcs_init(loaded_vmcs); ++ ++ if (cpu_has_vmx_msr_bitmap()) { ++ loaded_vmcs->msr_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); ++ if (!loaded_vmcs->msr_bitmap) ++ goto out_vmcs; ++ memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE); ++ } ++ return 0; ++ ++out_vmcs: ++ free_loaded_vmcs(loaded_vmcs); ++ return -ENOMEM; + } + + static void free_kvm_area(void) +@@ -4370,10 +4499,8 @@ static void free_vpid(int vpid) + spin_unlock(&vmx_vpid_lock); + } + +-#define MSR_TYPE_R 1 +-#define MSR_TYPE_W 2 +-static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, +- u32 msr, int type) ++static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, ++ u32 msr, int type) + { + int f = sizeof(unsigned long); + +@@ -4407,8 +4534,8 @@ static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, + } + } + +-static void __vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, +- u32 msr, int type) ++static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, ++ u32 msr, int type) + { + int f = sizeof(unsigned long); + +@@ -4488,37 +4615,76 @@ static void nested_vmx_disable_intercept_for_msr(unsigned long *msr_bitmap_l1, + } + } + +-static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only) ++static void __always_inline vmx_set_intercept_for_msr(unsigned long *msr_bitmap, ++ u32 msr, int type, bool value) + { +- if (!longmode_only) +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy, +- msr, MSR_TYPE_R | MSR_TYPE_W); +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode, +- msr, MSR_TYPE_R | MSR_TYPE_W); ++ if (value) ++ vmx_enable_intercept_for_msr(msr_bitmap, msr, type); ++ else ++ vmx_disable_intercept_for_msr(msr_bitmap, msr, type); + } + +-static void vmx_enable_intercept_msr_read_x2apic(u32 msr) ++static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu) + { +- __vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, +- msr, MSR_TYPE_R); +- __vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, +- msr, MSR_TYPE_R); ++ u8 mode = 0; ++ ++ if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { ++ mode |= MSR_BITMAP_MODE_X2APIC; ++ if (enable_apicv) ++ mode |= MSR_BITMAP_MODE_X2APIC_APICV; ++ } ++ ++ if (is_long_mode(vcpu)) ++ mode |= MSR_BITMAP_MODE_LM; ++ ++ return mode; + } + +-static void vmx_disable_intercept_msr_read_x2apic(u32 msr) ++#define X2APIC_MSR(r) (APIC_BASE_MSR + ((r) >> 4)) ++ ++static void vmx_update_msr_bitmap_x2apic(unsigned long *msr_bitmap, ++ u8 mode) + { +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, +- msr, MSR_TYPE_R); +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, +- msr, MSR_TYPE_R); ++ int msr; ++ ++ for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) { ++ unsigned word = msr / BITS_PER_LONG; ++ msr_bitmap[word] = (mode & MSR_BITMAP_MODE_X2APIC_APICV) ? 0 : ~0; ++ msr_bitmap[word + (0x800 / sizeof(long))] = ~0; ++ } ++ ++ if (mode & MSR_BITMAP_MODE_X2APIC) { ++ /* ++ * TPR reads and writes can be virtualized even if virtual interrupt ++ * delivery is not in use. ++ */ ++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_RW); ++ if (mode & MSR_BITMAP_MODE_X2APIC_APICV) { ++ vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_ID), MSR_TYPE_R); ++ vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R); ++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_EOI), MSR_TYPE_W); ++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W); ++ } ++ } + } + +-static void vmx_disable_intercept_msr_write_x2apic(u32 msr) ++static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu) + { +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, +- msr, MSR_TYPE_W); +- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, +- msr, MSR_TYPE_W); ++ struct vcpu_vmx *vmx = to_vmx(vcpu); ++ unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap; ++ u8 mode = vmx_msr_bitmap_mode(vcpu); ++ u8 changed = mode ^ vmx->msr_bitmap_mode; ++ ++ if (!changed) ++ return; ++ ++ vmx_set_intercept_for_msr(msr_bitmap, MSR_KERNEL_GS_BASE, MSR_TYPE_RW, ++ !(mode & MSR_BITMAP_MODE_LM)); ++ ++ if (changed & (MSR_BITMAP_MODE_X2APIC | MSR_BITMAP_MODE_X2APIC_APICV)) ++ vmx_update_msr_bitmap_x2apic(msr_bitmap, mode); ++ ++ vmx->msr_bitmap_mode = mode; + } + + static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu) +@@ -4526,6 +4692,28 @@ static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu) + return enable_apicv && lapic_in_kernel(vcpu); + } + ++static void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu) ++{ ++ struct vmcs12 *vmcs12 = get_vmcs12(vcpu); ++ gfn_t gfn; ++ ++ /* ++ * Don't need to mark the APIC access page dirty; it is never ++ * written to by the CPU during APIC virtualization. ++ */ ++ ++ if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) { ++ gfn = vmcs12->virtual_apic_page_addr >> PAGE_SHIFT; ++ kvm_vcpu_mark_page_dirty(vcpu, gfn); ++ } ++ ++ if (nested_cpu_has_posted_intr(vmcs12)) { ++ gfn = vmcs12->posted_intr_desc_addr >> PAGE_SHIFT; ++ kvm_vcpu_mark_page_dirty(vcpu, gfn); ++ } ++} ++ ++ + static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + { + struct vcpu_vmx *vmx = to_vmx(vcpu); +@@ -4533,18 +4721,15 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + void *vapic_page; + u16 status; + +- if (vmx->nested.pi_desc && +- vmx->nested.pi_pending) { +- vmx->nested.pi_pending = false; +- if (!pi_test_and_clear_on(vmx->nested.pi_desc)) +- return; +- +- max_irr = find_last_bit( +- (unsigned long *)vmx->nested.pi_desc->pir, 256); ++ if (!vmx->nested.pi_desc || !vmx->nested.pi_pending) ++ return; + +- if (max_irr == 256) +- return; ++ vmx->nested.pi_pending = false; ++ if (!pi_test_and_clear_on(vmx->nested.pi_desc)) ++ return; + ++ max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256); ++ if (max_irr != 256) { + vapic_page = kmap(vmx->nested.virtual_apic_page); + __kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page); + kunmap(vmx->nested.virtual_apic_page); +@@ -4556,6 +4741,8 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu) + vmcs_write16(GUEST_INTR_STATUS, status); + } + } ++ ++ nested_mark_vmcs12_pages_dirty(vcpu); + } + + static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu) +@@ -4818,7 +5005,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) + vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap)); + } + if (cpu_has_vmx_msr_bitmap()) +- vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_legacy)); ++ vmcs_write64(MSR_BITMAP, __pa(vmx->vmcs01.msr_bitmap)); + + vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */ + +@@ -4890,6 +5077,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) + ++vmx->nmsrs; + } + ++ if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) ++ rdmsrl(MSR_IA32_ARCH_CAPABILITIES, vmx->arch_capabilities); + + vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl); + +@@ -4918,6 +5107,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) + u64 cr0; + + vmx->rmode.vm86_active = 0; ++ vmx->spec_ctrl = 0; + + vmx->soft_vnmi_blocked = 0; + +@@ -6159,7 +6349,7 @@ static void wakeup_handler(void) + + static __init int hardware_setup(void) + { +- int r = -ENOMEM, i, msr; ++ int r = -ENOMEM, i; + + rdmsrl_safe(MSR_EFER, &host_efer); + +@@ -6174,38 +6364,13 @@ static __init int hardware_setup(void) + if (!vmx_io_bitmap_b) + goto out; + +- vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL); +- if (!vmx_msr_bitmap_legacy) +- goto out1; +- +- vmx_msr_bitmap_legacy_x2apic = +- (unsigned long *)__get_free_page(GFP_KERNEL); +- if (!vmx_msr_bitmap_legacy_x2apic) +- goto out2; +- +- vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); +- if (!vmx_msr_bitmap_longmode) +- goto out3; +- +- vmx_msr_bitmap_longmode_x2apic = +- (unsigned long *)__get_free_page(GFP_KERNEL); +- if (!vmx_msr_bitmap_longmode_x2apic) +- goto out4; +- +- if (nested) { +- vmx_msr_bitmap_nested = +- (unsigned long *)__get_free_page(GFP_KERNEL); +- if (!vmx_msr_bitmap_nested) +- goto out5; +- } +- + vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_vmread_bitmap) +- goto out6; ++ goto out1; + + vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!vmx_vmwrite_bitmap) +- goto out7; ++ goto out2; + + memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); + memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); +@@ -6214,14 +6379,9 @@ static __init int hardware_setup(void) + + memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE); + +- memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE); +- memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE); +- if (nested) +- memset(vmx_msr_bitmap_nested, 0xff, PAGE_SIZE); +- + if (setup_vmcs_config(&vmcs_config) < 0) { + r = -EIO; +- goto out8; ++ goto out3; + } + + if (boot_cpu_has(X86_FEATURE_NX)) +@@ -6287,38 +6447,8 @@ static __init int hardware_setup(void) + kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; + } + +- vmx_disable_intercept_for_msr(MSR_FS_BASE, false); +- vmx_disable_intercept_for_msr(MSR_GS_BASE, false); +- vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true); +- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); +- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); +- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); +- +- memcpy(vmx_msr_bitmap_legacy_x2apic, +- vmx_msr_bitmap_legacy, PAGE_SIZE); +- memcpy(vmx_msr_bitmap_longmode_x2apic, +- vmx_msr_bitmap_longmode, PAGE_SIZE); +- + set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */ + +- if (enable_apicv) { +- for (msr = 0x800; msr <= 0x8ff; msr++) +- vmx_disable_intercept_msr_read_x2apic(msr); +- +- /* According SDM, in x2apic mode, the whole id reg is used. +- * But in KVM, it only use the highest eight bits. Need to +- * intercept it */ +- vmx_enable_intercept_msr_read_x2apic(0x802); +- /* TMCCT */ +- vmx_enable_intercept_msr_read_x2apic(0x839); +- /* TPR */ +- vmx_disable_intercept_msr_write_x2apic(0x808); +- /* EOI */ +- vmx_disable_intercept_msr_write_x2apic(0x80b); +- /* SELF-IPI */ +- vmx_disable_intercept_msr_write_x2apic(0x83f); +- } +- + if (enable_ept) { + kvm_mmu_set_mask_ptes(0ull, + (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull, +@@ -6349,21 +6479,10 @@ static __init int hardware_setup(void) + + return alloc_kvm_area(); + +-out8: +- free_page((unsigned long)vmx_vmwrite_bitmap); +-out7: +- free_page((unsigned long)vmx_vmread_bitmap); +-out6: +- if (nested) +- free_page((unsigned long)vmx_msr_bitmap_nested); +-out5: +- free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); +-out4: +- free_page((unsigned long)vmx_msr_bitmap_longmode); + out3: +- free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); ++ free_page((unsigned long)vmx_vmwrite_bitmap); + out2: +- free_page((unsigned long)vmx_msr_bitmap_legacy); ++ free_page((unsigned long)vmx_vmread_bitmap); + out1: + free_page((unsigned long)vmx_io_bitmap_b); + out: +@@ -6374,16 +6493,10 @@ out: + + static __exit void hardware_unsetup(void) + { +- free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); +- free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); +- free_page((unsigned long)vmx_msr_bitmap_legacy); +- free_page((unsigned long)vmx_msr_bitmap_longmode); + free_page((unsigned long)vmx_io_bitmap_b); + free_page((unsigned long)vmx_io_bitmap_a); + free_page((unsigned long)vmx_vmwrite_bitmap); + free_page((unsigned long)vmx_vmread_bitmap); +- if (nested) +- free_page((unsigned long)vmx_msr_bitmap_nested); + + free_kvm_area(); + } +@@ -6426,93 +6539,6 @@ static int handle_monitor(struct kvm_vcpu *vcpu) + return handle_nop(vcpu); + } + +-/* +- * To run an L2 guest, we need a vmcs02 based on the L1-specified vmcs12. +- * We could reuse a single VMCS for all the L2 guests, but we also want the +- * option to allocate a separate vmcs02 for each separate loaded vmcs12 - this +- * allows keeping them loaded on the processor, and in the future will allow +- * optimizations where prepare_vmcs02 doesn't need to set all the fields on +- * every entry if they never change. +- * So we keep, in vmx->nested.vmcs02_pool, a cache of size VMCS02_POOL_SIZE +- * (>=0) with a vmcs02 for each recently loaded vmcs12s, most recent first. +- * +- * The following functions allocate and free a vmcs02 in this pool. +- */ +- +-/* Get a VMCS from the pool to use as vmcs02 for the current vmcs12. */ +-static struct loaded_vmcs *nested_get_current_vmcs02(struct vcpu_vmx *vmx) +-{ +- struct vmcs02_list *item; +- list_for_each_entry(item, &vmx->nested.vmcs02_pool, list) +- if (item->vmptr == vmx->nested.current_vmptr) { +- list_move(&item->list, &vmx->nested.vmcs02_pool); +- return &item->vmcs02; +- } +- +- if (vmx->nested.vmcs02_num >= max(VMCS02_POOL_SIZE, 1)) { +- /* Recycle the least recently used VMCS. */ +- item = list_entry(vmx->nested.vmcs02_pool.prev, +- struct vmcs02_list, list); +- item->vmptr = vmx->nested.current_vmptr; +- list_move(&item->list, &vmx->nested.vmcs02_pool); +- return &item->vmcs02; +- } +- +- /* Create a new VMCS */ +- item = kmalloc(sizeof(struct vmcs02_list), GFP_KERNEL); +- if (!item) +- return NULL; +- item->vmcs02.vmcs = alloc_vmcs(); +- if (!item->vmcs02.vmcs) { +- kfree(item); +- return NULL; +- } +- loaded_vmcs_init(&item->vmcs02); +- item->vmptr = vmx->nested.current_vmptr; +- list_add(&(item->list), &(vmx->nested.vmcs02_pool)); +- vmx->nested.vmcs02_num++; +- return &item->vmcs02; +-} +- +-/* Free and remove from pool a vmcs02 saved for a vmcs12 (if there is one) */ +-static void nested_free_vmcs02(struct vcpu_vmx *vmx, gpa_t vmptr) +-{ +- struct vmcs02_list *item; +- list_for_each_entry(item, &vmx->nested.vmcs02_pool, list) +- if (item->vmptr == vmptr) { +- free_loaded_vmcs(&item->vmcs02); +- list_del(&item->list); +- kfree(item); +- vmx->nested.vmcs02_num--; +- return; +- } +-} +- +-/* +- * Free all VMCSs saved for this vcpu, except the one pointed by +- * vmx->loaded_vmcs. We must be running L1, so vmx->loaded_vmcs +- * must be &vmx->vmcs01. +- */ +-static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx) +-{ +- struct vmcs02_list *item, *n; +- +- WARN_ON(vmx->loaded_vmcs != &vmx->vmcs01); +- list_for_each_entry_safe(item, n, &vmx->nested.vmcs02_pool, list) { +- /* +- * Something will leak if the above WARN triggers. Better than +- * a use-after-free. +- */ +- if (vmx->loaded_vmcs == &item->vmcs02) +- continue; +- +- free_loaded_vmcs(&item->vmcs02); +- list_del(&item->list); +- kfree(item); +- vmx->nested.vmcs02_num--; +- } +-} +- + /* + * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(), + * set the success or error code of an emulated VMX instruction, as specified +@@ -6786,6 +6812,7 @@ static int handle_vmon(struct kvm_vcpu *vcpu) + struct vmcs *shadow_vmcs; + const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED + | FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX; ++ int r; + + /* The Intel VMX Instruction Reference lists a bunch of bits that + * are prerequisite to running VMXON, most notably cr4.VMXE must be +@@ -6825,10 +6852,14 @@ static int handle_vmon(struct kvm_vcpu *vcpu) + return 1; + } + ++ r = alloc_loaded_vmcs(&vmx->nested.vmcs02); ++ if (r < 0) ++ goto out_vmcs02; ++ + if (enable_shadow_vmcs) { + shadow_vmcs = alloc_vmcs(); + if (!shadow_vmcs) +- return -ENOMEM; ++ goto out_shadow_vmcs; + /* mark vmcs as shadow */ + shadow_vmcs->revision_id |= (1u << 31); + /* init shadow vmcs */ +@@ -6836,9 +6867,6 @@ static int handle_vmon(struct kvm_vcpu *vcpu) + vmx->nested.current_shadow_vmcs = shadow_vmcs; + } + +- INIT_LIST_HEAD(&(vmx->nested.vmcs02_pool)); +- vmx->nested.vmcs02_num = 0; +- + hrtimer_init(&vmx->nested.preemption_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); + vmx->nested.preemption_timer.function = vmx_preemption_timer_fn; +@@ -6850,6 +6878,12 @@ static int handle_vmon(struct kvm_vcpu *vcpu) + skip_emulated_instruction(vcpu); + nested_vmx_succeed(vcpu); + return 1; ++ ++out_shadow_vmcs: ++ free_loaded_vmcs(&vmx->nested.vmcs02); ++ ++out_vmcs02: ++ return -ENOMEM; + } + + /* +@@ -6921,7 +6955,7 @@ static void free_nested(struct vcpu_vmx *vmx) + nested_release_vmcs12(vmx); + if (enable_shadow_vmcs) + free_vmcs(vmx->nested.current_shadow_vmcs); +- /* Unpin physical memory we referred to in current vmcs02 */ ++ /* Unpin physical memory we referred to in the vmcs02 */ + if (vmx->nested.apic_access_page) { + nested_release_page(vmx->nested.apic_access_page); + vmx->nested.apic_access_page = NULL; +@@ -6937,7 +6971,7 @@ static void free_nested(struct vcpu_vmx *vmx) + vmx->nested.pi_desc = NULL; + } + +- nested_free_all_saved_vmcss(vmx); ++ free_loaded_vmcs(&vmx->nested.vmcs02); + } + + /* Emulate the VMXOFF instruction */ +@@ -6971,8 +7005,6 @@ static int handle_vmclear(struct kvm_vcpu *vcpu) + vmptr + offsetof(struct vmcs12, launch_state), + &zero, sizeof(zero)); + +- nested_free_vmcs02(vmx, vmptr); +- + skip_emulated_instruction(vcpu); + nested_vmx_succeed(vcpu); + return 1; +@@ -7757,6 +7789,19 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu) + vmcs_read32(VM_EXIT_INTR_ERROR_CODE), + KVM_ISA_VMX); + ++ /* ++ * The host physical addresses of some pages of guest memory ++ * are loaded into the vmcs02 (e.g. vmcs12's Virtual APIC ++ * Page). The CPU may write to these pages via their host ++ * physical address while L2 is running, bypassing any ++ * address-translation-based dirty tracking (e.g. EPT write ++ * protection). ++ * ++ * Mark them dirty on every exit from L2 to prevent them from ++ * getting out of sync with dirty tracking. ++ */ ++ nested_mark_vmcs12_pages_dirty(vcpu); ++ + if (vmx->nested.nested_run_pending) + return false; + +@@ -8244,7 +8289,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) + } + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control); + +- vmx_set_msr_bitmap(vcpu); ++ vmx_update_msr_bitmap(vcpu); + } + + static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa) +@@ -8413,9 +8458,21 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) + local_irq_enable(); + } + +-static bool vmx_has_high_real_mode_segbase(void) ++static bool vmx_has_emulated_msr(int index) + { +- return enable_unrestricted_guest || emulate_invalid_guest_state; ++ switch (index) { ++ case MSR_IA32_SMBASE: ++ /* ++ * We cannot do SMM unless we can run the guest in big ++ * real mode. ++ */ ++ return enable_unrestricted_guest || emulate_invalid_guest_state; ++ case MSR_AMD64_VIRT_SPEC_CTRL: ++ /* This is AMD only. */ ++ return false; ++ default: ++ return true; ++ } + } + + static bool vmx_mpx_supported(void) +@@ -8607,7 +8664,16 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) + atomic_switch_perf_msrs(vmx); + debugctlmsr = get_debugctlmsr(); + ++ /* ++ * If this vCPU has touched SPEC_CTRL, restore the guest's value if ++ * it's non-zero. Since vmentry is serialising on affected CPUs, there ++ * is no need to worry about the conditional branch over the wrmsr ++ * being speculatively taken. ++ */ ++ x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); ++ + vmx->__launched = vmx->loaded_vmcs->launched; ++ + asm( + /* Store host registers */ + "push %%" _ASM_DX "; push %%" _ASM_BP ";" +@@ -8725,6 +8791,26 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) + #endif + ); + ++ /* ++ * We do not use IBRS in the kernel. If this vCPU has used the ++ * SPEC_CTRL MSR it may have left it on; save the value and ++ * turn it off. This is much more efficient than blindly adding ++ * it to the atomic save/restore list. Especially as the former ++ * (Saving guest MSRs on vmexit) doesn't even exist in KVM. ++ * ++ * For non-nested case: ++ * If the L01 MSR bitmap does not intercept the MSR, then we need to ++ * save it. ++ * ++ * For nested case: ++ * If the L02 MSR bitmap does not intercept the MSR, then we need to ++ * save it. ++ */ ++ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL)) ++ vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); ++ ++ x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0); ++ + /* Eliminate branch target predictions from guest mode */ + vmexit_fill_RSB(); + +@@ -8824,6 +8910,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) + { + int err; + struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); ++ unsigned long *msr_bitmap; + int cpu; + + if (!vmx) +@@ -8856,16 +8943,24 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) + if (!vmx->guest_msrs) + goto free_pml; + +- vmx->loaded_vmcs = &vmx->vmcs01; +- vmx->loaded_vmcs->vmcs = alloc_vmcs(); +- if (!vmx->loaded_vmcs->vmcs) +- goto free_msrs; + if (!vmm_exclusive) + kvm_cpu_vmxon(__pa(per_cpu(vmxarea, raw_smp_processor_id()))); +- loaded_vmcs_init(vmx->loaded_vmcs); ++ err = alloc_loaded_vmcs(&vmx->vmcs01); + if (!vmm_exclusive) + kvm_cpu_vmxoff(); ++ if (err < 0) ++ goto free_msrs; ++ ++ msr_bitmap = vmx->vmcs01.msr_bitmap; ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_FS_BASE, MSR_TYPE_RW); ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_GS_BASE, MSR_TYPE_RW); ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_KERNEL_GS_BASE, MSR_TYPE_RW); ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_CS, MSR_TYPE_RW); ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_ESP, MSR_TYPE_RW); ++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_EIP, MSR_TYPE_RW); ++ vmx->msr_bitmap_mode = 0; + ++ vmx->loaded_vmcs = &vmx->vmcs01; + cpu = get_cpu(); + vmx_vcpu_load(&vmx->vcpu, cpu); + vmx->vcpu.cpu = cpu; +@@ -9248,9 +9343,26 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu, + { + int msr; + struct page *page; +- unsigned long *msr_bitmap; ++ unsigned long *msr_bitmap_l1; ++ unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap; ++ /* ++ * pred_cmd & spec_ctrl are trying to verify two things: ++ * ++ * 1. L0 gave a permission to L1 to actually passthrough the MSR. This ++ * ensures that we do not accidentally generate an L02 MSR bitmap ++ * from the L12 MSR bitmap that is too permissive. ++ * 2. That L1 or L2s have actually used the MSR. This avoids ++ * unnecessarily merging of the bitmap if the MSR is unused. This ++ * works properly because we only update the L01 MSR bitmap lazily. ++ * So even if L0 should pass L1 these MSRs, the L01 bitmap is only ++ * updated to reflect this when L1 (or its L2s) actually write to ++ * the MSR. ++ */ ++ bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD); ++ bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL); + +- if (!nested_cpu_has_virt_x2apic_mode(vmcs12)) ++ if (!nested_cpu_has_virt_x2apic_mode(vmcs12) && ++ !pred_cmd && !spec_ctrl) + return false; + + page = nested_get_page(vcpu, vmcs12->msr_bitmap); +@@ -9258,59 +9370,46 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu, + WARN_ON(1); + return false; + } +- msr_bitmap = (unsigned long *)kmap(page); ++ msr_bitmap_l1 = (unsigned long *)kmap(page); ++ ++ memset(msr_bitmap_l0, 0xff, PAGE_SIZE); + + if (nested_cpu_has_virt_x2apic_mode(vmcs12)) { + if (nested_cpu_has_apic_reg_virt(vmcs12)) + for (msr = 0x800; msr <= 0x8ff; msr++) + nested_vmx_disable_intercept_for_msr( +- msr_bitmap, +- vmx_msr_bitmap_nested, ++ msr_bitmap_l1, msr_bitmap_l0, + msr, MSR_TYPE_R); +- /* TPR is allowed */ +- nested_vmx_disable_intercept_for_msr(msr_bitmap, +- vmx_msr_bitmap_nested, ++ ++ nested_vmx_disable_intercept_for_msr( ++ msr_bitmap_l1, msr_bitmap_l0, + APIC_BASE_MSR + (APIC_TASKPRI >> 4), + MSR_TYPE_R | MSR_TYPE_W); ++ + if (nested_cpu_has_vid(vmcs12)) { +- /* EOI and self-IPI are allowed */ + nested_vmx_disable_intercept_for_msr( +- msr_bitmap, +- vmx_msr_bitmap_nested, ++ msr_bitmap_l1, msr_bitmap_l0, + APIC_BASE_MSR + (APIC_EOI >> 4), + MSR_TYPE_W); + nested_vmx_disable_intercept_for_msr( +- msr_bitmap, +- vmx_msr_bitmap_nested, ++ msr_bitmap_l1, msr_bitmap_l0, + APIC_BASE_MSR + (APIC_SELF_IPI >> 4), + MSR_TYPE_W); + } +- } else { +- /* +- * Enable reading intercept of all the x2apic +- * MSRs. We should not rely on vmcs12 to do any +- * optimizations here, it may have been modified +- * by L1. +- */ +- for (msr = 0x800; msr <= 0x8ff; msr++) +- __vmx_enable_intercept_for_msr( +- vmx_msr_bitmap_nested, +- msr, +- MSR_TYPE_R); +- +- __vmx_enable_intercept_for_msr( +- vmx_msr_bitmap_nested, +- APIC_BASE_MSR + (APIC_TASKPRI >> 4), +- MSR_TYPE_W); +- __vmx_enable_intercept_for_msr( +- vmx_msr_bitmap_nested, +- APIC_BASE_MSR + (APIC_EOI >> 4), +- MSR_TYPE_W); +- __vmx_enable_intercept_for_msr( +- vmx_msr_bitmap_nested, +- APIC_BASE_MSR + (APIC_SELF_IPI >> 4), +- MSR_TYPE_W); + } ++ ++ if (spec_ctrl) ++ nested_vmx_disable_intercept_for_msr( ++ msr_bitmap_l1, msr_bitmap_l0, ++ MSR_IA32_SPEC_CTRL, ++ MSR_TYPE_R | MSR_TYPE_W); ++ ++ if (pred_cmd) ++ nested_vmx_disable_intercept_for_msr( ++ msr_bitmap_l1, msr_bitmap_l0, ++ MSR_IA32_PRED_CMD, ++ MSR_TYPE_W); ++ + kunmap(page); + nested_release_page_clean(page); + +@@ -9729,10 +9828,10 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) + } + + if (cpu_has_vmx_msr_bitmap() && +- exec_control & CPU_BASED_USE_MSR_BITMAPS) { +- nested_vmx_merge_msr_bitmap(vcpu, vmcs12); +- /* MSR_BITMAP will be set by following vmx_set_efer. */ +- } else ++ exec_control & CPU_BASED_USE_MSR_BITMAPS && ++ nested_vmx_merge_msr_bitmap(vcpu, vmcs12)) ++ ; /* MSR_BITMAP will be set by following vmx_set_efer. */ ++ else + exec_control &= ~CPU_BASED_USE_MSR_BITMAPS; + + /* +@@ -9784,6 +9883,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) + else + vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset); + ++ if (cpu_has_vmx_msr_bitmap()) ++ vmcs_write64(MSR_BITMAP, __pa(vmx->nested.vmcs02.msr_bitmap)); ++ + if (enable_vpid) { + /* + * There is no direct mapping between vpid02 and vpid12, the +@@ -9876,7 +9978,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) + struct vmcs12 *vmcs12; + struct vcpu_vmx *vmx = to_vmx(vcpu); + int cpu; +- struct loaded_vmcs *vmcs02; + bool ia32e; + u32 msr_entry_idx; + +@@ -10016,10 +10117,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) + * the nested entry. + */ + +- vmcs02 = nested_get_current_vmcs02(vmx); +- if (!vmcs02) +- return -ENOMEM; +- + enter_guest_mode(vcpu); + + vmx->nested.vmcs01_tsc_offset = vmcs_read64(TSC_OFFSET); +@@ -10028,7 +10125,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch) + vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL); + + cpu = get_cpu(); +- vmx->loaded_vmcs = vmcs02; ++ vmx->loaded_vmcs = &vmx->nested.vmcs02; + vmx_vcpu_put(vcpu); + vmx_vcpu_load(vcpu, cpu); + vcpu->cpu = cpu; +@@ -10489,7 +10586,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, + vmcs_write64(GUEST_IA32_DEBUGCTL, 0); + + if (cpu_has_vmx_msr_bitmap()) +- vmx_set_msr_bitmap(vcpu); ++ vmx_update_msr_bitmap(vcpu); + + if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr, + vmcs12->vm_exit_msr_load_count)) +@@ -10540,10 +10637,6 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, + vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); + vmx_segment_cache_clear(vmx); + +- /* if no vmcs02 cache requested, remove the one we used */ +- if (VMCS02_POOL_SIZE == 0) +- nested_free_vmcs02(vmx, vmx->nested.current_vmptr); +- + load_vmcs12_host_state(vcpu, vmcs12); + + /* Update TSC_OFFSET if TSC was changed while L2 ran */ +@@ -10871,7 +10964,7 @@ static struct kvm_x86_ops vmx_x86_ops = { + .hardware_enable = hardware_enable, + .hardware_disable = hardware_disable, + .cpu_has_accelerated_tpr = report_flexpriority, +- .cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase, ++ .has_emulated_msr = vmx_has_emulated_msr, + + .vcpu_create = vmx_create_vcpu, + .vcpu_free = vmx_free_vcpu, +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index e6ab034f0bc7..aa1a0277a678 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -961,6 +961,7 @@ static u32 msrs_to_save[] = { + #endif + MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, + MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, ++ MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES + }; + + static unsigned num_msrs_to_save; +@@ -984,6 +985,7 @@ static u32 emulated_msrs[] = { + MSR_IA32_MCG_STATUS, + MSR_IA32_MCG_CTL, + MSR_IA32_SMBASE, ++ MSR_AMD64_VIRT_SPEC_CTRL, + }; + + static unsigned num_emulated_msrs; +@@ -2583,7 +2585,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) + * fringe case that is not enabled except via specific settings + * of the module parameters. + */ +- r = kvm_x86_ops->cpu_has_high_real_mode_segbase(); ++ r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE); + break; + case KVM_CAP_COALESCED_MMIO: + r = KVM_COALESCED_MMIO_PAGE_OFFSET; +@@ -4072,14 +4074,8 @@ static void kvm_init_msr_list(void) + num_msrs_to_save = j; + + for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) { +- switch (emulated_msrs[i]) { +- case MSR_IA32_SMBASE: +- if (!kvm_x86_ops->cpu_has_high_real_mode_segbase()) +- continue; +- break; +- default: +- break; +- } ++ if (!kvm_x86_ops->has_emulated_msr(emulated_msrs[i])) ++ continue; + + if (j < i) + emulated_msrs[j] = emulated_msrs[i]; +diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c +index 91d93b95bd86..0a6fcae404f8 100644 +--- a/arch/x86/lib/usercopy_32.c ++++ b/arch/x86/lib/usercopy_32.c +@@ -570,12 +570,12 @@ do { \ + unsigned long __copy_to_user_ll(void __user *to, const void *from, + unsigned long n) + { +- stac(); ++ __uaccess_begin_nospec(); + if (movsl_is_ok(to, from, n)) + __copy_user(to, from, n); + else + n = __copy_user_intel(to, from, n); +- clac(); ++ __uaccess_end(); + return n; + } + EXPORT_SYMBOL(__copy_to_user_ll); +@@ -583,12 +583,12 @@ EXPORT_SYMBOL(__copy_to_user_ll); + unsigned long __copy_from_user_ll(void *to, const void __user *from, + unsigned long n) + { +- stac(); ++ __uaccess_begin_nospec(); + if (movsl_is_ok(to, from, n)) + __copy_user_zeroing(to, from, n); + else + n = __copy_user_zeroing_intel(to, from, n); +- clac(); ++ __uaccess_end(); + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll); +@@ -596,13 +596,13 @@ EXPORT_SYMBOL(__copy_from_user_ll); + unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, + unsigned long n) + { +- stac(); ++ __uaccess_begin_nospec(); + if (movsl_is_ok(to, from, n)) + __copy_user(to, from, n); + else + n = __copy_user_intel((void __user *)to, + (const void *)from, n); +- clac(); ++ __uaccess_end(); + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll_nozero); +@@ -610,7 +610,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero); + unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, + unsigned long n) + { +- stac(); ++ __uaccess_begin_nospec(); + #ifdef CONFIG_X86_INTEL_USERCOPY + if (n > 64 && cpu_has_xmm2) + n = __copy_user_zeroing_intel_nocache(to, from, n); +@@ -619,7 +619,7 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, + #else + __copy_user_zeroing(to, from, n); + #endif +- clac(); ++ __uaccess_end(); + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll_nocache); +@@ -627,7 +627,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache); + unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, + unsigned long n) + { +- stac(); ++ __uaccess_begin_nospec(); + #ifdef CONFIG_X86_INTEL_USERCOPY + if (n > 64 && cpu_has_xmm2) + n = __copy_user_intel_nocache(to, from, n); +@@ -636,7 +636,7 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr + #else + __copy_user(to, from, n); + #endif +- clac(); ++ __uaccess_end(); + return n; + } + EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero); +diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c +index ae9a37bf1371..7d2542ad346a 100644 +--- a/arch/x86/mm/gup.c ++++ b/arch/x86/mm/gup.c +@@ -388,7 +388,7 @@ slow_irqon: + + ret = get_user_pages_unlocked(current, mm, start, + (end - start) >> PAGE_SHIFT, +- write, 0, pages); ++ pages, write ? FOLL_WRITE : 0); + + /* Have to be a bit careful with return values */ + if (nr > 0) { +diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c +index 7ed47b1e6f42..7e94fc6f608a 100644 +--- a/arch/x86/mm/mpx.c ++++ b/arch/x86/mm/mpx.c +@@ -536,10 +536,9 @@ static int mpx_resolve_fault(long __user *addr, int write) + { + long gup_ret; + int nr_pages = 1; +- int force = 0; + + gup_ret = get_user_pages(current, current->mm, (unsigned long)addr, +- nr_pages, write, force, NULL, NULL); ++ nr_pages, write ? FOLL_WRITE : 0, NULL, NULL); + /* + * get_user_pages() returns number of pages gotten. + * 0 means we failed to fault in and get anything, +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +index e40a6d8b0b92..062c23125b2a 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -496,9 +496,13 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) + int r; + + int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); ++ unsigned int flags = 0; + enum dma_data_direction direction = write ? + DMA_BIDIRECTIONAL : DMA_TO_DEVICE; + ++ if (write) ++ flags |= FOLL_WRITE; ++ + if (current->mm != gtt->usermm) + return -EPERM; + +@@ -519,7 +523,7 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) + struct page **pages = ttm->pages + pinned; + + r = get_user_pages(current, current->mm, userptr, num_pages, +- write, 0, pages, NULL); ++ flags, pages, NULL); + if (r < 0) + goto release_pages; + +diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c +index 21085f669e21..b19ba1792607 100644 +--- a/drivers/gpu/drm/ast/ast_mode.c ++++ b/drivers/gpu/drm/ast/ast_mode.c +@@ -968,9 +968,21 @@ static int get_clock(void *i2c_priv) + { + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = i2c->dev->dev_private; +- uint32_t val; ++ uint32_t val, val2, count, pass; ++ ++ count = 0; ++ pass = 0; ++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; ++ do { ++ val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; ++ if (val == val2) { ++ pass++; ++ } else { ++ pass = 0; ++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; ++ } ++ } while ((pass < 5) && (count++ < 0x10000)); + +- val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4; + return val & 1 ? 1 : 0; + } + +@@ -978,9 +990,21 @@ static int get_data(void *i2c_priv) + { + struct ast_i2c_chan *i2c = i2c_priv; + struct ast_private *ast = i2c->dev->dev_private; +- uint32_t val; ++ uint32_t val, val2, count, pass; ++ ++ count = 0; ++ pass = 0; ++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; ++ do { ++ val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; ++ if (val == val2) { ++ pass++; ++ } else { ++ pass = 0; ++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; ++ } ++ } while ((pass < 5) && (count++ < 0x10000)); + +- val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5; + return val & 1 ? 1 : 0; + } + +@@ -993,7 +1017,7 @@ static void set_clock(void *i2c_priv, int clock) + + for (i = 0; i < 0x10000; i++) { + ujcrb7 = ((clock & 0x01) ? 0 : 1); +- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); + if (ujcrb7 == jtemp) + break; +@@ -1009,7 +1033,7 @@ static void set_data(void *i2c_priv, int data) + + for (i = 0; i < 0x10000; i++) { + ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; +- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7); ++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); + if (ujcrb7 == jtemp) + break; +diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c +index c17efdb238a6..639ea28808e2 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c +@@ -471,7 +471,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, + goto err_free; + } + +- ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec); ++ ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, ++ g2d_userptr->vec); + if (ret != npages) { + DRM_ERROR("failed to get user pages from userptr.\n"); + if (ret < 0) +diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c +index 359fe2b8bb8a..b02113b57d51 100644 +--- a/drivers/gpu/drm/i915/i915_gem_userptr.c ++++ b/drivers/gpu/drm/i915/i915_gem_userptr.c +@@ -581,13 +581,17 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) + pvec = drm_malloc_ab(npages, sizeof(struct page *)); + if (pvec != NULL) { + struct mm_struct *mm = obj->userptr.mm->mm; ++ unsigned int flags = 0; ++ ++ if (!obj->userptr.read_only) ++ flags |= FOLL_WRITE; + + down_read(&mm->mmap_sem); + while (pinned < npages) { + ret = get_user_pages(work->task, mm, + obj->userptr.ptr + pinned * PAGE_SIZE, + npages - pinned, +- !obj->userptr.read_only, 0, ++ flags, + pvec + pinned, NULL); + if (ret < 0) + break; +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index d684e2b79d2b..0c380fe77382 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -557,7 +557,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) + struct page **pages = ttm->pages + pinned; + + r = get_user_pages(current, current->mm, userptr, num_pages, +- write, 0, pages, NULL); ++ write ? FOLL_WRITE : 0, pages, NULL); + if (r < 0) + goto release_pages; + +diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c +index d0cbd5ecd7f0..4459cb32d1fe 100644 +--- a/drivers/gpu/drm/via/via_dmablit.c ++++ b/drivers/gpu/drm/via/via_dmablit.c +@@ -242,8 +242,8 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer) + ret = get_user_pages(current, current->mm, + (unsigned long)xfer->mem_addr, + vsg->num_pages, +- (vsg->direction == DMA_FROM_DEVICE), +- 0, vsg->pages, NULL); ++ (vsg->direction == DMA_FROM_DEVICE) ? FOLL_WRITE : 0, ++ vsg->pages, NULL); + + up_read(¤t->mm->mmap_sem); + if (ret != vsg->num_pages) { +diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c +index 9ac6e1673375..1f291b344178 100644 +--- a/drivers/hwmon/ina2xx.c ++++ b/drivers/hwmon/ina2xx.c +@@ -273,7 +273,7 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg, + break; + case INA2XX_CURRENT: + /* signed register, result in mA */ +- val = regval * data->current_lsb_uA; ++ val = (s16)regval * data->current_lsb_uA; + val = DIV_ROUND_CLOSEST(val, 1000); + break; + case INA2XX_CALIBRATION: +diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c +index 49276bbdac3d..1bb80f992aa8 100644 +--- a/drivers/hwmon/w83795.c ++++ b/drivers/hwmon/w83795.c +@@ -1691,7 +1691,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr, + * somewhere else in the code + */ + #define SENSOR_ATTR_TEMP(index) { \ +- SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ ++ SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 5 ? S_IWUSR : 0), \ + show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ + SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \ + NULL, TEMP_READ, index - 1), \ +diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c +index 98fd9a594841..8762eac47570 100644 +--- a/drivers/infiniband/core/umem.c ++++ b/drivers/infiniband/core/umem.c +@@ -95,6 +95,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, + DEFINE_DMA_ATTRS(attrs); + struct scatterlist *sg, *sg_list_start; + int need_release = 0; ++ unsigned int gup_flags = FOLL_WRITE; + + if (dmasync) + dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs); +@@ -177,6 +178,9 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, + if (ret) + goto out; + ++ if (!umem->writable) ++ gup_flags |= FOLL_FORCE; ++ + need_release = 1; + sg_list_start = umem->sg_head.sgl; + +@@ -184,7 +188,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, + ret = get_user_pages(current, current->mm, cur_base, + min_t(unsigned long, npages, + PAGE_SIZE / sizeof (struct page *)), +- 1, !umem->writable, page_list, vma_list); ++ gup_flags, page_list, vma_list); + + if (ret < 0) + goto out; +diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c +index 40becdb3196e..738ccfee7cae 100644 +--- a/drivers/infiniband/core/umem_odp.c ++++ b/drivers/infiniband/core/umem_odp.c +@@ -527,6 +527,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, + u64 off; + int j, k, ret = 0, start_idx, npages = 0; + u64 base_virt_addr; ++ unsigned int flags = 0; + + if (access_mask == 0) + return -EINVAL; +@@ -556,6 +557,9 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, + goto out_put_task; + } + ++ if (access_mask & ODP_WRITE_ALLOWED_BIT) ++ flags |= FOLL_WRITE; ++ + start_idx = (user_virt - ib_umem_start(umem)) >> PAGE_SHIFT; + k = start_idx; + +@@ -574,8 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt, + */ + npages = get_user_pages(owning_process, owning_mm, user_virt, + gup_num_pages, +- access_mask & ODP_WRITE_ALLOWED_BIT, 0, +- local_page_list, NULL); ++ flags, local_page_list, NULL); + up_read(&owning_mm->mmap_sem); + + if (npages < 0) +diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c +index 7d2e42dd6926..8676685dbf3d 100644 +--- a/drivers/infiniband/hw/mthca/mthca_memfree.c ++++ b/drivers/infiniband/hw/mthca/mthca_memfree.c +@@ -472,8 +472,8 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar, + goto out; + } + +- ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0, +- pages, NULL); ++ ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, ++ FOLL_WRITE, pages, NULL); + if (ret < 0) + goto out; + +diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c +index ab1588ae1c85..75c3f0dffe63 100644 +--- a/drivers/infiniband/hw/qib/qib_user_pages.c ++++ b/drivers/infiniband/hw/qib/qib_user_pages.c +@@ -68,7 +68,8 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages, + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages(current, current->mm, + start_page + got * PAGE_SIZE, +- num_pages - got, 1, 1, ++ num_pages - got, ++ FOLL_WRITE | FOLL_FORCE, + p + got, NULL); + if (ret < 0) + goto bail_release; +diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c +index 645a5f6e6c88..7f0d75e29441 100644 +--- a/drivers/infiniband/hw/usnic/usnic_uiom.c ++++ b/drivers/infiniband/hw/usnic/usnic_uiom.c +@@ -113,6 +113,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, + int flags; + dma_addr_t pa; + DEFINE_DMA_ATTRS(attrs); ++ unsigned int gup_flags; + + if (dmasync) + dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs); +@@ -140,6 +141,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, + + flags = IOMMU_READ | IOMMU_CACHE; + flags |= (writable) ? IOMMU_WRITE : 0; ++ gup_flags = FOLL_WRITE; ++ gup_flags |= (writable) ? 0 : FOLL_FORCE; + cur_base = addr & PAGE_MASK; + ret = 0; + +@@ -147,7 +150,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, + ret = get_user_pages(current, current->mm, cur_base, + min_t(unsigned long, npages, + PAGE_SIZE / sizeof(struct page *)), +- 1, !writable, page_list, NULL); ++ gup_flags, page_list, NULL); + + if (ret < 0) + goto out; +diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c +index f770f6a2c987..3ea9edc8cdbe 100644 +--- a/drivers/media/dvb-frontends/ascot2e.c ++++ b/drivers/media/dvb-frontends/ascot2e.c +@@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv, + + static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val) + { +- return ascot2e_write_regs(priv, reg, &val, 1); ++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return ascot2e_write_regs(priv, reg, &tmp, 1); + } + + static int ascot2e_read_regs(struct ascot2e_priv *priv, +diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c +index 107853b0fddd..bde77671a37c 100644 +--- a/drivers/media/dvb-frontends/cxd2841er.c ++++ b/drivers/media/dvb-frontends/cxd2841er.c +@@ -241,7 +241,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv, + static int cxd2841er_write_reg(struct cxd2841er_priv *priv, + u8 addr, u8 reg, u8 val) + { +- return cxd2841er_write_regs(priv, addr, reg, &val, 1); ++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return cxd2841er_write_regs(priv, addr, reg, &tmp, 1); + } + + static int cxd2841er_read_regs(struct cxd2841er_priv *priv, +diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c +index 000606af70f7..f770ab72a8e3 100644 +--- a/drivers/media/dvb-frontends/horus3a.c ++++ b/drivers/media/dvb-frontends/horus3a.c +@@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv, + + static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val) + { +- return horus3a_write_regs(priv, reg, &val, 1); ++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return horus3a_write_regs(priv, reg, &tmp, 1); + } + + static int horus3a_enter_power_save(struct horus3a_priv *priv) +diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c +index cadcae4cff89..ac9d2591bb6f 100644 +--- a/drivers/media/dvb-frontends/itd1000.c ++++ b/drivers/media/dvb-frontends/itd1000.c +@@ -99,8 +99,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg) + + static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v) + { +- int ret = itd1000_write_regs(state, r, &v, 1); +- state->shadow[r] = v; ++ u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ int ret = itd1000_write_regs(state, r, &tmp, 1); ++ state->shadow[r] = tmp; + return ret; + } + +diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c +index c36e6764eead..c44188271028 100644 +--- a/drivers/media/dvb-frontends/mt312.c ++++ b/drivers/media/dvb-frontends/mt312.c +@@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state, + static inline int mt312_writereg(struct mt312_state *state, + const enum mt312_reg_addr reg, const u8 val) + { +- return mt312_write(state, reg, &val, 1); ++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ ++ return mt312_write(state, reg, &tmp, 1); + } + + static inline u32 mt312_div(u32 a, u32 b) +diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c +index 756650f154ab..ad9b7d4f8d95 100644 +--- a/drivers/media/dvb-frontends/stb0899_drv.c ++++ b/drivers/media/dvb-frontends/stb0899_drv.c +@@ -552,7 +552,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, + + int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) + { +- return stb0899_write_regs(state, reg, &data, 1); ++ u8 tmp = data; ++ return stb0899_write_regs(state, reg, &tmp, 1); + } + + /* +diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c +index 4ef8a5c7003e..44fac2570034 100644 +--- a/drivers/media/dvb-frontends/stb6100.c ++++ b/drivers/media/dvb-frontends/stb6100.c +@@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st + + static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data) + { ++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ + if (unlikely(reg >= STB6100_NUMREGS)) { + dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); + return -EREMOTEIO; + } +- data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set; +- return stb6100_write_reg_range(state, &data, reg, 1); ++ tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set; ++ return stb6100_write_reg_range(state, &tmp, reg, 1); + } + + +diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c +index 44cb73f68af6..ddd0d778ad6e 100644 +--- a/drivers/media/dvb-frontends/stv0367.c ++++ b/drivers/media/dvb-frontends/stv0367.c +@@ -804,7 +804,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len) + + static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) + { +- return stv0367_writeregs(state, reg, &data, 1); ++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return stv0367_writeregs(state, reg, &tmp, 1); + } + + static u8 stv0367_readreg(struct stv0367_state *state, u16 reg) +diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c +index 25bdf6e0f963..f0377e2b341b 100644 +--- a/drivers/media/dvb-frontends/stv090x.c ++++ b/drivers/media/dvb-frontends/stv090x.c +@@ -761,7 +761,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 + + static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data) + { +- return stv090x_write_regs(state, reg, &data, 1); ++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return stv090x_write_regs(state, reg, &tmp, 1); + } + + static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable) +diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c +index e66154e5c1d7..45d14869e7b8 100644 +--- a/drivers/media/dvb-frontends/stv6110x.c ++++ b/drivers/media/dvb-frontends/stv6110x.c +@@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da + + static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) + { +- return stv6110x_write_regs(stv6110x, reg, &data, 1); ++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return stv6110x_write_regs(stv6110x, reg, &tmp, 1); + } + + static int stv6110x_init(struct dvb_frontend *fe) +diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c +index ee09ec26c553..b273e4fd8024 100644 +--- a/drivers/media/dvb-frontends/zl10039.c ++++ b/drivers/media/dvb-frontends/zl10039.c +@@ -138,7 +138,9 @@ static inline int zl10039_writereg(struct zl10039_state *state, + const enum zl10039_reg_addr reg, + const u8 val) + { +- return zl10039_write(state, reg, &val, 1); ++ const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ ++ ++ return zl10039_write(state, reg, &tmp, 1); + } + + static int zl10039_init(struct dvb_frontend *fe) +diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c +index 24152accc66c..8729fdebef8f 100644 +--- a/drivers/media/pci/ivtv/ivtv-udma.c ++++ b/drivers/media/pci/ivtv/ivtv-udma.c +@@ -125,7 +125,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr, + + /* Get user pages for DMA Xfer */ + err = get_user_pages_unlocked(current, current->mm, +- user_dma.uaddr, user_dma.page_count, 0, 1, dma->map); ++ user_dma.uaddr, user_dma.page_count, dma->map, ++ FOLL_FORCE); + + if (user_dma.page_count != err) { + IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n", +diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c +index 2b8e7b2f2b86..9cd995f418e0 100644 +--- a/drivers/media/pci/ivtv/ivtv-yuv.c ++++ b/drivers/media/pci/ivtv/ivtv-yuv.c +@@ -76,13 +76,13 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, + + /* Get user pages for DMA Xfer */ + y_pages = get_user_pages_unlocked(current, current->mm, +- y_dma.uaddr, y_dma.page_count, 0, 1, +- &dma->map[0]); ++ y_dma.uaddr, y_dma.page_count, ++ &dma->map[0], FOLL_FORCE); + uv_pages = 0; /* silence gcc. value is set and consumed only if: */ + if (y_pages == y_dma.page_count) { + uv_pages = get_user_pages_unlocked(current, current->mm, +- uv_dma.uaddr, uv_dma.page_count, 0, 1, +- &dma->map[y_pages]); ++ uv_dma.uaddr, uv_dma.page_count, ++ &dma->map[y_pages], FOLL_FORCE); + } + + if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) { +diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c +index 70c28d19ea04..596359576109 100644 +--- a/drivers/media/platform/omap/omap_vout.c ++++ b/drivers/media/platform/omap/omap_vout.c +@@ -214,7 +214,7 @@ static int omap_vout_get_userptr(struct videobuf_buffer *vb, u32 virtp, + if (!vec) + return -ENOMEM; + +- ret = get_vaddr_frames(virtp, 1, true, false, vec); ++ ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec); + if (ret != 1) { + frame_vector_destroy(vec); + return -EINVAL; +diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c +index f669cedca8bd..f74a74d91b9e 100644 +--- a/drivers/media/v4l2-core/videobuf-dma-sg.c ++++ b/drivers/media/v4l2-core/videobuf-dma-sg.c +@@ -156,6 +156,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, + { + unsigned long first, last; + int err, rw = 0; ++ unsigned int flags = FOLL_FORCE; + + dma->direction = direction; + switch (dma->direction) { +@@ -178,13 +179,15 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, + if (NULL == dma->pages) + return -ENOMEM; + ++ if (rw == READ) ++ flags |= FOLL_WRITE; ++ + dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n", + data, size, dma->nr_pages); + + err = get_user_pages(current, current->mm, + data & PAGE_MASK, dma->nr_pages, +- rw == READ, 1, /* force */ +- dma->pages, NULL); ++ flags, dma->pages, NULL); + + if (err != dma->nr_pages) { + dma->nr_pages = (err >= 0) ? err : 0; +diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c +index 3c3b517f1d1c..1cd322e939c7 100644 +--- a/drivers/media/v4l2-core/videobuf2-memops.c ++++ b/drivers/media/v4l2-core/videobuf2-memops.c +@@ -42,6 +42,10 @@ struct frame_vector *vb2_create_framevec(unsigned long start, + unsigned long first, last; + unsigned long nr; + struct frame_vector *vec; ++ unsigned int flags = FOLL_FORCE; ++ ++ if (write) ++ flags |= FOLL_WRITE; + + first = start >> PAGE_SHIFT; + last = (start + length - 1) >> PAGE_SHIFT; +@@ -49,7 +53,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start, + vec = frame_vector_create(nr); + if (!vec) + return ERR_PTR(-ENOMEM); +- ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec); ++ ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec); + if (ret < 0) + goto out_destroy; + /* We accept only complete set of PFNs */ +diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c +index 8bd63128d536..71c69e1c4ac0 100644 +--- a/drivers/misc/mic/scif/scif_rma.c ++++ b/drivers/misc/mic/scif/scif_rma.c +@@ -1398,8 +1398,7 @@ retry: + mm, + (u64)addr, + nr_pages, +- !!(prot & SCIF_PROT_WRITE), +- 0, ++ (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0, + pinned_pages->pages, + NULL); + up_write(&mm->mmap_sem); +diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c +index f74fc0ca2ef9..e6b723c6a2af 100644 +--- a/drivers/misc/sgi-gru/grufault.c ++++ b/drivers/misc/sgi-gru/grufault.c +@@ -199,7 +199,7 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma, + *pageshift = PAGE_SHIFT; + #endif + if (get_user_pages +- (current, current->mm, vaddr, 1, write, 0, &page, NULL) <= 0) ++ (current, current->mm, vaddr, 1, write ? FOLL_WRITE : 0, &page, NULL) <= 0) + return -EFAULT; + *paddr = page_to_phys(page); + put_page(page); +diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c +index 16baaafed26c..cbdeb54eab51 100644 +--- a/drivers/net/ethernet/cavium/thunder/nic_main.c ++++ b/drivers/net/ethernet/cavium/thunder/nic_main.c +@@ -1090,6 +1090,9 @@ static void nic_remove(struct pci_dev *pdev) + { + struct nicpf *nic = pci_get_drvdata(pdev); + ++ if (!nic) ++ return; ++ + if (nic->flags & NIC_SRIOV_ENABLED) + pci_disable_sriov(pdev); + +diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c +index 253f8ed0537a..60c727b0b7ab 100644 +--- a/drivers/net/ethernet/hisilicon/hip04_eth.c ++++ b/drivers/net/ethernet/hisilicon/hip04_eth.c +@@ -919,10 +919,8 @@ static int hip04_mac_probe(struct platform_device *pdev) + } + + ret = register_netdev(ndev); +- if (ret) { +- free_netdev(ndev); ++ if (ret) + goto alloc_fail; +- } + + return 0; + +diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +index ffd2e74e5638..dcd718ce13d5 100644 +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +@@ -1429,7 +1429,9 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw, + *autoneg = false; + + if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || +- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) { ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 || ++ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) { + *speed = IXGBE_LINK_SPEED_1GB_FULL; + return 0; + } +diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c +index deae10d7426d..9b588251f2a7 100644 +--- a/drivers/net/ethernet/realtek/8139cp.c ++++ b/drivers/net/ethernet/realtek/8139cp.c +@@ -578,6 +578,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) + struct cp_private *cp; + int handled = 0; + u16 status; ++ u16 mask; + + if (unlikely(dev == NULL)) + return IRQ_NONE; +@@ -585,6 +586,10 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance) + + spin_lock(&cp->lock); + ++ mask = cpr16(IntrMask); ++ if (!mask) ++ goto out_unlock; ++ + status = cpr16(IntrStatus); + if (!status || (status == 0xFFFF)) + goto out_unlock; +diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c +index 3920c3eb6006..df6063faad2e 100644 +--- a/drivers/net/ethernet/rocker/rocker.c ++++ b/drivers/net/ethernet/rocker/rocker.c +@@ -821,37 +821,49 @@ static int rocker_tlv_put(struct rocker_desc_info *desc_info, + static int rocker_tlv_put_u8(struct rocker_desc_info *desc_info, + int attrtype, u8 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &value); ++ u8 tmp = value; /* work around GCC PR81715 */ ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &tmp); + } + + static int rocker_tlv_put_u16(struct rocker_desc_info *desc_info, + int attrtype, u16 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &value); ++ u16 tmp = value; ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &tmp); + } + + static int rocker_tlv_put_be16(struct rocker_desc_info *desc_info, + int attrtype, __be16 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &value); ++ __be16 tmp = value; ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &tmp); + } + + static int rocker_tlv_put_u32(struct rocker_desc_info *desc_info, + int attrtype, u32 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &value); ++ u32 tmp = value; ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &tmp); + } + + static int rocker_tlv_put_be32(struct rocker_desc_info *desc_info, + int attrtype, __be32 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &value); ++ __be32 tmp = value; ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &tmp); + } + + static int rocker_tlv_put_u64(struct rocker_desc_info *desc_info, + int attrtype, u64 value) + { +- return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &value); ++ u64 tmp = value; ++ ++ return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &tmp); + } + + static struct rocker_tlv * +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index 1f2f25a71d18..70f26b30729c 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1265,20 +1265,17 @@ static int gen10g_resume(struct phy_device *phydev) + + static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) + { +- phydev->supported &= ~(PHY_1000BT_FEATURES | PHY_100BT_FEATURES | +- PHY_10BT_FEATURES); +- + switch (max_speed) { +- default: +- return -ENOTSUPP; +- case SPEED_1000: +- phydev->supported |= PHY_1000BT_FEATURES; ++ case SPEED_10: ++ phydev->supported &= ~PHY_100BT_FEATURES; + /* fall through */ + case SPEED_100: +- phydev->supported |= PHY_100BT_FEATURES; +- /* fall through */ +- case SPEED_10: +- phydev->supported |= PHY_10BT_FEATURES; ++ phydev->supported &= ~PHY_1000BT_FEATURES; ++ break; ++ case SPEED_1000: ++ break; ++ default: ++ return -ENOTSUPP; + } + + return 0; +diff --git a/drivers/net/tun.c b/drivers/net/tun.c +index 5ac0b850d6b1..fd9ff9eff237 100644 +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1475,9 +1475,9 @@ static void tun_setup(struct net_device *dev) + */ + static int tun_validate(struct nlattr *tb[], struct nlattr *data[]) + { +- if (!data) +- return 0; +- return -EINVAL; ++ /* NL_SET_ERR_MSG(extack, ++ "tun/tap creation via rtnetlink is not supported."); */ ++ return -EOPNOTSUPP; + } + + static struct rtnl_link_ops tun_link_ops __read_mostly = { +diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c +index 6ed26baca0e5..7af8479acb98 100644 +--- a/drivers/net/wireless/ath/wil6210/wmi.c ++++ b/drivers/net/wireless/ath/wil6210/wmi.c +@@ -1035,8 +1035,14 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) + }; + int rc; + u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; +- struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); ++ struct wmi_set_appie_cmd *cmd; + ++ if (len < ie_len) { ++ rc = -EINVAL; ++ goto out; ++ } ++ ++ cmd = kzalloc(len, GFP_KERNEL); + if (!cmd) { + rc = -ENOMEM; + goto out; +diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c +index 03054c0e7689..3c3e8115f73d 100644 +--- a/drivers/scsi/sr_ioctl.c ++++ b/drivers/scsi/sr_ioctl.c +@@ -187,30 +187,25 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) + struct scsi_device *SDev; + struct scsi_sense_hdr sshdr; + int result, err = 0, retries = 0; +- struct request_sense *sense = cgc->sense; ++ unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE]; + + SDev = cd->device; + +- if (!sense) { +- sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); +- if (!sense) { +- err = -ENOMEM; +- goto out; +- } +- } +- + retry: + if (!scsi_block_when_processing_errors(SDev)) { + err = -ENODEV; + goto out; + } + +- memset(sense, 0, sizeof(*sense)); ++ memset(sense_buffer, 0, sizeof(sense_buffer)); + result = scsi_execute(SDev, cgc->cmd, cgc->data_direction, +- cgc->buffer, cgc->buflen, (char *)sense, ++ cgc->buffer, cgc->buflen, sense_buffer, + cgc->timeout, IOCTL_RETRIES, 0, NULL); + +- scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr); ++ scsi_normalize_sense(sense_buffer, sizeof(sense_buffer), &sshdr); ++ ++ if (cgc->sense) ++ memcpy(cgc->sense, sense_buffer, sizeof(*cgc->sense)); + + /* Minimal error checking. Ignore cases we know about, and report the rest. */ + if (driver_byte(result) != 0) { +@@ -261,8 +256,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) + + /* Wake up a process waiting for device */ + out: +- if (!cgc->sense) +- kfree(sense); + cgc->stat = err; + return err; + } +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index 2e522951b619..088a68ab4246 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -4821,9 +4821,8 @@ static int sgl_map_user_pages(struct st_buffer *STbp, + current->mm, + uaddr, + nr_pages, +- rw == READ, +- 0, /* don't force */ +- pages); ++ pages, ++ rw == READ ? FOLL_WRITE : 0); /* don't force */ + + /* Errors and no page mapped should return here */ + if (res < nr_pages) +diff --git a/drivers/staging/rdma/hfi1/user_pages.c b/drivers/staging/rdma/hfi1/user_pages.c +index 9071afbd7bf4..b776b74d3d14 100644 +--- a/drivers/staging/rdma/hfi1/user_pages.c ++++ b/drivers/staging/rdma/hfi1/user_pages.c +@@ -85,7 +85,7 @@ static int __hfi1_get_user_pages(unsigned long start_page, size_t num_pages, + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages(current, current->mm, + start_page + got * PAGE_SIZE, +- num_pages - got, 1, 1, ++ num_pages - got, FOLL_WRITE | FOLL_FORCE, + p + got, NULL); + if (ret < 0) + goto bail_release; +diff --git a/drivers/staging/rdma/ipath/ipath_user_pages.c b/drivers/staging/rdma/ipath/ipath_user_pages.c +index d29b4daf61f8..f69ec728e0de 100644 +--- a/drivers/staging/rdma/ipath/ipath_user_pages.c ++++ b/drivers/staging/rdma/ipath/ipath_user_pages.c +@@ -72,7 +72,7 @@ static int __ipath_get_user_pages(unsigned long start_page, size_t num_pages, + for (got = 0; got < num_pages; got += ret) { + ret = get_user_pages(current, current->mm, + start_page + got * PAGE_SIZE, +- num_pages - got, 1, 1, ++ num_pages - got, FOLL_WRITE | FOLL_FORCE, + p + got, NULL); + if (ret < 0) + goto bail_release; +diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c +index 06ef26872462..52aed7cfeb24 100644 +--- a/drivers/staging/speakup/kobjects.c ++++ b/drivers/staging/speakup/kobjects.c +@@ -387,7 +387,7 @@ static ssize_t synth_store(struct kobject *kobj, struct kobj_attribute *attr, + len = strlen(buf); + if (len < 2 || len > 9) + return -EINVAL; +- strncpy(new_synth_name, buf, len); ++ memcpy(new_synth_name, buf, len); + if (new_synth_name[len - 1] == '\n') + len--; + new_synth_name[len] = '\0'; +@@ -514,7 +514,7 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr, + return -EINVAL; + } + +- strncpy(punc_buf, buf, x); ++ memcpy(punc_buf, buf, x); + + while (x && punc_buf[x - 1] == '\n') + x--; +diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c +index 9b7d39484ed3..d1ed92acafa3 100644 +--- a/drivers/usb/gadget/udc/omap_udc.c ++++ b/drivers/usb/gadget/udc/omap_udc.c +@@ -2037,6 +2037,7 @@ static inline int machine_without_vbus_sense(void) + { + return machine_is_omap_innovator() + || machine_is_omap_osk() ++ || machine_is_omap_palmte() + || machine_is_sx1() + /* No known omap7xx boards with vbus sense */ + || cpu_is_omap7xx(); +@@ -2045,7 +2046,7 @@ static inline int machine_without_vbus_sense(void) + static int omap_udc_start(struct usb_gadget *g, + struct usb_gadget_driver *driver) + { +- int status = -ENODEV; ++ int status; + struct omap_ep *ep; + unsigned long flags; + +@@ -2083,6 +2084,7 @@ static int omap_udc_start(struct usb_gadget *g, + goto done; + } + } else { ++ status = 0; + if (can_pullup(udc)) + pullup_enable(udc); + else +@@ -2612,9 +2614,22 @@ omap_ep_setup(char *name, u8 addr, u8 type, + + static void omap_udc_release(struct device *dev) + { +- complete(udc->done); ++ pullup_disable(udc); ++ if (!IS_ERR_OR_NULL(udc->transceiver)) { ++ usb_put_phy(udc->transceiver); ++ udc->transceiver = NULL; ++ } ++ omap_writew(0, UDC_SYSCON1); ++ remove_proc_file(); ++ if (udc->dc_clk) { ++ if (udc->clk_requested) ++ omap_udc_enable_clock(0); ++ clk_put(udc->hhc_clk); ++ clk_put(udc->dc_clk); ++ } ++ if (udc->done) ++ complete(udc->done); + kfree(udc); +- udc = NULL; + } + + static int +@@ -2886,8 +2901,8 @@ bad_on_1710: + udc->clr_halt = UDC_RESET_EP; + + /* USB general purpose IRQ: ep0, state changes, dma, etc */ +- status = request_irq(pdev->resource[1].start, omap_udc_irq, +- 0, driver_name, udc); ++ status = devm_request_irq(&pdev->dev, pdev->resource[1].start, ++ omap_udc_irq, 0, driver_name, udc); + if (status != 0) { + ERR("can't get irq %d, err %d\n", + (int) pdev->resource[1].start, status); +@@ -2895,20 +2910,20 @@ bad_on_1710: + } + + /* USB "non-iso" IRQ (PIO for all but ep0) */ +- status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, +- 0, "omap_udc pio", udc); ++ status = devm_request_irq(&pdev->dev, pdev->resource[2].start, ++ omap_udc_pio_irq, 0, "omap_udc pio", udc); + if (status != 0) { + ERR("can't get irq %d, err %d\n", + (int) pdev->resource[2].start, status); +- goto cleanup2; ++ goto cleanup1; + } + #ifdef USE_ISO +- status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, +- 0, "omap_udc iso", udc); ++ status = devm_request_irq(&pdev->dev, pdev->resource[3].start, ++ omap_udc_iso_irq, 0, "omap_udc iso", udc); + if (status != 0) { + ERR("can't get irq %d, err %d\n", + (int) pdev->resource[3].start, status); +- goto cleanup3; ++ goto cleanup1; + } + #endif + if (cpu_is_omap16xx() || cpu_is_omap7xx()) { +@@ -2919,23 +2934,8 @@ bad_on_1710: + } + + create_proc_file(); +- status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, +- omap_udc_release); +- if (status) +- goto cleanup4; +- +- return 0; +- +-cleanup4: +- remove_proc_file(); +- +-#ifdef USE_ISO +-cleanup3: +- free_irq(pdev->resource[2].start, udc); +-#endif +- +-cleanup2: +- free_irq(pdev->resource[1].start, udc); ++ return usb_add_gadget_udc_release(&pdev->dev, &udc->gadget, ++ omap_udc_release); + + cleanup1: + kfree(udc); +@@ -2962,42 +2962,15 @@ static int omap_udc_remove(struct platform_device *pdev) + { + DECLARE_COMPLETION_ONSTACK(done); + +- if (!udc) +- return -ENODEV; +- +- usb_del_gadget_udc(&udc->gadget); +- if (udc->driver) +- return -EBUSY; +- + udc->done = &done; + +- pullup_disable(udc); +- if (!IS_ERR_OR_NULL(udc->transceiver)) { +- usb_put_phy(udc->transceiver); +- udc->transceiver = NULL; +- } +- omap_writew(0, UDC_SYSCON1); +- +- remove_proc_file(); +- +-#ifdef USE_ISO +- free_irq(pdev->resource[3].start, udc); +-#endif +- free_irq(pdev->resource[2].start, udc); +- free_irq(pdev->resource[1].start, udc); ++ usb_del_gadget_udc(&udc->gadget); + +- if (udc->dc_clk) { +- if (udc->clk_requested) +- omap_udc_enable_clock(0); +- clk_put(udc->hhc_clk); +- clk_put(udc->dc_clk); +- } ++ wait_for_completion(&done); + + release_mem_region(pdev->resource[0].start, + pdev->resource[0].end - pdev->resource[0].start + 1); + +- wait_for_completion(&done); +- + return 0; + } + +diff --git a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c +index 195ad7cac1ba..68fa037d8cbc 100644 +--- a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c ++++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c +@@ -372,7 +372,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m) + + DBG(__func__) + +- memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg)); ++ memcpy(hw->DACreg, MGADACbpp32, sizeof(MGADACbpp32)); + switch (minfo->fbcon.var.bits_per_pixel) { + case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */ + hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR; +diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c +index 0e24eb9c219c..750a384bf191 100644 +--- a/drivers/video/fbdev/pvr2fb.c ++++ b/drivers/video/fbdev/pvr2fb.c +@@ -687,7 +687,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, + return -ENOMEM; + + ret = get_user_pages_unlocked(current, current->mm, (unsigned long)buf, +- nr_pages, WRITE, 0, pages); ++ nr_pages, pages, FOLL_WRITE); + + if (ret < nr_pages) { + nr_pages = ret; +diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c +index 32c8fc5f7a5c..590a0f51a249 100644 +--- a/drivers/virt/fsl_hypervisor.c ++++ b/drivers/virt/fsl_hypervisor.c +@@ -246,8 +246,8 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p) + down_read(¤t->mm->mmap_sem); + num_pinned = get_user_pages(current, current->mm, + param.local_vaddr - lb_offset, num_pages, +- (param.source == -1) ? READ : WRITE, +- 0, pages, NULL); ++ (param.source == -1) ? 0 : FOLL_WRITE, ++ pages, NULL); + up_read(¤t->mm->mmap_sem); + + if (num_pinned != num_pages) { +diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c +index 5063c5e796b7..84a1fab0dd6b 100644 +--- a/drivers/xen/xlate_mmu.c ++++ b/drivers/xen/xlate_mmu.c +@@ -34,6 +34,7 @@ + #include + + #include ++#include + #include + #include + #include +diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c +index 83c73738165e..40d1ab957fb6 100644 +--- a/fs/btrfs/send.c ++++ b/fs/btrfs/send.c +@@ -3232,7 +3232,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) + kfree(m); + } + +-static void tail_append_pending_moves(struct pending_dir_move *moves, ++static void tail_append_pending_moves(struct send_ctx *sctx, ++ struct pending_dir_move *moves, + struct list_head *stack) + { + if (list_empty(&moves->list)) { +@@ -3243,6 +3244,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves, + list_add_tail(&moves->list, stack); + list_splice_tail(&list, stack); + } ++ if (!RB_EMPTY_NODE(&moves->node)) { ++ rb_erase(&moves->node, &sctx->pending_dir_moves); ++ RB_CLEAR_NODE(&moves->node); ++ } + } + + static int apply_children_dir_moves(struct send_ctx *sctx) +@@ -3257,7 +3262,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx) + return 0; + + INIT_LIST_HEAD(&stack); +- tail_append_pending_moves(pm, &stack); ++ tail_append_pending_moves(sctx, pm, &stack); + + while (!list_empty(&stack)) { + pm = list_first_entry(&stack, struct pending_dir_move, list); +@@ -3268,7 +3273,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx) + goto out; + pm = get_pending_dir_moves(sctx, parent_ino); + if (pm) +- tail_append_pending_moves(pm, &stack); ++ tail_append_pending_moves(sctx, pm, &stack); + } + return 0; + +diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c +index 5b68cf526887..c05ab2ec0fef 100644 +--- a/fs/cachefiles/rdwr.c ++++ b/fs/cachefiles/rdwr.c +@@ -963,11 +963,8 @@ error: + void cachefiles_uncache_page(struct fscache_object *_object, struct page *page) + { + struct cachefiles_object *object; +- struct cachefiles_cache *cache; + + object = container_of(_object, struct cachefiles_object, fscache); +- cache = container_of(object->fscache.cache, +- struct cachefiles_cache, cache); + + _enter("%p,{%lu}", object, page->index); + +diff --git a/fs/exec.c b/fs/exec.c +index 910fc70c4542..3dad755b7048 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -191,6 +191,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, + { + struct page *page; + int ret; ++ unsigned int gup_flags = FOLL_FORCE; + + #ifdef CONFIG_STACK_GROWSUP + if (write) { +@@ -199,8 +200,12 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, + return NULL; + } + #endif +- ret = get_user_pages(current, bprm->mm, pos, +- 1, write, 1, &page, NULL); ++ ++ if (write) ++ gup_flags |= FOLL_WRITE; ++ ++ ret = get_user_pages(current, bprm->mm, pos, 1, gup_flags, ++ &page, NULL); + if (ret <= 0) + return NULL; + +diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c +index 714cd37a6ba3..6599c6124552 100644 +--- a/fs/exportfs/expfs.c ++++ b/fs/exportfs/expfs.c +@@ -76,7 +76,7 @@ static bool dentry_connected(struct dentry *dentry) + struct dentry *parent = dget_parent(dentry); + + dput(dentry); +- if (IS_ROOT(dentry)) { ++ if (dentry == parent) { + dput(parent); + return false; + } +diff --git a/fs/fscache/object.c b/fs/fscache/object.c +index 7a182c87f378..ab1d7f35f6c2 100644 +--- a/fs/fscache/object.c ++++ b/fs/fscache/object.c +@@ -715,6 +715,9 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob + + if (awaken) + wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING); ++ if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags)) ++ wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP); ++ + + /* Prevent a race with our last child, which has to signal EV_CLEARED + * before dropping our spinlock. +diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c +index 1ab19e660e69..1ff5774a5382 100644 +--- a/fs/hfs/btree.c ++++ b/fs/hfs/btree.c +@@ -328,13 +328,14 @@ void hfs_bmap_free(struct hfs_bnode *node) + + nidx -= len * 8; + i = node->next; +- hfs_bnode_put(node); + if (!i) { + /* panic */; + pr_crit("unable to free bnode %u. bmap not found!\n", + node->this); ++ hfs_bnode_put(node); + return; + } ++ hfs_bnode_put(node); + node = hfs_bnode_find(tree, i); + if (IS_ERR(node)) + return; +diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c +index 3345c7553edc..7adc8a327e03 100644 +--- a/fs/hfsplus/btree.c ++++ b/fs/hfsplus/btree.c +@@ -453,14 +453,15 @@ void hfs_bmap_free(struct hfs_bnode *node) + + nidx -= len * 8; + i = node->next; +- hfs_bnode_put(node); + if (!i) { + /* panic */; + pr_crit("unable to free bnode %u. " + "bmap not found!\n", + node->this); ++ hfs_bnode_put(node); + return; + } ++ hfs_bnode_put(node); + node = hfs_bnode_find(tree, i); + if (IS_ERR(node)) + return; +diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c +index a17da8b57fc6..ab34f613fa85 100644 +--- a/fs/hugetlbfs/inode.c ++++ b/fs/hugetlbfs/inode.c +@@ -118,6 +118,16 @@ static void huge_pagevec_release(struct pagevec *pvec) + pagevec_reinit(pvec); + } + ++/* ++ * Mask used when checking the page offset value passed in via system ++ * calls. This value will be converted to a loff_t which is signed. ++ * Therefore, we want to check the upper PAGE_SHIFT + 1 bits of the ++ * value. The extra bit (- 1 in the shift value) is to take the sign ++ * bit into account. ++ */ ++#define PGOFF_LOFFT_MAX \ ++ (((1UL << (PAGE_SHIFT + 1)) - 1) << (BITS_PER_LONG - (PAGE_SHIFT + 1))) ++ + static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) + { + struct inode *inode = file_inode(file); +@@ -136,17 +146,31 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) + vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; + vma->vm_ops = &hugetlb_vm_ops; + ++ /* ++ * page based offset in vm_pgoff could be sufficiently large to ++ * overflow a loff_t when converted to byte offset. This can ++ * only happen on architectures where sizeof(loff_t) == ++ * sizeof(unsigned long). So, only check in those instances. ++ */ ++ if (sizeof(unsigned long) == sizeof(loff_t)) { ++ if (vma->vm_pgoff & PGOFF_LOFFT_MAX) ++ return -EINVAL; ++ } ++ ++ /* must be huge page aligned */ + if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT)) + return -EINVAL; + + vma_len = (loff_t)(vma->vm_end - vma->vm_start); ++ len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); ++ /* check for overflow */ ++ if (len < vma_len) ++ return -EINVAL; + + mutex_lock(&inode->i_mutex); + file_accessed(file); + + ret = -ENOMEM; +- len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); +- + if (hugetlb_reserve_pages(inode, + vma->vm_pgoff >> huge_page_order(h), + len >> huge_page_shift(h), vma, +@@ -155,7 +179,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) + + ret = 0; + if (vma->vm_flags & VM_WRITE && inode->i_size < len) +- inode->i_size = len; ++ i_size_write(inode, len); + out: + mutex_unlock(&inode->i_mutex); + +diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c +index 827fc9809bc2..3494e220b510 100644 +--- a/fs/ocfs2/export.c ++++ b/fs/ocfs2/export.c +@@ -125,10 +125,10 @@ check_err: + + check_gen: + if (handle->ih_generation != inode->i_generation) { +- iput(inode); + trace_ocfs2_get_dentry_generation((unsigned long long)blkno, + handle->ih_generation, + inode->i_generation); ++ iput(inode); + result = ERR_PTR(-ESTALE); + goto bail; + } +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 124471d26a73..c1a83c58456e 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -156,18 +156,14 @@ out: + } + + /* +- * lock allocators, and reserving appropriate number of bits for +- * meta blocks and data clusters. +- * +- * in some cases, we don't need to reserve clusters, just let data_ac +- * be NULL. ++ * lock allocator, and reserve appropriate number of bits for ++ * meta blocks. + */ +-static int ocfs2_lock_allocators_move_extents(struct inode *inode, ++static int ocfs2_lock_meta_allocator_move_extents(struct inode *inode, + struct ocfs2_extent_tree *et, + u32 clusters_to_move, + u32 extents_to_split, + struct ocfs2_alloc_context **meta_ac, +- struct ocfs2_alloc_context **data_ac, + int extra_blocks, + int *credits) + { +@@ -192,13 +188,6 @@ static int ocfs2_lock_allocators_move_extents(struct inode *inode, + goto out; + } + +- if (data_ac) { +- ret = ocfs2_reserve_clusters(osb, clusters_to_move, data_ac); +- if (ret) { +- mlog_errno(ret); +- goto out; +- } +- } + + *credits += ocfs2_calc_extend_credits(osb->sb, et->et_root_el); + +@@ -260,10 +249,10 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context, + } + } + +- ret = ocfs2_lock_allocators_move_extents(inode, &context->et, *len, 1, +- &context->meta_ac, +- &context->data_ac, +- extra_blocks, &credits); ++ ret = ocfs2_lock_meta_allocator_move_extents(inode, &context->et, ++ *len, 1, ++ &context->meta_ac, ++ extra_blocks, &credits); + if (ret) { + mlog_errno(ret); + goto out; +@@ -286,6 +275,21 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context, + } + } + ++ /* ++ * Make sure ocfs2_reserve_cluster is called after ++ * __ocfs2_flush_truncate_log, otherwise, dead lock may happen. ++ * ++ * If ocfs2_reserve_cluster is called ++ * before __ocfs2_flush_truncate_log, dead lock on global bitmap ++ * may happen. ++ * ++ */ ++ ret = ocfs2_reserve_clusters(osb, *len, &context->data_ac); ++ if (ret) { ++ mlog_errno(ret); ++ goto out_unlock_mutex; ++ } ++ + handle = ocfs2_start_trans(osb, credits); + if (IS_ERR(handle)) { + ret = PTR_ERR(handle); +@@ -606,9 +610,10 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context, + } + } + +- ret = ocfs2_lock_allocators_move_extents(inode, &context->et, len, 1, +- &context->meta_ac, +- NULL, extra_blocks, &credits); ++ ret = ocfs2_lock_meta_allocator_move_extents(inode, &context->et, ++ len, 1, ++ &context->meta_ac, ++ extra_blocks, &credits); + if (ret) { + mlog_errno(ret); + goto out; +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 4beed301e224..bd8c26a409a7 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -254,7 +254,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + * Inherently racy -- command line shares address space + * with code and data. + */ +- rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0); ++ rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON); + if (rv <= 0) + goto out_free_page; + +@@ -272,7 +272,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + int nr_read; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -307,7 +307,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf, + bool final; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -356,7 +356,7 @@ skip_argv: + bool final; + + _count = min3(count, len, PAGE_SIZE); +- nr_read = access_remote_vm(mm, p, page, _count, 0); ++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON); + if (nr_read < 0) + rv = nr_read; + if (nr_read <= 0) +@@ -868,6 +868,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, + unsigned long addr = *ppos; + ssize_t copied; + char *page; ++ unsigned int flags; + + if (!mm) + return 0; +@@ -880,6 +881,11 @@ static ssize_t mem_rw(struct file *file, char __user *buf, + if (!atomic_inc_not_zero(&mm->mm_users)) + goto free; + ++ /* Maybe we should limit FOLL_FORCE to actual ptrace users? */ ++ flags = FOLL_FORCE; ++ if (write) ++ flags |= FOLL_WRITE; ++ + while (count > 0) { + int this_len = min_t(int, count, PAGE_SIZE); + +@@ -888,7 +894,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf, + break; + } + +- this_len = access_remote_vm(mm, addr, page, this_len, write); ++ this_len = access_remote_vm(mm, addr, page, this_len, flags); + if (!this_len) { + if (!copied) + copied = -EIO; +@@ -1000,8 +1006,7 @@ static ssize_t environ_read(struct file *file, char __user *buf, + max_len = min_t(size_t, PAGE_SIZE, count); + this_len = min(max_len, this_len); + +- retval = access_remote_vm(mm, (env_start + src), +- page, this_len, 0); ++ retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON); + + if (retval <= 0) { + ret = retval; +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index 588461bb2dd4..e97e7d74e134 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -392,8 +392,8 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) + } else { + spin_lock_irqsave(&psinfo->buf_lock, flags); + } +- memcpy(psinfo->buf, s, c); +- psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, 0, c, psinfo); ++ psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0, ++ s, 0, c, psinfo); + spin_unlock_irqrestore(&psinfo->buf_lock, flags); + s += c; + c = e - s; +diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c +index 02fa1dcc5969..29f5b2e589a1 100644 +--- a/fs/sysv/inode.c ++++ b/fs/sysv/inode.c +@@ -275,7 +275,7 @@ static int __sysv_write_inode(struct inode *inode, int wait) + } + } + brelse(bh); +- return 0; ++ return err; + } + + int sysv_write_inode(struct inode *inode, struct writeback_control *wbc) +diff --git a/include/linux/mm.h b/include/linux/mm.h +index d4e8077fca96..251adf4d8a71 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1191,7 +1191,7 @@ static inline int fixup_user_fault(struct task_struct *tsk, + + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); + extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, +- void *buf, int len, int write); ++ void *buf, int len, unsigned int gup_flags); + + long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +@@ -1199,19 +1199,17 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + struct vm_area_struct **vmas, int *nonblocking); + long get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, ++ unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas); + long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, +- int *locked); ++ unsigned int gup_flags, struct page **pages, int *locked); + long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, +- unsigned int gup_flags); ++ struct page **pages, unsigned int gup_flags); + long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages); ++ struct page **pages, unsigned int gup_flags); + int get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages); + +@@ -1229,7 +1227,7 @@ struct frame_vector { + struct frame_vector *frame_vector_create(unsigned int nr_frames); + void frame_vector_destroy(struct frame_vector *vec); + int get_vaddr_frames(unsigned long start, unsigned int nr_pfns, +- bool write, bool force, struct frame_vector *vec); ++ unsigned int gup_flags, struct frame_vector *vec); + void put_vaddr_frames(struct frame_vector *vec); + int frame_vector_to_pages(struct frame_vector *vec); + void frame_vector_to_pfns(struct frame_vector *vec); +@@ -2122,6 +2120,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, + #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ + #define FOLL_MLOCK 0x1000 /* lock present pages */ + #define FOLL_COW 0x4000 /* internal GUP flag */ ++#define FOLL_ANON 0x8000 /* don't do file mappings */ + + typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, + void *data); +diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h +index 907f3fd191ac..3e28a1a8d823 100644 +--- a/include/linux/posix-timers.h ++++ b/include/linux/posix-timers.h +@@ -65,8 +65,8 @@ struct k_itimer { + spinlock_t it_lock; + clockid_t it_clock; /* which timer type */ + timer_t it_id; /* timer id */ +- int it_overrun; /* overrun on pending signal */ +- int it_overrun_last; /* overrun on last delivered signal */ ++ s64 it_overrun; /* overrun on pending signal */ ++ s64 it_overrun_last; /* overrun on last delivered signal */ + int it_requeue_pending; /* waiting to requeue this timer */ + #define REQUEUE_PENDING 1 + int it_sigev_notify; /* notify word of sigevent struct */ +diff --git a/include/net/neighbour.h b/include/net/neighbour.h +index 8b683841e574..f6017ddc4ded 100644 +--- a/include/net/neighbour.h ++++ b/include/net/neighbour.h +@@ -448,6 +448,7 @@ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb) + + static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb) + { ++ unsigned int hh_alen = 0; + unsigned int seq; + int hh_len; + +@@ -455,16 +456,33 @@ static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb + seq = read_seqbegin(&hh->hh_lock); + hh_len = hh->hh_len; + if (likely(hh_len <= HH_DATA_MOD)) { +- /* this is inlined by gcc */ +- memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD); ++ hh_alen = HH_DATA_MOD; ++ ++ /* skb_push() would proceed silently if we have room for ++ * the unaligned size but not for the aligned size: ++ * check headroom explicitly. ++ */ ++ if (likely(skb_headroom(skb) >= HH_DATA_MOD)) { ++ /* this is inlined by gcc */ ++ memcpy(skb->data - HH_DATA_MOD, hh->hh_data, ++ HH_DATA_MOD); ++ } + } else { +- int hh_alen = HH_DATA_ALIGN(hh_len); ++ hh_alen = HH_DATA_ALIGN(hh_len); + +- memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); ++ if (likely(skb_headroom(skb) >= hh_alen)) { ++ memcpy(skb->data - hh_alen, hh->hh_data, ++ hh_alen); ++ } + } + } while (read_seqretry(&hh->hh_lock, seq)); + +- skb_push(skb, hh_len); ++ if (WARN_ON_ONCE(skb_headroom(skb) < hh_alen)) { ++ kfree_skb(skb); ++ return NET_XMIT_DROP; ++ } ++ ++ __skb_push(skb, hh_len); + return dev_queue_xmit(skb); + } + +diff --git a/include/sound/pcm.h b/include/sound/pcm.h +index b0be09279943..ffc161906d36 100644 +--- a/include/sound/pcm.h ++++ b/include/sound/pcm.h +@@ -100,7 +100,7 @@ struct snd_pcm_ops { + #endif + + #define SNDRV_PCM_IOCTL1_RESET 0 +-#define SNDRV_PCM_IOCTL1_INFO 1 ++/* 1 is absent slot. */ + #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 + #define SNDRV_PCM_IOCTL1_GSTATE 3 + #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 35dfa9e9d69e..c43ca9857479 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -191,6 +191,7 @@ struct bpf_insn_aux_data { + enum bpf_reg_type ptr_type; /* pointer type for load/store insns */ + struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */ + }; ++ int sanitize_stack_off; /* stack slot to be cleared */ + bool seen; /* this insn was processed by the verifier */ + }; + +@@ -569,10 +570,11 @@ static bool is_spillable_regtype(enum bpf_reg_type type) + /* check_stack_read/write functions track spill/fill of registers, + * stack boundary and alignment are checked in check_mem_access() + */ +-static int check_stack_write(struct verifier_state *state, int off, int size, +- int value_regno) ++static int check_stack_write(struct verifier_env *env, ++ struct verifier_state *state, int off, ++ int size, int value_regno, int insn_idx) + { +- int i; ++ int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE; + /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, + * so it's aligned access and [off, off + size) are within stack limits + */ +@@ -587,15 +589,37 @@ static int check_stack_write(struct verifier_state *state, int off, int size, + } + + /* save register state */ +- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = +- state->regs[value_regno]; +- +- for (i = 0; i < BPF_REG_SIZE; i++) ++ state->spilled_regs[spi] = state->regs[value_regno]; ++ ++ for (i = 0; i < BPF_REG_SIZE; i++) { ++ if (state->stack_slot_type[MAX_BPF_STACK + off + i] == STACK_MISC && ++ !env->allow_ptr_leaks) { ++ int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; ++ int soff = (-spi - 1) * BPF_REG_SIZE; ++ ++ /* detected reuse of integer stack slot with a pointer ++ * which means either llvm is reusing stack slot or ++ * an attacker is trying to exploit CVE-2018-3639 ++ * (speculative store bypass) ++ * Have to sanitize that slot with preemptive ++ * store of zero. ++ */ ++ if (*poff && *poff != soff) { ++ /* disallow programs where single insn stores ++ * into two different stack slots, since verifier ++ * cannot sanitize them ++ */ ++ verbose("insn %d cannot access two stack slots fp%d and fp%d", ++ insn_idx, *poff, soff); ++ return -EINVAL; ++ } ++ *poff = soff; ++ } + state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL; ++ } + } else { + /* regular write of data into stack */ +- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] = +- (struct reg_state) {}; ++ state->spilled_regs[spi] = (struct reg_state) {}; + + for (i = 0; i < size; i++) + state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC; +@@ -696,7 +720,7 @@ static bool is_ctx_reg(struct verifier_env *env, int regno) + * if t==write && value_regno==-1, some unknown value is stored into memory + * if t==read && value_regno==-1, don't care what we read from memory + */ +-static int check_mem_access(struct verifier_env *env, u32 regno, int off, ++static int check_mem_access(struct verifier_env *env, int insn_idx, u32 regno, int off, + int bpf_size, enum bpf_access_type t, + int value_regno) + { +@@ -748,7 +772,8 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off, + verbose("attempt to corrupt spilled pointer on stack\n"); + return -EACCES; + } +- err = check_stack_write(state, off, size, value_regno); ++ err = check_stack_write(env, state, off, size, ++ value_regno, insn_idx); + } else { + err = check_stack_read(state, off, size, value_regno); + } +@@ -760,7 +785,7 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off, + return err; + } + +-static int check_xadd(struct verifier_env *env, struct bpf_insn *insn) ++static int check_xadd(struct verifier_env *env, int insn_idx, struct bpf_insn *insn) + { + struct reg_state *regs = env->cur_state.regs; + int err; +@@ -793,13 +818,13 @@ static int check_xadd(struct verifier_env *env, struct bpf_insn *insn) + } + + /* check whether atomic_add can read the memory */ +- err = check_mem_access(env, insn->dst_reg, insn->off, ++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_READ, -1); + if (err) + return err; + + /* check whether atomic_add can write into the same memory */ +- return check_mem_access(env, insn->dst_reg, insn->off, ++ return check_mem_access(env, insn_idx, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_WRITE, -1); + } + +@@ -1838,13 +1863,14 @@ static int do_check(struct verifier_env *env) + /* check that memory (src_reg + off) is readable, + * the state of dst_reg will be updated by this func + */ +- err = check_mem_access(env, insn->src_reg, insn->off, ++ err = check_mem_access(env, insn_idx, insn->src_reg, insn->off, + BPF_SIZE(insn->code), BPF_READ, + insn->dst_reg); + if (err) + return err; + +- if (BPF_SIZE(insn->code) != BPF_W) { ++ if (BPF_SIZE(insn->code) != BPF_W && ++ BPF_SIZE(insn->code) != BPF_DW) { + insn_idx++; + continue; + } +@@ -1876,7 +1902,7 @@ static int do_check(struct verifier_env *env) + enum bpf_reg_type *prev_dst_type, dst_reg_type; + + if (BPF_MODE(insn->code) == BPF_XADD) { +- err = check_xadd(env, insn); ++ err = check_xadd(env, insn_idx, insn); + if (err) + return err; + insn_idx++; +@@ -1895,7 +1921,7 @@ static int do_check(struct verifier_env *env) + dst_reg_type = regs[insn->dst_reg].type; + + /* check that memory (dst_reg + off) is writeable */ +- err = check_mem_access(env, insn->dst_reg, insn->off, ++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_WRITE, + insn->src_reg); + if (err) +@@ -1930,7 +1956,7 @@ static int do_check(struct verifier_env *env) + } + + /* check that memory (dst_reg + off) is writeable */ +- err = check_mem_access(env, insn->dst_reg, insn->off, ++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off, + BPF_SIZE(insn->code), BPF_WRITE, + -1); + if (err) +@@ -2220,13 +2246,43 @@ static int convert_ctx_accesses(struct verifier_env *env) + for (i = 0; i < insn_cnt; i++, insn++) { + u32 cnt; + +- if (insn->code == (BPF_LDX | BPF_MEM | BPF_W)) ++ if (insn->code == (BPF_LDX | BPF_MEM | BPF_W) || ++ insn->code == (BPF_LDX | BPF_MEM | BPF_DW)) + type = BPF_READ; +- else if (insn->code == (BPF_STX | BPF_MEM | BPF_W)) ++ else if (insn->code == (BPF_STX | BPF_MEM | BPF_W) || ++ insn->code == (BPF_STX | BPF_MEM | BPF_DW)) + type = BPF_WRITE; + else + continue; + ++ if (type == BPF_WRITE && ++ env->insn_aux_data[i + delta].sanitize_stack_off) { ++ struct bpf_insn patch[] = { ++ /* Sanitize suspicious stack slot with zero. ++ * There are no memory dependencies for this store, ++ * since it's only using frame pointer and immediate ++ * constant of zero ++ */ ++ BPF_ST_MEM(BPF_DW, BPF_REG_FP, ++ env->insn_aux_data[i + delta].sanitize_stack_off, ++ 0), ++ /* the original STX instruction will immediately ++ * overwrite the same stack slot with appropriate value ++ */ ++ *insn, ++ }; ++ ++ cnt = ARRAY_SIZE(patch); ++ new_prog = bpf_patch_insn_data(env, i + delta, patch, cnt); ++ if (!new_prog) ++ return -ENOMEM; ++ ++ delta += cnt - 1; ++ env->prog = new_prog; ++ insn = new_prog->insnsi + i + delta; ++ continue; ++ } ++ + if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) + continue; + +diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c +index 7108097fa2f2..aad43c88a668 100644 +--- a/kernel/events/uprobes.c ++++ b/kernel/events/uprobes.c +@@ -299,7 +299,7 @@ int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr, + + retry: + /* Read the page with vaddr into memory */ +- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma); ++ ret = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page, &vma); + if (ret <= 0) + return ret; + +@@ -1700,7 +1700,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr) + if (likely(result == 0)) + goto out; + +- result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL); ++ result = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &page, NULL); + if (result < 0) + return result; + +diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c +index 80016b329d94..8fc68e60c795 100644 +--- a/kernel/time/posix-cpu-timers.c ++++ b/kernel/time/posix-cpu-timers.c +@@ -103,7 +103,7 @@ static void bump_cpu_timer(struct k_itimer *timer, + continue; + + timer->it.cpu.expires += incr; +- timer->it_overrun += 1 << i; ++ timer->it_overrun += 1LL << i; + delta -= incr; + } + } +diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c +index fc7c37ad90a0..0e6ed2e7d066 100644 +--- a/kernel/time/posix-timers.c ++++ b/kernel/time/posix-timers.c +@@ -355,6 +355,17 @@ static __init int init_posix_timers(void) + + __initcall(init_posix_timers); + ++/* ++ * The siginfo si_overrun field and the return value of timer_getoverrun(2) ++ * are of type int. Clamp the overrun value to INT_MAX ++ */ ++static inline int timer_overrun_to_int(struct k_itimer *timr, int baseval) ++{ ++ s64 sum = timr->it_overrun_last + (s64)baseval; ++ ++ return sum > (s64)INT_MAX ? INT_MAX : (int)sum; ++} ++ + static void schedule_next_timer(struct k_itimer *timr) + { + struct hrtimer *timer = &timr->it.real.timer; +@@ -362,12 +373,11 @@ static void schedule_next_timer(struct k_itimer *timr) + if (timr->it.real.interval.tv64 == 0) + return; + +- timr->it_overrun += (unsigned int) hrtimer_forward(timer, +- timer->base->get_time(), +- timr->it.real.interval); ++ timr->it_overrun += hrtimer_forward(timer, timer->base->get_time(), ++ timr->it.real.interval); + + timr->it_overrun_last = timr->it_overrun; +- timr->it_overrun = -1; ++ timr->it_overrun = -1LL; + ++timr->it_requeue_pending; + hrtimer_restart(timer); + } +@@ -396,7 +406,7 @@ void do_schedule_next_timer(struct siginfo *info) + else + schedule_next_timer(timr); + +- info->si_overrun += timr->it_overrun_last; ++ info->si_overrun = timer_overrun_to_int(timr, info->si_overrun); + } + + if (timr) +@@ -491,8 +501,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer) + now = ktime_add(now, kj); + } + #endif +- timr->it_overrun += (unsigned int) +- hrtimer_forward(timer, now, ++ timr->it_overrun += hrtimer_forward(timer, now, + timr->it.real.interval); + ret = HRTIMER_RESTART; + ++timr->it_requeue_pending; +@@ -633,7 +642,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, + it_id_set = IT_ID_SET; + new_timer->it_id = (timer_t) new_timer_id; + new_timer->it_clock = which_clock; +- new_timer->it_overrun = -1; ++ new_timer->it_overrun = -1LL; + + if (timer_event_spec) { + if (copy_from_user(&event, timer_event_spec, sizeof (event))) { +@@ -762,7 +771,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) + */ + if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING || + timr->it_sigev_notify == SIGEV_NONE)) +- timr->it_overrun += (unsigned int) hrtimer_forward(timer, now, iv); ++ timr->it_overrun += hrtimer_forward(timer, now, iv); + + remaining = __hrtimer_expires_remaining_adjusted(timer, now); + /* Return 0 only, when the timer is expired and not pending */ +@@ -824,7 +833,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) + if (!timr) + return -EINVAL; + +- overrun = timr->it_overrun_last; ++ overrun = timer_overrun_to_int(timr, 0); + unlock_timer(timr, flags); + + return overrun; +diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c +index 4228fd3682c3..3dd40c736067 100644 +--- a/kernel/trace/bpf_trace.c ++++ b/kernel/trace/bpf_trace.c +@@ -119,11 +119,13 @@ static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5) + i++; + } else if (fmt[i] == 'p' || fmt[i] == 's') { + mod[fmt_cnt]++; +- i++; +- if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0) ++ /* disallow any further format extensions */ ++ if (fmt[i + 1] != 0 && ++ !isspace(fmt[i + 1]) && ++ !ispunct(fmt[i + 1])) + return -EINVAL; + fmt_cnt++; +- if (fmt[i - 1] == 's') { ++ if (fmt[i] == 's') { + if (str_seen) + /* allow only one '%s' per fmt string */ + return -EINVAL; +diff --git a/lib/debugobjects.c b/lib/debugobjects.c +index a26328ec39f1..bb37541cd441 100644 +--- a/lib/debugobjects.c ++++ b/lib/debugobjects.c +@@ -1088,7 +1088,8 @@ void __init debug_objects_mem_init(void) + + obj_cache = kmem_cache_create("debug_objects_cache", + sizeof (struct debug_obj), 0, +- SLAB_DEBUG_OBJECTS, NULL); ++ SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE, ++ NULL); + + if (!obj_cache || debug_objects_replace_static_objects()) { + debug_objects_enabled = 0; +diff --git a/lib/swiotlb.c b/lib/swiotlb.c +index 771234d050c7..6bc452b33b76 100644 +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -17,6 +17,8 @@ + * 08/12/11 beckyb Add highmem support + */ + ++#define pr_fmt(fmt) "software IO TLB: " fmt ++ + #include + #include + #include +@@ -143,20 +145,16 @@ static bool no_iotlb_memory; + void swiotlb_print_info(void) + { + unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT; +- unsigned char *vstart, *vend; + + if (no_iotlb_memory) { +- pr_warn("software IO TLB: No low mem\n"); ++ pr_warn("No low mem\n"); + return; + } + +- vstart = phys_to_virt(io_tlb_start); +- vend = phys_to_virt(io_tlb_end); +- +- printk(KERN_INFO "software IO TLB [mem %#010llx-%#010llx] (%luMB) mapped at [%p-%p]\n", ++ pr_info("mapped [mem %#010llx-%#010llx] (%luMB)\n", + (unsigned long long)io_tlb_start, + (unsigned long long)io_tlb_end, +- bytes >> 20, vstart, vend - 1); ++ bytes >> 20); + } + + int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose) +@@ -230,7 +228,7 @@ swiotlb_init(int verbose) + if (io_tlb_start) + memblock_free_early(io_tlb_start, + PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); +- pr_warn("Cannot allocate SWIOTLB buffer"); ++ pr_warn("Cannot allocate buffer"); + no_iotlb_memory = true; + } + +@@ -272,8 +270,8 @@ swiotlb_late_init_with_default_size(size_t default_size) + return -ENOMEM; + } + if (order != get_order(bytes)) { +- printk(KERN_WARNING "Warning: only able to allocate %ld MB " +- "for software IO TLB\n", (PAGE_SIZE << order) >> 20); ++ pr_warn("only able to allocate %ld MB\n", ++ (PAGE_SIZE << order) >> 20); + io_tlb_nslabs = SLABS_PER_PAGE << order; + } + rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs); +@@ -680,7 +678,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, + return ret; + + err_warn: +- pr_warn("swiotlb: coherent allocation failed for device %s size=%zu\n", ++ pr_warn("coherent allocation failed for device %s size=%zu\n", + dev_name(hwdev), size); + dump_stack(); + +diff --git a/mm/frame_vector.c b/mm/frame_vector.c +index 7cf2b7163222..c1e7926a41c4 100644 +--- a/mm/frame_vector.c ++++ b/mm/frame_vector.c +@@ -11,10 +11,7 @@ + * get_vaddr_frames() - map virtual addresses to pfns + * @start: starting user address + * @nr_frames: number of pages / pfns from start to map +- * @write: whether pages will be written to by the caller +- * @force: whether to force write access even if user mapping is +- * readonly. See description of the same argument of +- get_user_pages(). ++ * @gup_flags: flags modifying lookup behaviour + * @vec: structure which receives pages / pfns of the addresses mapped. + * It should have space for at least nr_frames entries. + * +@@ -34,7 +31,7 @@ + * This function takes care of grabbing mmap_sem as necessary. + */ + int get_vaddr_frames(unsigned long start, unsigned int nr_frames, +- bool write, bool force, struct frame_vector *vec) ++ unsigned int gup_flags, struct frame_vector *vec) + { + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; +@@ -59,7 +56,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, + vec->got_ref = true; + vec->is_pfns = false; + ret = get_user_pages_locked(current, mm, start, nr_frames, +- write, force, (struct page **)(vec->ptrs), &locked); ++ gup_flags, (struct page **)(vec->ptrs), &locked); + goto out; + } + +diff --git a/mm/gup.c b/mm/gup.c +index 018144c4b9ec..2cd3b31e3666 100644 +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -368,6 +368,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) + if (vm_flags & (VM_IO | VM_PFNMAP)) + return -EFAULT; + ++ if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma)) ++ return -EFAULT; ++ + if (gup_flags & FOLL_WRITE) { + if (!(vm_flags & VM_WRITE)) { + if (!(gup_flags & FOLL_FORCE)) +@@ -627,7 +630,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, + struct mm_struct *mm, + unsigned long start, + unsigned long nr_pages, +- int write, int force, + struct page **pages, + struct vm_area_struct **vmas, + int *locked, bool notify_drop, +@@ -645,10 +647,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, + + if (pages) + flags |= FOLL_GET; +- if (write) +- flags |= FOLL_WRITE; +- if (force) +- flags |= FOLL_FORCE; + + pages_done = 0; + lock_dropped = false; +@@ -742,11 +740,12 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, + */ + long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, ++ unsigned int gup_flags, struct page **pages, + int *locked) + { +- return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, +- pages, NULL, locked, true, FOLL_TOUCH); ++ return __get_user_pages_locked(tsk, mm, start, nr_pages, ++ pages, NULL, locked, true, ++ gup_flags | FOLL_TOUCH); + } + EXPORT_SYMBOL(get_user_pages_locked); + +@@ -762,14 +761,14 @@ EXPORT_SYMBOL(get_user_pages_locked); + */ + __always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, +- unsigned int gup_flags) ++ struct page **pages, unsigned int gup_flags) + { + long ret; + int locked = 1; ++ + down_read(&mm->mmap_sem); +- ret = __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, +- pages, NULL, &locked, false, gup_flags); ++ ret = __get_user_pages_locked(tsk, mm, start, nr_pages, pages, NULL, ++ &locked, false, gup_flags); + if (locked) + up_read(&mm->mmap_sem); + return ret; +@@ -795,10 +794,10 @@ EXPORT_SYMBOL(__get_user_pages_unlocked); + */ + long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages) ++ struct page **pages, unsigned int gup_flags) + { +- return __get_user_pages_unlocked(tsk, mm, start, nr_pages, write, +- force, pages, FOLL_TOUCH); ++ return __get_user_pages_unlocked(tsk, mm, start, nr_pages, ++ pages, gup_flags | FOLL_TOUCH); + } + EXPORT_SYMBOL(get_user_pages_unlocked); + +@@ -858,11 +857,13 @@ EXPORT_SYMBOL(get_user_pages_unlocked); + * FAULT_FLAG_ALLOW_RETRY to handle_mm_fault. + */ + long get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +- unsigned long start, unsigned long nr_pages, int write, +- int force, struct page **pages, struct vm_area_struct **vmas) ++ unsigned long start, unsigned long nr_pages, ++ unsigned int gup_flags, struct page **pages, ++ struct vm_area_struct **vmas) + { +- return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, +- pages, vmas, NULL, false, FOLL_TOUCH); ++ return __get_user_pages_locked(tsk, mm, start, nr_pages, ++ pages, vmas, NULL, false, ++ gup_flags | FOLL_TOUCH); + } + EXPORT_SYMBOL(get_user_pages); + +@@ -1411,7 +1412,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, + pages += nr; + + ret = get_user_pages_unlocked(current, mm, start, +- nr_pages - nr, write, 0, pages); ++ nr_pages - nr, pages, ++ write ? FOLL_WRITE : 0); + + /* Have to be a bit careful with return values */ + if (nr > 0) { +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index 6f99a0f906bb..f1a45f5077fe 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4053,6 +4053,14 @@ int hugetlb_reserve_pages(struct inode *inode, + struct resv_map *resv_map; + long gbl_reserve; + ++ /* This should never happen */ ++ if (from > to) { ++#ifdef CONFIG_DEBUG_VM ++ WARN(1, "%s called with a negative range\n", __func__); ++#endif ++ return -EINVAL; ++ } ++ + /* + * Only apply hugepage reservation if asked. At fault time, an + * attempt will be made for VM_NORESERVE to allocate a page +@@ -4142,7 +4150,9 @@ int hugetlb_reserve_pages(struct inode *inode, + return 0; + out_err: + if (!vma || vma->vm_flags & VM_MAYSHARE) +- region_abort(resv_map, from, to); ++ /* Don't call region_abort if region_chg failed */ ++ if (chg >= 0) ++ region_abort(resv_map, from, to); + if (vma && is_vma_resv_set(vma, HPAGE_RESV_OWNER)) + kref_put(&resv_map->refs, resv_map_release); + return ret; +diff --git a/mm/memory.c b/mm/memory.c +index 5aee9ec8b8c6..fa752df6dc85 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -3711,10 +3711,11 @@ EXPORT_SYMBOL_GPL(generic_access_phys); + * given task for page fault accounting. + */ + static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, +- unsigned long addr, void *buf, int len, int write) ++ unsigned long addr, void *buf, int len, unsigned int gup_flags) + { + struct vm_area_struct *vma; + void *old_buf = buf; ++ int write = gup_flags & FOLL_WRITE; + + down_read(&mm->mmap_sem); + /* ignore errors, just check how much was successfully transferred */ +@@ -3724,7 +3725,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, + struct page *page = NULL; + + ret = get_user_pages(tsk, mm, addr, 1, +- write, 1, &page, &vma); ++ gup_flags, &page, &vma); + if (ret <= 0) { + #ifndef CONFIG_HAVE_IOREMAP_PROT + break; +@@ -3776,14 +3777,14 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, + * @addr: start address to access + * @buf: source or destination buffer + * @len: number of bytes to transfer +- * @write: whether the access is a write ++ * @gup_flags: flags modifying lookup behaviour + * + * The caller must hold a reference on @mm. + */ + int access_remote_vm(struct mm_struct *mm, unsigned long addr, +- void *buf, int len, int write) ++ void *buf, int len, unsigned int gup_flags) + { +- return __access_remote_vm(NULL, mm, addr, buf, len, write); ++ return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags); + } + + /* +@@ -3796,12 +3797,17 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, + { + struct mm_struct *mm; + int ret; ++ unsigned int flags = FOLL_FORCE; + + mm = get_task_mm(tsk); + if (!mm) + return 0; + +- ret = __access_remote_vm(tsk, mm, addr, buf, len, write); ++ if (write) ++ flags |= FOLL_WRITE; ++ ++ ret = __access_remote_vm(tsk, mm, addr, buf, len, flags); ++ + mmput(mm); + + return ret; +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index be9840bf11d1..44134ba6fb53 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -818,7 +818,7 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr) + struct page *p; + int err; + +- err = get_user_pages(current, mm, addr & PAGE_MASK, 1, 0, 0, &p, NULL); ++ err = get_user_pages(current, mm, addr & PAGE_MASK, 1, 0, &p, NULL); + if (err >= 0) { + err = page_to_nid(p); + put_page(p); +diff --git a/mm/nommu.c b/mm/nommu.c +index 92be862c859b..2360546db065 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -184,40 +184,32 @@ finish_or_fault: + */ + long get_user_pages(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, ++ unsigned int gup_flags, struct page **pages, + struct vm_area_struct **vmas) + { +- int flags = 0; +- +- if (write) +- flags |= FOLL_WRITE; +- if (force) +- flags |= FOLL_FORCE; +- +- return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas, +- NULL); ++ return __get_user_pages(tsk, mm, start, nr_pages, ++ gup_flags, pages, vmas, NULL); + } + EXPORT_SYMBOL(get_user_pages); + + long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, ++ unsigned int gup_flags, struct page **pages, + int *locked) + { +- return get_user_pages(tsk, mm, start, nr_pages, write, force, ++ return get_user_pages(tsk, mm, start, nr_pages, gup_flags, + pages, NULL); + } + EXPORT_SYMBOL(get_user_pages_locked); + + long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages, +- unsigned int gup_flags) ++ struct page **pages, unsigned int gup_flags) + { + long ret; + down_read(&mm->mmap_sem); +- ret = get_user_pages(tsk, mm, start, nr_pages, write, force, +- pages, NULL); ++ ret = __get_user_pages(tsk, mm, start, nr_pages, gup_flags, pages, ++ NULL, NULL); + up_read(&mm->mmap_sem); + return ret; + } +@@ -225,10 +217,10 @@ EXPORT_SYMBOL(__get_user_pages_unlocked); + + long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm, + unsigned long start, unsigned long nr_pages, +- int write, int force, struct page **pages) ++ struct page **pages, unsigned int gup_flags) + { +- return __get_user_pages_unlocked(tsk, mm, start, nr_pages, write, +- force, pages, 0); ++ return __get_user_pages_unlocked(tsk, mm, start, nr_pages, ++ pages, gup_flags); + } + EXPORT_SYMBOL(get_user_pages_unlocked); + +@@ -1937,9 +1929,10 @@ void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf) + EXPORT_SYMBOL(filemap_map_pages); + + static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, +- unsigned long addr, void *buf, int len, int write) ++ unsigned long addr, void *buf, int len, unsigned int gup_flags) + { + struct vm_area_struct *vma; ++ int write = gup_flags & FOLL_WRITE; + + down_read(&mm->mmap_sem); + +@@ -1974,14 +1967,14 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm, + * @addr: start address to access + * @buf: source or destination buffer + * @len: number of bytes to transfer +- * @write: whether the access is a write ++ * @gup_flags: flags modifying lookup behaviour + * + * The caller must hold a reference on @mm. + */ + int access_remote_vm(struct mm_struct *mm, unsigned long addr, +- void *buf, int len, int write) ++ void *buf, int len, unsigned int gup_flags) + { +- return __access_remote_vm(NULL, mm, addr, buf, len, write); ++ return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags); + } + + /* +@@ -1999,7 +1992,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in + if (!mm) + return 0; + +- len = __access_remote_vm(tsk, mm, addr, buf, len, write); ++ len = __access_remote_vm(tsk, mm, addr, buf, len, ++ write ? FOLL_WRITE : 0); + + mmput(mm); + return len; +diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c +index 5d453e58ddbf..1b5a6104c5fc 100644 +--- a/mm/process_vm_access.c ++++ b/mm/process_vm_access.c +@@ -88,19 +88,23 @@ static int process_vm_rw_single_vec(unsigned long addr, + ssize_t rc = 0; + unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES + / sizeof(struct pages *); ++ unsigned int flags = 0; + + /* Work out address and page range required */ + if (len == 0) + return 0; + nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1; + ++ if (vm_write) ++ flags |= FOLL_WRITE; ++ + while (!rc && nr_pages && iov_iter_count(iter)) { + int pages = min(nr_pages, max_pages_per_loop); + size_t bytes; + + /* Get the pages we're interested in */ + pages = get_user_pages_unlocked(task, mm, pa, pages, +- vm_write, 0, process_pages); ++ process_pages, flags); + if (pages <= 0) + return -EFAULT; + +diff --git a/mm/util.c b/mm/util.c +index 5fae5b9c2885..db39235970c6 100644 +--- a/mm/util.c ++++ b/mm/util.c +@@ -278,7 +278,7 @@ int __weak get_user_pages_fast(unsigned long start, + { + struct mm_struct *mm = current->mm; + return get_user_pages_unlocked(current, mm, start, nr_pages, +- write, 0, pages); ++ pages, write ? FOLL_WRITE : 0); + } + EXPORT_SYMBOL_GPL(get_user_pages_fast); + +diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c +index d4f5f220a8e5..28453d698d86 100644 +--- a/net/ceph/pagevec.c ++++ b/net/ceph/pagevec.c +@@ -26,7 +26,7 @@ struct page **ceph_get_direct_page_vector(const void __user *data, + while (got < num_pages) { + rc = get_user_pages_unlocked(current, current->mm, + (unsigned long)data + ((unsigned long)got * PAGE_SIZE), +- num_pages - got, write_page, 0, pages + got); ++ num_pages - got, pages + got, write_page ? FOLL_WRITE : 0); + if (rc < 0) + break; + BUG_ON(rc == 0); +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index d2a46ffe6382..d52b633164c9 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -2931,6 +2931,9 @@ int ndo_dflt_fdb_dump(struct sk_buff *skb, + { + int err; + ++ if (dev->type != ARPHRD_ETHER) ++ return -EINVAL; ++ + netif_addr_lock_bh(dev); + err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc); + if (err) +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c +index 2d3c9df8d75c..b55b8954dae5 100644 +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2263,14 +2263,18 @@ void tcp_send_loss_probe(struct sock *sk) + skb = tcp_write_queue_tail(sk); + } + ++ if (unlikely(!skb)) { ++ WARN_ONCE(tp->packets_out, ++ "invalid inflight: %u state %u cwnd %u mss %d\n", ++ tp->packets_out, sk->sk_state, tp->snd_cwnd, mss); ++ inet_csk(sk)->icsk_pending = 0; ++ return; ++ } ++ + /* At most one outstanding TLP retransmission. */ + if (tp->tlp_high_seq) + goto rearm_timer; + +- /* Retransmit last segment. */ +- if (WARN_ON(!skb)) +- goto rearm_timer; +- + if (skb_still_in_host_queue(sk, skb)) + goto rearm_timer; + +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 530b62fd6b64..f8cca81d66f2 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -169,37 +169,37 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, + const struct ipv6_pinfo *np = inet6_sk(sk); + struct in6_addr *first_hop = &fl6->daddr; + struct dst_entry *dst = skb_dst(skb); ++ unsigned int head_room; + struct ipv6hdr *hdr; + u8 proto = fl6->flowi6_proto; + int seg_len = skb->len; + int hlimit = -1; + u32 mtu; + +- if (opt) { +- unsigned int head_room; ++ head_room = sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev); ++ if (opt) ++ head_room += opt->opt_nflen + opt->opt_flen; + +- /* First: exthdrs may take lots of space (~8K for now) +- MAX_HEADER is not enough. +- */ +- head_room = opt->opt_nflen + opt->opt_flen; +- seg_len += head_room; +- head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev); +- +- if (skb_headroom(skb) < head_room) { +- struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); +- if (!skb2) { +- IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), +- IPSTATS_MIB_OUTDISCARDS); +- kfree_skb(skb); +- return -ENOBUFS; +- } +- if (skb->sk) +- skb_set_owner_w(skb2, skb->sk); +- consume_skb(skb); +- skb = skb2; ++ if (unlikely(skb_headroom(skb) < head_room)) { ++ struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); ++ if (!skb2) { ++ IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), ++ IPSTATS_MIB_OUTDISCARDS); ++ kfree_skb(skb); ++ return -ENOBUFS; + } ++ if (skb->sk) ++ skb_set_owner_w(skb2, skb->sk); ++ consume_skb(skb); ++ skb = skb2; ++ } ++ ++ if (opt) { ++ seg_len += opt->opt_nflen + opt->opt_flen; ++ + if (opt->opt_flen) + ipv6_push_frag_opts(skb, opt, &proto); ++ + if (opt->opt_nflen) + ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop); + } +diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c +index 743ff23885da..7acf1f2b8dfc 100644 +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -432,6 +432,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) + int count = 1; + int rc = NET_XMIT_SUCCESS; + ++ /* Do not fool qdisc_drop_all() */ ++ skb->prev = NULL; ++ + /* Random duplication */ + if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) + ++count; +diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c +index 38651454ed08..6f388e77999c 100644 +--- a/security/tomoyo/domain.c ++++ b/security/tomoyo/domain.c +@@ -874,7 +874,8 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos, + } + /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */ + #ifdef CONFIG_MMU +- if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) ++ if (get_user_pages(current, bprm->mm, pos, 1, ++ FOLL_FORCE, &page, NULL) <= 0) + return false; + #else + page = bprm->page[pos / PAGE_SIZE]; +diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c +index 5bc7ddf8fc70..3ce2b8771762 100644 +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -1849,8 +1849,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, + unsigned int cmd, void *arg) + { + switch (cmd) { +- case SNDRV_PCM_IOCTL1_INFO: +- return 0; + case SNDRV_PCM_IOCTL1_RESET: + return snd_pcm_lib_ioctl_reset(substream, arg); + case SNDRV_PCM_IOCTL1_CHANNEL_INFO: +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index 0ad194002c0c..9b6dcdea4431 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -214,11 +214,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info) + info->subdevices_avail = pstr->substream_count - pstr->substream_opened; + strlcpy(info->subname, substream->name, sizeof(info->subname)); + runtime = substream->runtime; +- /* AB: FIXME!!! This is definitely nonsense */ +- if (runtime) { +- info->sync = runtime->sync; +- substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info); +- } ++ + return 0; + } + +diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c +index 09db2aec12a3..776e809a8aab 100644 +--- a/sound/soc/omap/omap-dmic.c ++++ b/sound/soc/omap/omap-dmic.c +@@ -48,6 +48,8 @@ struct omap_dmic { + struct device *dev; + void __iomem *io_base; + struct clk *fclk; ++ struct pm_qos_request pm_qos_req; ++ int latency; + int fclk_freq; + int out_freq; + int clk_div; +@@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream, + + mutex_lock(&dmic->mutex); + ++ pm_qos_remove_request(&dmic->pm_qos_req); ++ + if (!dai->active) + dmic->active = 0; + +@@ -226,6 +230,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, + /* packet size is threshold * channels */ + dma_data = snd_soc_dai_get_dma_data(dai, substream); + dma_data->maxburst = dmic->threshold * channels; ++ dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC / ++ params_rate(params); + + return 0; + } +@@ -236,6 +242,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream, + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + u32 ctrl; + ++ if (pm_qos_request_active(&dmic->pm_qos_req)) ++ pm_qos_update_request(&dmic->pm_qos_req, dmic->latency); ++ + /* Configure uplink threshold */ + omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold); + +diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c +index 8d0d45d330e7..8eb2d12b6a34 100644 +--- a/sound/soc/omap/omap-mcpdm.c ++++ b/sound/soc/omap/omap-mcpdm.c +@@ -54,6 +54,8 @@ struct omap_mcpdm { + unsigned long phys_base; + void __iomem *io_base; + int irq; ++ struct pm_qos_request pm_qos_req; ++ int latency[2]; + + struct mutex mutex; + +@@ -273,6 +275,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { + struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); ++ int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); ++ int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; ++ int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + + mutex_lock(&mcpdm->mutex); + +@@ -285,6 +290,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, + } + } + ++ if (mcpdm->latency[stream2]) ++ pm_qos_update_request(&mcpdm->pm_qos_req, ++ mcpdm->latency[stream2]); ++ else if (mcpdm->latency[stream1]) ++ pm_qos_remove_request(&mcpdm->pm_qos_req); ++ ++ mcpdm->latency[stream1] = 0; ++ + mutex_unlock(&mcpdm->mutex); + } + +@@ -296,7 +309,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, + int stream = substream->stream; + struct snd_dmaengine_dai_dma_data *dma_data; + u32 threshold; +- int channels; ++ int channels, latency; + int link_mask = 0; + + channels = params_channels(params); +@@ -336,14 +349,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, + + dma_data->maxburst = + (MCPDM_DN_THRES_MAX - threshold) * channels; ++ latency = threshold; + } else { + /* If playback is not running assume a stereo stream to come */ + if (!mcpdm->config[!stream].link_mask) + mcpdm->config[!stream].link_mask = (0x3 << 3); + + dma_data->maxburst = threshold * channels; ++ latency = (MCPDM_DN_THRES_MAX - threshold); + } + ++ /* ++ * The DMA must act to a DMA request within latency time (usec) to avoid ++ * under/overflow ++ */ ++ mcpdm->latency[stream] = latency * USEC_PER_SEC / params_rate(params); ++ ++ if (!mcpdm->latency[stream]) ++ mcpdm->latency[stream] = 10; ++ + /* Check if we need to restart McPDM with this stream */ + if (mcpdm->config[stream].link_mask && + mcpdm->config[stream].link_mask != link_mask) +@@ -358,6 +382,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { + struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); ++ struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req; ++ int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); ++ int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; ++ int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; ++ int latency = mcpdm->latency[stream2]; ++ ++ /* Prevent omap hardware from hitting off between FIFO fills */ ++ if (!latency || mcpdm->latency[stream1] < latency) ++ latency = mcpdm->latency[stream1]; ++ ++ if (pm_qos_request_active(pm_qos_req)) ++ pm_qos_update_request(pm_qos_req, latency); ++ else if (latency) ++ pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); + + if (!omap_mcpdm_active(mcpdm)) { + omap_mcpdm_start(mcpdm); +@@ -419,6 +457,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) + free_irq(mcpdm->irq, (void *)mcpdm); + pm_runtime_disable(mcpdm->dev); + ++ if (pm_qos_request_active(&mcpdm->pm_qos_req)) ++ pm_qos_remove_request(&mcpdm->pm_qos_req); ++ + return 0; + } + +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index fa6b74a304a7..b927f9c81d92 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -1711,6 +1711,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) + } + + card->instantiated = 1; ++ dapm_mark_endpoints_dirty(card); + snd_soc_dapm_sync(&card->dapm); + mutex_unlock(&card->mutex); + mutex_unlock(&client_mutex); +diff --git a/tools/testing/selftests/networking/timestamping/.gitignore b/tools/testing/selftests/networking/timestamping/.gitignore +new file mode 100644 +index 000000000000..9e69e982fb38 +--- /dev/null ++++ b/tools/testing/selftests/networking/timestamping/.gitignore +@@ -0,0 +1,3 @@ ++timestamping ++txtimestamp ++hwtstamp_config +diff --git a/tools/testing/selftests/networking/timestamping/Makefile b/tools/testing/selftests/networking/timestamping/Makefile +new file mode 100644 +index 000000000000..ccbb9edbbbb9 +--- /dev/null ++++ b/tools/testing/selftests/networking/timestamping/Makefile +@@ -0,0 +1,8 @@ ++TEST_PROGS := hwtstamp_config timestamping txtimestamp ++ ++all: $(TEST_PROGS) ++ ++include ../../lib.mk ++ ++clean: ++ rm -fr $(TEST_PROGS) +diff --git a/tools/testing/selftests/networking/timestamping/hwtstamp_config.c b/tools/testing/selftests/networking/timestamping/hwtstamp_config.c +new file mode 100644 +index 000000000000..e8b685a7f15f +--- /dev/null ++++ b/tools/testing/selftests/networking/timestamping/hwtstamp_config.c +@@ -0,0 +1,134 @@ ++/* Test program for SIOC{G,S}HWTSTAMP ++ * Copyright 2013 Solarflare Communications ++ * Author: Ben Hutchings ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++static int ++lookup_value(const char **names, int size, const char *name) ++{ ++ int value; ++ ++ for (value = 0; value < size; value++) ++ if (names[value] && strcasecmp(names[value], name) == 0) ++ return value; ++ ++ return -1; ++} ++ ++static const char * ++lookup_name(const char **names, int size, int value) ++{ ++ return (value >= 0 && value < size) ? names[value] : NULL; ++} ++ ++static void list_names(FILE *f, const char **names, int size) ++{ ++ int value; ++ ++ for (value = 0; value < size; value++) ++ if (names[value]) ++ fprintf(f, " %s\n", names[value]); ++} ++ ++static const char *tx_types[] = { ++#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name ++ TX_TYPE(OFF), ++ TX_TYPE(ON), ++ TX_TYPE(ONESTEP_SYNC) ++#undef TX_TYPE ++}; ++#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0]))) ++ ++static const char *rx_filters[] = { ++#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name ++ RX_FILTER(NONE), ++ RX_FILTER(ALL), ++ RX_FILTER(SOME), ++ RX_FILTER(PTP_V1_L4_EVENT), ++ RX_FILTER(PTP_V1_L4_SYNC), ++ RX_FILTER(PTP_V1_L4_DELAY_REQ), ++ RX_FILTER(PTP_V2_L4_EVENT), ++ RX_FILTER(PTP_V2_L4_SYNC), ++ RX_FILTER(PTP_V2_L4_DELAY_REQ), ++ RX_FILTER(PTP_V2_L2_EVENT), ++ RX_FILTER(PTP_V2_L2_SYNC), ++ RX_FILTER(PTP_V2_L2_DELAY_REQ), ++ RX_FILTER(PTP_V2_EVENT), ++ RX_FILTER(PTP_V2_SYNC), ++ RX_FILTER(PTP_V2_DELAY_REQ), ++#undef RX_FILTER ++}; ++#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0]))) ++ ++static void usage(void) ++{ ++ fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n" ++ "tx_type is any of (case-insensitive):\n", ++ stderr); ++ list_names(stderr, tx_types, N_TX_TYPES); ++ fputs("rx_filter is any of (case-insensitive):\n", stderr); ++ list_names(stderr, rx_filters, N_RX_FILTERS); ++} ++ ++int main(int argc, char **argv) ++{ ++ struct ifreq ifr; ++ struct hwtstamp_config config; ++ const char *name; ++ int sock; ++ ++ if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) { ++ usage(); ++ return 2; ++ } ++ ++ if (argc == 4) { ++ config.flags = 0; ++ config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]); ++ config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]); ++ if (config.tx_type < 0 || config.rx_filter < 0) { ++ usage(); ++ return 2; ++ } ++ } ++ ++ sock = socket(AF_INET, SOCK_DGRAM, 0); ++ if (sock < 0) { ++ perror("socket"); ++ return 1; ++ } ++ ++ strcpy(ifr.ifr_name, argv[1]); ++ ifr.ifr_data = (caddr_t)&config; ++ ++ if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) { ++ perror("ioctl"); ++ return 1; ++ } ++ ++ printf("flags = %#x\n", config.flags); ++ name = lookup_name(tx_types, N_TX_TYPES, config.tx_type); ++ if (name) ++ printf("tx_type = %s\n", name); ++ else ++ printf("tx_type = %d\n", config.tx_type); ++ name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter); ++ if (name) ++ printf("rx_filter = %s\n", name); ++ else ++ printf("rx_filter = %d\n", config.rx_filter); ++ ++ return 0; ++} +diff --git a/tools/testing/selftests/networking/timestamping/timestamping.c b/tools/testing/selftests/networking/timestamping/timestamping.c +new file mode 100644 +index 000000000000..5cdfd743447b +--- /dev/null ++++ b/tools/testing/selftests/networking/timestamping/timestamping.c +@@ -0,0 +1,528 @@ ++/* ++ * This program demonstrates how the various time stamping features in ++ * the Linux kernel work. It emulates the behavior of a PTP ++ * implementation in stand-alone master mode by sending PTPv1 Sync ++ * multicasts once every second. It looks for similar packets, but ++ * beyond that doesn't actually implement PTP. ++ * ++ * Outgoing packets are time stamped with SO_TIMESTAMPING with or ++ * without hardware support. ++ * ++ * Incoming packets are time stamped with SO_TIMESTAMPING with or ++ * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and ++ * SO_TIMESTAMP[NS]. ++ * ++ * Copyright (C) 2009 Intel Corporation. ++ * Author: Patrick Ohly ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#ifndef SO_TIMESTAMPING ++# define SO_TIMESTAMPING 37 ++# define SCM_TIMESTAMPING SO_TIMESTAMPING ++#endif ++ ++#ifndef SO_TIMESTAMPNS ++# define SO_TIMESTAMPNS 35 ++#endif ++ ++#ifndef SIOCGSTAMPNS ++# define SIOCGSTAMPNS 0x8907 ++#endif ++ ++#ifndef SIOCSHWTSTAMP ++# define SIOCSHWTSTAMP 0x89b0 ++#endif ++ ++static void usage(const char *error) ++{ ++ if (error) ++ printf("invalid option: %s\n", error); ++ printf("timestamping interface option*\n\n" ++ "Options:\n" ++ " IP_MULTICAST_LOOP - looping outgoing multicasts\n" ++ " SO_TIMESTAMP - normal software time stamping, ms resolution\n" ++ " SO_TIMESTAMPNS - more accurate software time stamping\n" ++ " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n" ++ " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n" ++ " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n" ++ " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n" ++ " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n" ++ " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n" ++ " SIOCGSTAMP - check last socket time stamp\n" ++ " SIOCGSTAMPNS - more accurate socket time stamp\n"); ++ exit(1); ++} ++ ++static void bail(const char *error) ++{ ++ printf("%s: %s\n", error, strerror(errno)); ++ exit(1); ++} ++ ++static const unsigned char sync[] = { ++ 0x00, 0x01, 0x00, 0x01, ++ 0x5f, 0x44, 0x46, 0x4c, ++ 0x54, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x01, ++ ++ /* fake uuid */ ++ 0x00, 0x01, ++ 0x02, 0x03, 0x04, 0x05, ++ ++ 0x00, 0x01, 0x00, 0x37, ++ 0x00, 0x00, 0x00, 0x08, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x49, 0x05, 0xcd, 0x01, ++ 0x29, 0xb1, 0x8d, 0xb0, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x01, ++ ++ /* fake uuid */ ++ 0x00, 0x01, ++ 0x02, 0x03, 0x04, 0x05, ++ ++ 0x00, 0x00, 0x00, 0x37, ++ 0x00, 0x00, 0x00, 0x04, ++ 0x44, 0x46, 0x4c, 0x54, ++ 0x00, 0x00, 0xf0, 0x60, ++ 0x00, 0x01, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x01, ++ 0x00, 0x00, 0xf0, 0x60, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x04, ++ 0x44, 0x46, 0x4c, 0x54, ++ 0x00, 0x01, ++ ++ /* fake uuid */ ++ 0x00, 0x01, ++ 0x02, 0x03, 0x04, 0x05, ++ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00 ++}; ++ ++static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len) ++{ ++ struct timeval now; ++ int res; ++ ++ res = sendto(sock, sync, sizeof(sync), 0, ++ addr, addr_len); ++ gettimeofday(&now, 0); ++ if (res < 0) ++ printf("%s: %s\n", "send", strerror(errno)); ++ else ++ printf("%ld.%06ld: sent %d bytes\n", ++ (long)now.tv_sec, (long)now.tv_usec, ++ res); ++} ++ ++static void printpacket(struct msghdr *msg, int res, ++ char *data, ++ int sock, int recvmsg_flags, ++ int siocgstamp, int siocgstampns) ++{ ++ struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name; ++ struct cmsghdr *cmsg; ++ struct timeval tv; ++ struct timespec ts; ++ struct timeval now; ++ ++ gettimeofday(&now, 0); ++ ++ printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n", ++ (long)now.tv_sec, (long)now.tv_usec, ++ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", ++ res, ++ inet_ntoa(from_addr->sin_addr), ++ msg->msg_controllen); ++ for (cmsg = CMSG_FIRSTHDR(msg); ++ cmsg; ++ cmsg = CMSG_NXTHDR(msg, cmsg)) { ++ printf(" cmsg len %zu: ", cmsg->cmsg_len); ++ switch (cmsg->cmsg_level) { ++ case SOL_SOCKET: ++ printf("SOL_SOCKET "); ++ switch (cmsg->cmsg_type) { ++ case SO_TIMESTAMP: { ++ struct timeval *stamp = ++ (struct timeval *)CMSG_DATA(cmsg); ++ printf("SO_TIMESTAMP %ld.%06ld", ++ (long)stamp->tv_sec, ++ (long)stamp->tv_usec); ++ break; ++ } ++ case SO_TIMESTAMPNS: { ++ struct timespec *stamp = ++ (struct timespec *)CMSG_DATA(cmsg); ++ printf("SO_TIMESTAMPNS %ld.%09ld", ++ (long)stamp->tv_sec, ++ (long)stamp->tv_nsec); ++ break; ++ } ++ case SO_TIMESTAMPING: { ++ struct timespec *stamp = ++ (struct timespec *)CMSG_DATA(cmsg); ++ printf("SO_TIMESTAMPING "); ++ printf("SW %ld.%09ld ", ++ (long)stamp->tv_sec, ++ (long)stamp->tv_nsec); ++ stamp++; ++ /* skip deprecated HW transformed */ ++ stamp++; ++ printf("HW raw %ld.%09ld", ++ (long)stamp->tv_sec, ++ (long)stamp->tv_nsec); ++ break; ++ } ++ default: ++ printf("type %d", cmsg->cmsg_type); ++ break; ++ } ++ break; ++ case IPPROTO_IP: ++ printf("IPPROTO_IP "); ++ switch (cmsg->cmsg_type) { ++ case IP_RECVERR: { ++ struct sock_extended_err *err = ++ (struct sock_extended_err *)CMSG_DATA(cmsg); ++ printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s", ++ strerror(err->ee_errno), ++ err->ee_origin, ++#ifdef SO_EE_ORIGIN_TIMESTAMPING ++ err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ? ++ "bounced packet" : "unexpected origin" ++#else ++ "probably SO_EE_ORIGIN_TIMESTAMPING" ++#endif ++ ); ++ if (res < sizeof(sync)) ++ printf(" => truncated data?!"); ++ else if (!memcmp(sync, data + res - sizeof(sync), ++ sizeof(sync))) ++ printf(" => GOT OUR DATA BACK (HURRAY!)"); ++ break; ++ } ++ case IP_PKTINFO: { ++ struct in_pktinfo *pktinfo = ++ (struct in_pktinfo *)CMSG_DATA(cmsg); ++ printf("IP_PKTINFO interface index %u", ++ pktinfo->ipi_ifindex); ++ break; ++ } ++ default: ++ printf("type %d", cmsg->cmsg_type); ++ break; ++ } ++ break; ++ default: ++ printf("level %d type %d", ++ cmsg->cmsg_level, ++ cmsg->cmsg_type); ++ break; ++ } ++ printf("\n"); ++ } ++ ++ if (siocgstamp) { ++ if (ioctl(sock, SIOCGSTAMP, &tv)) ++ printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno)); ++ else ++ printf("SIOCGSTAMP %ld.%06ld\n", ++ (long)tv.tv_sec, ++ (long)tv.tv_usec); ++ } ++ if (siocgstampns) { ++ if (ioctl(sock, SIOCGSTAMPNS, &ts)) ++ printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno)); ++ else ++ printf("SIOCGSTAMPNS %ld.%09ld\n", ++ (long)ts.tv_sec, ++ (long)ts.tv_nsec); ++ } ++} ++ ++static void recvpacket(int sock, int recvmsg_flags, ++ int siocgstamp, int siocgstampns) ++{ ++ char data[256]; ++ struct msghdr msg; ++ struct iovec entry; ++ struct sockaddr_in from_addr; ++ struct { ++ struct cmsghdr cm; ++ char control[512]; ++ } control; ++ int res; ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_iov = &entry; ++ msg.msg_iovlen = 1; ++ entry.iov_base = data; ++ entry.iov_len = sizeof(data); ++ msg.msg_name = (caddr_t)&from_addr; ++ msg.msg_namelen = sizeof(from_addr); ++ msg.msg_control = &control; ++ msg.msg_controllen = sizeof(control); ++ ++ res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT); ++ if (res < 0) { ++ printf("%s %s: %s\n", ++ "recvmsg", ++ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular", ++ strerror(errno)); ++ } else { ++ printpacket(&msg, res, data, ++ sock, recvmsg_flags, ++ siocgstamp, siocgstampns); ++ } ++} ++ ++int main(int argc, char **argv) ++{ ++ int so_timestamping_flags = 0; ++ int so_timestamp = 0; ++ int so_timestampns = 0; ++ int siocgstamp = 0; ++ int siocgstampns = 0; ++ int ip_multicast_loop = 0; ++ char *interface; ++ int i; ++ int enabled = 1; ++ int sock; ++ struct ifreq device; ++ struct ifreq hwtstamp; ++ struct hwtstamp_config hwconfig, hwconfig_requested; ++ struct sockaddr_in addr; ++ struct ip_mreq imr; ++ struct in_addr iaddr; ++ int val; ++ socklen_t len; ++ struct timeval next; ++ ++ if (argc < 2) ++ usage(0); ++ interface = argv[1]; ++ ++ for (i = 2; i < argc; i++) { ++ if (!strcasecmp(argv[i], "SO_TIMESTAMP")) ++ so_timestamp = 1; ++ else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS")) ++ so_timestampns = 1; ++ else if (!strcasecmp(argv[i], "SIOCGSTAMP")) ++ siocgstamp = 1; ++ else if (!strcasecmp(argv[i], "SIOCGSTAMPNS")) ++ siocgstampns = 1; ++ else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP")) ++ ip_multicast_loop = 1; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE; ++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE")) ++ so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE; ++ else ++ usage(argv[i]); ++ } ++ ++ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); ++ if (sock < 0) ++ bail("socket"); ++ ++ memset(&device, 0, sizeof(device)); ++ strncpy(device.ifr_name, interface, sizeof(device.ifr_name)); ++ if (ioctl(sock, SIOCGIFADDR, &device) < 0) ++ bail("getting interface IP address"); ++ ++ memset(&hwtstamp, 0, sizeof(hwtstamp)); ++ strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name)); ++ hwtstamp.ifr_data = (void *)&hwconfig; ++ memset(&hwconfig, 0, sizeof(hwconfig)); ++ hwconfig.tx_type = ++ (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ? ++ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; ++ hwconfig.rx_filter = ++ (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ? ++ HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE; ++ hwconfig_requested = hwconfig; ++ if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) { ++ if ((errno == EINVAL || errno == ENOTSUP) && ++ hwconfig_requested.tx_type == HWTSTAMP_TX_OFF && ++ hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE) ++ printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n"); ++ else ++ bail("SIOCSHWTSTAMP"); ++ } ++ printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n", ++ hwconfig_requested.tx_type, hwconfig.tx_type, ++ hwconfig_requested.rx_filter, hwconfig.rx_filter); ++ ++ /* bind to PTP port */ ++ addr.sin_family = AF_INET; ++ addr.sin_addr.s_addr = htonl(INADDR_ANY); ++ addr.sin_port = htons(319 /* PTP event port */); ++ if (bind(sock, ++ (struct sockaddr *)&addr, ++ sizeof(struct sockaddr_in)) < 0) ++ bail("bind"); ++ ++ /* set multicast group for outgoing packets */ ++ inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */ ++ addr.sin_addr = iaddr; ++ imr.imr_multiaddr.s_addr = iaddr.s_addr; ++ imr.imr_interface.s_addr = ++ ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr; ++ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, ++ &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0) ++ bail("set multicast"); ++ ++ /* join multicast group, loop our own packet */ ++ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, ++ &imr, sizeof(struct ip_mreq)) < 0) ++ bail("join multicast group"); ++ ++ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, ++ &ip_multicast_loop, sizeof(enabled)) < 0) { ++ bail("loop multicast"); ++ } ++ ++ /* set socket options for time stamping */ ++ if (so_timestamp && ++ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, ++ &enabled, sizeof(enabled)) < 0) ++ bail("setsockopt SO_TIMESTAMP"); ++ ++ if (so_timestampns && ++ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, ++ &enabled, sizeof(enabled)) < 0) ++ bail("setsockopt SO_TIMESTAMPNS"); ++ ++ if (so_timestamping_flags && ++ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, ++ &so_timestamping_flags, ++ sizeof(so_timestamping_flags)) < 0) ++ bail("setsockopt SO_TIMESTAMPING"); ++ ++ /* request IP_PKTINFO for debugging purposes */ ++ if (setsockopt(sock, SOL_IP, IP_PKTINFO, ++ &enabled, sizeof(enabled)) < 0) ++ printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno)); ++ ++ /* verify socket options */ ++ len = sizeof(val); ++ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0) ++ printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno)); ++ else ++ printf("SO_TIMESTAMP %d\n", val); ++ ++ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0) ++ printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS", ++ strerror(errno)); ++ else ++ printf("SO_TIMESTAMPNS %d\n", val); ++ ++ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) { ++ printf("%s: %s\n", "getsockopt SO_TIMESTAMPING", ++ strerror(errno)); ++ } else { ++ printf("SO_TIMESTAMPING %d\n", val); ++ if (val != so_timestamping_flags) ++ printf(" not the expected value %d\n", ++ so_timestamping_flags); ++ } ++ ++ /* send packets forever every five seconds */ ++ gettimeofday(&next, 0); ++ next.tv_sec = (next.tv_sec + 1) / 5 * 5; ++ next.tv_usec = 0; ++ while (1) { ++ struct timeval now; ++ struct timeval delta; ++ long delta_us; ++ int res; ++ fd_set readfs, errorfs; ++ ++ gettimeofday(&now, 0); ++ delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 + ++ (long)(next.tv_usec - now.tv_usec); ++ if (delta_us > 0) { ++ /* continue waiting for timeout or data */ ++ delta.tv_sec = delta_us / 1000000; ++ delta.tv_usec = delta_us % 1000000; ++ ++ FD_ZERO(&readfs); ++ FD_ZERO(&errorfs); ++ FD_SET(sock, &readfs); ++ FD_SET(sock, &errorfs); ++ printf("%ld.%06ld: select %ldus\n", ++ (long)now.tv_sec, (long)now.tv_usec, ++ delta_us); ++ res = select(sock + 1, &readfs, 0, &errorfs, &delta); ++ gettimeofday(&now, 0); ++ printf("%ld.%06ld: select returned: %d, %s\n", ++ (long)now.tv_sec, (long)now.tv_usec, ++ res, ++ res < 0 ? strerror(errno) : "success"); ++ if (res > 0) { ++ if (FD_ISSET(sock, &readfs)) ++ printf("ready for reading\n"); ++ if (FD_ISSET(sock, &errorfs)) ++ printf("has error\n"); ++ recvpacket(sock, 0, ++ siocgstamp, ++ siocgstampns); ++ recvpacket(sock, MSG_ERRQUEUE, ++ siocgstamp, ++ siocgstampns); ++ } ++ } else { ++ /* write one packet */ ++ sendpacket(sock, ++ (struct sockaddr *)&addr, ++ sizeof(addr)); ++ next.tv_sec += 5; ++ continue; ++ } ++ } ++ ++ return 0; ++} +diff --git a/tools/testing/selftests/networking/timestamping/txtimestamp.c b/tools/testing/selftests/networking/timestamping/txtimestamp.c +new file mode 100644 +index 000000000000..5df07047ca86 +--- /dev/null ++++ b/tools/testing/selftests/networking/timestamping/txtimestamp.c +@@ -0,0 +1,549 @@ ++/* ++ * Copyright 2014 Google Inc. ++ * Author: willemb@google.com (Willem de Bruijn) ++ * ++ * Test software tx timestamping, including ++ * ++ * - SCHED, SND and ACK timestamps ++ * - RAW, UDP and TCP ++ * - IPv4 and IPv6 ++ * - various packet sizes (to test GSO and TSO) ++ * ++ * Consult the command line arguments for help on running ++ * the various testcases. ++ * ++ * This test requires a dummy TCP server. ++ * A simple `nc6 [-u] -l -p $DESTPORT` will do ++ * ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* command line parameters */ ++static int cfg_proto = SOCK_STREAM; ++static int cfg_ipproto = IPPROTO_TCP; ++static int cfg_num_pkts = 4; ++static int do_ipv4 = 1; ++static int do_ipv6 = 1; ++static int cfg_payload_len = 10; ++static bool cfg_show_payload; ++static bool cfg_do_pktinfo; ++static bool cfg_loop_nodata; ++static uint16_t dest_port = 9000; ++ ++static struct sockaddr_in daddr; ++static struct sockaddr_in6 daddr6; ++static struct timespec ts_prev; ++ ++static void __print_timestamp(const char *name, struct timespec *cur, ++ uint32_t key, int payload_len) ++{ ++ if (!(cur->tv_sec | cur->tv_nsec)) ++ return; ++ ++ fprintf(stderr, " %s: %lu s %lu us (seq=%u, len=%u)", ++ name, cur->tv_sec, cur->tv_nsec / 1000, ++ key, payload_len); ++ ++ if ((ts_prev.tv_sec | ts_prev.tv_nsec)) { ++ int64_t cur_ms, prev_ms; ++ ++ cur_ms = (long) cur->tv_sec * 1000 * 1000; ++ cur_ms += cur->tv_nsec / 1000; ++ ++ prev_ms = (long) ts_prev.tv_sec * 1000 * 1000; ++ prev_ms += ts_prev.tv_nsec / 1000; ++ ++ fprintf(stderr, " (%+" PRId64 " us)", cur_ms - prev_ms); ++ } ++ ++ ts_prev = *cur; ++ fprintf(stderr, "\n"); ++} ++ ++static void print_timestamp_usr(void) ++{ ++ struct timespec ts; ++ struct timeval tv; /* avoid dependency on -lrt */ ++ ++ gettimeofday(&tv, NULL); ++ ts.tv_sec = tv.tv_sec; ++ ts.tv_nsec = tv.tv_usec * 1000; ++ ++ __print_timestamp(" USR", &ts, 0, 0); ++} ++ ++static void print_timestamp(struct scm_timestamping *tss, int tstype, ++ int tskey, int payload_len) ++{ ++ const char *tsname; ++ ++ switch (tstype) { ++ case SCM_TSTAMP_SCHED: ++ tsname = " ENQ"; ++ break; ++ case SCM_TSTAMP_SND: ++ tsname = " SND"; ++ break; ++ case SCM_TSTAMP_ACK: ++ tsname = " ACK"; ++ break; ++ default: ++ error(1, 0, "unknown timestamp type: %u", ++ tstype); ++ } ++ __print_timestamp(tsname, &tss->ts[0], tskey, payload_len); ++} ++ ++/* TODO: convert to check_and_print payload once API is stable */ ++static void print_payload(char *data, int len) ++{ ++ int i; ++ ++ if (!len) ++ return; ++ ++ if (len > 70) ++ len = 70; ++ ++ fprintf(stderr, "payload: "); ++ for (i = 0; i < len; i++) ++ fprintf(stderr, "%02hhx ", data[i]); ++ fprintf(stderr, "\n"); ++} ++ ++static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr) ++{ ++ char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN]; ++ ++ fprintf(stderr, " pktinfo: ifindex=%u src=%s dst=%s\n", ++ ifindex, ++ saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown", ++ daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown"); ++} ++ ++static void __poll(int fd) ++{ ++ struct pollfd pollfd; ++ int ret; ++ ++ memset(&pollfd, 0, sizeof(pollfd)); ++ pollfd.fd = fd; ++ ret = poll(&pollfd, 1, 100); ++ if (ret != 1) ++ error(1, errno, "poll"); ++} ++ ++static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len) ++{ ++ struct sock_extended_err *serr = NULL; ++ struct scm_timestamping *tss = NULL; ++ struct cmsghdr *cm; ++ int batch = 0; ++ ++ for (cm = CMSG_FIRSTHDR(msg); ++ cm && cm->cmsg_len; ++ cm = CMSG_NXTHDR(msg, cm)) { ++ if (cm->cmsg_level == SOL_SOCKET && ++ cm->cmsg_type == SCM_TIMESTAMPING) { ++ tss = (void *) CMSG_DATA(cm); ++ } else if ((cm->cmsg_level == SOL_IP && ++ cm->cmsg_type == IP_RECVERR) || ++ (cm->cmsg_level == SOL_IPV6 && ++ cm->cmsg_type == IPV6_RECVERR)) { ++ serr = (void *) CMSG_DATA(cm); ++ if (serr->ee_errno != ENOMSG || ++ serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { ++ fprintf(stderr, "unknown ip error %d %d\n", ++ serr->ee_errno, ++ serr->ee_origin); ++ serr = NULL; ++ } ++ } else if (cm->cmsg_level == SOL_IP && ++ cm->cmsg_type == IP_PKTINFO) { ++ struct in_pktinfo *info = (void *) CMSG_DATA(cm); ++ print_pktinfo(AF_INET, info->ipi_ifindex, ++ &info->ipi_spec_dst, &info->ipi_addr); ++ } else if (cm->cmsg_level == SOL_IPV6 && ++ cm->cmsg_type == IPV6_PKTINFO) { ++ struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm); ++ print_pktinfo(AF_INET6, info6->ipi6_ifindex, ++ NULL, &info6->ipi6_addr); ++ } else ++ fprintf(stderr, "unknown cmsg %d,%d\n", ++ cm->cmsg_level, cm->cmsg_type); ++ ++ if (serr && tss) { ++ print_timestamp(tss, serr->ee_info, serr->ee_data, ++ payload_len); ++ serr = NULL; ++ tss = NULL; ++ batch++; ++ } ++ } ++ ++ if (batch > 1) ++ fprintf(stderr, "batched %d timestamps\n", batch); ++} ++ ++static int recv_errmsg(int fd) ++{ ++ static char ctrl[1024 /* overprovision*/]; ++ static struct msghdr msg; ++ struct iovec entry; ++ static char *data; ++ int ret = 0; ++ ++ data = malloc(cfg_payload_len); ++ if (!data) ++ error(1, 0, "malloc"); ++ ++ memset(&msg, 0, sizeof(msg)); ++ memset(&entry, 0, sizeof(entry)); ++ memset(ctrl, 0, sizeof(ctrl)); ++ ++ entry.iov_base = data; ++ entry.iov_len = cfg_payload_len; ++ msg.msg_iov = &entry; ++ msg.msg_iovlen = 1; ++ msg.msg_name = NULL; ++ msg.msg_namelen = 0; ++ msg.msg_control = ctrl; ++ msg.msg_controllen = sizeof(ctrl); ++ ++ ret = recvmsg(fd, &msg, MSG_ERRQUEUE); ++ if (ret == -1 && errno != EAGAIN) ++ error(1, errno, "recvmsg"); ++ ++ if (ret >= 0) { ++ __recv_errmsg_cmsg(&msg, ret); ++ if (cfg_show_payload) ++ print_payload(data, cfg_payload_len); ++ } ++ ++ free(data); ++ return ret == -1; ++} ++ ++static void do_test(int family, unsigned int opt) ++{ ++ char *buf; ++ int fd, i, val = 1, total_len; ++ ++ if (family == AF_INET6 && cfg_proto != SOCK_STREAM) { ++ /* due to lack of checksum generation code */ ++ fprintf(stderr, "test: skipping datagram over IPv6\n"); ++ return; ++ } ++ ++ total_len = cfg_payload_len; ++ if (cfg_proto == SOCK_RAW) { ++ total_len += sizeof(struct udphdr); ++ if (cfg_ipproto == IPPROTO_RAW) ++ total_len += sizeof(struct iphdr); ++ } ++ ++ buf = malloc(total_len); ++ if (!buf) ++ error(1, 0, "malloc"); ++ ++ fd = socket(family, cfg_proto, cfg_ipproto); ++ if (fd < 0) ++ error(1, errno, "socket"); ++ ++ if (cfg_proto == SOCK_STREAM) { ++ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, ++ (char*) &val, sizeof(val))) ++ error(1, 0, "setsockopt no nagle"); ++ ++ if (family == PF_INET) { ++ if (connect(fd, (void *) &daddr, sizeof(daddr))) ++ error(1, errno, "connect ipv4"); ++ } else { ++ if (connect(fd, (void *) &daddr6, sizeof(daddr6))) ++ error(1, errno, "connect ipv6"); ++ } ++ } ++ ++ if (cfg_do_pktinfo) { ++ if (family == AF_INET6) { ++ if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO, ++ &val, sizeof(val))) ++ error(1, errno, "setsockopt pktinfo ipv6"); ++ } else { ++ if (setsockopt(fd, SOL_IP, IP_PKTINFO, ++ &val, sizeof(val))) ++ error(1, errno, "setsockopt pktinfo ipv4"); ++ } ++ } ++ ++ opt |= SOF_TIMESTAMPING_SOFTWARE | ++ SOF_TIMESTAMPING_OPT_CMSG | ++ SOF_TIMESTAMPING_OPT_ID; ++ if (cfg_loop_nodata) ++ opt |= SOF_TIMESTAMPING_OPT_TSONLY; ++ ++ if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, ++ (char *) &opt, sizeof(opt))) ++ error(1, 0, "setsockopt timestamping"); ++ ++ for (i = 0; i < cfg_num_pkts; i++) { ++ memset(&ts_prev, 0, sizeof(ts_prev)); ++ memset(buf, 'a' + i, total_len); ++ ++ if (cfg_proto == SOCK_RAW) { ++ struct udphdr *udph; ++ int off = 0; ++ ++ if (cfg_ipproto == IPPROTO_RAW) { ++ struct iphdr *iph = (void *) buf; ++ ++ memset(iph, 0, sizeof(*iph)); ++ iph->ihl = 5; ++ iph->version = 4; ++ iph->ttl = 2; ++ iph->daddr = daddr.sin_addr.s_addr; ++ iph->protocol = IPPROTO_UDP; ++ /* kernel writes saddr, csum, len */ ++ ++ off = sizeof(*iph); ++ } ++ ++ udph = (void *) buf + off; ++ udph->source = ntohs(9000); /* random spoof */ ++ udph->dest = ntohs(dest_port); ++ udph->len = ntohs(sizeof(*udph) + cfg_payload_len); ++ udph->check = 0; /* not allowed for IPv6 */ ++ } ++ ++ print_timestamp_usr(); ++ if (cfg_proto != SOCK_STREAM) { ++ if (family == PF_INET) ++ val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr)); ++ else ++ val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6)); ++ } else { ++ val = send(fd, buf, cfg_payload_len, 0); ++ } ++ if (val != total_len) ++ error(1, errno, "send"); ++ ++ /* wait for all errors to be queued, else ACKs arrive OOO */ ++ usleep(50 * 1000); ++ ++ __poll(fd); ++ ++ while (!recv_errmsg(fd)) {} ++ } ++ ++ if (close(fd)) ++ error(1, errno, "close"); ++ ++ free(buf); ++ usleep(400 * 1000); ++} ++ ++static void __attribute__((noreturn)) usage(const char *filepath) ++{ ++ fprintf(stderr, "\nUsage: %s [options] hostname\n" ++ "\nwhere options are:\n" ++ " -4: only IPv4\n" ++ " -6: only IPv6\n" ++ " -h: show this message\n" ++ " -I: request PKTINFO\n" ++ " -l N: send N bytes at a time\n" ++ " -n: set no-payload option\n" ++ " -r: use raw\n" ++ " -R: use raw (IP_HDRINCL)\n" ++ " -p N: connect to port N\n" ++ " -u: use udp\n" ++ " -x: show payload (up to 70 bytes)\n", ++ filepath); ++ exit(1); ++} ++ ++static void parse_opt(int argc, char **argv) ++{ ++ int proto_count = 0; ++ char c; ++ ++ while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) { ++ switch (c) { ++ case '4': ++ do_ipv6 = 0; ++ break; ++ case '6': ++ do_ipv4 = 0; ++ break; ++ case 'I': ++ cfg_do_pktinfo = true; ++ break; ++ case 'n': ++ cfg_loop_nodata = true; ++ break; ++ case 'r': ++ proto_count++; ++ cfg_proto = SOCK_RAW; ++ cfg_ipproto = IPPROTO_UDP; ++ break; ++ case 'R': ++ proto_count++; ++ cfg_proto = SOCK_RAW; ++ cfg_ipproto = IPPROTO_RAW; ++ break; ++ case 'u': ++ proto_count++; ++ cfg_proto = SOCK_DGRAM; ++ cfg_ipproto = IPPROTO_UDP; ++ break; ++ case 'l': ++ cfg_payload_len = strtoul(optarg, NULL, 10); ++ break; ++ case 'p': ++ dest_port = strtoul(optarg, NULL, 10); ++ break; ++ case 'x': ++ cfg_show_payload = true; ++ break; ++ case 'h': ++ default: ++ usage(argv[0]); ++ } ++ } ++ ++ if (!cfg_payload_len) ++ error(1, 0, "payload may not be nonzero"); ++ if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472) ++ error(1, 0, "udp packet might exceed expected MTU"); ++ if (!do_ipv4 && !do_ipv6) ++ error(1, 0, "pass -4 or -6, not both"); ++ if (proto_count > 1) ++ error(1, 0, "pass -r, -R or -u, not multiple"); ++ ++ if (optind != argc - 1) ++ error(1, 0, "missing required hostname argument"); ++} ++ ++static void resolve_hostname(const char *hostname) ++{ ++ struct addrinfo *addrs, *cur; ++ int have_ipv4 = 0, have_ipv6 = 0; ++ ++ if (getaddrinfo(hostname, NULL, NULL, &addrs)) ++ error(1, errno, "getaddrinfo"); ++ ++ cur = addrs; ++ while (cur && !have_ipv4 && !have_ipv6) { ++ if (!have_ipv4 && cur->ai_family == AF_INET) { ++ memcpy(&daddr, cur->ai_addr, sizeof(daddr)); ++ daddr.sin_port = htons(dest_port); ++ have_ipv4 = 1; ++ } ++ else if (!have_ipv6 && cur->ai_family == AF_INET6) { ++ memcpy(&daddr6, cur->ai_addr, sizeof(daddr6)); ++ daddr6.sin6_port = htons(dest_port); ++ have_ipv6 = 1; ++ } ++ cur = cur->ai_next; ++ } ++ if (addrs) ++ freeaddrinfo(addrs); ++ ++ do_ipv4 &= have_ipv4; ++ do_ipv6 &= have_ipv6; ++} ++ ++static void do_main(int family) ++{ ++ fprintf(stderr, "family: %s\n", ++ family == PF_INET ? "INET" : "INET6"); ++ ++ fprintf(stderr, "test SND\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE); ++ ++ fprintf(stderr, "test ENQ\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_SCHED); ++ ++ fprintf(stderr, "test ENQ + SND\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_SCHED | ++ SOF_TIMESTAMPING_TX_SOFTWARE); ++ ++ if (cfg_proto == SOCK_STREAM) { ++ fprintf(stderr, "\ntest ACK\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_ACK); ++ ++ fprintf(stderr, "\ntest SND + ACK\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE | ++ SOF_TIMESTAMPING_TX_ACK); ++ ++ fprintf(stderr, "\ntest ENQ + SND + ACK\n"); ++ do_test(family, SOF_TIMESTAMPING_TX_SCHED | ++ SOF_TIMESTAMPING_TX_SOFTWARE | ++ SOF_TIMESTAMPING_TX_ACK); ++ } ++} ++ ++const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" }; ++ ++int main(int argc, char **argv) ++{ ++ if (argc == 1) ++ usage(argv[0]); ++ ++ parse_opt(argc, argv); ++ resolve_hostname(argv[argc - 1]); ++ ++ fprintf(stderr, "protocol: %s\n", sock_names[cfg_proto]); ++ fprintf(stderr, "payload: %u\n", cfg_payload_len); ++ fprintf(stderr, "server port: %u\n", dest_port); ++ fprintf(stderr, "\n"); ++ ++ if (do_ipv4) ++ do_main(PF_INET); ++ if (do_ipv6) ++ do_main(PF_INET6); ++ ++ return 0; ++} +diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c +index 4f70d12e392d..eddce59986ee 100644 +--- a/virt/kvm/async_pf.c ++++ b/virt/kvm/async_pf.c +@@ -80,7 +80,7 @@ static void async_pf_execute(struct work_struct *work) + + might_sleep(); + +- get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL); ++ get_user_pages_unlocked(NULL, mm, addr, 1, NULL, FOLL_WRITE); + kvm_async_page_present_sync(vcpu, apf); + + spin_lock(&vcpu->async_pf.lock); +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index b814ae6822b6..e4be695eb789 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1352,10 +1352,15 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault, + npages = get_user_page_nowait(current, current->mm, + addr, write_fault, page); + up_read(¤t->mm->mmap_sem); +- } else ++ } else { ++ unsigned int flags = FOLL_TOUCH | FOLL_HWPOISON; ++ ++ if (write_fault) ++ flags |= FOLL_WRITE; ++ + npages = __get_user_pages_unlocked(current, current->mm, addr, 1, +- write_fault, 0, page, +- FOLL_TOUCH|FOLL_HWPOISON); ++ page, flags); ++ } + if (npages != 1) + return npages; + +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index a83798cc448b..611bf28851c6 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -141,7 +141,7 @@ static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma) + struct page *page; + + pages_pinned = get_user_pages(current, mm, page_start_vaddr, +- 1, 0, 0, &page, NULL); ++ 1, 0, &page, NULL); + if (pages_pinned < 1) { + seq_puts(m, "]"); + return; diff --git a/patch/kernel/rockchip64-default/04-patch-4.4.168-169.patch b/patch/kernel/rockchip64-default/04-patch-4.4.168-169.patch new file mode 100644 index 0000000000..b0ece2fd13 --- /dev/null +++ b/patch/kernel/rockchip64-default/04-patch-4.4.168-169.patch @@ -0,0 +1,1260 @@ +diff --git a/Makefile b/Makefile +index 082f82471b51..0d41b0626c0c 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 168 ++SUBLEVEL = 169 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h +index cb69299a492e..f120d823e8c2 100644 +--- a/arch/arc/include/asm/io.h ++++ b/arch/arc/include/asm/io.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #ifdef CONFIG_ISA_ARCV2 + #include +@@ -85,6 +86,42 @@ static inline u32 __raw_readl(const volatile void __iomem *addr) + return w; + } + ++/* ++ * {read,write}s{b,w,l}() repeatedly access the same IO address in ++ * native endianness in 8-, 16-, 32-bit chunks {into,from} memory, ++ * @count times ++ */ ++#define __raw_readsx(t,f) \ ++static inline void __raw_reads##f(const volatile void __iomem *addr, \ ++ void *ptr, unsigned int count) \ ++{ \ ++ bool is_aligned = ((unsigned long)ptr % ((t) / 8)) == 0; \ ++ u##t *buf = ptr; \ ++ \ ++ if (!count) \ ++ return; \ ++ \ ++ /* Some ARC CPU's don't support unaligned accesses */ \ ++ if (is_aligned) { \ ++ do { \ ++ u##t x = __raw_read##f(addr); \ ++ *buf++ = x; \ ++ } while (--count); \ ++ } else { \ ++ do { \ ++ u##t x = __raw_read##f(addr); \ ++ put_unaligned(x, buf++); \ ++ } while (--count); \ ++ } \ ++} ++ ++#define __raw_readsb __raw_readsb ++__raw_readsx(8, b) ++#define __raw_readsw __raw_readsw ++__raw_readsx(16, w) ++#define __raw_readsl __raw_readsl ++__raw_readsx(32, l) ++ + #define __raw_writeb __raw_writeb + static inline void __raw_writeb(u8 b, volatile void __iomem *addr) + { +@@ -117,6 +154,35 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) + + } + ++#define __raw_writesx(t,f) \ ++static inline void __raw_writes##f(volatile void __iomem *addr, \ ++ const void *ptr, unsigned int count) \ ++{ \ ++ bool is_aligned = ((unsigned long)ptr % ((t) / 8)) == 0; \ ++ const u##t *buf = ptr; \ ++ \ ++ if (!count) \ ++ return; \ ++ \ ++ /* Some ARC CPU's don't support unaligned accesses */ \ ++ if (is_aligned) { \ ++ do { \ ++ __raw_write##f(*buf++, addr); \ ++ } while (--count); \ ++ } else { \ ++ do { \ ++ __raw_write##f(get_unaligned(buf++), addr); \ ++ } while (--count); \ ++ } \ ++} ++ ++#define __raw_writesb __raw_writesb ++__raw_writesx(8, b) ++#define __raw_writesw __raw_writesw ++__raw_writesx(16, w) ++#define __raw_writesl __raw_writesl ++__raw_writesx(32, l) ++ + /* + * MMIO can also get buffered/optimized in micro-arch, so barriers needed + * Based on ARM model for the typical use case +@@ -132,10 +198,16 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) + #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) + #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) + #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) ++#define readsb(p,d,l) ({ __raw_readsb(p,d,l); __iormb(); }) ++#define readsw(p,d,l) ({ __raw_readsw(p,d,l); __iormb(); }) ++#define readsl(p,d,l) ({ __raw_readsl(p,d,l); __iormb(); }) + + #define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); }) + #define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) + #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) ++#define writesb(p,d,l) ({ __iowmb(); __raw_writesb(p,d,l); }) ++#define writesw(p,d,l) ({ __iowmb(); __raw_writesw(p,d,l); }) ++#define writesl(p,d,l) ({ __iowmb(); __raw_writesl(p,d,l); }) + + /* + * Relaxed API for drivers which can handle barrier ordering themselves +diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S +index a134d8a13d00..11d699af30ed 100644 +--- a/arch/arm/mm/cache-v7.S ++++ b/arch/arm/mm/cache-v7.S +@@ -359,14 +359,16 @@ v7_dma_inv_range: + ALT_UP(W(nop)) + #endif + mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line ++ addne r0, r0, r2 + + tst r1, r3 + bic r1, r1, r3 + mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line +-1: +- mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line +- add r0, r0, r2 + cmp r0, r1 ++1: ++ mcrlo p15, 0, r0, c7, c6, 1 @ invalidate D / U line ++ addlo r0, r0, r2 ++ cmplo r0, r1 + blo 1b + dsb st + ret lr +diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile +index 99e4487248ff..57003d1bd243 100644 +--- a/arch/powerpc/boot/Makefile ++++ b/arch/powerpc/boot/Makefile +@@ -70,7 +70,8 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o): \ + libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c + libfdtheader := fdt.h libfdt.h libfdt_internal.h + +-$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ ++$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o \ ++ treeboot-akebono.o treeboot-currituck.o treeboot-iss4xx.o): \ + $(addprefix $(obj)/,$(libfdtheader)) + + src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \ +diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c +index dab616a33b8d..f2197654be07 100644 +--- a/arch/powerpc/kernel/msi.c ++++ b/arch/powerpc/kernel/msi.c +@@ -34,5 +34,10 @@ void arch_teardown_msi_irqs(struct pci_dev *dev) + { + struct pci_controller *phb = pci_bus_to_host(dev->bus); + +- phb->controller_ops.teardown_msi_irqs(dev); ++ /* ++ * We can be called even when arch_setup_msi_irqs() returns -ENOSYS, ++ * so check the pointer again. ++ */ ++ if (phb->controller_ops.teardown_msi_irqs) ++ phb->controller_ops.teardown_msi_irqs(dev); + } +diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c +index 524142117296..82324fc25d5e 100644 +--- a/arch/x86/platform/efi/early_printk.c ++++ b/arch/x86/platform/efi/early_printk.c +@@ -179,7 +179,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) + num--; + } + +- if (efi_x >= si->lfb_width) { ++ if (efi_x + font->width > si->lfb_width) { + efi_x = 0; + efi_y += font->height; + } +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index ba514fa733de..d543172b20b3 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4297,6 +4297,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { + { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, ++ { "SAMSUNG*MZ7KM*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, + + /* +diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c +index 61893fe73251..18b6c9b55b95 100644 +--- a/drivers/clk/mmp/clk.c ++++ b/drivers/clk/mmp/clk.c +@@ -182,7 +182,7 @@ void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id, + pr_err("CLK %d has invalid pointer %p\n", id, clk); + return; + } +- if (id > unit->nr_clks) { ++ if (id >= unit->nr_clks) { + pr_err("CLK %d is invalid\n", id); + return; + } +diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c +index 7eb253bc24df..221eaea651d4 100644 +--- a/drivers/gpu/drm/msm/msm_atomic.c ++++ b/drivers/gpu/drm/msm/msm_atomic.c +@@ -107,7 +107,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev, + if (old_state->legacy_cursor_update) + continue; + ++ if (drm_crtc_vblank_get(crtc)) ++ continue; ++ + kms->funcs->wait_for_crtc_commit_done(kms, crtc); ++ ++ drm_crtc_vblank_put(crtc); + } + } + +diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c +index c335cc7852f9..9c9fd2e87a4b 100644 +--- a/drivers/i2c/busses/i2c-axxia.c ++++ b/drivers/i2c/busses/i2c-axxia.c +@@ -74,8 +74,7 @@ + MST_STATUS_ND) + #define MST_STATUS_ERR (MST_STATUS_NAK | \ + MST_STATUS_AL | \ +- MST_STATUS_IP | \ +- MST_STATUS_TSS) ++ MST_STATUS_IP) + #define MST_TX_BYTES_XFRD 0x50 + #define MST_RX_BYTES_XFRD 0x54 + #define SCL_HIGH_PERIOD 0x80 +@@ -241,7 +240,7 @@ static int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev) + */ + if (c <= 0 || c > I2C_SMBUS_BLOCK_MAX) { + idev->msg_err = -EPROTO; +- i2c_int_disable(idev, ~0); ++ i2c_int_disable(idev, ~MST_STATUS_TSS); + complete(&idev->msg_complete); + break; + } +@@ -299,14 +298,19 @@ static irqreturn_t axxia_i2c_isr(int irq, void *_dev) + + if (status & MST_STATUS_SCC) { + /* Stop completed */ +- i2c_int_disable(idev, ~0); ++ i2c_int_disable(idev, ~MST_STATUS_TSS); + complete(&idev->msg_complete); + } else if (status & MST_STATUS_SNS) { + /* Transfer done */ +- i2c_int_disable(idev, ~0); ++ i2c_int_disable(idev, ~MST_STATUS_TSS); + if (i2c_m_rd(idev->msg) && idev->msg_xfrd < idev->msg->len) + axxia_i2c_empty_rx_fifo(idev); + complete(&idev->msg_complete); ++ } else if (status & MST_STATUS_TSS) { ++ /* Transfer timeout */ ++ idev->msg_err = -ETIMEDOUT; ++ i2c_int_disable(idev, ~MST_STATUS_TSS); ++ complete(&idev->msg_complete); + } else if (unlikely(status & MST_STATUS_ERR)) { + /* Transfer error */ + i2c_int_disable(idev, ~0); +@@ -339,10 +343,10 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) + u32 rx_xfer, tx_xfer; + u32 addr_1, addr_2; + unsigned long time_left; ++ unsigned int wt_value; + + idev->msg = msg; + idev->msg_xfrd = 0; +- idev->msg_err = 0; + reinit_completion(&idev->msg_complete); + + if (i2c_m_ten(msg)) { +@@ -382,9 +386,18 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) + else if (axxia_i2c_fill_tx_fifo(idev) != 0) + int_mask |= MST_STATUS_TFL; + ++ wt_value = WT_VALUE(readl(idev->base + WAIT_TIMER_CONTROL)); ++ /* Disable wait timer temporarly */ ++ writel(wt_value, idev->base + WAIT_TIMER_CONTROL); ++ /* Check if timeout error happened */ ++ if (idev->msg_err) ++ goto out; ++ + /* Start manual mode */ + writel(CMD_MANUAL, idev->base + MST_COMMAND); + ++ writel(WT_EN | wt_value, idev->base + WAIT_TIMER_CONTROL); ++ + i2c_int_enable(idev, int_mask); + + time_left = wait_for_completion_timeout(&idev->msg_complete, +@@ -395,13 +408,15 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) + if (readl(idev->base + MST_COMMAND) & CMD_BUSY) + dev_warn(idev->dev, "busy after xfer\n"); + +- if (time_left == 0) ++ if (time_left == 0) { + idev->msg_err = -ETIMEDOUT; +- +- if (idev->msg_err == -ETIMEDOUT) + i2c_recover_bus(&idev->adapter); ++ axxia_i2c_init(idev); ++ } + +- if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO) ++out: ++ if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO && ++ idev->msg_err != -ETIMEDOUT) + axxia_i2c_init(idev); + + return idev->msg_err; +@@ -409,7 +424,7 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) + + static int axxia_i2c_stop(struct axxia_i2c_dev *idev) + { +- u32 int_mask = MST_STATUS_ERR | MST_STATUS_SCC; ++ u32 int_mask = MST_STATUS_ERR | MST_STATUS_SCC | MST_STATUS_TSS; + unsigned long time_left; + + reinit_completion(&idev->msg_complete); +@@ -436,6 +451,9 @@ axxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) + int i; + int ret = 0; + ++ idev->msg_err = 0; ++ i2c_int_enable(idev, MST_STATUS_TSS); ++ + for (i = 0; ret == 0 && i < num; ++i) + ret = axxia_i2c_xfer_msg(idev, &msgs[i]); + +diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c +index efefcfa24a4c..d2178f701b41 100644 +--- a/drivers/i2c/busses/i2c-scmi.c ++++ b/drivers/i2c/busses/i2c-scmi.c +@@ -364,6 +364,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) + { + struct acpi_smbus_cmi *smbus_cmi; + const struct acpi_device_id *id; ++ int ret; + + smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL); + if (!smbus_cmi) +@@ -385,8 +386,10 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) + acpi_walk_namespace(ACPI_TYPE_METHOD, smbus_cmi->handle, 1, + acpi_smbus_cmi_query_methods, NULL, smbus_cmi, NULL); + +- if (smbus_cmi->cap_info == 0) ++ if (smbus_cmi->cap_info == 0) { ++ ret = -ENODEV; + goto err; ++ } + + snprintf(smbus_cmi->adapter.name, sizeof(smbus_cmi->adapter.name), + "SMBus CMI adapter %s", +@@ -397,7 +400,8 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) + smbus_cmi->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + smbus_cmi->adapter.dev.parent = &device->dev; + +- if (i2c_add_adapter(&smbus_cmi->adapter)) { ++ ret = i2c_add_adapter(&smbus_cmi->adapter); ++ if (ret) { + dev_err(&device->dev, "Couldn't register adapter!\n"); + goto err; + } +@@ -407,7 +411,7 @@ static int acpi_smbus_cmi_add(struct acpi_device *device) + err: + kfree(smbus_cmi); + device->driver_data = NULL; +- return -EIO; ++ return ret; + } + + static int acpi_smbus_cmi_remove(struct acpi_device *device) +diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c +index 96a345248224..0add5bb3cee8 100644 +--- a/drivers/ide/pmac.c ++++ b/drivers/ide/pmac.c +@@ -920,6 +920,7 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif) + struct device_node *root = of_find_node_by_path("/"); + const char *model = of_get_property(root, "model", NULL); + ++ of_node_put(root); + /* Get cable type from device-tree. */ + if (cable && !strncmp(cable, "80-", 3)) { + /* Some drives fail to detect 80c cable in PowerBook */ +diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c +index 6639b2b8528a..f78c464899db 100644 +--- a/drivers/input/keyboard/omap4-keypad.c ++++ b/drivers/input/keyboard/omap4-keypad.c +@@ -60,8 +60,18 @@ + + /* OMAP4 values */ + #define OMAP4_VAL_IRQDISABLE 0x0 +-#define OMAP4_VAL_DEBOUNCINGTIME 0x7 +-#define OMAP4_VAL_PVT 0x7 ++ ++/* ++ * Errata i689: If a key is released for a time shorter than debounce time, ++ * the keyboard will idle and never detect the key release. The workaround ++ * is to use at least a 12ms debounce time. See omap5432 TRM chapter ++ * "26.4.6.2 Keyboard Controller Timer" for more information. ++ */ ++#define OMAP4_KEYPAD_PTV_DIV_128 0x6 ++#define OMAP4_KEYPAD_DEBOUNCINGTIME_MS(dbms, ptv) \ ++ ((((dbms) * 1000) / ((1 << ((ptv) + 1)) * (1000000 / 32768))) - 1) ++#define OMAP4_VAL_DEBOUNCINGTIME_16MS \ ++ OMAP4_KEYPAD_DEBOUNCINGTIME_MS(16, OMAP4_KEYPAD_PTV_DIV_128) + + enum { + KBD_REVISION_OMAP4 = 0, +@@ -181,9 +191,9 @@ static int omap4_keypad_open(struct input_dev *input) + + kbd_writel(keypad_data, OMAP4_KBD_CTRL, + OMAP4_DEF_CTRL_NOSOFTMODE | +- (OMAP4_VAL_PVT << OMAP4_DEF_CTRL_PTV_SHIFT)); ++ (OMAP4_KEYPAD_PTV_DIV_128 << OMAP4_DEF_CTRL_PTV_SHIFT)); + kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, +- OMAP4_VAL_DEBOUNCINGTIME); ++ OMAP4_VAL_DEBOUNCINGTIME_16MS); + /* clear pending interrupts */ + kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, + kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); +diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c +index b9958a123594..5bcf4f45f8b4 100644 +--- a/drivers/mmc/host/omap.c ++++ b/drivers/mmc/host/omap.c +@@ -105,6 +105,7 @@ struct mmc_omap_slot { + unsigned int vdd; + u16 saved_con; + u16 bus_mode; ++ u16 power_mode; + unsigned int fclk_freq; + + struct tasklet_struct cover_tasklet; +@@ -1156,7 +1157,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + struct mmc_omap_slot *slot = mmc_priv(mmc); + struct mmc_omap_host *host = slot->host; + int i, dsor; +- int clk_enabled; ++ int clk_enabled, init_stream; + + mmc_omap_select_slot(slot, 0); + +@@ -1166,6 +1167,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + slot->vdd = ios->vdd; + + clk_enabled = 0; ++ init_stream = 0; + switch (ios->power_mode) { + case MMC_POWER_OFF: + mmc_omap_set_power(slot, 0, ios->vdd); +@@ -1173,13 +1175,17 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + case MMC_POWER_UP: + /* Cannot touch dsor yet, just power up MMC */ + mmc_omap_set_power(slot, 1, ios->vdd); ++ slot->power_mode = ios->power_mode; + goto exit; + case MMC_POWER_ON: + mmc_omap_fclk_enable(host, 1); + clk_enabled = 1; + dsor |= 1 << 11; ++ if (slot->power_mode != MMC_POWER_ON) ++ init_stream = 1; + break; + } ++ slot->power_mode = ios->power_mode; + + if (slot->bus_mode != ios->bus_mode) { + if (slot->pdata->set_bus_mode != NULL) +@@ -1195,7 +1201,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + for (i = 0; i < 2; i++) + OMAP_MMC_WRITE(host, CON, dsor); + slot->saved_con = dsor; +- if (ios->power_mode == MMC_POWER_ON) { ++ if (init_stream) { + /* worst case at 400kHz, 80 cycles makes 200 microsecs */ + int usecs = 250; + +@@ -1233,6 +1239,7 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) + slot->host = host; + slot->mmc = mmc; + slot->id = id; ++ slot->power_mode = MMC_POWER_UNDEFINED; + slot->pdata = &host->pdata->slots[id]; + + host->slots[id] = slot; +diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c +index 940e2ebbdea8..399c627b15cc 100644 +--- a/drivers/net/bonding/bond_3ad.c ++++ b/drivers/net/bonding/bond_3ad.c +@@ -2011,6 +2011,9 @@ void bond_3ad_unbind_slave(struct slave *slave) + aggregator->aggregator_identifier); + + /* Tell the partner that this port is not suitable for aggregation */ ++ port->actor_oper_port_state &= ~AD_STATE_SYNCHRONIZATION; ++ port->actor_oper_port_state &= ~AD_STATE_COLLECTING; ++ port->actor_oper_port_state &= ~AD_STATE_DISTRIBUTING; + port->actor_oper_port_state &= ~AD_STATE_AGGREGATION; + __update_lacpdu_from_port(port); + ad_lacpdu_send(port); +diff --git a/drivers/net/dsa/mv88e6060.c b/drivers/net/dsa/mv88e6060.c +index 0527f485c3dc..973fcd442aea 100644 +--- a/drivers/net/dsa/mv88e6060.c ++++ b/drivers/net/dsa/mv88e6060.c +@@ -98,8 +98,7 @@ static int mv88e6060_switch_reset(struct dsa_switch *ds) + /* Reset the switch. */ + REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL, + GLOBAL_ATU_CONTROL_SWRESET | +- GLOBAL_ATU_CONTROL_ATUSIZE_1024 | +- GLOBAL_ATU_CONTROL_ATE_AGE_5MIN); ++ GLOBAL_ATU_CONTROL_LEARNDIS); + + /* Wait up to one second for reset to complete. */ + timeout = jiffies + 1 * HZ; +@@ -124,13 +123,10 @@ static int mv88e6060_setup_global(struct dsa_switch *ds) + */ + REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, GLOBAL_CONTROL_MAX_FRAME_1536); + +- /* Enable automatic address learning, set the address +- * database size to 1024 entries, and set the default aging +- * time to 5 minutes. ++ /* Disable automatic address learning. + */ + REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL, +- GLOBAL_ATU_CONTROL_ATUSIZE_1024 | +- GLOBAL_ATU_CONTROL_ATE_AGE_5MIN); ++ GLOBAL_ATU_CONTROL_LEARNDIS); + + return 0; + } +diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c +index ab480ea6d95a..0d1abcfec003 100644 +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -3195,16 +3195,16 @@ static int __init init_mac80211_hwsim(void) + if (err) + return err; + ++ err = hwsim_init_netlink(); ++ if (err) ++ goto out_unregister_driver; ++ + hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); + if (IS_ERR(hwsim_class)) { + err = PTR_ERR(hwsim_class); +- goto out_unregister_driver; ++ goto out_exit_netlink; + } + +- err = hwsim_init_netlink(); +- if (err < 0) +- goto out_unregister_driver; +- + for (i = 0; i < radios; i++) { + struct hwsim_new_radio_params param = { 0 }; + +@@ -3310,6 +3310,8 @@ out_free_mon: + free_netdev(hwsim_mon); + out_free_radios: + mac80211_hwsim_free(); ++out_exit_netlink: ++ hwsim_exit_netlink(); + out_unregister_driver: + platform_driver_unregister(&mac80211_hwsim_driver); + return err; +diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +index a7c81e988656..383977ea3a3c 100644 +--- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c ++++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +@@ -568,7 +568,7 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = { + SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 11), + SUNXI_FUNCTION(0x0, "gpio_in"), + SUNXI_FUNCTION(0x1, "gpio_out"), +- SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 1)), /* PH_EINT11 */ ++ SUNXI_FUNCTION_IRQ_BANK(0x6, 2, 11)), /* PH_EINT11 */ + }; + + static const struct sunxi_pinctrl_desc sun8i_a83t_pinctrl_data = { +diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c +index a161fbf6f172..63ad5b543f14 100644 +--- a/drivers/rtc/rtc-snvs.c ++++ b/drivers/rtc/rtc-snvs.c +@@ -47,49 +47,83 @@ struct snvs_rtc_data { + struct clk *clk; + }; + ++/* Read 64 bit timer register, which could be in inconsistent state */ ++static u64 rtc_read_lpsrt(struct snvs_rtc_data *data) ++{ ++ u32 msb, lsb; ++ ++ regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb); ++ regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb); ++ return (u64)msb << 32 | lsb; ++} ++ ++/* Read the secure real time counter, taking care to deal with the cases of the ++ * counter updating while being read. ++ */ + static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) + { + u64 read1, read2; +- u32 val; ++ unsigned int timeout = 100; + ++ /* As expected, the registers might update between the read of the LSB ++ * reg and the MSB reg. It's also possible that one register might be ++ * in partially modified state as well. ++ */ ++ read1 = rtc_read_lpsrt(data); + do { +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); +- read1 = val; +- read1 <<= 32; +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); +- read1 |= val; +- +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); +- read2 = val; +- read2 <<= 32; +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); +- read2 |= val; +- } while (read1 != read2); ++ read2 = read1; ++ read1 = rtc_read_lpsrt(data); ++ } while (read1 != read2 && --timeout); ++ if (!timeout) ++ dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); + + /* Convert 47-bit counter to 32-bit raw second count */ + return (u32) (read1 >> CNTR_TO_SECS_SH); + } + +-static void rtc_write_sync_lp(struct snvs_rtc_data *data) ++/* Just read the lsb from the counter, dealing with inconsistent state */ ++static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb) + { +- u32 count1, count2, count3; +- int i; +- +- /* Wait for 3 CKIL cycles */ +- for (i = 0; i < 3; i++) { +- do { +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); +- } while (count1 != count2); +- +- /* Now wait until counter value changes */ +- do { +- do { +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); +- regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3); +- } while (count2 != count3); +- } while (count3 == count1); ++ u32 count1, count2; ++ unsigned int timeout = 100; ++ ++ regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); ++ do { ++ count2 = count1; ++ regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); ++ } while (count1 != count2 && --timeout); ++ if (!timeout) { ++ dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); ++ return -ETIMEDOUT; + } ++ ++ *lsb = count1; ++ return 0; ++} ++ ++static int rtc_write_sync_lp(struct snvs_rtc_data *data) ++{ ++ u32 count1, count2; ++ u32 elapsed; ++ unsigned int timeout = 1000; ++ int ret; ++ ++ ret = rtc_read_lp_counter_lsb(data, &count1); ++ if (ret) ++ return ret; ++ ++ /* Wait for 3 CKIL cycles, about 61.0-91.5 µs */ ++ do { ++ ret = rtc_read_lp_counter_lsb(data, &count2); ++ if (ret) ++ return ret; ++ elapsed = count2 - count1; /* wrap around _is_ handled! */ ++ } while (elapsed < 3 && --timeout); ++ if (!timeout) { ++ dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n"); ++ return -ETIMEDOUT; ++ } ++ return 0; + } + + static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) +@@ -173,9 +207,7 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) + (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), + enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); + +- rtc_write_sync_lp(data); +- +- return 0; ++ return rtc_write_sync_lp(data); + } + + static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +@@ -183,10 +215,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) + struct snvs_rtc_data *data = dev_get_drvdata(dev); + struct rtc_time *alrm_tm = &alrm->time; + unsigned long time; ++ int ret; + + rtc_tm_to_time(alrm_tm, &time); + + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); ++ ret = rtc_write_sync_lp(data); ++ if (ret) ++ return ret; + regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); + + /* Clear alarm interrupt status bit */ +diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c +index 33fbe8249fd5..044cffbc45e8 100644 +--- a/drivers/sbus/char/display7seg.c ++++ b/drivers/sbus/char/display7seg.c +@@ -221,6 +221,7 @@ static int d7s_probe(struct platform_device *op) + dev_set_drvdata(&op->dev, p); + d7s_device = p; + err = 0; ++ of_node_put(opts); + + out: + return err; +diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c +index 5609b602c54d..baa9b322520b 100644 +--- a/drivers/sbus/char/envctrl.c ++++ b/drivers/sbus/char/envctrl.c +@@ -910,8 +910,10 @@ static void envctrl_init_i2c_child(struct device_node *dp, + for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { + pchild->mon_type[len] = ENVCTRL_NOMON; + } ++ of_node_put(root_node); + return; + } ++ of_node_put(root_node); + } + + /* Get the monitor channels. */ +diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c +index a74f8fbefd33..009a2ef829d6 100644 +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -2416,8 +2416,8 @@ int iscsi_eh_session_reset(struct scsi_cmnd *sc) + failed: + ISCSI_DBG_EH(session, + "failing session reset: Could not log back into " +- "%s, %s [age %d]\n", session->targetname, +- conn->persistent_address, session->age); ++ "%s [age %d]\n", session->targetname, ++ session->age); + spin_unlock_bh(&session->frwd_lock); + mutex_unlock(&session->eh_mutex); + return FAILED; +diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c +index 0de2f9069e23..23081ed8f1e3 100644 +--- a/drivers/scsi/vmw_pvscsi.c ++++ b/drivers/scsi/vmw_pvscsi.c +@@ -1199,8 +1199,6 @@ static void pvscsi_shutdown_intr(struct pvscsi_adapter *adapter) + + static void pvscsi_release_resources(struct pvscsi_adapter *adapter) + { +- pvscsi_shutdown_intr(adapter); +- + if (adapter->workqueue) + destroy_workqueue(adapter->workqueue); + +@@ -1529,6 +1527,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_reset_adapter: + ll_adapter_reset(adapter); + out_release_resources: ++ pvscsi_shutdown_intr(adapter); + pvscsi_release_resources(adapter); + scsi_host_put(host); + out_disable_device: +@@ -1537,6 +1536,7 @@ out_disable_device: + return error; + + out_release_resources_and_disable: ++ pvscsi_shutdown_intr(adapter); + pvscsi_release_resources(adapter); + goto out_disable_device; + } +diff --git a/drivers/tty/serial/suncore.c b/drivers/tty/serial/suncore.c +index 127472bd6a7c..209f314745ab 100644 +--- a/drivers/tty/serial/suncore.c ++++ b/drivers/tty/serial/suncore.c +@@ -111,6 +111,7 @@ void sunserial_console_termios(struct console *con, struct device_node *uart_dp) + mode = of_get_property(dp, mode_prop, NULL); + if (!mode) + mode = "9600,8,n,1,-"; ++ of_node_put(dp); + } + + cflag = CREAD | HUPCL | CLOCAL; +diff --git a/fs/aio.c b/fs/aio.c +index c283eb03cb38..7187d03aa0bc 100644 +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1063,6 +1064,7 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id) + if (!table || id >= table->nr) + goto out; + ++ id = array_index_nospec(id, table->nr); + ctx = rcu_dereference(table->table[id]); + if (ctx && ctx->user_id == ctx_id) { + if (percpu_ref_tryget_live(&ctx->users)) +diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig +index e7b478b49985..8bef27b8f85d 100644 +--- a/fs/cifs/Kconfig ++++ b/fs/cifs/Kconfig +@@ -111,7 +111,7 @@ config CIFS_XATTR + + config CIFS_POSIX + bool "CIFS POSIX Extensions" +- depends on CIFS_XATTR ++ depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY && CIFS_XATTR + help + Enabling this option will cause the cifs client to attempt to + negotiate a newer dialect with servers, such as Samba 3.0.5 +diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c +index ef4f16e81283..1407ed20ea93 100644 +--- a/kernel/time/timer_list.c ++++ b/kernel/time/timer_list.c +@@ -399,7 +399,7 @@ static int __init init_timer_list_procfs(void) + { + struct proc_dir_entry *pe; + +- pe = proc_create("timer_list", 0444, NULL, &timer_list_fops); ++ pe = proc_create("timer_list", 0400, NULL, &timer_list_fops); + if (!pe) + return -ENOMEM; + return 0; +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index ac758a53fcea..d90b42b39908 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -4767,6 +4767,7 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops) + if (ops->flags & FTRACE_OPS_FL_ENABLED) + ftrace_shutdown(ops, 0); + ops->flags |= FTRACE_OPS_FL_DELETED; ++ ftrace_free_filter(ops); + mutex_unlock(&ftrace_lock); + } + +diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c +index b8a894adab2c..8be66a2b0cac 100644 +--- a/kernel/trace/trace_events_trigger.c ++++ b/kernel/trace/trace_events_trigger.c +@@ -727,8 +727,10 @@ static int set_trigger_filter(char *filter_str, + + /* The filter is for the 'trigger' event, not the triggered event */ + ret = create_event_filter(file->event_call, filter_str, false, &filter); +- if (ret) +- goto out; ++ /* ++ * If create_event_filter() fails, filter still needs to be freed. ++ * Which the calling code will do with data->filter. ++ */ + assign: + tmp = rcu_access_pointer(data->filter); + +diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c +index 245900b98c8e..222c8010bda0 100644 +--- a/lib/interval_tree_test.c ++++ b/lib/interval_tree_test.c +@@ -1,27 +1,38 @@ + #include ++#include + #include + #include ++#include + #include + +-#define NODES 100 +-#define PERF_LOOPS 100000 +-#define SEARCHES 100 +-#define SEARCH_LOOPS 10000 ++#define __param(type, name, init, msg) \ ++ static type name = init; \ ++ module_param(name, type, 0444); \ ++ MODULE_PARM_DESC(name, msg); ++ ++__param(int, nnodes, 100, "Number of nodes in the interval tree"); ++__param(int, perf_loops, 1000, "Number of iterations modifying the tree"); ++ ++__param(int, nsearches, 100, "Number of searches to the interval tree"); ++__param(int, search_loops, 1000, "Number of iterations searching the tree"); ++__param(bool, search_all, false, "Searches will iterate all nodes in the tree"); ++ ++__param(uint, max_endpoint, ~0, "Largest value for the interval's endpoint"); + + static struct rb_root root = RB_ROOT; +-static struct interval_tree_node nodes[NODES]; +-static u32 queries[SEARCHES]; ++static struct interval_tree_node *nodes = NULL; ++static u32 *queries = NULL; + + static struct rnd_state rnd; + + static inline unsigned long +-search(unsigned long query, struct rb_root *root) ++search(struct rb_root *root, unsigned long start, unsigned long last) + { + struct interval_tree_node *node; + unsigned long results = 0; + +- for (node = interval_tree_iter_first(root, query, query); node; +- node = interval_tree_iter_next(node, query, query)) ++ for (node = interval_tree_iter_first(root, start, last); node; ++ node = interval_tree_iter_next(node, start, last)) + results++; + return results; + } +@@ -29,19 +40,22 @@ search(unsigned long query, struct rb_root *root) + static void init(void) + { + int i; +- for (i = 0; i < NODES; i++) { +- u32 a = prandom_u32_state(&rnd); +- u32 b = prandom_u32_state(&rnd); +- if (a <= b) { +- nodes[i].start = a; +- nodes[i].last = b; +- } else { +- nodes[i].start = b; +- nodes[i].last = a; +- } ++ ++ for (i = 0; i < nnodes; i++) { ++ u32 b = (prandom_u32_state(&rnd) >> 4) % max_endpoint; ++ u32 a = (prandom_u32_state(&rnd) >> 4) % b; ++ ++ nodes[i].start = a; ++ nodes[i].last = b; + } +- for (i = 0; i < SEARCHES; i++) +- queries[i] = prandom_u32_state(&rnd); ++ ++ /* ++ * Limit the search scope to what the user defined. ++ * Otherwise we are merely measuring empty walks, ++ * which is pointless. ++ */ ++ for (i = 0; i < nsearches; i++) ++ queries[i] = (prandom_u32_state(&rnd) >> 4) % max_endpoint; + } + + static int interval_tree_test_init(void) +@@ -50,6 +64,16 @@ static int interval_tree_test_init(void) + unsigned long results; + cycles_t time1, time2, time; + ++ nodes = kmalloc(nnodes * sizeof(struct interval_tree_node), GFP_KERNEL); ++ if (!nodes) ++ return -ENOMEM; ++ ++ queries = kmalloc(nsearches * sizeof(int), GFP_KERNEL); ++ if (!queries) { ++ kfree(nodes); ++ return -ENOMEM; ++ } ++ + printk(KERN_ALERT "interval tree insert/remove"); + + prandom_seed_state(&rnd, 3141592653589793238ULL); +@@ -57,39 +81,46 @@ static int interval_tree_test_init(void) + + time1 = get_cycles(); + +- for (i = 0; i < PERF_LOOPS; i++) { +- for (j = 0; j < NODES; j++) ++ for (i = 0; i < perf_loops; i++) { ++ for (j = 0; j < nnodes; j++) + interval_tree_insert(nodes + j, &root); +- for (j = 0; j < NODES; j++) ++ for (j = 0; j < nnodes; j++) + interval_tree_remove(nodes + j, &root); + } + + time2 = get_cycles(); + time = time2 - time1; + +- time = div_u64(time, PERF_LOOPS); ++ time = div_u64(time, perf_loops); + printk(" -> %llu cycles\n", (unsigned long long)time); + + printk(KERN_ALERT "interval tree search"); + +- for (j = 0; j < NODES; j++) ++ for (j = 0; j < nnodes; j++) + interval_tree_insert(nodes + j, &root); + + time1 = get_cycles(); + + results = 0; +- for (i = 0; i < SEARCH_LOOPS; i++) +- for (j = 0; j < SEARCHES; j++) +- results += search(queries[j], &root); ++ for (i = 0; i < search_loops; i++) ++ for (j = 0; j < nsearches; j++) { ++ unsigned long start = search_all ? 0 : queries[j]; ++ unsigned long last = search_all ? max_endpoint : queries[j]; ++ ++ results += search(&root, start, last); ++ } + + time2 = get_cycles(); + time = time2 - time1; + +- time = div_u64(time, SEARCH_LOOPS); +- results = div_u64(results, SEARCH_LOOPS); ++ time = div_u64(time, search_loops); ++ results = div_u64(results, search_loops); + printk(" -> %llu cycles (%lu results)\n", + (unsigned long long)time, results); + ++ kfree(queries); ++ kfree(nodes); ++ + return -EAGAIN; /* Fail will directly unload the module */ + } + +diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c +index 8b3c9dc88262..afedd3770562 100644 +--- a/lib/rbtree_test.c ++++ b/lib/rbtree_test.c +@@ -1,11 +1,18 @@ + #include ++#include + #include + #include ++#include + #include + +-#define NODES 100 +-#define PERF_LOOPS 100000 +-#define CHECK_LOOPS 100 ++#define __param(type, name, init, msg) \ ++ static type name = init; \ ++ module_param(name, type, 0444); \ ++ MODULE_PARM_DESC(name, msg); ++ ++__param(int, nnodes, 100, "Number of nodes in the rb-tree"); ++__param(int, perf_loops, 1000, "Number of iterations modifying the rb-tree"); ++__param(int, check_loops, 100, "Number of iterations modifying and verifying the rb-tree"); + + struct test_node { + u32 key; +@@ -17,7 +24,7 @@ struct test_node { + }; + + static struct rb_root root = RB_ROOT; +-static struct test_node nodes[NODES]; ++static struct test_node *nodes = NULL; + + static struct rnd_state rnd; + +@@ -95,7 +102,7 @@ static void erase_augmented(struct test_node *node, struct rb_root *root) + static void init(void) + { + int i; +- for (i = 0; i < NODES; i++) { ++ for (i = 0; i < nnodes; i++) { + nodes[i].key = prandom_u32_state(&rnd); + nodes[i].val = prandom_u32_state(&rnd); + } +@@ -177,6 +184,10 @@ static int __init rbtree_test_init(void) + int i, j; + cycles_t time1, time2, time; + ++ nodes = kmalloc(nnodes * sizeof(*nodes), GFP_KERNEL); ++ if (!nodes) ++ return -ENOMEM; ++ + printk(KERN_ALERT "rbtree testing"); + + prandom_seed_state(&rnd, 3141592653589793238ULL); +@@ -184,27 +195,27 @@ static int __init rbtree_test_init(void) + + time1 = get_cycles(); + +- for (i = 0; i < PERF_LOOPS; i++) { +- for (j = 0; j < NODES; j++) ++ for (i = 0; i < perf_loops; i++) { ++ for (j = 0; j < nnodes; j++) + insert(nodes + j, &root); +- for (j = 0; j < NODES; j++) ++ for (j = 0; j < nnodes; j++) + erase(nodes + j, &root); + } + + time2 = get_cycles(); + time = time2 - time1; + +- time = div_u64(time, PERF_LOOPS); ++ time = div_u64(time, perf_loops); + printk(" -> %llu cycles\n", (unsigned long long)time); + +- for (i = 0; i < CHECK_LOOPS; i++) { ++ for (i = 0; i < check_loops; i++) { + init(); +- for (j = 0; j < NODES; j++) { ++ for (j = 0; j < nnodes; j++) { + check(j); + insert(nodes + j, &root); + } +- for (j = 0; j < NODES; j++) { +- check(NODES - j); ++ for (j = 0; j < nnodes; j++) { ++ check(nnodes - j); + erase(nodes + j, &root); + } + check(0); +@@ -216,32 +227,34 @@ static int __init rbtree_test_init(void) + + time1 = get_cycles(); + +- for (i = 0; i < PERF_LOOPS; i++) { +- for (j = 0; j < NODES; j++) ++ for (i = 0; i < perf_loops; i++) { ++ for (j = 0; j < nnodes; j++) + insert_augmented(nodes + j, &root); +- for (j = 0; j < NODES; j++) ++ for (j = 0; j < nnodes; j++) + erase_augmented(nodes + j, &root); + } + + time2 = get_cycles(); + time = time2 - time1; + +- time = div_u64(time, PERF_LOOPS); ++ time = div_u64(time, perf_loops); + printk(" -> %llu cycles\n", (unsigned long long)time); + +- for (i = 0; i < CHECK_LOOPS; i++) { ++ for (i = 0; i < check_loops; i++) { + init(); +- for (j = 0; j < NODES; j++) { ++ for (j = 0; j < nnodes; j++) { + check_augmented(j); + insert_augmented(nodes + j, &root); + } +- for (j = 0; j < NODES; j++) { +- check_augmented(NODES - j); ++ for (j = 0; j < nnodes; j++) { ++ check_augmented(nnodes - j); + erase_augmented(nodes + j, &root); + } + check_augmented(0); + } + ++ kfree(nodes); ++ + return -EAGAIN; /* Fail will directly unload the module */ + } + +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index a5e11280f405..ed4fef32b394 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -1886,7 +1886,8 @@ static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, + params[ac].acm = acm; + params[ac].uapsd = uapsd; + +- if (params[ac].cw_min > params[ac].cw_max) { ++ if (params[ac].cw_min == 0 || ++ params[ac].cw_min > params[ac].cw_max) { + sdata_info(sdata, + "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n", + params[ac].cw_min, params[ac].cw_max, aci); +diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c +index 2e98f4a243e5..112c191b8336 100644 +--- a/net/sunrpc/xprt.c ++++ b/net/sunrpc/xprt.c +@@ -758,8 +758,15 @@ void xprt_connect(struct rpc_task *task) + return; + if (xprt_test_and_set_connecting(xprt)) + return; +- xprt->stat.connect_start = jiffies; +- xprt->ops->connect(xprt, task); ++ /* Race breaker */ ++ if (!xprt_connected(xprt)) { ++ xprt->stat.connect_start = jiffies; ++ xprt->ops->connect(xprt, task); ++ } else { ++ xprt_clear_connecting(xprt); ++ task->tk_status = 0; ++ rpc_wake_up_queued_task(&xprt->pending, task); ++ } + } + xprt_release_write(xprt, task); + } +diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c +index 69f76ff5693d..718d5e3b7806 100644 +--- a/sound/isa/wavefront/wavefront_synth.c ++++ b/sound/isa/wavefront/wavefront_synth.c +@@ -785,6 +785,9 @@ wavefront_send_patch (snd_wavefront_t *dev, wavefront_patch_info *header) + DPRINT (WF_DEBUG_LOAD_PATCH, "downloading patch %d\n", + header->number); + ++ if (header->number >= ARRAY_SIZE(dev->patch_status)) ++ return -EINVAL; ++ + dev->patch_status[header->number] |= WF_SLOT_FILLED; + + bptr = buf; +@@ -809,6 +812,9 @@ wavefront_send_program (snd_wavefront_t *dev, wavefront_patch_info *header) + DPRINT (WF_DEBUG_LOAD_PATCH, "downloading program %d\n", + header->number); + ++ if (header->number >= ARRAY_SIZE(dev->prog_status)) ++ return -EINVAL; ++ + dev->prog_status[header->number] = WF_SLOT_USED; + + /* XXX need to zero existing SLOT_USED bit for program_status[i] +@@ -898,6 +904,9 @@ wavefront_send_sample (snd_wavefront_t *dev, + header->number = x; + } + ++ if (header->number >= WF_MAX_SAMPLE) ++ return -EINVAL; ++ + if (header->size) { + + /* XXX it's a debatable point whether or not RDONLY semantics diff --git a/patch/kernel/rockchip64-default/04-patch-4.4.169-170.patch b/patch/kernel/rockchip64-default/04-patch-4.4.169-170.patch new file mode 100644 index 0000000000..db38c6d6a6 --- /dev/null +++ b/patch/kernel/rockchip64-default/04-patch-4.4.169-170.patch @@ -0,0 +1,2154 @@ +diff --git a/Makefile b/Makefile +index 0d41b0626c0c..bc58f206c0da 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 169 ++SUBLEVEL = 170 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c +index 3c6672b3796b..7f5df8992008 100644 +--- a/arch/arm/mach-imx/cpuidle-imx6sx.c ++++ b/arch/arm/mach-imx/cpuidle-imx6sx.c +@@ -97,7 +97,7 @@ int __init imx6sx_cpuidle_init(void) + * except for power up sw2iso which need to be + * larger than LDO ramp up time. + */ +- imx_gpc_set_arm_power_up_timing(2, 1); ++ imx_gpc_set_arm_power_up_timing(0xf, 1); + imx_gpc_set_arm_power_down_timing(1, 1); + + return cpuidle_register(&imx6sx_cpuidle_driver, NULL); +diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c +index 37fe58c19a90..542c3ede9722 100644 +--- a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c ++++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include "../../../../include/linux/sizes.h" + + int main(int argc, char *argv[]) + { +@@ -45,11 +46,11 @@ int main(int argc, char *argv[]) + vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size; + + /* +- * Align with 16 bytes: "greater than that used for any standard data +- * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition). ++ * Align with 64KB: KEXEC needs load sections to be aligned to PAGE_SIZE, ++ * which may be as large as 64KB depending on the kernel configuration. + */ + +- vmlinuz_load_addr += (16 - vmlinux_size % 16); ++ vmlinuz_load_addr += (SZ_64K - vmlinux_size % SZ_64K); + + printf("0x%llx\n", vmlinuz_load_addr); + +diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h +index cf661a2fb141..16fade4f49dd 100644 +--- a/arch/mips/include/asm/pgtable-64.h ++++ b/arch/mips/include/asm/pgtable-64.h +@@ -189,6 +189,11 @@ static inline int pmd_bad(pmd_t pmd) + + static inline int pmd_present(pmd_t pmd) + { ++#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT ++ if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) ++ return pmd_val(pmd) & _PAGE_PRESENT; ++#endif ++ + return pmd_val(pmd) != (unsigned long) invalid_pte_table; + } + +diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S +index 5c2199857aa8..a3550e8f1a77 100644 +--- a/arch/powerpc/boot/crt0.S ++++ b/arch/powerpc/boot/crt0.S +@@ -15,7 +15,7 @@ + RELA = 7 + RELACOUNT = 0x6ffffff9 + +- .text ++ .data + /* A procedure descriptor used when booting this as a COFF file. + * When making COFF, this comes first in the link and we're + * linked at 0x500000. +@@ -23,6 +23,8 @@ RELACOUNT = 0x6ffffff9 + .globl _zimage_start_opd + _zimage_start_opd: + .long 0x500000, 0, 0, 0 ++ .text ++ b _zimage_start + + #ifdef __powerpc64__ + .balign 8 +diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c +index 8baaff5af0b5..75b9d43069f1 100644 +--- a/arch/x86/crypto/chacha20_glue.c ++++ b/arch/x86/crypto/chacha20_glue.c +@@ -77,6 +77,7 @@ static int chacha20_simd(struct blkcipher_desc *desc, struct scatterlist *dst, + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt_block(desc, &walk, CHACHA20_BLOCK_SIZE); ++ desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP; + + crypto_chacha20_init(state, crypto_blkcipher_ctx(desc->tfm), walk.iv); + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index c048d0d70cc4..2cb49ac1b2b2 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1200,7 +1200,7 @@ asmlinkage void kvm_spurious_fault(void); + "cmpb $0, kvm_rebooting \n\t" \ + "jne 668b \n\t" \ + __ASM_SIZE(push) " $666b \n\t" \ +- "call kvm_spurious_fault \n\t" \ ++ "jmp kvm_spurious_fault \n\t" \ + ".popsection \n\t" \ + _ASM_EXTABLE(666b, 667b) + +diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c +index d76f13d6d8d6..ec894bf5eeb0 100644 +--- a/arch/x86/kernel/cpu/mtrr/if.c ++++ b/arch/x86/kernel/cpu/mtrr/if.c +@@ -173,6 +173,8 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) + struct mtrr_gentry gentry; + void __user *arg = (void __user *) __arg; + ++ memset(&gentry, 0, sizeof(gentry)); ++ + switch (cmd) { + case MTRRIOC_ADD_ENTRY: + case MTRRIOC_SET_ENTRY: +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index e4b5fd72ca24..3bdb2e747b89 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -6163,9 +6163,24 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu) + + gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); + if (!kvm_io_bus_write(vcpu, KVM_FAST_MMIO_BUS, gpa, 0, NULL)) { +- skip_emulated_instruction(vcpu); + trace_kvm_fast_mmio(gpa); +- return 1; ++ /* ++ * Doing kvm_skip_emulated_instruction() depends on undefined ++ * behavior: Intel's manual doesn't mandate ++ * VM_EXIT_INSTRUCTION_LEN to be set in VMCS when EPT MISCONFIG ++ * occurs and while on real hardware it was observed to be set, ++ * other hypervisors (namely Hyper-V) don't set it, we end up ++ * advancing IP with some random value. Disable fast mmio when ++ * running nested and keep it for real hardware in hope that ++ * VM_EXIT_INSTRUCTION_LEN will always be set correctly. ++ */ ++ if (!static_cpu_has(X86_FEATURE_HYPERVISOR)) { ++ skip_emulated_instruction(vcpu); ++ return 1; ++ } ++ else ++ return x86_emulate_instruction(vcpu, gpa, EMULTYPE_SKIP, ++ NULL, 0) == EMULATE_DONE; + } + + ret = handle_mmio_page_fault(vcpu, gpa, true); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index aa1a0277a678..1a934bb8ed1c 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -5436,7 +5436,8 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, + * handle watchpoints yet, those would be handled in + * the emulate_ops. + */ +- if (kvm_vcpu_check_breakpoint(vcpu, &r)) ++ if (!(emulation_type & EMULTYPE_SKIP) && ++ kvm_vcpu_check_breakpoint(vcpu, &r)) + return r; + + ctxt->interruptibility = 0; +diff --git a/drivers/gpio/gpio-max7301.c b/drivers/gpio/gpio-max7301.c +index 05813fbf3daf..647dfbbc4e1c 100644 +--- a/drivers/gpio/gpio-max7301.c ++++ b/drivers/gpio/gpio-max7301.c +@@ -25,7 +25,7 @@ static int max7301_spi_write(struct device *dev, unsigned int reg, + struct spi_device *spi = to_spi_device(dev); + u16 word = ((reg & 0x7F) << 8) | (val & 0xFF); + +- return spi_write(spi, (const u8 *)&word, sizeof(word)); ++ return spi_write_then_read(spi, &word, sizeof(word), NULL, 0); + } + + /* A read from the MAX7301 means two transfers; here, one message each */ +@@ -37,14 +37,8 @@ static int max7301_spi_read(struct device *dev, unsigned int reg) + struct spi_device *spi = to_spi_device(dev); + + word = 0x8000 | (reg << 8); +- ret = spi_write(spi, (const u8 *)&word, sizeof(word)); +- if (ret) +- return ret; +- /* +- * This relies on the fact, that a transfer with NULL tx_buf shifts out +- * zero bytes (=NOOP for MAX7301) +- */ +- ret = spi_read(spi, (u8 *)&word, sizeof(word)); ++ ret = spi_write_then_read(spi, &word, sizeof(word), &word, ++ sizeof(word)); + if (ret) + return ret; + return word & 0xff; +diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c +index 8ce2a0c59116..a7030ada81fd 100644 +--- a/drivers/gpu/drm/drm_ioctl.c ++++ b/drivers/gpu/drm/drm_ioctl.c +@@ -36,6 +36,7 @@ + + #include + #include ++#include + + static int drm_version(struct drm_device *dev, void *data, + struct drm_file *file_priv); +@@ -702,13 +703,17 @@ long drm_ioctl(struct file *filp, + + if (is_driver_ioctl) { + /* driver ioctl */ +- if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls) ++ unsigned int index = nr - DRM_COMMAND_BASE; ++ ++ if (index >= dev->driver->num_ioctls) + goto err_i1; +- ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; ++ index = array_index_nospec(index, dev->driver->num_ioctls); ++ ioctl = &dev->driver->ioctls[index]; + } else { + /* core ioctl */ + if (nr >= DRM_CORE_IOCTL_COUNT) + goto err_i1; ++ nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT); + ioctl = &drm_ioctls[nr]; + } + +@@ -810,6 +815,7 @@ bool drm_ioctl_flags(unsigned int nr, unsigned int *flags) + + if (nr >= DRM_CORE_IOCTL_COUNT) + return false; ++ nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT); + + *flags = drm_ioctls[nr].flags; + return true; +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index 802dcb409030..b877cce0409b 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -316,6 +316,8 @@ static ssize_t out_intr_mask_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); + return sprintf(buf, "%d\n", outbound.current_interrupt_mask); + } +@@ -329,6 +331,8 @@ static ssize_t out_read_index_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); + return sprintf(buf, "%d\n", outbound.current_read_index); + } +@@ -343,6 +347,8 @@ static ssize_t out_write_index_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); + return sprintf(buf, "%d\n", outbound.current_write_index); + } +@@ -357,6 +363,8 @@ static ssize_t out_read_bytes_avail_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); + return sprintf(buf, "%d\n", outbound.bytes_avail_toread); + } +@@ -371,6 +379,8 @@ static ssize_t out_write_bytes_avail_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); + return sprintf(buf, "%d\n", outbound.bytes_avail_towrite); + } +@@ -384,6 +394,8 @@ static ssize_t in_intr_mask_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); + return sprintf(buf, "%d\n", inbound.current_interrupt_mask); + } +@@ -397,6 +409,8 @@ static ssize_t in_read_index_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); + return sprintf(buf, "%d\n", inbound.current_read_index); + } +@@ -410,6 +424,8 @@ static ssize_t in_write_index_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); + return sprintf(buf, "%d\n", inbound.current_write_index); + } +@@ -424,6 +440,8 @@ static ssize_t in_read_bytes_avail_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); + return sprintf(buf, "%d\n", inbound.bytes_avail_toread); + } +@@ -438,6 +456,8 @@ static ssize_t in_write_bytes_avail_show(struct device *dev, + + if (!hv_dev->channel) + return -ENODEV; ++ if (hv_dev->channel->state != CHANNEL_OPENED_STATE) ++ return -EINVAL; + hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); + return sprintf(buf, "%d\n", inbound.bytes_avail_towrite); + } +diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c +index 70ca27e45602..9d9e47eb0842 100644 +--- a/drivers/hwtracing/intel_th/msu.c ++++ b/drivers/hwtracing/intel_th/msu.c +@@ -1418,7 +1418,8 @@ nr_pages_store(struct device *dev, struct device_attribute *attr, + if (!end) + break; + +- len -= end - p; ++ /* consume the number and the following comma, hence +1 */ ++ len -= end - p + 1; + p = end + 1; + } while (len); + +diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c +index f78c464899db..3d2c60c8de83 100644 +--- a/drivers/input/keyboard/omap4-keypad.c ++++ b/drivers/input/keyboard/omap4-keypad.c +@@ -126,12 +126,8 @@ static irqreturn_t omap4_keypad_irq_handler(int irq, void *dev_id) + { + struct omap4_keypad *keypad_data = dev_id; + +- if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) { +- /* Disable interrupts */ +- kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, +- OMAP4_VAL_IRQDISABLE); ++ if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) + return IRQ_WAKE_THREAD; +- } + + return IRQ_NONE; + } +@@ -173,11 +169,6 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) + kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, + kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); + +- /* enable interrupts */ +- kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, +- OMAP4_DEF_IRQENABLE_EVENTEN | +- OMAP4_DEF_IRQENABLE_LONGKEY); +- + return IRQ_HANDLED; + } + +@@ -214,9 +205,10 @@ static void omap4_keypad_close(struct input_dev *input) + + disable_irq(keypad_data->irq); + +- /* Disable interrupts */ ++ /* Disable interrupts and wake-up events */ + kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, + OMAP4_VAL_IRQDISABLE); ++ kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, 0); + + /* clear pending interrupts */ + kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, +@@ -364,7 +356,7 @@ static int omap4_keypad_probe(struct platform_device *pdev) + } + + error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, +- omap4_keypad_irq_thread_fn, 0, ++ omap4_keypad_irq_thread_fn, IRQF_ONESHOT, + "omap4-keypad", keypad_data); + if (error) { + dev_err(&pdev->dev, "failed to register interrupt\n"); +diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c +index 471984ec2db0..30adc5745cba 100644 +--- a/drivers/input/mouse/elan_i2c_core.c ++++ b/drivers/input/mouse/elan_i2c_core.c +@@ -1240,6 +1240,7 @@ MODULE_DEVICE_TABLE(i2c, elan_id); + static const struct acpi_device_id elan_acpi_id[] = { + { "ELAN0000", 0 }, + { "ELAN0100", 0 }, ++ { "ELAN0501", 0 }, + { "ELAN0600", 0 }, + { "ELAN0602", 0 }, + { "ELAN0605", 0 }, +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index 7feaa82f8c7c..8b4a4d95669a 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -2041,7 +2041,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, + * than default. Unnecessary for PT mode. + */ + if (translation != CONTEXT_TT_PASS_THROUGH) { +- for (agaw = domain->agaw; agaw != iommu->agaw; agaw--) { ++ for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) { + ret = -ENOMEM; + pgd = phys_to_virt(dma_pte_addr(pgd)); + if (!dma_pte_present(pgd)) +@@ -2055,7 +2055,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, + translation = CONTEXT_TT_MULTI_LEVEL; + + context_set_address_root(context, virt_to_phys(pgd)); +- context_set_address_width(context, iommu->agaw); ++ context_set_address_width(context, agaw); + } else { + /* + * In pass through mode, AW must be programmed to +diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c +index dd7e38ac29bd..d15347de415a 100644 +--- a/drivers/isdn/capi/kcapi.c ++++ b/drivers/isdn/capi/kcapi.c +@@ -851,7 +851,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 *buf) + u16 ret; + + if (contr == 0) { +- strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); ++ strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); + return CAPI_NOERROR; + } + +@@ -859,7 +859,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 *buf) + + ctr = get_capi_ctr_by_nr(contr); + if (ctr && ctr->state == CAPI_CTR_RUNNING) { +- strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); ++ strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); + ret = CAPI_NOERROR; + } else + ret = CAPI_REGNOTINSTALLED; +diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c +index ef5412311b2f..a84954f1be34 100644 +--- a/drivers/media/platform/vivid/vivid-vid-cap.c ++++ b/drivers/media/platform/vivid/vivid-vid-cap.c +@@ -461,6 +461,8 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) + tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap)); + break; + } ++ vfree(dev->bitmap_cap); ++ dev->bitmap_cap = NULL; + vivid_update_quality(dev); + tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); + dev->crop_cap = dev->src_rect; +diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c +index 524660510599..0c15ba21fa54 100644 +--- a/drivers/misc/genwqe/card_utils.c ++++ b/drivers/misc/genwqe/card_utils.c +@@ -217,7 +217,7 @@ u32 genwqe_crc32(u8 *buff, size_t len, u32 init) + void *__genwqe_alloc_consistent(struct genwqe_dev *cd, size_t size, + dma_addr_t *dma_handle) + { +- if (get_order(size) > MAX_ORDER) ++ if (get_order(size) >= MAX_ORDER) + return NULL; + + return dma_alloc_coherent(&cd->pci_dev->dev, size, dma_handle, +diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c +index 79a0c26e1419..a31789be0840 100644 +--- a/drivers/mmc/core/mmc.c ++++ b/drivers/mmc/core/mmc.c +@@ -1608,9 +1608,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, + if (err) { + pr_warn("%s: Enabling HPI failed\n", + mmc_hostname(card->host)); ++ card->ext_csd.hpi_en = 0; + err = 0; +- } else ++ } else { + card->ext_csd.hpi_en = 1; ++ } + } + + /* +diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c +index 6b814d7d6560..af937d3e8c3e 100644 +--- a/drivers/mmc/host/omap_hsmmc.c ++++ b/drivers/mmc/host/omap_hsmmc.c +@@ -2117,7 +2117,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) + mmc->max_blk_size = 512; /* Block Length at max can be 1024 */ + mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */ + mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; +- mmc->max_seg_size = mmc->max_req_size; + + mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; +@@ -2174,6 +2173,17 @@ static int omap_hsmmc_probe(struct platform_device *pdev) + goto err_irq; + } + ++ /* ++ * Limit the maximum segment size to the lower of the request size ++ * and the DMA engine device segment size limits. In reality, with ++ * 32-bit transfers, the DMA engine can do longer segments than this ++ * but there is no way to represent that in the DMA model - if we ++ * increase this figure here, we get warnings from the DMA API debug. ++ */ ++ mmc->max_seg_size = min3(mmc->max_req_size, ++ dma_get_max_seg_size(host->rx_chan->device->dev), ++ dma_get_max_seg_size(host->tx_chan->device->dev)); ++ + /* Request IRQ for MMC operations */ + ret = devm_request_irq(&pdev->dev, host->irq, omap_hsmmc_irq, 0, + mmc_hostname(mmc), host); +diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c +index 2f9b12cf9ee5..61a9ab4fe047 100644 +--- a/drivers/net/ethernet/ibm/ibmveth.c ++++ b/drivers/net/ethernet/ibm/ibmveth.c +@@ -1163,11 +1163,15 @@ out: + + map_failed_frags: + last = i+1; +- for (i = 0; i < last; i++) ++ for (i = 1; i < last; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); + ++ dma_unmap_single(&adapter->vdev->dev, ++ descs[0].fields.address, ++ descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK, ++ DMA_TO_DEVICE); + map_failed: + if (!firmware_has_feature(FW_FEATURE_CMO)) + netdev_err(netdev, "tx: unable to map xmit buffer\n"); +diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c +index 111d907e0c11..79cede19e0c4 100644 +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -2825,6 +2825,12 @@ static int hso_get_config_data(struct usb_interface *interface) + return -EIO; + } + ++ /* check if we have a valid interface */ ++ if (if_num > 16) { ++ kfree(config_data); ++ return -EINVAL; ++ } ++ + switch (config_data[if_num]) { + case 0x0: + result = 0; +@@ -2895,10 +2901,18 @@ static int hso_probe(struct usb_interface *interface, + + /* Get the interface/port specification from either driver_info or from + * the device itself */ +- if (id->driver_info) ++ if (id->driver_info) { ++ /* if_num is controlled by the device, driver_info is a 0 terminated ++ * array. Make sure, the access is in bounds! */ ++ for (i = 0; i <= if_num; ++i) ++ if (((u32 *)(id->driver_info))[i] == 0) ++ goto exit; + port_spec = ((u32 *)(id->driver_info))[if_num]; +- else ++ } else { + port_spec = hso_get_config_data(interface); ++ if (port_spec < 0) ++ goto exit; ++ } + + /* Check if we need to switch to alt interfaces prior to port + * configuration */ +diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c +index ec2b9c577b90..3644c9edaf81 100644 +--- a/drivers/net/wireless/b43/phy_common.c ++++ b/drivers/net/wireless/b43/phy_common.c +@@ -616,7 +616,7 @@ struct b43_c32 b43_cordic(int theta) + u8 i; + s32 tmp; + s8 signx = 1; +- u32 angle = 0; ++ s32 angle = 0; + struct b43_c32 ret = { .i = 39797, .q = 0, }; + + while (theta > (180 << 16)) +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index 0a4bd73caae5..6f55ab4f7959 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -889,7 +889,7 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue, + if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) { + unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; + +- BUG_ON(pull_to <= skb_headlen(skb)); ++ BUG_ON(pull_to < skb_headlen(skb)); + __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); + } + if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) { +diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c +index 9e29b1321648..15783869e1a0 100644 +--- a/drivers/power/olpc_battery.c ++++ b/drivers/power/olpc_battery.c +@@ -427,14 +427,14 @@ static int olpc_bat_get_property(struct power_supply *psy, + if (ret) + return ret; + +- val->intval = (s16)be16_to_cpu(ec_word) * 100 / 256; ++ val->intval = (s16)be16_to_cpu(ec_word) * 10 / 256; + break; + case POWER_SUPPLY_PROP_TEMP_AMBIENT: + ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2); + if (ret) + return ret; + +- val->intval = (int)be16_to_cpu(ec_word) * 100 / 256; ++ val->intval = (int)be16_to_cpu(ec_word) * 10 / 256; + break; + case POWER_SUPPLY_PROP_CHARGE_COUNTER: + ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2); +diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c +index 38c8e308d4c8..a96c98e3fc73 100644 +--- a/drivers/s390/scsi/zfcp_aux.c ++++ b/drivers/s390/scsi/zfcp_aux.c +@@ -275,16 +275,16 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) + */ + int zfcp_status_read_refill(struct zfcp_adapter *adapter) + { +- while (atomic_read(&adapter->stat_miss) > 0) ++ while (atomic_add_unless(&adapter->stat_miss, -1, 0)) + if (zfcp_fsf_status_read(adapter->qdio)) { ++ atomic_inc(&adapter->stat_miss); /* undo add -1 */ + if (atomic_read(&adapter->stat_miss) >= + adapter->stat_read_buf_num) { + zfcp_erp_adapter_reopen(adapter, 0, "axsref1"); + return 1; + } + break; +- } else +- atomic_dec(&adapter->stat_miss); ++ } + return 0; + } + +diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +index d0b227ffbd5f..573aeec7a02b 100644 +--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c ++++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +@@ -2279,7 +2279,7 @@ static int _bnx2fc_create(struct net_device *netdev, + if (!interface) { + printk(KERN_ERR PFX "bnx2fc_interface_create failed\n"); + rc = -ENOMEM; +- goto ifput_err; ++ goto netdev_err; + } + + if (netdev->priv_flags & IFF_802_1Q_VLAN) { +diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c +index cf04960cc3e6..1a1368f5863c 100644 +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -88,7 +88,7 @@ struct bcm2835_spi { + u8 *rx_buf; + int tx_len; + int rx_len; +- bool dma_pending; ++ unsigned int dma_pending; + }; + + static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) +@@ -155,8 +155,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) + /* Write as many bytes as possible to FIFO */ + bcm2835_wr_fifo(bs); + +- /* based on flags decide if we can finish the transfer */ +- if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) { ++ if (!bs->rx_len) { + /* Transfer complete - reset SPI HW */ + bcm2835_spi_reset_hw(master); + /* wake up the framework */ +@@ -233,10 +232,9 @@ static void bcm2835_spi_dma_done(void *data) + * is called the tx-dma must have finished - can't get to this + * situation otherwise... + */ +- dmaengine_terminate_all(master->dma_tx); +- +- /* mark as no longer pending */ +- bs->dma_pending = 0; ++ if (cmpxchg(&bs->dma_pending, true, false)) { ++ dmaengine_terminate_all(master->dma_tx); ++ } + + /* and mark as completed */; + complete(&master->xfer_completion); +@@ -342,6 +340,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_master *master, + if (ret) { + /* need to reset on errors */ + dmaengine_terminate_all(master->dma_tx); ++ bs->dma_pending = false; + bcm2835_spi_reset_hw(master); + return ret; + } +@@ -617,10 +616,9 @@ static void bcm2835_spi_handle_err(struct spi_master *master, + struct bcm2835_spi *bs = spi_master_get_devdata(master); + + /* if an error occurred and we have an active dma, then terminate */ +- if (bs->dma_pending) { ++ if (cmpxchg(&bs->dma_pending, true, false)) { + dmaengine_terminate_all(master->dma_tx); + dmaengine_terminate_all(master->dma_rx); +- bs->dma_pending = 0; + } + /* and reset */ + bcm2835_spi_reset_hw(master); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 0a8e5ac891d4..3919ea066bf9 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -507,6 +507,13 @@ static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty) + if (retval) + goto error_init_termios; + ++ /* ++ * Suppress initial echoing for some devices which might send data ++ * immediately after acm driver has been installed. ++ */ ++ if (acm->quirks & DISABLE_ECHO) ++ tty->termios.c_lflag &= ~ECHO; ++ + tty->driver_data = acm; + + return 0; +@@ -1677,6 +1684,9 @@ static const struct usb_device_id acm_ids[] = { + { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, ++ { USB_DEVICE(0x0e8d, 0x2000), /* MediaTek Inc Preloader */ ++ .driver_info = DISABLE_ECHO, /* DISABLE ECHO in termios flag */ ++ }, + { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, +diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h +index b30ac5fcde68..1ad9ff9f493d 100644 +--- a/drivers/usb/class/cdc-acm.h ++++ b/drivers/usb/class/cdc-acm.h +@@ -134,3 +134,4 @@ struct acm { + #define QUIRK_CONTROL_LINE_STATE BIT(6) + #define CLEAR_HALT_CONDITIONS BIT(7) + #define SEND_ZERO_PACKET BIT(8) ++#define DISABLE_ECHO BIT(9) +diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c +index a11c2c8bda53..a217f71b45c6 100644 +--- a/drivers/usb/host/r8a66597-hcd.c ++++ b/drivers/usb/host/r8a66597-hcd.c +@@ -1990,6 +1990,8 @@ static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, + + static void r8a66597_endpoint_disable(struct usb_hcd *hcd, + struct usb_host_endpoint *hep) ++__acquires(r8a66597->lock) ++__releases(r8a66597->lock) + { + struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); + struct r8a66597_pipe *pipe = (struct r8a66597_pipe *)hep->hcpriv; +@@ -2002,13 +2004,14 @@ static void r8a66597_endpoint_disable(struct usb_hcd *hcd, + return; + pipenum = pipe->info.pipenum; + ++ spin_lock_irqsave(&r8a66597->lock, flags); + if (pipenum == 0) { + kfree(hep->hcpriv); + hep->hcpriv = NULL; ++ spin_unlock_irqrestore(&r8a66597->lock, flags); + return; + } + +- spin_lock_irqsave(&r8a66597->lock, flags); + pipe_stop(r8a66597, pipe); + pipe_irq_disable(r8a66597, pipenum); + disable_irq_empty(r8a66597, pipenum); +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 5d21cd8359d4..421825b44202 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -1329,7 +1329,8 @@ int xhci_bus_suspend(struct usb_hcd *hcd) + portsc_buf[port_index] = 0; + + /* Bail out if a USB3 port has a new device in link training */ +- if ((t1 & PORT_PLS_MASK) == XDEV_POLLING) { ++ if ((hcd->speed >= HCD_USB3) && ++ (t1 & PORT_PLS_MASK) == XDEV_POLLING) { + bus_state->bus_suspended = 0; + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_dbg(xhci, "Bus suspend bailout, port in polling\n"); +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 2b81939fecd7..7bc2c9fef605 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1163,6 +1163,10 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, ++ { USB_DEVICE(TELIT_VENDOR_ID, 0x1900), /* Telit LN940 (QMI) */ ++ .driver_info = NCTRL(0) | RSVD(1) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1901, 0xff), /* Telit LN940 (MBIM) */ ++ .driver_info = NCTRL(0) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), + .driver_info = RSVD(1) }, +@@ -1327,6 +1331,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x0602, 0xff) }, /* GosunCn ZTE WeLink ME3630 (MBIM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), + .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), +@@ -1530,6 +1535,7 @@ static const struct usb_device_id option_ids[] = { + .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ + .driver_info = RSVD(2) }, ++ { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) }, /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, +@@ -1757,6 +1763,7 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E), + .driver_info = RSVD(5) | RSVD(6) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */ + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), + .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), +@@ -1941,7 +1948,18 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD200, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x10) }, /* HP lt4132 (Huawei ME906s-158) */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x12) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x13) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x14) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0xa31d, 0xff, 0x06, 0x1b) }, ++ { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 */ ++ .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, ++ { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ ++ .driver_info = RSVD(4) | RSVD(5) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ ++ .driver_info = RSVD(6) }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, option_ids); +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index 3da25ad267a2..4966768d3c98 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -86,9 +86,14 @@ static const struct usb_device_id id_table[] = { + { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, + { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, ++ { USB_DEVICE(HP_VENDOR_ID, HP_LD220TA_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, ++ { USB_DEVICE(HP_VENDOR_ID, HP_LD960TA_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, ++ { USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) }, ++ { USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) }, ++ { USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) }, + { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, + { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, +diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h +index 123289085ee2..a84f0959ab34 100644 +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -123,10 +123,15 @@ + + /* Hewlett-Packard POS Pole Displays */ + #define HP_VENDOR_ID 0x03f0 ++#define HP_LM920_PRODUCT_ID 0x026b ++#define HP_TD620_PRODUCT_ID 0x0956 + #define HP_LD960_PRODUCT_ID 0x0b39 + #define HP_LCM220_PRODUCT_ID 0x3139 + #define HP_LCM960_PRODUCT_ID 0x3239 + #define HP_LD220_PRODUCT_ID 0x3524 ++#define HP_LD220TA_PRODUCT_ID 0x4349 ++#define HP_LD960TA_PRODUCT_ID 0x4439 ++#define HP_LM940_PRODUCT_ID 0x5039 + + /* Cressi Edy (diving computer) PC interface */ + #define CRESSI_VENDOR_ID 0x04b8 +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index c54d388310f0..2ed0a356d1d3 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -1550,6 +1550,8 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads, + return -EFAULT; + } + if (unlikely(vq->log_used)) { ++ /* Make sure used idx is seen before log. */ ++ smp_wmb(); + /* Log used index update. */ + log_write(vq->log_base, + vq->log_addr + offsetof(struct vring_used, idx), +diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c +index 0e3de1bb6500..e7b54514d99a 100644 +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -3243,7 +3243,6 @@ retry: + tcap->cap_id = t_cap_id; + tcap->seq = t_seq - 1; + tcap->issue_seq = t_seq - 1; +- tcap->mseq = t_mseq; + tcap->issued |= issued; + tcap->implemented |= issued; + if (cap == ci->i_auth_cap) +diff --git a/fs/cifs/smb2maperror.c b/fs/cifs/smb2maperror.c +index 8257a5a97cc0..98c25b969ab8 100644 +--- a/fs/cifs/smb2maperror.c ++++ b/fs/cifs/smb2maperror.c +@@ -377,8 +377,8 @@ static const struct status_to_posix_error smb2_error_map_table[] = { + {STATUS_NONEXISTENT_EA_ENTRY, -EIO, "STATUS_NONEXISTENT_EA_ENTRY"}, + {STATUS_NO_EAS_ON_FILE, -ENODATA, "STATUS_NO_EAS_ON_FILE"}, + {STATUS_EA_CORRUPT_ERROR, -EIO, "STATUS_EA_CORRUPT_ERROR"}, +- {STATUS_FILE_LOCK_CONFLICT, -EIO, "STATUS_FILE_LOCK_CONFLICT"}, +- {STATUS_LOCK_NOT_GRANTED, -EIO, "STATUS_LOCK_NOT_GRANTED"}, ++ {STATUS_FILE_LOCK_CONFLICT, -EACCES, "STATUS_FILE_LOCK_CONFLICT"}, ++ {STATUS_LOCK_NOT_GRANTED, -EACCES, "STATUS_LOCK_NOT_GRANTED"}, + {STATUS_DELETE_PENDING, -ENOENT, "STATUS_DELETE_PENDING"}, + {STATUS_CTL_FILE_NOT_SUPPORTED, -ENOSYS, + "STATUS_CTL_FILE_NOT_SUPPORTED"}, +diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c +index 35502d4046f5..3a7f401e943c 100644 +--- a/fs/dlm/lock.c ++++ b/fs/dlm/lock.c +@@ -1210,6 +1210,7 @@ static int create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) + + if (rv < 0) { + log_error(ls, "create_lkb idr error %d", rv); ++ dlm_free_lkb(lkb); + return rv; + } + +@@ -4177,6 +4178,7 @@ static int receive_convert(struct dlm_ls *ls, struct dlm_message *ms) + (unsigned long long)lkb->lkb_recover_seq, + ms->m_header.h_nodeid, ms->m_lkid); + error = -ENOENT; ++ dlm_put_lkb(lkb); + goto fail; + } + +@@ -4230,6 +4232,7 @@ static int receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) + lkb->lkb_id, lkb->lkb_remid, + ms->m_header.h_nodeid, ms->m_lkid); + error = -ENOENT; ++ dlm_put_lkb(lkb); + goto fail; + } + +@@ -5792,20 +5795,20 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, + goto out; + } + } +- +- /* After ua is attached to lkb it will be freed by dlm_free_lkb(). +- When DLM_IFL_USER is set, the dlm knows that this is a userspace +- lock and that lkb_astparam is the dlm_user_args structure. */ +- + error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs, + fake_astfn, ua, fake_bastfn, &args); +- lkb->lkb_flags |= DLM_IFL_USER; +- + if (error) { ++ kfree(ua->lksb.sb_lvbptr); ++ ua->lksb.sb_lvbptr = NULL; ++ kfree(ua); + __put_lkb(ls, lkb); + goto out; + } + ++ /* After ua is attached to lkb it will be freed by dlm_free_lkb(). ++ When DLM_IFL_USER is set, the dlm knows that this is a userspace ++ lock and that lkb_astparam is the dlm_user_args structure. */ ++ lkb->lkb_flags |= DLM_IFL_USER; + error = request_lock(ls, lkb, name, namelen, &args); + + switch (error) { +diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c +index f3e72787e7f9..30e4e01db35a 100644 +--- a/fs/dlm/lockspace.c ++++ b/fs/dlm/lockspace.c +@@ -673,11 +673,11 @@ static int new_lockspace(const char *name, const char *cluster, + kfree(ls->ls_recover_buf); + out_lkbidr: + idr_destroy(&ls->ls_lkbidr); ++ out_rsbtbl: + for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) { + if (ls->ls_remove_names[i]) + kfree(ls->ls_remove_names[i]); + } +- out_rsbtbl: + vfree(ls->ls_rsbtbl); + out_lsfree: + if (do_unreg) +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index 1aec46733ef8..46d4fac48cf4 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -701,8 +701,11 @@ int ext4_try_to_write_inline_data(struct address_space *mapping, + + if (!PageUptodate(page)) { + ret = ext4_read_inline_page(inode, page); +- if (ret < 0) ++ if (ret < 0) { ++ unlock_page(page); ++ put_page(page); + goto out_up_read; ++ } + } + + ret = 1; +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index bad13f049fb0..2fc1564f62dd 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -1600,7 +1600,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) + } + + if (reserved_gdb || gdb_off == 0) { +- if (ext4_has_feature_resize_inode(sb) || ++ if (!ext4_has_feature_resize_inode(sb) || + !le16_to_cpu(es->s_reserved_gdt_blocks)) { + ext4_warning(sb, + "No reserved GDT blocks, can't resize"); +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index cd9cd581fd92..6a7df72cb3da 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1049,6 +1049,16 @@ static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, + ext4_nfs_get_inode); + } + ++static int ext4_nfs_commit_metadata(struct inode *inode) ++{ ++ struct writeback_control wbc = { ++ .sync_mode = WB_SYNC_ALL ++ }; ++ ++ trace_ext4_nfs_commit_metadata(inode); ++ return ext4_write_inode(inode, &wbc); ++} ++ + /* + * Try to release metadata pages (indirect blocks, directories) which are + * mapped via the block device. Since these pages could have journal heads +@@ -1143,6 +1153,7 @@ static const struct export_operations ext4_export_ops = { + .fh_to_dentry = ext4_fh_to_dentry, + .fh_to_parent = ext4_fh_to_parent, + .get_parent = ext4_get_parent, ++ .commit_metadata = ext4_nfs_commit_metadata, + }; + + enum { +@@ -5184,9 +5195,9 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id, + qf_inode->i_flags |= S_NOQUOTA; + lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA); + err = dquot_enable(qf_inode, type, format_id, flags); +- iput(qf_inode); + if (err) + lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL); ++ iput(qf_inode); + + return err; + } +diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c +index ef24894edecc..763fe7737065 100644 +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -1720,9 +1720,9 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext, + goto next_iter; + } + if (ret == -E2BIG) { ++ n += rbm->bii - initial_bii; + rbm->bii = 0; + rbm->offset = 0; +- n += (rbm->bii - initial_bii); + goto res_covered_end_of_rgrp; + } + return ret; +diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h +index cf6c74550baa..86316f90ea1e 100644 +--- a/include/net/gro_cells.h ++++ b/include/net/gro_cells.h +@@ -84,6 +84,7 @@ static inline void gro_cells_destroy(struct gro_cells *gcells) + for_each_possible_cpu(i) { + struct gro_cell *cell = per_cpu_ptr(gcells->cells, i); + ++ napi_disable(&cell->napi); + netif_napi_del(&cell->napi); + __skb_queue_purge(&cell->napi_skbs); + } +diff --git a/include/net/sock.h b/include/net/sock.h +index 577075713ad5..7420299c31f5 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -299,6 +299,7 @@ struct cg_proto; + * @sk_filter: socket filtering instructions + * @sk_timer: sock cleanup timer + * @sk_stamp: time stamp of last packet received ++ * @sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only + * @sk_tsflags: SO_TIMESTAMPING socket options + * @sk_tskey: counter to disambiguate concurrent tstamp requests + * @sk_socket: Identd and reporting IO signals +@@ -434,6 +435,9 @@ struct sock { + long sk_sndtimeo; + struct timer_list sk_timer; + ktime_t sk_stamp; ++#if BITS_PER_LONG==32 ++ seqlock_t sk_stamp_seq; ++#endif + u16 sk_tsflags; + u32 sk_tskey; + struct socket *sk_socket; +@@ -2146,6 +2150,34 @@ static inline void sk_drops_add(struct sock *sk, const struct sk_buff *skb) + atomic_add(segs, &sk->sk_drops); + } + ++static inline ktime_t sock_read_timestamp(struct sock *sk) ++{ ++#if BITS_PER_LONG==32 ++ unsigned int seq; ++ ktime_t kt; ++ ++ do { ++ seq = read_seqbegin(&sk->sk_stamp_seq); ++ kt = sk->sk_stamp; ++ } while (read_seqretry(&sk->sk_stamp_seq, seq)); ++ ++ return kt; ++#else ++ return sk->sk_stamp; ++#endif ++} ++ ++static inline void sock_write_timestamp(struct sock *sk, ktime_t kt) ++{ ++#if BITS_PER_LONG==32 ++ write_seqlock(&sk->sk_stamp_seq); ++ sk->sk_stamp = kt; ++ write_sequnlock(&sk->sk_stamp_seq); ++#else ++ sk->sk_stamp = kt; ++#endif ++} ++ + void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, + struct sk_buff *skb); + void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, +@@ -2170,7 +2202,7 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) + (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) + __sock_recv_timestamp(msg, sk, skb); + else +- sk->sk_stamp = kt; ++ sock_write_timestamp(sk, kt); + + if (sock_flag(sk, SOCK_WIFI_STATUS) && skb->wifi_acked_valid) + __sock_recv_wifi_status(msg, sk, skb); +@@ -2190,7 +2222,7 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, + if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY) + __sock_recv_ts_and_drops(msg, sk, skb); + else +- sk->sk_stamp = skb->tstamp; ++ sock_write_timestamp(sk, skb->tstamp); + } + + void __sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags); +diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h +index 594b4b29a224..7ef11b97cb2a 100644 +--- a/include/trace/events/ext4.h ++++ b/include/trace/events/ext4.h +@@ -223,6 +223,26 @@ TRACE_EVENT(ext4_drop_inode, + (unsigned long) __entry->ino, __entry->drop) + ); + ++TRACE_EVENT(ext4_nfs_commit_metadata, ++ TP_PROTO(struct inode *inode), ++ ++ TP_ARGS(inode), ++ ++ TP_STRUCT__entry( ++ __field( dev_t, dev ) ++ __field( ino_t, ino ) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = inode->i_sb->s_dev; ++ __entry->ino = inode->i_ino; ++ ), ++ ++ TP_printk("dev %d,%d ino %lu", ++ MAJOR(__entry->dev), MINOR(__entry->dev), ++ (unsigned long) __entry->ino) ++); ++ + TRACE_EVENT(ext4_mark_inode_dirty, + TP_PROTO(struct inode *inode, unsigned long IP), + +diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h +index 87cf351bab03..9e07bf4259e1 100644 +--- a/include/uapi/linux/input-event-codes.h ++++ b/include/uapi/linux/input-event-codes.h +@@ -708,6 +708,15 @@ + + #define ABS_MISC 0x28 + ++/* ++ * 0x2e is reserved and should not be used in input drivers. ++ * It was used by HID as ABS_MISC+6 and userspace needs to detect if ++ * the next ABS_* event is correct or is just ABS_MISC + n. ++ * We define here ABS_RESERVED so userspace can rely on it and detect ++ * the situation described above. ++ */ ++#define ABS_RESERVED 0x2e ++ + #define ABS_MT_SLOT 0x2f /* MT slot being modified */ + #define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */ + #define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */ +diff --git a/kernel/fork.c b/kernel/fork.c +index dd2f79ac0771..e4b81913a998 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1411,8 +1411,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, + + posix_cpu_timers_init(p); + +- p->start_time = ktime_get_ns(); +- p->real_start_time = ktime_get_boot_ns(); + p->io_context = NULL; + p->audit_context = NULL; + cgroup_fork(p); +@@ -1572,6 +1570,17 @@ static struct task_struct *copy_process(unsigned long clone_flags, + if (retval) + goto bad_fork_free_pid; + ++ /* ++ * From this point on we must avoid any synchronous user-space ++ * communication until we take the tasklist-lock. In particular, we do ++ * not want user-space to be able to predict the process start-time by ++ * stalling fork(2) after we recorded the start_time but before it is ++ * visible to the system. ++ */ ++ ++ p->start_time = ktime_get_ns(); ++ p->real_start_time = ktime_get_boot_ns(); ++ + /* + * Make it visible to the rest of the system, but dont wake it up yet. + * Need tasklist lock for parent etc handling! +diff --git a/kernel/memremap.c b/kernel/memremap.c +index f719c925cb54..1be42f9b3e00 100644 +--- a/kernel/memremap.c ++++ b/kernel/memremap.c +@@ -171,15 +171,12 @@ void *devm_memremap_pages(struct device *dev, struct resource *res) + struct page_map *page_map; + int error, nid; + +- if (is_ram == REGION_MIXED) { +- WARN_ONCE(1, "%s attempted on mixed region %pr\n", +- __func__, res); ++ if (is_ram != REGION_DISJOINT) { ++ WARN_ONCE(1, "%s attempted on %s region %pr\n", __func__, ++ is_ram == REGION_MIXED ? "mixed" : "ram", res); + return ERR_PTR(-ENXIO); + } + +- if (is_ram == REGION_INTERSECTS) +- return __va(res->start); +- + page_map = devres_alloc_node(devm_memremap_pages_release, + sizeof(*page_map), GFP_KERNEL, dev_to_node(dev)); + if (!page_map) +@@ -202,5 +199,5 @@ void *devm_memremap_pages(struct device *dev, struct resource *res) + devres_add(dev, page_map); + return __va(res->start); + } +-EXPORT_SYMBOL(devm_memremap_pages); ++EXPORT_SYMBOL_GPL(devm_memremap_pages); + #endif /* CONFIG_ZONE_DEVICE */ +diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c +index a18923e4359d..0addef5f8aa3 100644 +--- a/mm/memory_hotplug.c ++++ b/mm/memory_hotplug.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1471,6 +1472,21 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) + continue; + } + ++ /* ++ * HWPoison pages have elevated reference counts so the migration would ++ * fail on them. It also doesn't make any sense to migrate them in the ++ * first place. Still try to unmap such a page in case it is still mapped ++ * (e.g. current hwpoison implementation doesn't unmap KSM pages but keep ++ * the unmap as the catch all safety net). ++ */ ++ if (PageHWPoison(page)) { ++ if (WARN_ON(PageLRU(page))) ++ isolate_lru_page(page); ++ if (page_mapped(page)) ++ try_to_unmap(page, TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS); ++ continue; ++ } ++ + if (!get_page_unless_zero(page)) + continue; + /* +diff --git a/net/9p/client.c b/net/9p/client.c +index ed8738c4dc09..8fba9cd973c1 100644 +--- a/net/9p/client.c ++++ b/net/9p/client.c +@@ -156,6 +156,12 @@ static int parse_opts(char *opts, struct p9_client *clnt) + ret = r; + continue; + } ++ if (option < 4096) { ++ p9_debug(P9_DEBUG_ERROR, ++ "msize should be at least 4k\n"); ++ ret = -EINVAL; ++ continue; ++ } + clnt->msize = option; + break; + case Opt_trans: +@@ -972,10 +978,18 @@ static int p9_client_version(struct p9_client *c) + else if (!strncmp(version, "9P2000", 6)) + c->proto_version = p9_proto_legacy; + else { ++ p9_debug(P9_DEBUG_ERROR, ++ "server returned an unknown version: %s\n", version); + err = -EREMOTEIO; + goto error; + } + ++ if (msize < 4096) { ++ p9_debug(P9_DEBUG_ERROR, ++ "server returned a msize < 4096: %d\n", msize); ++ err = -EREMOTEIO; ++ goto error; ++ } + if (msize < c->msize) + c->msize = msize; + +@@ -1040,6 +1054,13 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) + if (clnt->msize > clnt->trans_mod->maxsize) + clnt->msize = clnt->trans_mod->maxsize; + ++ if (clnt->msize < 4096) { ++ p9_debug(P9_DEBUG_ERROR, ++ "Please specify a msize of at least 4k\n"); ++ err = -EINVAL; ++ goto free_client; ++ } ++ + err = p9_client_version(clnt); + if (err) + goto close_trans; +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index 2fdebabbfacd..2772f6a13fcb 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -654,15 +654,22 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, + break; + } + +- dev = dev_get_by_name(&init_net, devname); ++ rtnl_lock(); ++ dev = __dev_get_by_name(&init_net, devname); + if (!dev) { ++ rtnl_unlock(); + res = -ENODEV; + break; + } + + ax25->ax25_dev = ax25_dev_ax25dev(dev); ++ if (!ax25->ax25_dev) { ++ rtnl_unlock(); ++ res = -ENODEV; ++ break; ++ } + ax25_fillin_cb(ax25, ax25->ax25_dev); +- dev_put(dev); ++ rtnl_unlock(); + break; + + default: +diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c +index 3d106767b272..5faca5db6385 100644 +--- a/net/ax25/ax25_dev.c ++++ b/net/ax25/ax25_dev.c +@@ -116,6 +116,7 @@ void ax25_dev_device_down(struct net_device *dev) + if ((s = ax25_dev_list) == ax25_dev) { + ax25_dev_list = s->next; + spin_unlock_bh(&ax25_dev_lock); ++ dev->ax25_ptr = NULL; + dev_put(dev); + kfree(ax25_dev); + return; +@@ -125,6 +126,7 @@ void ax25_dev_device_down(struct net_device *dev) + if (s->next == ax25_dev) { + s->next = ax25_dev->next; + spin_unlock_bh(&ax25_dev_lock); ++ dev->ax25_ptr = NULL; + dev_put(dev); + kfree(ax25_dev); + return; +diff --git a/net/compat.c b/net/compat.c +index 17e97b106458..d67684010455 100644 +--- a/net/compat.c ++++ b/net/compat.c +@@ -443,12 +443,14 @@ int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) + err = -ENOENT; + if (!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- tv = ktime_to_timeval(sk->sk_stamp); ++ tv = ktime_to_timeval(sock_read_timestamp(sk)); ++ + if (tv.tv_sec == -1) + return err; + if (tv.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); +- tv = ktime_to_timeval(sk->sk_stamp); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); ++ tv = ktime_to_timeval(kt); + } + err = 0; + if (put_user(tv.tv_sec, &ctv->tv_sec) || +@@ -471,12 +473,13 @@ int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *usersta + err = -ENOENT; + if (!sock_flag(sk, SOCK_TIMESTAMP)) + sock_enable_timestamp(sk, SOCK_TIMESTAMP); +- ts = ktime_to_timespec(sk->sk_stamp); ++ ts = ktime_to_timespec(sock_read_timestamp(sk)); + if (ts.tv_sec == -1) + return err; + if (ts.tv_sec == 0) { +- sk->sk_stamp = ktime_get_real(); +- ts = ktime_to_timespec(sk->sk_stamp); ++ ktime_t kt = ktime_get_real(); ++ sock_write_timestamp(sk, kt); ++ ts = ktime_to_timespec(kt); + } + err = 0; + if (put_user(ts.tv_sec, &ctv->tv_sec) || +diff --git a/net/core/sock.c b/net/core/sock.c +index 4238835a0e4e..9fb1c073d0c4 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2423,6 +2423,9 @@ void sock_init_data(struct socket *sock, struct sock *sk) + sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; + + sk->sk_stamp = ktime_set(-1L, 0); ++#if BITS_PER_LONG==32 ++ seqlock_init(&sk->sk_stamp_seq); ++#endif + + #ifdef CONFIG_NET_RX_BUSY_POLL + sk->sk_napi_id = 0; +diff --git a/net/ieee802154/6lowpan/tx.c b/net/ieee802154/6lowpan/tx.c +index a10db45b2e1e..df32134da924 100644 +--- a/net/ieee802154/6lowpan/tx.c ++++ b/net/ieee802154/6lowpan/tx.c +@@ -55,6 +55,9 @@ int lowpan_header_create(struct sk_buff *skb, struct net_device *ldev, + const u8 *daddr = _daddr; + struct lowpan_addr_info *info; + ++ if (!daddr) ++ return -EINVAL; ++ + /* TODO: + * if this package isn't ipv6 one, where should it be routed? + */ +diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c +index 8e77786549c6..1cb865fcc91b 100644 +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -66,6 +66,7 @@ + #include + #include + #include ++#include + + #if defined(CONFIG_IP_PIMSM_V1) || defined(CONFIG_IP_PIMSM_V2) + #define CONFIG_IP_PIMSM 1 +@@ -1574,6 +1575,7 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) + return -EFAULT; + if (vr.vifi >= mrt->maxvif) + return -EINVAL; ++ vr.vifi = array_index_nospec(vr.vifi, mrt->maxvif); + read_lock(&mrt_lock); + vif = &mrt->vif_table[vr.vifi]; + if (VIF_EXISTS(mrt, vr.vifi)) { +diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c +index 14dacf1df529..30b03d8e321a 100644 +--- a/net/ipv6/ip6_udp_tunnel.c ++++ b/net/ipv6/ip6_udp_tunnel.c +@@ -15,7 +15,7 @@ + int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, + struct socket **sockp) + { +- struct sockaddr_in6 udp6_addr; ++ struct sockaddr_in6 udp6_addr = {}; + int err; + struct socket *sock = NULL; + +@@ -42,6 +42,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, + goto error; + + if (cfg->peer_udp_port) { ++ memset(&udp6_addr, 0, sizeof(udp6_addr)); + udp6_addr.sin6_family = AF_INET6; + memcpy(&udp6_addr.sin6_addr, &cfg->peer_ip6, + sizeof(udp6_addr.sin6_addr)); +diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c +index 9b92960f024d..74b3e9718e84 100644 +--- a/net/ipv6/ip6mr.c ++++ b/net/ipv6/ip6mr.c +@@ -72,6 +72,8 @@ struct mr6_table { + #endif + }; + ++#include ++ + struct ip6mr_rule { + struct fib_rule common; + }; +@@ -1871,6 +1873,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) + return -EFAULT; + if (vr.mifi >= mrt->maxvif) + return -EINVAL; ++ vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif); + read_lock(&mrt_lock); + vif = &mrt->vif6_table[vr.mifi]; + if (MIF_EXISTS(mrt, vr.mifi)) { +@@ -1945,6 +1948,7 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) + return -EFAULT; + if (vr.mifi >= mrt->maxvif) + return -EINVAL; ++ vr.mifi = array_index_nospec(vr.mifi, mrt->maxvif); + read_lock(&mrt_lock); + vif = &mrt->vif6_table[vr.mifi]; + if (MIF_EXISTS(mrt, vr.mifi)) { +diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c +index ed212ffc1d9d..046ae1caecea 100644 +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -153,7 +153,7 @@ static struct sock *nr_find_listener(ax25_address *addr) + sk_for_each(s, &nr_list) + if (!ax25cmp(&nr_sk(s)->source_addr, addr) && + s->sk_state == TCP_LISTEN) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + s = NULL; +@@ -174,7 +174,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id) + struct nr_sock *nr = nr_sk(s); + + if (nr->my_index == index && nr->my_id == id) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + } +@@ -198,7 +198,7 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id, + + if (nr->your_index == index && nr->your_id == id && + !ax25cmp(&nr->dest_addr, dest)) { +- bh_lock_sock(s); ++ sock_hold(s); + goto found; + } + } +@@ -224,7 +224,7 @@ static unsigned short nr_find_next_circuit(void) + if (i != 0 && j != 0) { + if ((sk=nr_find_socket(i, j)) == NULL) + break; +- bh_unlock_sock(sk); ++ sock_put(sk); + } + + id++; +@@ -918,6 +918,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev) + } + + if (sk != NULL) { ++ bh_lock_sock(sk); + skb_reset_transport_header(skb); + + if (frametype == NR_CONNACK && skb->len == 22) +@@ -927,6 +928,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev) + + ret = nr_process_rx_frame(sk, skb); + bh_unlock_sock(sk); ++ sock_put(sk); + return ret; + } + +@@ -958,10 +960,12 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev) + (make = nr_make_new(sk)) == NULL) { + nr_transmit_refusal(skb, 0); + if (sk) +- bh_unlock_sock(sk); ++ sock_put(sk); + return 0; + } + ++ bh_lock_sock(sk); ++ + window = skb->data[20]; + + skb->sk = make; +@@ -1014,6 +1018,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev) + sk->sk_data_ready(sk); + + bh_unlock_sock(sk); ++ sock_put(sk); + + nr_insert_socket(make); + +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index 07668f152a3a..0f50977ed53b 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -2511,8 +2511,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) + sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_addr; ++ addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); ++ if (addr && dev && saddr->sll_halen < dev->addr_len) ++ goto out; + } + + err = -ENXIO; +@@ -2678,8 +2680,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) + if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) + goto out; + proto = saddr->sll_protocol; +- addr = saddr->sll_addr; ++ addr = saddr->sll_halen ? saddr->sll_addr : NULL; + dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); ++ if (addr && dev && saddr->sll_halen < dev->addr_len) ++ goto out; + } + + err = -ENXIO; +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index 5ca8309ea7b1..7dffc97a953c 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -101,6 +101,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, + if (addr) { + addr->a.v6.sin6_family = AF_INET6; + addr->a.v6.sin6_port = 0; ++ addr->a.v6.sin6_flowinfo = 0; + addr->a.v6.sin6_addr = ifa->addr; + addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex; + addr->valid = 1; +diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c +index 036bbf2b44c1..b5291ea54a3d 100644 +--- a/net/sunrpc/auth_gss/svcauth_gss.c ++++ b/net/sunrpc/auth_gss/svcauth_gss.c +@@ -1105,7 +1105,7 @@ static int svcauth_gss_legacy_init(struct svc_rqst *rqstp, + struct kvec *resv = &rqstp->rq_res.head[0]; + struct rsi *rsip, rsikey; + int ret; +- struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); ++ struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); + + memset(&rsikey, 0, sizeof(rsikey)); + ret = gss_read_verf(gc, argv, authp, +@@ -1216,7 +1216,7 @@ static int svcauth_gss_proxy_init(struct svc_rqst *rqstp, + uint64_t handle; + int status; + int ret; +- struct net *net = rqstp->rq_xprt->xpt_net; ++ struct net *net = SVC_NET(rqstp); + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); + + memset(&ud, 0, sizeof(ud)); +@@ -1406,7 +1406,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) + __be32 *rpcstart; + __be32 *reject_stat = resv->iov_base + resv->iov_len; + int ret; +- struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); ++ struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); + + dprintk("RPC: svcauth_gss: argv->iov_len = %zd\n", + argv->iov_len); +@@ -1694,7 +1694,7 @@ svcauth_gss_release(struct svc_rqst *rqstp) + struct rpc_gss_wire_cred *gc = &gsd->clcred; + struct xdr_buf *resbuf = &rqstp->rq_res; + int stat = -EINVAL; +- struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id); ++ struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id); + + if (gc->gc_proc != RPC_GSS_PROC_DATA) + goto out; +diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c +index 63fb5ee212cf..af17b00145e1 100644 +--- a/net/sunrpc/cache.c ++++ b/net/sunrpc/cache.c +@@ -54,6 +54,11 @@ static void cache_init(struct cache_head *h, struct cache_detail *detail) + h->last_refresh = now; + } + ++static void cache_fresh_locked(struct cache_head *head, time_t expiry, ++ struct cache_detail *detail); ++static void cache_fresh_unlocked(struct cache_head *head, ++ struct cache_detail *detail); ++ + struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, + struct cache_head *key, int hash) + { +@@ -95,6 +100,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, + if (cache_is_expired(detail, tmp)) { + hlist_del_init(&tmp->cache_list); + detail->entries --; ++ cache_fresh_locked(tmp, 0, detail); + freeme = tmp; + break; + } +@@ -110,8 +116,10 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, + cache_get(new); + write_unlock(&detail->hash_lock); + +- if (freeme) ++ if (freeme) { ++ cache_fresh_unlocked(freeme, detail); + cache_put(freeme, detail); ++ } + return new; + } + EXPORT_SYMBOL_GPL(sunrpc_cache_lookup); +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index 1413cdcc131c..9701fcca002c 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -614,7 +614,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp) + /* Don't enable netstamp, sunrpc doesn't + need that much accuracy */ + } +- svsk->sk_sk->sk_stamp = skb->tstamp; ++ sock_write_timestamp(svsk->sk_sk, skb->tstamp); + set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */ + + len = skb->len - sizeof(struct udphdr); +diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c +index 589c8b9908a5..d24773552b64 100644 +--- a/net/vmw_vsock/vmci_transport.c ++++ b/net/vmw_vsock/vmci_transport.c +@@ -272,6 +272,31 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src, + false); + } + ++static int ++vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src, ++ struct sockaddr_vm *dst, ++ enum vmci_transport_packet_type type, ++ u64 size, ++ u64 mode, ++ struct vmci_transport_waiting_info *wait, ++ u16 proto, ++ struct vmci_handle handle) ++{ ++ struct vmci_transport_packet *pkt; ++ int err; ++ ++ pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); ++ if (!pkt) ++ return -ENOMEM; ++ ++ err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size, ++ mode, wait, proto, handle, ++ true); ++ kfree(pkt); ++ ++ return err; ++} ++ + static int + vmci_transport_send_control_pkt(struct sock *sk, + enum vmci_transport_packet_type type, +@@ -281,9 +306,7 @@ vmci_transport_send_control_pkt(struct sock *sk, + u16 proto, + struct vmci_handle handle) + { +- struct vmci_transport_packet *pkt; + struct vsock_sock *vsk; +- int err; + + vsk = vsock_sk(sk); + +@@ -293,17 +316,10 @@ vmci_transport_send_control_pkt(struct sock *sk, + if (!vsock_addr_bound(&vsk->remote_addr)) + return -EINVAL; + +- pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); +- if (!pkt) +- return -ENOMEM; +- +- err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr, +- &vsk->remote_addr, type, size, +- mode, wait, proto, handle, +- true); +- kfree(pkt); +- +- return err; ++ return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, ++ &vsk->remote_addr, ++ type, size, mode, ++ wait, proto, handle); + } + + static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, +@@ -321,12 +337,29 @@ static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, + static int vmci_transport_send_reset(struct sock *sk, + struct vmci_transport_packet *pkt) + { ++ struct sockaddr_vm *dst_ptr; ++ struct sockaddr_vm dst; ++ struct vsock_sock *vsk; ++ + if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST) + return 0; +- return vmci_transport_send_control_pkt(sk, +- VMCI_TRANSPORT_PACKET_TYPE_RST, +- 0, 0, NULL, VSOCK_PROTO_INVALID, +- VMCI_INVALID_HANDLE); ++ ++ vsk = vsock_sk(sk); ++ ++ if (!vsock_addr_bound(&vsk->local_addr)) ++ return -EINVAL; ++ ++ if (vsock_addr_bound(&vsk->remote_addr)) { ++ dst_ptr = &vsk->remote_addr; ++ } else { ++ vsock_addr_init(&dst, pkt->dg.src.context, ++ pkt->src_port); ++ dst_ptr = &dst; ++ } ++ return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, dst_ptr, ++ VMCI_TRANSPORT_PACKET_TYPE_RST, ++ 0, 0, NULL, VSOCK_PROTO_INVALID, ++ VMCI_INVALID_HANDLE); + } + + static int vmci_transport_send_negotiate(struct sock *sk, size_t size) +diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c +index 9b6e51450fc5..13f261feb75c 100644 +--- a/net/xfrm/xfrm_state.c ++++ b/net/xfrm/xfrm_state.c +@@ -623,7 +623,7 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si) + { + spin_lock_bh(&net->xfrm.xfrm_state_lock); + si->sadcnt = net->xfrm.state_num; +- si->sadhcnt = net->xfrm.state_hmask; ++ si->sadhcnt = net->xfrm.state_hmask + 1; + si->sadhmcnt = xfrm_state_hashmax; + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + } +diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl +index dd8397894d5c..12a6940741fe 100755 +--- a/scripts/checkstack.pl ++++ b/scripts/checkstack.pl +@@ -46,8 +46,8 @@ my (@stack, $re, $dre, $x, $xs, $funcre); + $xs = "[0-9a-f ]"; # hex character or space + $funcre = qr/^$x* <(.*)>:$/; + if ($arch eq 'aarch64') { +- #ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp,#-80]! +- $re = qr/^.*stp.*sp,\#-([0-9]{1,8})\]\!/o; ++ #ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp, #-80]! ++ $re = qr/^.*stp.*sp, \#-([0-9]{1,8})\]\!/o; + } elsif ($arch eq 'arm') { + #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 + $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; +diff --git a/sound/core/pcm.c b/sound/core/pcm.c +index 6bda8f6c5f84..cdff5f976480 100644 +--- a/sound/core/pcm.c ++++ b/sound/core/pcm.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -125,6 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, + return -EFAULT; + if (stream < 0 || stream > 1) + return -EINVAL; ++ stream = array_index_nospec(stream, 2); + if (get_user(subdevice, &info->subdevice)) + return -EFAULT; + mutex_lock(®ister_mutex); +diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c +index d2951ed4bf71..1984291ebd07 100644 +--- a/sound/pci/cs46xx/dsp_spos.c ++++ b/sound/pci/cs46xx/dsp_spos.c +@@ -899,6 +899,9 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip) + struct dsp_spos_instance * ins = chip->dsp_spos_instance; + int i; + ++ if (!ins) ++ return 0; ++ + snd_info_free_entry(ins->proc_sym_info_entry); + ins->proc_sym_info_entry = NULL; + +diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c +index 50b216fc369f..5d422d65e62b 100644 +--- a/sound/pci/emu10k1/emufx.c ++++ b/sound/pci/emu10k1/emufx.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1000,6 +1001,8 @@ static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu, + + if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) + return -EINVAL; ++ ipcm->substream = array_index_nospec(ipcm->substream, ++ EMU10K1_FX8010_PCM_COUNT); + if (ipcm->channels > 32) + return -EINVAL; + pcm = &emu->fx8010.pcm[ipcm->substream]; +@@ -1046,6 +1049,8 @@ static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu, + + if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT) + return -EINVAL; ++ ipcm->substream = array_index_nospec(ipcm->substream, ++ EMU10K1_FX8010_PCM_COUNT); + pcm = &emu->fx8010.pcm[ipcm->substream]; + mutex_lock(&emu->fx8010.lock); + spin_lock_irq(&emu->reg_lock); +diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c +index 17fd81736d3d..039fbbb1e53c 100644 +--- a/sound/pci/hda/hda_tegra.c ++++ b/sound/pci/hda/hda_tegra.c +@@ -249,10 +249,12 @@ static int hda_tegra_suspend(struct device *dev) + struct snd_card *card = dev_get_drvdata(dev); + struct azx *chip = card->private_data; + struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); ++ struct hdac_bus *bus = azx_bus(chip); + + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + + azx_stop_chip(chip); ++ synchronize_irq(bus->irq); + azx_enter_link_reset(chip); + hda_tegra_disable_clocks(hda); + +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index aea3cc2abe3a..536184ac315d 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -853,6 +853,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { + SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), ++ SND_PCI_QUIRK(0x103c, 0x828c, "HP EliteBook 840 G4", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83b3, "HP EliteBook 830 G5", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x83d3, "HP ProBook 640 G4", CXT_FIXUP_HP_DOCK), + SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), +diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c +index 7c8941b8b2de..dd6c9e6a1d53 100644 +--- a/sound/pci/rme9652/hdsp.c ++++ b/sound/pci/rme9652/hdsp.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -4065,15 +4066,16 @@ static int snd_hdsp_channel_info(struct snd_pcm_substream *substream, + struct snd_pcm_channel_info *info) + { + struct hdsp *hdsp = snd_pcm_substream_chip(substream); +- int mapped_channel; ++ unsigned int channel = info->channel; + +- if (snd_BUG_ON(info->channel >= hdsp->max_channels)) ++ if (snd_BUG_ON(channel >= hdsp->max_channels)) + return -EINVAL; ++ channel = array_index_nospec(channel, hdsp->max_channels); + +- if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) ++ if (hdsp->channel_map[channel] < 0) + return -EINVAL; + +- info->offset = mapped_channel * HDSP_CHANNEL_BUFFER_BYTES; ++ info->offset = hdsp->channel_map[channel] * HDSP_CHANNEL_BUFFER_BYTES; + info->first = 0; + info->step = 32; + return 0; +diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c +index e557946718a9..d9fcae071b47 100644 +--- a/sound/synth/emux/emux_hwdep.c ++++ b/sound/synth/emux/emux_hwdep.c +@@ -22,9 +22,9 @@ + #include + #include + #include ++#include + #include "emux_voice.h" + +- + #define TMP_CLIENT_ID 0x1001 + + /* +@@ -66,13 +66,16 @@ snd_emux_hwdep_misc_mode(struct snd_emux *emu, void __user *arg) + return -EFAULT; + if (info.mode < 0 || info.mode >= EMUX_MD_END) + return -EINVAL; ++ info.mode = array_index_nospec(info.mode, EMUX_MD_END); + + if (info.port < 0) { + for (i = 0; i < emu->num_ports; i++) + emu->portptrs[i]->ctrls[info.mode] = info.value; + } else { +- if (info.port < emu->num_ports) ++ if (info.port < emu->num_ports) { ++ info.port = array_index_nospec(info.port, emu->num_ports); + emu->portptrs[info.port]->ctrls[info.mode] = info.value; ++ } + } + return 0; + } +diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c +index 97d6a18e6956..f7eb0d2f797b 100644 +--- a/sound/usb/mixer.c ++++ b/sound/usb/mixer.c +@@ -1816,7 +1816,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, + char *name) + { + struct uac_processing_unit_descriptor *desc = raw_desc; +- int num_ins = desc->bNrInPins; ++ int num_ins; + struct usb_mixer_elem_info *cval; + struct snd_kcontrol *kctl; + int i, err, nameid, type, len; +@@ -1831,7 +1831,13 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, + 0, NULL, default_value_info + }; + +- if (desc->bLength < 13 || desc->bLength < 13 + num_ins || ++ if (desc->bLength < 13) { ++ usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid); ++ return -EINVAL; ++ } ++ ++ num_ins = desc->bNrInPins; ++ if (desc->bLength < 13 + num_ins || + desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) { + usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid); + return -EINVAL; +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index 15cbe2565703..d32727c74a16 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -3321,6 +3321,9 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), + } + } + }, ++ { ++ .ifnum = -1 ++ }, + } + } + }, +diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c +index 593066c68e3d..4f650ebd564a 100644 +--- a/tools/perf/util/pmu.c ++++ b/tools/perf/util/pmu.c +@@ -100,7 +100,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char * + char path[PATH_MAX]; + const char *lc; + +- snprintf(path, PATH_MAX, "%s/%s.scale", dir, name); ++ scnprintf(path, PATH_MAX, "%s/%s.scale", dir, name); + + fd = open(path, O_RDONLY); + if (fd == -1) +@@ -147,7 +147,7 @@ static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *n + ssize_t sret; + int fd; + +- snprintf(path, PATH_MAX, "%s/%s.unit", dir, name); ++ scnprintf(path, PATH_MAX, "%s/%s.unit", dir, name); + + fd = open(path, O_RDONLY); + if (fd == -1) +@@ -177,7 +177,7 @@ perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name) + char path[PATH_MAX]; + int fd; + +- snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name); ++ scnprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name); + + fd = open(path, O_RDONLY); + if (fd == -1) +@@ -195,7 +195,7 @@ static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias, + char path[PATH_MAX]; + int fd; + +- snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name); ++ scnprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name); + + fd = open(path, O_RDONLY); + if (fd == -1) diff --git a/patch/kernel/rockchip64-default/04-patch-4.4.170-171.patch b/patch/kernel/rockchip64-default/04-patch-4.4.170-171.patch new file mode 100644 index 0000000000..4061abc0c7 --- /dev/null +++ b/patch/kernel/rockchip64-default/04-patch-4.4.170-171.patch @@ -0,0 +1,2650 @@ +diff --git a/Makefile b/Makefile +index bc58f206c0da..c6b680faedd8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 170 ++SUBLEVEL = 171 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/crypto/cts.c b/crypto/cts.c +index e467ec0acf9f..e65688d6a4ca 100644 +--- a/crypto/cts.c ++++ b/crypto/cts.c +@@ -137,8 +137,8 @@ static int crypto_cts_encrypt(struct blkcipher_desc *desc, + lcldesc.info = desc->info; + lcldesc.flags = desc->flags; + +- if (tot_blocks == 1) { +- err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, bsize); ++ if (tot_blocks <= 1) { ++ err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, nbytes); + } else if (nbytes <= bsize * 2) { + err = cts_cbc_encrypt(ctx, desc, dst, src, 0, nbytes); + } else { +@@ -232,8 +232,8 @@ static int crypto_cts_decrypt(struct blkcipher_desc *desc, + lcldesc.info = desc->info; + lcldesc.flags = desc->flags; + +- if (tot_blocks == 1) { +- err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, bsize); ++ if (tot_blocks <= 1) { ++ err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, nbytes); + } else if (nbytes <= bsize * 2) { + err = cts_cbc_decrypt(ctx, desc, dst, src, 0, nbytes); + } else { +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index 1c2b846c5776..f28b4949cb9d 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -131,6 +131,23 @@ void acpi_power_resources_list_free(struct list_head *list) + } + } + ++static bool acpi_power_resource_is_dup(union acpi_object *package, ++ unsigned int start, unsigned int i) ++{ ++ acpi_handle rhandle, dup; ++ unsigned int j; ++ ++ /* The caller is expected to check the package element types */ ++ rhandle = package->package.elements[i].reference.handle; ++ for (j = start; j < i; j++) { ++ dup = package->package.elements[j].reference.handle; ++ if (dup == rhandle) ++ return true; ++ } ++ ++ return false; ++} ++ + int acpi_extract_power_resources(union acpi_object *package, unsigned int start, + struct list_head *list) + { +@@ -150,6 +167,11 @@ int acpi_extract_power_resources(union acpi_object *package, unsigned int start, + err = -ENODEV; + break; + } ++ ++ /* Some ACPI tables contain duplicate power resource references */ ++ if (acpi_power_resource_is_dup(package, start, i)) ++ continue; ++ + err = acpi_add_power_resource(rhandle); + if (err) + break; +diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c +index 94c837046786..57e3790c87b1 100644 +--- a/drivers/i2c/i2c-dev.c ++++ b/drivers/i2c/i2c-dev.c +@@ -459,9 +459,15 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + return i2cdev_ioctl_smbus(client, arg); + + case I2C_RETRIES: ++ if (arg > INT_MAX) ++ return -EINVAL; ++ + client->adapter->retries = arg; + break; + case I2C_TIMEOUT: ++ if (arg > INT_MAX) ++ return -EINVAL; ++ + /* For historical reasons, user-space sets the timeout + * value in units of 10 ms. + */ +diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c +index 99da549d5d06..0118287a8a10 100644 +--- a/drivers/pci/host/pcie-altera.c ++++ b/drivers/pci/host/pcie-altera.c +@@ -40,8 +40,10 @@ + #define P2A_INT_ENABLE 0x3070 + #define P2A_INT_ENA_ALL 0xf + #define RP_LTSSM 0x3c64 ++#define RP_LTSSM_MASK 0x1f + #define LTSSM_L0 0xf + ++#define PCIE_CAP_OFFSET 0x80 + /* TLP configuration type 0 and 1 */ + #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ + #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ +@@ -60,6 +62,9 @@ + #define TLP_LOOP 500 + #define RP_DEVFN 0 + ++#define LINK_UP_TIMEOUT HZ ++#define LINK_RETRAIN_TIMEOUT HZ ++ + #define INTX_NUM 4 + + #define DWORD_MASK 3 +@@ -80,25 +85,21 @@ struct tlp_rp_regpair_t { + u32 reg1; + }; + +-static void altera_pcie_retrain(struct pci_dev *dev) ++static inline void cra_writel(struct altera_pcie *pcie, const u32 value, ++ const u32 reg) + { +- u16 linkcap, linkstat; +- +- /* +- * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but +- * current speed is 2.5 GB/s. +- */ +- pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap); ++ writel_relaxed(value, pcie->cra_base + reg); ++} + +- if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB) +- return; ++static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) ++{ ++ return readl_relaxed(pcie->cra_base + reg); ++} + +- pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat); +- if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) +- pcie_capability_set_word(dev, PCI_EXP_LNKCTL, +- PCI_EXP_LNKCTL_RL); ++static bool altera_pcie_link_is_up(struct altera_pcie *pcie) ++{ ++ return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); + } +-DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain); + + /* + * Altera PCIe port uses BAR0 of RC's configuration space as the translation +@@ -119,17 +120,6 @@ static bool altera_pcie_hide_rc_bar(struct pci_bus *bus, unsigned int devfn, + return false; + } + +-static inline void cra_writel(struct altera_pcie *pcie, const u32 value, +- const u32 reg) +-{ +- writel_relaxed(value, pcie->cra_base + reg); +-} +- +-static inline u32 cra_readl(struct altera_pcie *pcie, const u32 reg) +-{ +- return readl_relaxed(pcie->cra_base + reg); +-} +- + static void tlp_write_tx(struct altera_pcie *pcie, + struct tlp_rp_regpair_t *tlp_rp_regdata) + { +@@ -138,11 +128,6 @@ static void tlp_write_tx(struct altera_pcie *pcie, + cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL); + } + +-static bool altera_pcie_link_is_up(struct altera_pcie *pcie) +-{ +- return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0); +-} +- + static bool altera_pcie_valid_config(struct altera_pcie *pcie, + struct pci_bus *bus, int dev) + { +@@ -286,22 +271,14 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn, + return PCIBIOS_SUCCESSFUL; + } + +-static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn, +- int where, int size, u32 *value) ++static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno, ++ unsigned int devfn, int where, int size, ++ u32 *value) + { +- struct altera_pcie *pcie = bus->sysdata; + int ret; + u32 data; + u8 byte_en; + +- if (altera_pcie_hide_rc_bar(bus, devfn, where)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- +- if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) { +- *value = 0xffffffff; +- return PCIBIOS_DEVICE_NOT_FOUND; +- } +- + switch (size) { + case 1: + byte_en = 1 << (where & 3); +@@ -314,7 +291,7 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn, + break; + } + +- ret = tlp_cfg_dword_read(pcie, bus->number, devfn, ++ ret = tlp_cfg_dword_read(pcie, busno, devfn, + (where & ~DWORD_MASK), byte_en, &data); + if (ret != PCIBIOS_SUCCESSFUL) + return ret; +@@ -334,20 +311,14 @@ static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn, + return PCIBIOS_SUCCESSFUL; + } + +-static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn, +- int where, int size, u32 value) ++static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno, ++ unsigned int devfn, int where, int size, ++ u32 value) + { +- struct altera_pcie *pcie = bus->sysdata; + u32 data32; + u32 shift = 8 * (where & 3); + u8 byte_en; + +- if (altera_pcie_hide_rc_bar(bus, devfn, where)) +- return PCIBIOS_BAD_REGISTER_NUMBER; +- +- if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) +- return PCIBIOS_DEVICE_NOT_FOUND; +- + switch (size) { + case 1: + data32 = (value & 0xff) << shift; +@@ -363,8 +334,40 @@ static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn, + break; + } + +- return tlp_cfg_dword_write(pcie, bus->number, devfn, +- (where & ~DWORD_MASK), byte_en, data32); ++ return tlp_cfg_dword_write(pcie, busno, devfn, (where & ~DWORD_MASK), ++ byte_en, data32); ++} ++ ++static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *value) ++{ ++ struct altera_pcie *pcie = bus->sysdata; ++ ++ if (altera_pcie_hide_rc_bar(bus, devfn, where)) ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ ++ if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) { ++ *value = 0xffffffff; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size, ++ value); ++} ++ ++static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 value) ++{ ++ struct altera_pcie *pcie = bus->sysdata; ++ ++ if (altera_pcie_hide_rc_bar(bus, devfn, where)) ++ return PCIBIOS_BAD_REGISTER_NUMBER; ++ ++ if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ return _altera_pcie_cfg_write(pcie, bus->number, devfn, where, size, ++ value); + } + + static struct pci_ops altera_pcie_ops = { +@@ -372,6 +375,90 @@ static struct pci_ops altera_pcie_ops = { + .write = altera_pcie_cfg_write, + }; + ++static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno, ++ unsigned int devfn, int offset, u16 *value) ++{ ++ u32 data; ++ int ret; ++ ++ ret = _altera_pcie_cfg_read(pcie, busno, devfn, ++ PCIE_CAP_OFFSET + offset, sizeof(*value), ++ &data); ++ *value = data; ++ return ret; ++} ++ ++static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno, ++ unsigned int devfn, int offset, u16 value) ++{ ++ return _altera_pcie_cfg_write(pcie, busno, devfn, ++ PCIE_CAP_OFFSET + offset, sizeof(value), ++ value); ++} ++ ++static void altera_wait_link_retrain(struct altera_pcie *pcie) ++{ ++ u16 reg16; ++ unsigned long start_jiffies; ++ ++ /* Wait for link training end. */ ++ start_jiffies = jiffies; ++ for (;;) { ++ altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, ++ PCI_EXP_LNKSTA, ®16); ++ if (!(reg16 & PCI_EXP_LNKSTA_LT)) ++ break; ++ ++ if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) { ++ dev_err(&pcie->pdev->dev, "link retrain timeout\n"); ++ break; ++ } ++ udelay(100); ++ } ++ ++ /* Wait for link is up */ ++ start_jiffies = jiffies; ++ for (;;) { ++ if (altera_pcie_link_is_up(pcie)) ++ break; ++ ++ if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) { ++ dev_err(&pcie->pdev->dev, "link up timeout\n"); ++ break; ++ } ++ udelay(100); ++ } ++} ++ ++static void altera_pcie_retrain(struct altera_pcie *pcie) ++{ ++ u16 linkcap, linkstat, linkctl; ++ ++ if (!altera_pcie_link_is_up(pcie)) ++ return; ++ ++ /* ++ * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but ++ * current speed is 2.5 GB/s. ++ */ ++ altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKCAP, ++ &linkcap); ++ if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB) ++ return; ++ ++ altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKSTA, ++ &linkstat); ++ if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { ++ altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, ++ PCI_EXP_LNKCTL, &linkctl); ++ linkctl |= PCI_EXP_LNKCTL_RL; ++ altera_write_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, ++ PCI_EXP_LNKCTL, linkctl); ++ ++ altera_wait_link_retrain(pcie); ++ } ++} ++ + static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) + { +@@ -506,6 +593,11 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) + return 0; + } + ++static void altera_pcie_host_init(struct altera_pcie *pcie) ++{ ++ altera_pcie_retrain(pcie); ++} ++ + static int altera_pcie_probe(struct platform_device *pdev) + { + struct altera_pcie *pcie; +@@ -543,6 +635,7 @@ static int altera_pcie_probe(struct platform_device *pdev) + cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS); + /* enable all interrupts */ + cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE); ++ altera_pcie_host_init(pcie); + + bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops, + pcie, &pcie->resources); +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 3919ea066bf9..736de1021d8b 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1885,6 +1885,13 @@ static const struct usb_device_id acm_ids[] = { + .driver_info = IGNORE_DEVICE, + }, + ++ { USB_DEVICE(0x1bc7, 0x0021), /* Telit 3G ACM only composition */ ++ .driver_info = SEND_ZERO_PACKET, ++ }, ++ { USB_DEVICE(0x1bc7, 0x0023), /* Telit 3G ACM + ECM composition */ ++ .driver_info = SEND_ZERO_PACKET, ++ }, ++ + /* control interfaces without any protocol set */ + { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, + USB_CDC_PROTO_NONE) }, +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index cf378b1ed373..733479ddf8a7 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -240,7 +240,8 @@ static const struct usb_device_id usb_quirk_list[] = { + USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + + /* Corsair K70 RGB */ +- { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT }, ++ { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT | ++ USB_QUIRK_DELAY_CTRL_MSG }, + + /* Corsair Strafe */ + { USB_DEVICE(0x1b1c, 0x1b15), .driver_info = USB_QUIRK_DELAY_INIT | +diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c +index 6c186b4df94a..b3344a77dcce 100644 +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -223,8 +223,12 @@ static int slave_configure(struct scsi_device *sdev) + if (!(us->fflags & US_FL_NEEDS_CAP16)) + sdev->try_rc_10_first = 1; + +- /* assume SPC3 or latter devices support sense size > 18 */ +- if (sdev->scsi_level > SCSI_SPC_2) ++ /* ++ * assume SPC3 or latter devices support sense size > 18 ++ * unless US_FL_BAD_SENSE quirk is specified. ++ */ ++ if (sdev->scsi_level > SCSI_SPC_2 && ++ !(us->fflags & US_FL_BAD_SENSE)) + us->fflags |= US_FL_SANE_SENSE; + + /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable +diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h +index 898215cad351..d92b974f0635 100644 +--- a/drivers/usb/storage/unusual_devs.h ++++ b/drivers/usb/storage/unusual_devs.h +@@ -1392,6 +1392,18 @@ UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE), + ++/* ++ * Reported by Icenowy Zheng ++ * The SMI SM3350 USB-UFS bridge controller will enter a wrong state ++ * that do not process read/write command if a long sense is requested, ++ * so force to use 18-byte sense. ++ */ ++UNUSUAL_DEV( 0x090c, 0x3350, 0x0000, 0xffff, ++ "SMI", ++ "SM3350 UFS-to-USB-Mass-Storage bridge", ++ USB_SC_DEVICE, USB_PR_DEVICE, NULL, ++ US_FL_BAD_SENSE ), ++ + /* + * Pete Zaitcev , bz#164688. + * The device blatantly ignores LUN and returns 1 in GetMaxLUN. +diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile +index 6d1d0b93b1aa..c792df826e12 100644 +--- a/fs/btrfs/Makefile ++++ b/fs/btrfs/Makefile +@@ -9,7 +9,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ + export.o tree-log.o free-space-cache.o zlib.o lzo.o \ + compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ + reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ +- uuid-tree.o props.o hash.o ++ uuid-tree.o props.o hash.o tree-checker.o + + btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o + btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 38ee08675468..8f4baa3cb992 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -1726,20 +1726,6 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, + return err; + } + +-/* +- * The leaf data grows from end-to-front in the node. +- * this returns the address of the start of the last item, +- * which is the stop of the leaf data stack +- */ +-static inline unsigned int leaf_data_end(struct btrfs_root *root, +- struct extent_buffer *leaf) +-{ +- u32 nr = btrfs_header_nritems(leaf); +- if (nr == 0) +- return BTRFS_LEAF_DATA_SIZE(root); +- return btrfs_item_offset_nr(leaf, nr - 1); +-} +- + + /* + * search for key in the extent_buffer. The items start at offset p, +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index e847573c6db0..4a91d3119e59 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include "extent_io.h" + #include "extent_map.h" + #include "async-thread.h" +@@ -897,6 +898,7 @@ struct btrfs_balance_item { + #define BTRFS_FILE_EXTENT_INLINE 0 + #define BTRFS_FILE_EXTENT_REG 1 + #define BTRFS_FILE_EXTENT_PREALLOC 2 ++#define BTRFS_FILE_EXTENT_TYPES 2 + + struct btrfs_file_extent_item { + /* +@@ -2283,7 +2285,7 @@ do { \ + #define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) + + struct btrfs_map_token { +- struct extent_buffer *eb; ++ const struct extent_buffer *eb; + char *kaddr; + unsigned long offset; + }; +@@ -2314,18 +2316,19 @@ static inline void btrfs_init_map_token (struct btrfs_map_token *token) + sizeof(((type *)0)->member))) + + #define DECLARE_BTRFS_SETGET_BITS(bits) \ +-u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ +- unsigned long off, \ +- struct btrfs_map_token *token); \ +-void btrfs_set_token_##bits(struct extent_buffer *eb, void *ptr, \ ++u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ ++ const void *ptr, unsigned long off, \ ++ struct btrfs_map_token *token); \ ++void btrfs_set_token_##bits(struct extent_buffer *eb, const void *ptr, \ + unsigned long off, u##bits val, \ + struct btrfs_map_token *token); \ +-static inline u##bits btrfs_get_##bits(struct extent_buffer *eb, void *ptr, \ ++static inline u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ ++ const void *ptr, \ + unsigned long off) \ + { \ + return btrfs_get_token_##bits(eb, ptr, off, NULL); \ + } \ +-static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr, \ ++static inline void btrfs_set_##bits(struct extent_buffer *eb, void *ptr,\ + unsigned long off, u##bits val) \ + { \ + btrfs_set_token_##bits(eb, ptr, off, val, NULL); \ +@@ -2337,7 +2340,8 @@ DECLARE_BTRFS_SETGET_BITS(32) + DECLARE_BTRFS_SETGET_BITS(64) + + #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ +-static inline u##bits btrfs_##name(struct extent_buffer *eb, type *s) \ ++static inline u##bits btrfs_##name(const struct extent_buffer *eb, \ ++ const type *s) \ + { \ + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ + return btrfs_get_##bits(eb, s, offsetof(type, member)); \ +@@ -2348,7 +2352,8 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, type *s, \ + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ + btrfs_set_##bits(eb, s, offsetof(type, member), val); \ + } \ +-static inline u##bits btrfs_token_##name(struct extent_buffer *eb, type *s, \ ++static inline u##bits btrfs_token_##name(const struct extent_buffer *eb,\ ++ const type *s, \ + struct btrfs_map_token *token) \ + { \ + BUILD_BUG_ON(sizeof(u##bits) != sizeof(((type *)0))->member); \ +@@ -2363,9 +2368,9 @@ static inline void btrfs_set_token_##name(struct extent_buffer *eb, \ + } + + #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ +-static inline u##bits btrfs_##name(struct extent_buffer *eb) \ ++static inline u##bits btrfs_##name(const struct extent_buffer *eb) \ + { \ +- type *p = page_address(eb->pages[0]); \ ++ const type *p = page_address(eb->pages[0]); \ + u##bits res = le##bits##_to_cpu(p->member); \ + return res; \ + } \ +@@ -2377,7 +2382,7 @@ static inline void btrfs_set_##name(struct extent_buffer *eb, \ + } + + #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ +-static inline u##bits btrfs_##name(type *s) \ ++static inline u##bits btrfs_##name(const type *s) \ + { \ + return le##bits##_to_cpu(s->member); \ + } \ +@@ -2678,7 +2683,7 @@ static inline unsigned long btrfs_node_key_ptr_offset(int nr) + sizeof(struct btrfs_key_ptr) * nr; + } + +-void btrfs_node_key(struct extent_buffer *eb, ++void btrfs_node_key(const struct extent_buffer *eb, + struct btrfs_disk_key *disk_key, int nr); + + static inline void btrfs_set_node_key(struct extent_buffer *eb, +@@ -2707,28 +2712,28 @@ static inline struct btrfs_item *btrfs_item_nr(int nr) + return (struct btrfs_item *)btrfs_item_nr_offset(nr); + } + +-static inline u32 btrfs_item_end(struct extent_buffer *eb, ++static inline u32 btrfs_item_end(const struct extent_buffer *eb, + struct btrfs_item *item) + { + return btrfs_item_offset(eb, item) + btrfs_item_size(eb, item); + } + +-static inline u32 btrfs_item_end_nr(struct extent_buffer *eb, int nr) ++static inline u32 btrfs_item_end_nr(const struct extent_buffer *eb, int nr) + { + return btrfs_item_end(eb, btrfs_item_nr(nr)); + } + +-static inline u32 btrfs_item_offset_nr(struct extent_buffer *eb, int nr) ++static inline u32 btrfs_item_offset_nr(const struct extent_buffer *eb, int nr) + { + return btrfs_item_offset(eb, btrfs_item_nr(nr)); + } + +-static inline u32 btrfs_item_size_nr(struct extent_buffer *eb, int nr) ++static inline u32 btrfs_item_size_nr(const struct extent_buffer *eb, int nr) + { + return btrfs_item_size(eb, btrfs_item_nr(nr)); + } + +-static inline void btrfs_item_key(struct extent_buffer *eb, ++static inline void btrfs_item_key(const struct extent_buffer *eb, + struct btrfs_disk_key *disk_key, int nr) + { + struct btrfs_item *item = btrfs_item_nr(nr); +@@ -2764,8 +2769,8 @@ BTRFS_SETGET_STACK_FUNCS(stack_dir_name_len, struct btrfs_dir_item, + BTRFS_SETGET_STACK_FUNCS(stack_dir_transid, struct btrfs_dir_item, + transid, 64); + +-static inline void btrfs_dir_item_key(struct extent_buffer *eb, +- struct btrfs_dir_item *item, ++static inline void btrfs_dir_item_key(const struct extent_buffer *eb, ++ const struct btrfs_dir_item *item, + struct btrfs_disk_key *key) + { + read_eb_member(eb, item, struct btrfs_dir_item, location, key); +@@ -2773,7 +2778,7 @@ static inline void btrfs_dir_item_key(struct extent_buffer *eb, + + static inline void btrfs_set_dir_item_key(struct extent_buffer *eb, + struct btrfs_dir_item *item, +- struct btrfs_disk_key *key) ++ const struct btrfs_disk_key *key) + { + write_eb_member(eb, item, struct btrfs_dir_item, location, key); + } +@@ -2785,8 +2790,8 @@ BTRFS_SETGET_FUNCS(free_space_bitmaps, struct btrfs_free_space_header, + BTRFS_SETGET_FUNCS(free_space_generation, struct btrfs_free_space_header, + generation, 64); + +-static inline void btrfs_free_space_key(struct extent_buffer *eb, +- struct btrfs_free_space_header *h, ++static inline void btrfs_free_space_key(const struct extent_buffer *eb, ++ const struct btrfs_free_space_header *h, + struct btrfs_disk_key *key) + { + read_eb_member(eb, h, struct btrfs_free_space_header, location, key); +@@ -2794,7 +2799,7 @@ static inline void btrfs_free_space_key(struct extent_buffer *eb, + + static inline void btrfs_set_free_space_key(struct extent_buffer *eb, + struct btrfs_free_space_header *h, +- struct btrfs_disk_key *key) ++ const struct btrfs_disk_key *key) + { + write_eb_member(eb, h, struct btrfs_free_space_header, location, key); + } +@@ -2821,25 +2826,25 @@ static inline void btrfs_cpu_key_to_disk(struct btrfs_disk_key *disk, + disk->objectid = cpu_to_le64(cpu->objectid); + } + +-static inline void btrfs_node_key_to_cpu(struct extent_buffer *eb, +- struct btrfs_key *key, int nr) ++static inline void btrfs_node_key_to_cpu(const struct extent_buffer *eb, ++ struct btrfs_key *key, int nr) + { + struct btrfs_disk_key disk_key; + btrfs_node_key(eb, &disk_key, nr); + btrfs_disk_key_to_cpu(key, &disk_key); + } + +-static inline void btrfs_item_key_to_cpu(struct extent_buffer *eb, +- struct btrfs_key *key, int nr) ++static inline void btrfs_item_key_to_cpu(const struct extent_buffer *eb, ++ struct btrfs_key *key, int nr) + { + struct btrfs_disk_key disk_key; + btrfs_item_key(eb, &disk_key, nr); + btrfs_disk_key_to_cpu(key, &disk_key); + } + +-static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb, +- struct btrfs_dir_item *item, +- struct btrfs_key *key) ++static inline void btrfs_dir_item_key_to_cpu(const struct extent_buffer *eb, ++ const struct btrfs_dir_item *item, ++ struct btrfs_key *key) + { + struct btrfs_disk_key disk_key; + btrfs_dir_item_key(eb, item, &disk_key); +@@ -2872,7 +2877,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, + nritems, 32); + BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64); + +-static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag) ++static inline int btrfs_header_flag(const struct extent_buffer *eb, u64 flag) + { + return (btrfs_header_flags(eb) & flag) == flag; + } +@@ -2891,7 +2896,7 @@ static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag) + return (flags & flag) == flag; + } + +-static inline int btrfs_header_backref_rev(struct extent_buffer *eb) ++static inline int btrfs_header_backref_rev(const struct extent_buffer *eb) + { + u64 flags = btrfs_header_flags(eb); + return flags >> BTRFS_BACKREF_REV_SHIFT; +@@ -2911,12 +2916,12 @@ static inline unsigned long btrfs_header_fsid(void) + return offsetof(struct btrfs_header, fsid); + } + +-static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *eb) ++static inline unsigned long btrfs_header_chunk_tree_uuid(const struct extent_buffer *eb) + { + return offsetof(struct btrfs_header, chunk_tree_uuid); + } + +-static inline int btrfs_is_leaf(struct extent_buffer *eb) ++static inline int btrfs_is_leaf(const struct extent_buffer *eb) + { + return btrfs_header_level(eb) == 0; + } +@@ -2950,12 +2955,12 @@ BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item, + BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item, + rtransid, 64); + +-static inline bool btrfs_root_readonly(struct btrfs_root *root) ++static inline bool btrfs_root_readonly(const struct btrfs_root *root) + { + return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; + } + +-static inline bool btrfs_root_dead(struct btrfs_root *root) ++static inline bool btrfs_root_dead(const struct btrfs_root *root) + { + return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_DEAD)) != 0; + } +@@ -3012,51 +3017,51 @@ BTRFS_SETGET_STACK_FUNCS(backup_num_devices, struct btrfs_root_backup, + /* struct btrfs_balance_item */ + BTRFS_SETGET_FUNCS(balance_flags, struct btrfs_balance_item, flags, 64); + +-static inline void btrfs_balance_data(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, ++static inline void btrfs_balance_data(const struct extent_buffer *eb, ++ const struct btrfs_balance_item *bi, + struct btrfs_disk_balance_args *ba) + { + read_eb_member(eb, bi, struct btrfs_balance_item, data, ba); + } + + static inline void btrfs_set_balance_data(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, +- struct btrfs_disk_balance_args *ba) ++ struct btrfs_balance_item *bi, ++ const struct btrfs_disk_balance_args *ba) + { + write_eb_member(eb, bi, struct btrfs_balance_item, data, ba); + } + +-static inline void btrfs_balance_meta(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, ++static inline void btrfs_balance_meta(const struct extent_buffer *eb, ++ const struct btrfs_balance_item *bi, + struct btrfs_disk_balance_args *ba) + { + read_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); + } + + static inline void btrfs_set_balance_meta(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, +- struct btrfs_disk_balance_args *ba) ++ struct btrfs_balance_item *bi, ++ const struct btrfs_disk_balance_args *ba) + { + write_eb_member(eb, bi, struct btrfs_balance_item, meta, ba); + } + +-static inline void btrfs_balance_sys(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, ++static inline void btrfs_balance_sys(const struct extent_buffer *eb, ++ const struct btrfs_balance_item *bi, + struct btrfs_disk_balance_args *ba) + { + read_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); + } + + static inline void btrfs_set_balance_sys(struct extent_buffer *eb, +- struct btrfs_balance_item *bi, +- struct btrfs_disk_balance_args *ba) ++ struct btrfs_balance_item *bi, ++ const struct btrfs_disk_balance_args *ba) + { + write_eb_member(eb, bi, struct btrfs_balance_item, sys, ba); + } + + static inline void + btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, +- struct btrfs_disk_balance_args *disk) ++ const struct btrfs_disk_balance_args *disk) + { + memset(cpu, 0, sizeof(*cpu)); + +@@ -3076,7 +3081,7 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu, + + static inline void + btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk, +- struct btrfs_balance_args *cpu) ++ const struct btrfs_balance_args *cpu) + { + memset(disk, 0, sizeof(*disk)); + +@@ -3144,7 +3149,7 @@ BTRFS_SETGET_STACK_FUNCS(super_magic, struct btrfs_super_block, magic, 64); + BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block, + uuid_tree_generation, 64); + +-static inline int btrfs_super_csum_size(struct btrfs_super_block *s) ++static inline int btrfs_super_csum_size(const struct btrfs_super_block *s) + { + u16 t = btrfs_super_csum_type(s); + /* +@@ -3158,6 +3163,21 @@ static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) + return offsetof(struct btrfs_leaf, items); + } + ++/* ++ * The leaf data grows from end-to-front in the node. ++ * this returns the address of the start of the last item, ++ * which is the stop of the leaf data stack ++ */ ++static inline unsigned int leaf_data_end(const struct btrfs_root *root, ++ const struct extent_buffer *leaf) ++{ ++ u32 nr = btrfs_header_nritems(leaf); ++ ++ if (nr == 0) ++ return BTRFS_LEAF_DATA_SIZE(root); ++ return btrfs_item_offset_nr(leaf, nr - 1); ++} ++ + /* struct btrfs_file_extent_item */ + BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); + BTRFS_SETGET_STACK_FUNCS(stack_file_extent_disk_bytenr, +@@ -3174,7 +3194,7 @@ BTRFS_SETGET_STACK_FUNCS(stack_file_extent_compression, + struct btrfs_file_extent_item, compression, 8); + + static inline unsigned long +-btrfs_file_extent_inline_start(struct btrfs_file_extent_item *e) ++btrfs_file_extent_inline_start(const struct btrfs_file_extent_item *e) + { + return (unsigned long)e + BTRFS_FILE_EXTENT_INLINE_DATA_START; + } +@@ -3208,8 +3228,9 @@ BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item, + * size of any extent headers. If a file is compressed on disk, this is + * the compressed size + */ +-static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, +- struct btrfs_item *e) ++static inline u32 btrfs_file_extent_inline_item_len( ++ const struct extent_buffer *eb, ++ struct btrfs_item *e) + { + return btrfs_item_size(eb, e) - BTRFS_FILE_EXTENT_INLINE_DATA_START; + } +@@ -3217,9 +3238,9 @@ static inline u32 btrfs_file_extent_inline_item_len(struct extent_buffer *eb, + /* this returns the number of file bytes represented by the inline item. + * If an item is compressed, this is the uncompressed size + */ +-static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, +- int slot, +- struct btrfs_file_extent_item *fi) ++static inline u32 btrfs_file_extent_inline_len(const struct extent_buffer *eb, ++ int slot, ++ const struct btrfs_file_extent_item *fi) + { + struct btrfs_map_token token; + +@@ -3241,8 +3262,8 @@ static inline u32 btrfs_file_extent_inline_len(struct extent_buffer *eb, + + + /* btrfs_dev_stats_item */ +-static inline u64 btrfs_dev_stats_value(struct extent_buffer *eb, +- struct btrfs_dev_stats_item *ptr, ++static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb, ++ const struct btrfs_dev_stats_item *ptr, + int index) + { + u64 val; +diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c +index 176a27bc63aa..81e5bc62e8e3 100644 +--- a/fs/btrfs/dev-replace.c ++++ b/fs/btrfs/dev-replace.c +@@ -620,7 +620,7 @@ static void btrfs_dev_replace_update_device_in_mapping_tree( + em = lookup_extent_mapping(em_tree, start, (u64)-1); + if (!em) + break; +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + for (i = 0; i < map->num_stripes; i++) + if (srcdev == map->stripes[i].dev) + map->stripes[i].dev = tgtdev; +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 1f21c6c33228..f80a0af68736 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -49,6 +49,7 @@ + #include "raid56.h" + #include "sysfs.h" + #include "qgroup.h" ++#include "tree-checker.h" + + #ifdef CONFIG_X86 + #include +@@ -522,72 +523,6 @@ static int check_tree_block_fsid(struct btrfs_fs_info *fs_info, + return ret; + } + +-#define CORRUPT(reason, eb, root, slot) \ +- btrfs_crit(root->fs_info, "corrupt leaf, %s: block=%llu," \ +- "root=%llu, slot=%d", reason, \ +- btrfs_header_bytenr(eb), root->objectid, slot) +- +-static noinline int check_leaf(struct btrfs_root *root, +- struct extent_buffer *leaf) +-{ +- struct btrfs_key key; +- struct btrfs_key leaf_key; +- u32 nritems = btrfs_header_nritems(leaf); +- int slot; +- +- if (nritems == 0) +- return 0; +- +- /* Check the 0 item */ +- if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) != +- BTRFS_LEAF_DATA_SIZE(root)) { +- CORRUPT("invalid item offset size pair", leaf, root, 0); +- return -EIO; +- } +- +- /* +- * Check to make sure each items keys are in the correct order and their +- * offsets make sense. We only have to loop through nritems-1 because +- * we check the current slot against the next slot, which verifies the +- * next slot's offset+size makes sense and that the current's slot +- * offset is correct. +- */ +- for (slot = 0; slot < nritems - 1; slot++) { +- btrfs_item_key_to_cpu(leaf, &leaf_key, slot); +- btrfs_item_key_to_cpu(leaf, &key, slot + 1); +- +- /* Make sure the keys are in the right order */ +- if (btrfs_comp_cpu_keys(&leaf_key, &key) >= 0) { +- CORRUPT("bad key order", leaf, root, slot); +- return -EIO; +- } +- +- /* +- * Make sure the offset and ends are right, remember that the +- * item data starts at the end of the leaf and grows towards the +- * front. +- */ +- if (btrfs_item_offset_nr(leaf, slot) != +- btrfs_item_end_nr(leaf, slot + 1)) { +- CORRUPT("slot offset bad", leaf, root, slot); +- return -EIO; +- } +- +- /* +- * Check to make sure that we don't point outside of the leaf, +- * just incase all the items are consistent to eachother, but +- * all point outside of the leaf. +- */ +- if (btrfs_item_end_nr(leaf, slot) > +- BTRFS_LEAF_DATA_SIZE(root)) { +- CORRUPT("slot end outside of leaf", leaf, root, slot); +- return -EIO; +- } +- } +- +- return 0; +-} +- + static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, + u64 phy_offset, struct page *page, + u64 start, u64 end, int mirror) +@@ -654,11 +589,14 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio, + * that we don't try and read the other copies of this block, just + * return -EIO. + */ +- if (found_level == 0 && check_leaf(root, eb)) { ++ if (found_level == 0 && btrfs_check_leaf_full(root, eb)) { + set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); + ret = -EIO; + } + ++ if (found_level > 0 && btrfs_check_node(root, eb)) ++ ret = -EIO; ++ + if (!ret) + set_extent_buffer_uptodate(eb); + err: +@@ -3958,7 +3896,13 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) + buf->len, + root->fs_info->dirty_metadata_batch); + #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY +- if (btrfs_header_level(buf) == 0 && check_leaf(root, buf)) { ++ /* ++ * Since btrfs_mark_buffer_dirty() can be called with item pointer set ++ * but item data not updated. ++ * So here we should only check item pointers, not item data. ++ */ ++ if (btrfs_header_level(buf) == 0 && ++ btrfs_check_leaf_relaxed(root, buf)) { + btrfs_print_leaf(root, buf); + ASSERT(0); + } +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 13ff0fdae03e..978bbfed5a2c 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -2342,7 +2342,13 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, + ins.type = BTRFS_EXTENT_ITEM_KEY; + } + +- BUG_ON(node->ref_mod != 1); ++ if (node->ref_mod != 1) { ++ btrfs_err(root->fs_info, ++ "btree block(%llu) has %d references rather than 1: action %d ref_root %llu parent %llu", ++ node->bytenr, node->ref_mod, node->action, ref_root, ++ parent); ++ return -EIO; ++ } + if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { + BUG_ON(!extent_op || !extent_op->update_flags); + ret = alloc_reserved_tree_block(trans, root, +@@ -9481,6 +9487,8 @@ static int find_first_block_group(struct btrfs_root *root, + int ret = 0; + struct btrfs_key found_key; + struct extent_buffer *leaf; ++ struct btrfs_block_group_item bg; ++ u64 flags; + int slot; + + ret = btrfs_search_slot(NULL, root, key, path, 0, 0); +@@ -9502,7 +9510,47 @@ static int find_first_block_group(struct btrfs_root *root, + + if (found_key.objectid >= key->objectid && + found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) { +- ret = 0; ++ struct extent_map_tree *em_tree; ++ struct extent_map *em; ++ ++ em_tree = &root->fs_info->mapping_tree.map_tree; ++ read_lock(&em_tree->lock); ++ em = lookup_extent_mapping(em_tree, found_key.objectid, ++ found_key.offset); ++ read_unlock(&em_tree->lock); ++ if (!em) { ++ btrfs_err(root->fs_info, ++ "logical %llu len %llu found bg but no related chunk", ++ found_key.objectid, found_key.offset); ++ ret = -ENOENT; ++ } else if (em->start != found_key.objectid || ++ em->len != found_key.offset) { ++ btrfs_err(root->fs_info, ++ "block group %llu len %llu mismatch with chunk %llu len %llu", ++ found_key.objectid, found_key.offset, ++ em->start, em->len); ++ ret = -EUCLEAN; ++ } else { ++ read_extent_buffer(leaf, &bg, ++ btrfs_item_ptr_offset(leaf, slot), ++ sizeof(bg)); ++ flags = btrfs_block_group_flags(&bg) & ++ BTRFS_BLOCK_GROUP_TYPE_MASK; ++ ++ if (flags != (em->map_lookup->type & ++ BTRFS_BLOCK_GROUP_TYPE_MASK)) { ++ btrfs_err(root->fs_info, ++"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx", ++ found_key.objectid, ++ found_key.offset, flags, ++ (BTRFS_BLOCK_GROUP_TYPE_MASK & ++ em->map_lookup->type)); ++ ret = -EUCLEAN; ++ } else { ++ ret = 0; ++ } ++ } ++ free_extent_map(em); + goto out; + } + path->slots[0]++; +@@ -9717,6 +9765,62 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) + return cache; + } + ++ ++/* ++ * Iterate all chunks and verify that each of them has the corresponding block ++ * group ++ */ ++static int check_chunk_block_group_mappings(struct btrfs_fs_info *fs_info) ++{ ++ struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; ++ struct extent_map *em; ++ struct btrfs_block_group_cache *bg; ++ u64 start = 0; ++ int ret = 0; ++ ++ while (1) { ++ read_lock(&map_tree->map_tree.lock); ++ /* ++ * lookup_extent_mapping will return the first extent map ++ * intersecting the range, so setting @len to 1 is enough to ++ * get the first chunk. ++ */ ++ em = lookup_extent_mapping(&map_tree->map_tree, start, 1); ++ read_unlock(&map_tree->map_tree.lock); ++ if (!em) ++ break; ++ ++ bg = btrfs_lookup_block_group(fs_info, em->start); ++ if (!bg) { ++ btrfs_err(fs_info, ++ "chunk start=%llu len=%llu doesn't have corresponding block group", ++ em->start, em->len); ++ ret = -EUCLEAN; ++ free_extent_map(em); ++ break; ++ } ++ if (bg->key.objectid != em->start || ++ bg->key.offset != em->len || ++ (bg->flags & BTRFS_BLOCK_GROUP_TYPE_MASK) != ++ (em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK)) { ++ btrfs_err(fs_info, ++"chunk start=%llu len=%llu flags=0x%llx doesn't match block group start=%llu len=%llu flags=0x%llx", ++ em->start, em->len, ++ em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK, ++ bg->key.objectid, bg->key.offset, ++ bg->flags & BTRFS_BLOCK_GROUP_TYPE_MASK); ++ ret = -EUCLEAN; ++ free_extent_map(em); ++ btrfs_put_block_group(bg); ++ break; ++ } ++ start = em->start + em->len; ++ free_extent_map(em); ++ btrfs_put_block_group(bg); ++ } ++ return ret; ++} ++ + int btrfs_read_block_groups(struct btrfs_root *root) + { + struct btrfs_path *path; +@@ -9903,7 +10007,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) + } + + init_global_block_rsv(info); +- ret = 0; ++ ret = check_chunk_block_group_mappings(info); + error: + btrfs_free_path(path); + return ret; +@@ -10388,7 +10492,7 @@ btrfs_start_trans_remove_block_group(struct btrfs_fs_info *fs_info, + * more device items and remove one chunk item), but this is done at + * btrfs_remove_chunk() through a call to check_system_chunk(). + */ +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + num_items = 3 + map->num_stripes; + free_extent_map(em); + +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 88bee6703cc0..42e7f6a8f91d 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -3847,8 +3847,10 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, + struct block_device *bdev = fs_info->fs_devices->latest_bdev; + struct extent_io_tree *tree = &BTRFS_I(fs_info->btree_inode)->io_tree; + u64 offset = eb->start; ++ u32 nritems; + unsigned long i, num_pages; + unsigned long bio_flags = 0; ++ unsigned long start, end; + int rw = (epd->sync_io ? WRITE_SYNC : WRITE) | REQ_META; + int ret = 0; + +@@ -3858,6 +3860,23 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, + if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID) + bio_flags = EXTENT_BIO_TREE_LOG; + ++ /* set btree blocks beyond nritems with 0 to avoid stale content. */ ++ nritems = btrfs_header_nritems(eb); ++ if (btrfs_header_level(eb) > 0) { ++ end = btrfs_node_key_ptr_offset(nritems); ++ ++ memset_extent_buffer(eb, 0, end, eb->len - end); ++ } else { ++ /* ++ * leaf: ++ * header 0 1 2 .. N ... data_N .. data_2 data_1 data_0 ++ */ ++ start = btrfs_item_nr_offset(nritems); ++ end = btrfs_leaf_data(eb) + ++ leaf_data_end(fs_info->tree_root, eb); ++ memset_extent_buffer(eb, 0, start, end - start); ++ } ++ + for (i = 0; i < num_pages; i++) { + struct page *p = eb->pages[i]; + +@@ -5362,9 +5381,8 @@ unlock_exit: + return ret; + } + +-void read_extent_buffer(struct extent_buffer *eb, void *dstv, +- unsigned long start, +- unsigned long len) ++void read_extent_buffer(const struct extent_buffer *eb, void *dstv, ++ unsigned long start, unsigned long len) + { + size_t cur; + size_t offset; +@@ -5393,9 +5411,9 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, + } + } + +-int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, +- unsigned long start, +- unsigned long len) ++int read_extent_buffer_to_user(const struct extent_buffer *eb, ++ void __user *dstv, ++ unsigned long start, unsigned long len) + { + size_t cur; + size_t offset; +@@ -5430,10 +5448,10 @@ int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, + return ret; + } + +-int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, +- unsigned long min_len, char **map, +- unsigned long *map_start, +- unsigned long *map_len) ++int map_private_extent_buffer(const struct extent_buffer *eb, ++ unsigned long start, unsigned long min_len, ++ char **map, unsigned long *map_start, ++ unsigned long *map_len) + { + size_t offset = start & (PAGE_CACHE_SIZE - 1); + char *kaddr; +@@ -5468,9 +5486,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, + return 0; + } + +-int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, +- unsigned long start, +- unsigned long len) ++int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, ++ unsigned long start, unsigned long len) + { + size_t cur; + size_t offset; +diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h +index f4c1ae11855f..751435967724 100644 +--- a/fs/btrfs/extent_io.h ++++ b/fs/btrfs/extent_io.h +@@ -308,14 +308,13 @@ static inline void extent_buffer_get(struct extent_buffer *eb) + atomic_inc(&eb->refs); + } + +-int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, +- unsigned long start, +- unsigned long len); +-void read_extent_buffer(struct extent_buffer *eb, void *dst, ++int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, ++ unsigned long start, unsigned long len); ++void read_extent_buffer(const struct extent_buffer *eb, void *dst, + unsigned long start, + unsigned long len); +-int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dst, +- unsigned long start, ++int read_extent_buffer_to_user(const struct extent_buffer *eb, ++ void __user *dst, unsigned long start, + unsigned long len); + void write_extent_buffer(struct extent_buffer *eb, const void *src, + unsigned long start, unsigned long len); +@@ -334,10 +333,10 @@ int set_extent_buffer_uptodate(struct extent_buffer *eb); + int clear_extent_buffer_uptodate(struct extent_buffer *eb); + int extent_buffer_uptodate(struct extent_buffer *eb); + int extent_buffer_under_io(struct extent_buffer *eb); +-int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset, +- unsigned long min_len, char **map, +- unsigned long *map_start, +- unsigned long *map_len); ++int map_private_extent_buffer(const struct extent_buffer *eb, ++ unsigned long offset, unsigned long min_len, ++ char **map, unsigned long *map_start, ++ unsigned long *map_len); + int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); + int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end); + int extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end, +diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c +index 6a98bddd8f33..84fb56d5c018 100644 +--- a/fs/btrfs/extent_map.c ++++ b/fs/btrfs/extent_map.c +@@ -76,7 +76,7 @@ void free_extent_map(struct extent_map *em) + WARN_ON(extent_map_in_tree(em)); + WARN_ON(!list_empty(&em->list)); + if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) +- kfree(em->bdev); ++ kfree(em->map_lookup); + kmem_cache_free(extent_map_cache, em); + } + } +diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h +index b2991fd8583e..eb8b8fae036b 100644 +--- a/fs/btrfs/extent_map.h ++++ b/fs/btrfs/extent_map.h +@@ -32,7 +32,15 @@ struct extent_map { + u64 block_len; + u64 generation; + unsigned long flags; +- struct block_device *bdev; ++ union { ++ struct block_device *bdev; ++ ++ /* ++ * used for chunk mappings ++ * flags & EXTENT_FLAG_FS_MAPPING must be set ++ */ ++ struct map_lookup *map_lookup; ++ }; + atomic_t refs; + unsigned int compress_type; + struct list_head list; +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index 6dca9f937bf6..cc9ccc42f469 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -3460,7 +3460,7 @@ static noinline_for_stack int scrub_chunk(struct scrub_ctx *sctx, + return ret; + } + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + if (em->start != chunk_offset) + goto out; + +diff --git a/fs/btrfs/struct-funcs.c b/fs/btrfs/struct-funcs.c +index b976597b0721..63ffd213b0b7 100644 +--- a/fs/btrfs/struct-funcs.c ++++ b/fs/btrfs/struct-funcs.c +@@ -50,8 +50,8 @@ static inline void put_unaligned_le8(u8 val, void *p) + */ + + #define DEFINE_BTRFS_SETGET_BITS(bits) \ +-u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ +- unsigned long off, \ ++u##bits btrfs_get_token_##bits(const struct extent_buffer *eb, \ ++ const void *ptr, unsigned long off, \ + struct btrfs_map_token *token) \ + { \ + unsigned long part_offset = (unsigned long)ptr; \ +@@ -90,7 +90,8 @@ u##bits btrfs_get_token_##bits(struct extent_buffer *eb, void *ptr, \ + return res; \ + } \ + void btrfs_set_token_##bits(struct extent_buffer *eb, \ +- void *ptr, unsigned long off, u##bits val, \ ++ const void *ptr, unsigned long off, \ ++ u##bits val, \ + struct btrfs_map_token *token) \ + { \ + unsigned long part_offset = (unsigned long)ptr; \ +@@ -133,7 +134,7 @@ DEFINE_BTRFS_SETGET_BITS(16) + DEFINE_BTRFS_SETGET_BITS(32) + DEFINE_BTRFS_SETGET_BITS(64) + +-void btrfs_node_key(struct extent_buffer *eb, ++void btrfs_node_key(const struct extent_buffer *eb, + struct btrfs_disk_key *disk_key, int nr) + { + unsigned long ptr = btrfs_node_key_ptr_offset(nr); +diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c +new file mode 100644 +index 000000000000..5b98f3c76ce4 +--- /dev/null ++++ b/fs/btrfs/tree-checker.c +@@ -0,0 +1,649 @@ ++/* ++ * Copyright (C) Qu Wenruo 2017. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License v2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program. ++ */ ++ ++/* ++ * The module is used to catch unexpected/corrupted tree block data. ++ * Such behavior can be caused either by a fuzzed image or bugs. ++ * ++ * The objective is to do leaf/node validation checks when tree block is read ++ * from disk, and check *every* possible member, so other code won't ++ * need to checking them again. ++ * ++ * Due to the potential and unwanted damage, every checker needs to be ++ * carefully reviewed otherwise so it does not prevent mount of valid images. ++ */ ++ ++#include "ctree.h" ++#include "tree-checker.h" ++#include "disk-io.h" ++#include "compression.h" ++#include "hash.h" ++#include "volumes.h" ++ ++#define CORRUPT(reason, eb, root, slot) \ ++ btrfs_crit(root->fs_info, \ ++ "corrupt %s, %s: block=%llu, root=%llu, slot=%d", \ ++ btrfs_header_level(eb) == 0 ? "leaf" : "node", \ ++ reason, btrfs_header_bytenr(eb), root->objectid, slot) ++ ++/* ++ * Error message should follow the following format: ++ * corrupt : , [, ] ++ * ++ * @type: leaf or node ++ * @identifier: the necessary info to locate the leaf/node. ++ * It's recommened to decode key.objecitd/offset if it's ++ * meaningful. ++ * @reason: describe the error ++ * @bad_value: optional, it's recommened to output bad value and its ++ * expected value (range). ++ * ++ * Since comma is used to separate the components, only space is allowed ++ * inside each component. ++ */ ++ ++/* ++ * Append generic "corrupt leaf/node root=%llu block=%llu slot=%d: " to @fmt. ++ * Allows callers to customize the output. ++ */ ++__printf(4, 5) ++static void generic_err(const struct btrfs_root *root, ++ const struct extent_buffer *eb, int slot, ++ const char *fmt, ...) ++{ ++ struct va_format vaf; ++ va_list args; ++ ++ va_start(args, fmt); ++ ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ btrfs_crit(root->fs_info, ++ "corrupt %s: root=%llu block=%llu slot=%d, %pV", ++ btrfs_header_level(eb) == 0 ? "leaf" : "node", ++ root->objectid, btrfs_header_bytenr(eb), slot, &vaf); ++ va_end(args); ++} ++ ++static int check_extent_data_item(struct btrfs_root *root, ++ struct extent_buffer *leaf, ++ struct btrfs_key *key, int slot) ++{ ++ struct btrfs_file_extent_item *fi; ++ u32 sectorsize = root->sectorsize; ++ u32 item_size = btrfs_item_size_nr(leaf, slot); ++ ++ if (!IS_ALIGNED(key->offset, sectorsize)) { ++ CORRUPT("unaligned key offset for file extent", ++ leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); ++ ++ if (btrfs_file_extent_type(leaf, fi) > BTRFS_FILE_EXTENT_TYPES) { ++ CORRUPT("invalid file extent type", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ /* ++ * Support for new compression/encrption must introduce incompat flag, ++ * and must be caught in open_ctree(). ++ */ ++ if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { ++ CORRUPT("invalid file extent compression", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ if (btrfs_file_extent_encryption(leaf, fi)) { ++ CORRUPT("invalid file extent encryption", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { ++ /* Inline extent must have 0 as key offset */ ++ if (key->offset) { ++ CORRUPT("inline extent has non-zero key offset", ++ leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ /* Compressed inline extent has no on-disk size, skip it */ ++ if (btrfs_file_extent_compression(leaf, fi) != ++ BTRFS_COMPRESS_NONE) ++ return 0; ++ ++ /* Uncompressed inline extent size must match item size */ ++ if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START + ++ btrfs_file_extent_ram_bytes(leaf, fi)) { ++ CORRUPT("plaintext inline extent has invalid size", ++ leaf, root, slot); ++ return -EUCLEAN; ++ } ++ return 0; ++ } ++ ++ /* Regular or preallocated extent has fixed item size */ ++ if (item_size != sizeof(*fi)) { ++ CORRUPT( ++ "regluar or preallocated extent data item size is invalid", ++ leaf, root, slot); ++ return -EUCLEAN; ++ } ++ if (!IS_ALIGNED(btrfs_file_extent_ram_bytes(leaf, fi), sectorsize) || ++ !IS_ALIGNED(btrfs_file_extent_disk_bytenr(leaf, fi), sectorsize) || ++ !IS_ALIGNED(btrfs_file_extent_disk_num_bytes(leaf, fi), sectorsize) || ++ !IS_ALIGNED(btrfs_file_extent_offset(leaf, fi), sectorsize) || ++ !IS_ALIGNED(btrfs_file_extent_num_bytes(leaf, fi), sectorsize)) { ++ CORRUPT( ++ "regular or preallocated extent data item has unaligned value", ++ leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ return 0; ++} ++ ++static int check_csum_item(struct btrfs_root *root, struct extent_buffer *leaf, ++ struct btrfs_key *key, int slot) ++{ ++ u32 sectorsize = root->sectorsize; ++ u32 csumsize = btrfs_super_csum_size(root->fs_info->super_copy); ++ ++ if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) { ++ CORRUPT("invalid objectid for csum item", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ if (!IS_ALIGNED(key->offset, sectorsize)) { ++ CORRUPT("unaligned key offset for csum item", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) { ++ CORRUPT("unaligned csum item size", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ return 0; ++} ++ ++/* ++ * Customized reported for dir_item, only important new info is key->objectid, ++ * which represents inode number ++ */ ++__printf(4, 5) ++static void dir_item_err(const struct btrfs_root *root, ++ const struct extent_buffer *eb, int slot, ++ const char *fmt, ...) ++{ ++ struct btrfs_key key; ++ struct va_format vaf; ++ va_list args; ++ ++ btrfs_item_key_to_cpu(eb, &key, slot); ++ va_start(args, fmt); ++ ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ btrfs_crit(root->fs_info, ++ "corrupt %s: root=%llu block=%llu slot=%d ino=%llu, %pV", ++ btrfs_header_level(eb) == 0 ? "leaf" : "node", root->objectid, ++ btrfs_header_bytenr(eb), slot, key.objectid, &vaf); ++ va_end(args); ++} ++ ++static int check_dir_item(struct btrfs_root *root, ++ struct extent_buffer *leaf, ++ struct btrfs_key *key, int slot) ++{ ++ struct btrfs_dir_item *di; ++ u32 item_size = btrfs_item_size_nr(leaf, slot); ++ u32 cur = 0; ++ ++ di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); ++ while (cur < item_size) { ++ u32 name_len; ++ u32 data_len; ++ u32 max_name_len; ++ u32 total_size; ++ u32 name_hash; ++ u8 dir_type; ++ ++ /* header itself should not cross item boundary */ ++ if (cur + sizeof(*di) > item_size) { ++ dir_item_err(root, leaf, slot, ++ "dir item header crosses item boundary, have %zu boundary %u", ++ cur + sizeof(*di), item_size); ++ return -EUCLEAN; ++ } ++ ++ /* dir type check */ ++ dir_type = btrfs_dir_type(leaf, di); ++ if (dir_type >= BTRFS_FT_MAX) { ++ dir_item_err(root, leaf, slot, ++ "invalid dir item type, have %u expect [0, %u)", ++ dir_type, BTRFS_FT_MAX); ++ return -EUCLEAN; ++ } ++ ++ if (key->type == BTRFS_XATTR_ITEM_KEY && ++ dir_type != BTRFS_FT_XATTR) { ++ dir_item_err(root, leaf, slot, ++ "invalid dir item type for XATTR key, have %u expect %u", ++ dir_type, BTRFS_FT_XATTR); ++ return -EUCLEAN; ++ } ++ if (dir_type == BTRFS_FT_XATTR && ++ key->type != BTRFS_XATTR_ITEM_KEY) { ++ dir_item_err(root, leaf, slot, ++ "xattr dir type found for non-XATTR key"); ++ return -EUCLEAN; ++ } ++ if (dir_type == BTRFS_FT_XATTR) ++ max_name_len = XATTR_NAME_MAX; ++ else ++ max_name_len = BTRFS_NAME_LEN; ++ ++ /* Name/data length check */ ++ name_len = btrfs_dir_name_len(leaf, di); ++ data_len = btrfs_dir_data_len(leaf, di); ++ if (name_len > max_name_len) { ++ dir_item_err(root, leaf, slot, ++ "dir item name len too long, have %u max %u", ++ name_len, max_name_len); ++ return -EUCLEAN; ++ } ++ if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(root)) { ++ dir_item_err(root, leaf, slot, ++ "dir item name and data len too long, have %u max %zu", ++ name_len + data_len, ++ BTRFS_MAX_XATTR_SIZE(root)); ++ return -EUCLEAN; ++ } ++ ++ if (data_len && dir_type != BTRFS_FT_XATTR) { ++ dir_item_err(root, leaf, slot, ++ "dir item with invalid data len, have %u expect 0", ++ data_len); ++ return -EUCLEAN; ++ } ++ ++ total_size = sizeof(*di) + name_len + data_len; ++ ++ /* header and name/data should not cross item boundary */ ++ if (cur + total_size > item_size) { ++ dir_item_err(root, leaf, slot, ++ "dir item data crosses item boundary, have %u boundary %u", ++ cur + total_size, item_size); ++ return -EUCLEAN; ++ } ++ ++ /* ++ * Special check for XATTR/DIR_ITEM, as key->offset is name ++ * hash, should match its name ++ */ ++ if (key->type == BTRFS_DIR_ITEM_KEY || ++ key->type == BTRFS_XATTR_ITEM_KEY) { ++ char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; ++ ++ read_extent_buffer(leaf, namebuf, ++ (unsigned long)(di + 1), name_len); ++ name_hash = btrfs_name_hash(namebuf, name_len); ++ if (key->offset != name_hash) { ++ dir_item_err(root, leaf, slot, ++ "name hash mismatch with key, have 0x%016x expect 0x%016llx", ++ name_hash, key->offset); ++ return -EUCLEAN; ++ } ++ } ++ cur += total_size; ++ di = (struct btrfs_dir_item *)((void *)di + total_size); ++ } ++ return 0; ++} ++ ++__printf(4, 5) ++__cold ++static void block_group_err(const struct btrfs_fs_info *fs_info, ++ const struct extent_buffer *eb, int slot, ++ const char *fmt, ...) ++{ ++ struct btrfs_key key; ++ struct va_format vaf; ++ va_list args; ++ ++ btrfs_item_key_to_cpu(eb, &key, slot); ++ va_start(args, fmt); ++ ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ btrfs_crit(fs_info, ++ "corrupt %s: root=%llu block=%llu slot=%d bg_start=%llu bg_len=%llu, %pV", ++ btrfs_header_level(eb) == 0 ? "leaf" : "node", ++ btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, ++ key.objectid, key.offset, &vaf); ++ va_end(args); ++} ++ ++static int check_block_group_item(struct btrfs_fs_info *fs_info, ++ struct extent_buffer *leaf, ++ struct btrfs_key *key, int slot) ++{ ++ struct btrfs_block_group_item bgi; ++ u32 item_size = btrfs_item_size_nr(leaf, slot); ++ u64 flags; ++ u64 type; ++ ++ /* ++ * Here we don't really care about alignment since extent allocator can ++ * handle it. We care more about the size, as if one block group is ++ * larger than maximum size, it's must be some obvious corruption. ++ */ ++ if (key->offset > BTRFS_MAX_DATA_CHUNK_SIZE || key->offset == 0) { ++ block_group_err(fs_info, leaf, slot, ++ "invalid block group size, have %llu expect (0, %llu]", ++ key->offset, BTRFS_MAX_DATA_CHUNK_SIZE); ++ return -EUCLEAN; ++ } ++ ++ if (item_size != sizeof(bgi)) { ++ block_group_err(fs_info, leaf, slot, ++ "invalid item size, have %u expect %zu", ++ item_size, sizeof(bgi)); ++ return -EUCLEAN; ++ } ++ ++ read_extent_buffer(leaf, &bgi, btrfs_item_ptr_offset(leaf, slot), ++ sizeof(bgi)); ++ if (btrfs_block_group_chunk_objectid(&bgi) != ++ BTRFS_FIRST_CHUNK_TREE_OBJECTID) { ++ block_group_err(fs_info, leaf, slot, ++ "invalid block group chunk objectid, have %llu expect %llu", ++ btrfs_block_group_chunk_objectid(&bgi), ++ BTRFS_FIRST_CHUNK_TREE_OBJECTID); ++ return -EUCLEAN; ++ } ++ ++ if (btrfs_block_group_used(&bgi) > key->offset) { ++ block_group_err(fs_info, leaf, slot, ++ "invalid block group used, have %llu expect [0, %llu)", ++ btrfs_block_group_used(&bgi), key->offset); ++ return -EUCLEAN; ++ } ++ ++ flags = btrfs_block_group_flags(&bgi); ++ if (hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) > 1) { ++ block_group_err(fs_info, leaf, slot, ++"invalid profile flags, have 0x%llx (%lu bits set) expect no more than 1 bit set", ++ flags & BTRFS_BLOCK_GROUP_PROFILE_MASK, ++ hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK)); ++ return -EUCLEAN; ++ } ++ ++ type = flags & BTRFS_BLOCK_GROUP_TYPE_MASK; ++ if (type != BTRFS_BLOCK_GROUP_DATA && ++ type != BTRFS_BLOCK_GROUP_METADATA && ++ type != BTRFS_BLOCK_GROUP_SYSTEM && ++ type != (BTRFS_BLOCK_GROUP_METADATA | ++ BTRFS_BLOCK_GROUP_DATA)) { ++ block_group_err(fs_info, leaf, slot, ++"invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llx or 0x%llx", ++ type, hweight64(type), ++ BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA, ++ BTRFS_BLOCK_GROUP_SYSTEM, ++ BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA); ++ return -EUCLEAN; ++ } ++ return 0; ++} ++ ++/* ++ * Common point to switch the item-specific validation. ++ */ ++static int check_leaf_item(struct btrfs_root *root, ++ struct extent_buffer *leaf, ++ struct btrfs_key *key, int slot) ++{ ++ int ret = 0; ++ ++ switch (key->type) { ++ case BTRFS_EXTENT_DATA_KEY: ++ ret = check_extent_data_item(root, leaf, key, slot); ++ break; ++ case BTRFS_EXTENT_CSUM_KEY: ++ ret = check_csum_item(root, leaf, key, slot); ++ break; ++ case BTRFS_DIR_ITEM_KEY: ++ case BTRFS_DIR_INDEX_KEY: ++ case BTRFS_XATTR_ITEM_KEY: ++ ret = check_dir_item(root, leaf, key, slot); ++ break; ++ case BTRFS_BLOCK_GROUP_ITEM_KEY: ++ ret = check_block_group_item(root->fs_info, leaf, key, slot); ++ break; ++ } ++ return ret; ++} ++ ++static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, ++ bool check_item_data) ++{ ++ struct btrfs_fs_info *fs_info = root->fs_info; ++ /* No valid key type is 0, so all key should be larger than this key */ ++ struct btrfs_key prev_key = {0, 0, 0}; ++ struct btrfs_key key; ++ u32 nritems = btrfs_header_nritems(leaf); ++ int slot; ++ ++ if (btrfs_header_level(leaf) != 0) { ++ generic_err(root, leaf, 0, ++ "invalid level for leaf, have %d expect 0", ++ btrfs_header_level(leaf)); ++ return -EUCLEAN; ++ } ++ ++ /* ++ * Extent buffers from a relocation tree have a owner field that ++ * corresponds to the subvolume tree they are based on. So just from an ++ * extent buffer alone we can not find out what is the id of the ++ * corresponding subvolume tree, so we can not figure out if the extent ++ * buffer corresponds to the root of the relocation tree or not. So ++ * skip this check for relocation trees. ++ */ ++ if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) { ++ u64 owner = btrfs_header_owner(leaf); ++ struct btrfs_root *check_root; ++ ++ /* These trees must never be empty */ ++ if (owner == BTRFS_ROOT_TREE_OBJECTID || ++ owner == BTRFS_CHUNK_TREE_OBJECTID || ++ owner == BTRFS_EXTENT_TREE_OBJECTID || ++ owner == BTRFS_DEV_TREE_OBJECTID || ++ owner == BTRFS_FS_TREE_OBJECTID || ++ owner == BTRFS_DATA_RELOC_TREE_OBJECTID) { ++ generic_err(root, leaf, 0, ++ "invalid root, root %llu must never be empty", ++ owner); ++ return -EUCLEAN; ++ } ++ key.objectid = owner; ++ key.type = BTRFS_ROOT_ITEM_KEY; ++ key.offset = (u64)-1; ++ ++ check_root = btrfs_get_fs_root(fs_info, &key, false); ++ /* ++ * The only reason we also check NULL here is that during ++ * open_ctree() some roots has not yet been set up. ++ */ ++ if (!IS_ERR_OR_NULL(check_root)) { ++ struct extent_buffer *eb; ++ ++ eb = btrfs_root_node(check_root); ++ /* if leaf is the root, then it's fine */ ++ if (leaf != eb) { ++ CORRUPT("non-root leaf's nritems is 0", ++ leaf, check_root, 0); ++ free_extent_buffer(eb); ++ return -EUCLEAN; ++ } ++ free_extent_buffer(eb); ++ } ++ return 0; ++ } ++ ++ if (nritems == 0) ++ return 0; ++ ++ /* ++ * Check the following things to make sure this is a good leaf, and ++ * leaf users won't need to bother with similar sanity checks: ++ * ++ * 1) key ordering ++ * 2) item offset and size ++ * No overlap, no hole, all inside the leaf. ++ * 3) item content ++ * If possible, do comprehensive sanity check. ++ * NOTE: All checks must only rely on the item data itself. ++ */ ++ for (slot = 0; slot < nritems; slot++) { ++ u32 item_end_expected; ++ int ret; ++ ++ btrfs_item_key_to_cpu(leaf, &key, slot); ++ ++ /* Make sure the keys are in the right order */ ++ if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) { ++ CORRUPT("bad key order", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ /* ++ * Make sure the offset and ends are right, remember that the ++ * item data starts at the end of the leaf and grows towards the ++ * front. ++ */ ++ if (slot == 0) ++ item_end_expected = BTRFS_LEAF_DATA_SIZE(root); ++ else ++ item_end_expected = btrfs_item_offset_nr(leaf, ++ slot - 1); ++ if (btrfs_item_end_nr(leaf, slot) != item_end_expected) { ++ CORRUPT("slot offset bad", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ /* ++ * Check to make sure that we don't point outside of the leaf, ++ * just in case all the items are consistent to each other, but ++ * all point outside of the leaf. ++ */ ++ if (btrfs_item_end_nr(leaf, slot) > ++ BTRFS_LEAF_DATA_SIZE(root)) { ++ CORRUPT("slot end outside of leaf", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ /* Also check if the item pointer overlaps with btrfs item. */ ++ if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) > ++ btrfs_item_ptr_offset(leaf, slot)) { ++ CORRUPT("slot overlap with its data", leaf, root, slot); ++ return -EUCLEAN; ++ } ++ ++ if (check_item_data) { ++ /* ++ * Check if the item size and content meet other ++ * criteria ++ */ ++ ret = check_leaf_item(root, leaf, &key, slot); ++ if (ret < 0) ++ return ret; ++ } ++ ++ prev_key.objectid = key.objectid; ++ prev_key.type = key.type; ++ prev_key.offset = key.offset; ++ } ++ ++ return 0; ++} ++ ++int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf) ++{ ++ return check_leaf(root, leaf, true); ++} ++ ++int btrfs_check_leaf_relaxed(struct btrfs_root *root, ++ struct extent_buffer *leaf) ++{ ++ return check_leaf(root, leaf, false); ++} ++ ++int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) ++{ ++ unsigned long nr = btrfs_header_nritems(node); ++ struct btrfs_key key, next_key; ++ int slot; ++ int level = btrfs_header_level(node); ++ u64 bytenr; ++ int ret = 0; ++ ++ if (level <= 0 || level >= BTRFS_MAX_LEVEL) { ++ generic_err(root, node, 0, ++ "invalid level for node, have %d expect [1, %d]", ++ level, BTRFS_MAX_LEVEL - 1); ++ return -EUCLEAN; ++ } ++ if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) { ++ btrfs_crit(root->fs_info, ++"corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%zu]", ++ root->objectid, node->start, ++ nr == 0 ? "small" : "large", nr, ++ BTRFS_NODEPTRS_PER_BLOCK(root)); ++ return -EUCLEAN; ++ } ++ ++ for (slot = 0; slot < nr - 1; slot++) { ++ bytenr = btrfs_node_blockptr(node, slot); ++ btrfs_node_key_to_cpu(node, &key, slot); ++ btrfs_node_key_to_cpu(node, &next_key, slot + 1); ++ ++ if (!bytenr) { ++ generic_err(root, node, slot, ++ "invalid NULL node pointer"); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ if (!IS_ALIGNED(bytenr, root->sectorsize)) { ++ generic_err(root, node, slot, ++ "unaligned pointer, have %llu should be aligned to %u", ++ bytenr, root->sectorsize); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ ++ if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { ++ generic_err(root, node, slot, ++ "bad key order, current (%llu %u %llu) next (%llu %u %llu)", ++ key.objectid, key.type, key.offset, ++ next_key.objectid, next_key.type, ++ next_key.offset); ++ ret = -EUCLEAN; ++ goto out; ++ } ++ } ++out: ++ return ret; ++} +diff --git a/fs/btrfs/tree-checker.h b/fs/btrfs/tree-checker.h +new file mode 100644 +index 000000000000..3d53e8d6fda0 +--- /dev/null ++++ b/fs/btrfs/tree-checker.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (C) Qu Wenruo 2017. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public ++ * License v2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program. ++ */ ++ ++#ifndef __BTRFS_TREE_CHECKER__ ++#define __BTRFS_TREE_CHECKER__ ++ ++#include "ctree.h" ++#include "extent_io.h" ++ ++/* ++ * Comprehensive leaf checker. ++ * Will check not only the item pointers, but also every possible member ++ * in item data. ++ */ ++int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf); ++ ++/* ++ * Less strict leaf checker. ++ * Will only check item pointers, not reading item data. ++ */ ++int btrfs_check_leaf_relaxed(struct btrfs_root *root, ++ struct extent_buffer *leaf); ++int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node); ++ ++#endif +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index b4d63a9842fa..5e8fe8f3942d 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -1184,7 +1184,7 @@ again: + struct map_lookup *map; + int i; + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + for (i = 0; i < map->num_stripes; i++) { + u64 end; + +@@ -2757,7 +2757,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, + free_extent_map(em); + return -EINVAL; + } +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + lock_chunks(root->fs_info->chunk_root); + check_system_chunk(trans, extent_root, map->type); + unlock_chunks(root->fs_info->chunk_root); +@@ -4540,7 +4540,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, + + if (type & BTRFS_BLOCK_GROUP_DATA) { + max_stripe_size = 1024 * 1024 * 1024; +- max_chunk_size = 10 * max_stripe_size; ++ max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE; + if (!devs_max) + devs_max = BTRFS_MAX_DEVS(info->chunk_root); + } else if (type & BTRFS_BLOCK_GROUP_METADATA) { +@@ -4731,7 +4731,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, + goto error; + } + set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags); +- em->bdev = (struct block_device *)map; ++ em->map_lookup = map; + em->start = start; + em->len = num_bytes; + em->block_start = 0; +@@ -4826,7 +4826,7 @@ int btrfs_finish_chunk_alloc(struct btrfs_trans_handle *trans, + return -EINVAL; + } + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + item_size = btrfs_chunk_item_size(map->num_stripes); + stripe_size = em->orig_block_len; + +@@ -4968,7 +4968,7 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset) + if (!em) + return 1; + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + for (i = 0; i < map->num_stripes; i++) { + if (map->stripes[i].dev->missing) { + miss_ndevs++; +@@ -5048,7 +5048,7 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len) + return 1; + } + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + if (map->type & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1)) + ret = map->num_stripes; + else if (map->type & BTRFS_BLOCK_GROUP_RAID10) +@@ -5091,7 +5091,7 @@ unsigned long btrfs_full_stripe_len(struct btrfs_root *root, + BUG_ON(!em); + + BUG_ON(em->start > logical || em->start + em->len < logical); +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) + len = map->stripe_len * nr_data_stripes(map); + free_extent_map(em); +@@ -5112,7 +5112,7 @@ int btrfs_is_parity_mirror(struct btrfs_mapping_tree *map_tree, + BUG_ON(!em); + + BUG_ON(em->start > logical || em->start + em->len < logical); +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) + ret = 1; + free_extent_map(em); +@@ -5271,7 +5271,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, + return -EINVAL; + } + +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + offset = logical - em->start; + + stripe_len = map->stripe_len; +@@ -5813,7 +5813,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, + free_extent_map(em); + return -EIO; + } +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + + length = em->len; + rmap_len = map->stripe_len; +@@ -6208,6 +6208,101 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, + return dev; + } + ++/* Return -EIO if any error, otherwise return 0. */ ++static int btrfs_check_chunk_valid(struct btrfs_root *root, ++ struct extent_buffer *leaf, ++ struct btrfs_chunk *chunk, u64 logical) ++{ ++ u64 length; ++ u64 stripe_len; ++ u16 num_stripes; ++ u16 sub_stripes; ++ u64 type; ++ u64 features; ++ bool mixed = false; ++ ++ length = btrfs_chunk_length(leaf, chunk); ++ stripe_len = btrfs_chunk_stripe_len(leaf, chunk); ++ num_stripes = btrfs_chunk_num_stripes(leaf, chunk); ++ sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); ++ type = btrfs_chunk_type(leaf, chunk); ++ ++ if (!num_stripes) { ++ btrfs_err(root->fs_info, "invalid chunk num_stripes: %u", ++ num_stripes); ++ return -EIO; ++ } ++ if (!IS_ALIGNED(logical, root->sectorsize)) { ++ btrfs_err(root->fs_info, ++ "invalid chunk logical %llu", logical); ++ return -EIO; ++ } ++ if (btrfs_chunk_sector_size(leaf, chunk) != root->sectorsize) { ++ btrfs_err(root->fs_info, "invalid chunk sectorsize %u", ++ btrfs_chunk_sector_size(leaf, chunk)); ++ return -EIO; ++ } ++ if (!length || !IS_ALIGNED(length, root->sectorsize)) { ++ btrfs_err(root->fs_info, ++ "invalid chunk length %llu", length); ++ return -EIO; ++ } ++ if (!is_power_of_2(stripe_len)) { ++ btrfs_err(root->fs_info, "invalid chunk stripe length: %llu", ++ stripe_len); ++ return -EIO; ++ } ++ if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) & ++ type) { ++ btrfs_err(root->fs_info, "unrecognized chunk type: %llu", ++ ~(BTRFS_BLOCK_GROUP_TYPE_MASK | ++ BTRFS_BLOCK_GROUP_PROFILE_MASK) & ++ btrfs_chunk_type(leaf, chunk)); ++ return -EIO; ++ } ++ ++ if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) { ++ btrfs_err(root->fs_info, "missing chunk type flag: 0x%llx", type); ++ return -EIO; ++ } ++ ++ if ((type & BTRFS_BLOCK_GROUP_SYSTEM) && ++ (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA))) { ++ btrfs_err(root->fs_info, ++ "system chunk with data or metadata type: 0x%llx", type); ++ return -EIO; ++ } ++ ++ features = btrfs_super_incompat_flags(root->fs_info->super_copy); ++ if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) ++ mixed = true; ++ ++ if (!mixed) { ++ if ((type & BTRFS_BLOCK_GROUP_METADATA) && ++ (type & BTRFS_BLOCK_GROUP_DATA)) { ++ btrfs_err(root->fs_info, ++ "mixed chunk type in non-mixed mode: 0x%llx", type); ++ return -EIO; ++ } ++ } ++ ++ if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) || ++ (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes < 1) || ++ (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) || ++ (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) || ++ (type & BTRFS_BLOCK_GROUP_DUP && num_stripes > 2) || ++ ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 && ++ num_stripes != 1)) { ++ btrfs_err(root->fs_info, ++ "invalid num_stripes:sub_stripes %u:%u for profile %llu", ++ num_stripes, sub_stripes, ++ type & BTRFS_BLOCK_GROUP_PROFILE_MASK); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ + static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + struct extent_buffer *leaf, + struct btrfs_chunk *chunk) +@@ -6217,6 +6312,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + struct extent_map *em; + u64 logical; + u64 length; ++ u64 stripe_len; + u64 devid; + u8 uuid[BTRFS_UUID_SIZE]; + int num_stripes; +@@ -6225,6 +6321,12 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + + logical = key->offset; + length = btrfs_chunk_length(leaf, chunk); ++ stripe_len = btrfs_chunk_stripe_len(leaf, chunk); ++ num_stripes = btrfs_chunk_num_stripes(leaf, chunk); ++ ++ ret = btrfs_check_chunk_valid(root, leaf, chunk, logical); ++ if (ret) ++ return ret; + + read_lock(&map_tree->map_tree.lock); + em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); +@@ -6241,7 +6343,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + em = alloc_extent_map(); + if (!em) + return -ENOMEM; +- num_stripes = btrfs_chunk_num_stripes(leaf, chunk); + map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); + if (!map) { + free_extent_map(em); +@@ -6249,7 +6350,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + } + + set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags); +- em->bdev = (struct block_device *)map; ++ em->map_lookup = map; + em->start = logical; + em->len = length; + em->orig_start = 0; +@@ -6473,6 +6574,7 @@ int btrfs_read_sys_array(struct btrfs_root *root) + u32 array_size; + u32 len = 0; + u32 cur_offset; ++ u64 type; + struct btrfs_key key; + + ASSERT(BTRFS_SUPER_INFO_SIZE <= root->nodesize); +@@ -6539,6 +6641,15 @@ int btrfs_read_sys_array(struct btrfs_root *root) + break; + } + ++ type = btrfs_chunk_type(sb, chunk); ++ if ((type & BTRFS_BLOCK_GROUP_SYSTEM) == 0) { ++ btrfs_err(root->fs_info, ++ "invalid chunk type %llu in sys_array at offset %u", ++ type, cur_offset); ++ ret = -EIO; ++ break; ++ } ++ + len = btrfs_chunk_item_size(num_stripes); + if (cur_offset + len > array_size) + goto out_short_read; +@@ -6948,7 +7059,7 @@ void btrfs_update_commit_device_bytes_used(struct btrfs_root *root, + /* In order to kick the device replace finish process */ + lock_chunks(root); + list_for_each_entry(em, &transaction->pending_chunks, list) { +- map = (struct map_lookup *)em->bdev; ++ map = em->map_lookup; + + for (i = 0; i < map->num_stripes; i++) { + dev = map->stripes[i].dev; +diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h +index d5c84f6b1353..3c651df420be 100644 +--- a/fs/btrfs/volumes.h ++++ b/fs/btrfs/volumes.h +@@ -24,6 +24,8 @@ + #include + #include "async-thread.h" + ++#define BTRFS_MAX_DATA_CHUNK_SIZE (10ULL * SZ_1G) ++ + extern struct mutex uuid_mutex; + + #define BTRFS_STRIPE_LEN (64 * 1024) +diff --git a/fs/cifs/file.c b/fs/cifs/file.c +index 0141aba9eca6..026b399af215 100644 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@ -1073,10 +1073,10 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) + + /* + * Accessing maxBuf is racy with cifs_reconnect - need to store value +- * and check it for zero before using. ++ * and check it before using. + */ + max_buf = tcon->ses->server->maxBuf; +- if (!max_buf) { ++ if (max_buf < (sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE))) { + free_xid(xid); + return -EINVAL; + } +@@ -1404,10 +1404,10 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, + + /* + * Accessing maxBuf is racy with cifs_reconnect - need to store value +- * and check it for zero before using. ++ * and check it before using. + */ + max_buf = tcon->ses->server->maxBuf; +- if (!max_buf) ++ if (max_buf < (sizeof(struct smb_hdr) + sizeof(LOCKING_ANDX_RANGE))) + return -EINVAL; + + max_num = (max_buf - sizeof(struct smb_hdr)) / +diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c +index b2aff0c6f22c..b7885dc0d9bb 100644 +--- a/fs/cifs/smb2file.c ++++ b/fs/cifs/smb2file.c +@@ -123,10 +123,10 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, + + /* + * Accessing maxBuf is racy with cifs_reconnect - need to store value +- * and check it for zero before using. ++ * and check it before using. + */ + max_buf = tcon->ses->server->maxBuf; +- if (!max_buf) ++ if (max_buf < sizeof(struct smb2_lock_element)) + return -EINVAL; + + max_num = max_buf / sizeof(struct smb2_lock_element); +diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c +index 54af10204e83..1cf0a336ec06 100644 +--- a/fs/cifs/transport.c ++++ b/fs/cifs/transport.c +@@ -360,7 +360,7 @@ uncork: + if (rc < 0 && rc != -EINTR) + cifs_dbg(VFS, "Error %d sending data on socket to server\n", + rc); +- else ++ else if (rc > 0) + rc = 0; + + return rc; +diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c +index 46d4fac48cf4..0dcd33f62637 100644 +--- a/fs/ext4/inline.c ++++ b/fs/ext4/inline.c +@@ -1861,12 +1861,12 @@ int ext4_inline_data_fiemap(struct inode *inode, + physical += (char *)ext4_raw_inode(&iloc) - iloc.bh->b_data; + physical += offsetof(struct ext4_inode, i_block); + +- if (physical) +- error = fiemap_fill_next_extent(fieinfo, start, physical, +- inline_len, flags); + brelse(iloc.bh); + out: + up_read(&EXT4_I(inode)->xattr_sem); ++ if (physical) ++ error = fiemap_fill_next_extent(fieinfo, start, physical, ++ inline_len, flags); + return (error < 0 ? error : 0); + } + +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index cc0fc712bb82..a8ac3f25b4ec 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -290,9 +290,12 @@ struct svc_rqst { + struct svc_cacherep * rq_cacherep; /* cache info */ + struct task_struct *rq_task; /* service thread */ + spinlock_t rq_lock; /* per-request lock */ ++ struct net *rq_bc_net; /* pointer to backchannel's ++ * net namespace ++ */ + }; + +-#define SVC_NET(svc_rqst) (svc_rqst->rq_xprt->xpt_net) ++#define SVC_NET(rqst) (rqst->rq_xprt ? rqst->rq_xprt->xpt_net : rqst->rq_bc_net) + + /* + * Rigorous type checking on sockaddr type conversions +diff --git a/mm/slab.c b/mm/slab.c +index fa49c01225a7..92df044f5e00 100644 +--- a/mm/slab.c ++++ b/mm/slab.c +@@ -875,8 +875,10 @@ static struct alien_cache *__alloc_alien_cache(int node, int entries, + struct alien_cache *alc = NULL; + + alc = kmalloc_node(memsize, gfp, node); +- init_arraycache(&alc->ac, entries, batch); +- spin_lock_init(&alc->lock); ++ if (alc) { ++ init_arraycache(&alc->ac, entries, batch); ++ spin_lock_init(&alc->lock); ++ } + return alc; + } + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index c5b0cb4f4056..41f6e964fe91 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1062,6 +1062,8 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) + static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {} + #endif + ++extern void svc_tcp_prep_reply_hdr(struct svc_rqst *); ++ + /* + * Common routine for processing the RPC request. + */ +@@ -1091,7 +1093,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + clear_bit(RQ_DROPME, &rqstp->rq_flags); + + /* Setup reply header */ +- rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); ++ if (rqstp->rq_prot == IPPROTO_TCP) ++ svc_tcp_prep_reply_hdr(rqstp); + + svc_putu32(resv, rqstp->rq_xid); + +@@ -1138,7 +1141,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + case SVC_DENIED: + goto err_bad_auth; + case SVC_CLOSE: +- if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) ++ if (rqstp->rq_xprt && ++ test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags)) + svc_close_xprt(rqstp->rq_xprt); + case SVC_DROP: + goto dropit; +@@ -1360,10 +1364,10 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, + dprintk("svc: %s(%p)\n", __func__, req); + + /* Build the svc_rqst used by the common processing routine */ +- rqstp->rq_xprt = serv->sv_bc_xprt; + rqstp->rq_xid = req->rq_xid; + rqstp->rq_prot = req->rq_xprt->prot; + rqstp->rq_server = serv; ++ rqstp->rq_bc_net = req->rq_xprt->xprt_net; + + rqstp->rq_addrlen = sizeof(req->rq_xprt->addr); + memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen); +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index 71f15da72f02..2b8e80c721db 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -454,10 +454,11 @@ out: + */ + void svc_reserve(struct svc_rqst *rqstp, int space) + { ++ struct svc_xprt *xprt = rqstp->rq_xprt; ++ + space += rqstp->rq_res.head[0].iov_len; + +- if (space < rqstp->rq_reserved) { +- struct svc_xprt *xprt = rqstp->rq_xprt; ++ if (xprt && space < rqstp->rq_reserved) { + atomic_sub((rqstp->rq_reserved - space), &xprt->xpt_reserved); + rqstp->rq_reserved = space; + +diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c +index 9701fcca002c..0a9fe033132c 100644 +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -1240,7 +1240,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp) + /* + * Setup response header. TCP has a 4B record length field. + */ +-static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp) ++void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp) + { + struct kvec *resv = &rqstp->rq_res.head[0]; + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 0467e5ba82e0..5d8ac2d798df 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4792,6 +4792,13 @@ static void alc280_fixup_hp_9480m(struct hda_codec *codec, + } + } + ++static void alc_fixup_disable_mic_vref(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ if (action == HDA_FIXUP_ACT_PRE_PROBE) ++ snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ); ++} ++ + /* for hda_fixup_thinkpad_acpi() */ + #include "thinkpad_helper.c" + +@@ -4891,6 +4898,7 @@ enum { + ALC293_FIXUP_LENOVO_SPK_NOISE, + ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY, + ALC255_FIXUP_DELL_SPK_NOISE, ++ ALC225_FIXUP_DISABLE_MIC_VREF, + ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC295_FIXUP_DISABLE_DAC3, + ALC280_FIXUP_HP_HEADSET_MIC, +@@ -5546,6 +5554,12 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE + }, ++ [ALC225_FIXUP_DISABLE_MIC_VREF] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_disable_mic_vref, ++ .chained = true, ++ .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE ++ }, + [ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { +@@ -5555,7 +5569,7 @@ static const struct hda_fixup alc269_fixups[] = { + {} + }, + .chained = true, +- .chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE ++ .chain_id = ALC225_FIXUP_DISABLE_MIC_VREF + }, + [ALC280_FIXUP_HP_HEADSET_MIC] = { + .type = HDA_FIXUP_FUNC,