summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2018-12-17 16:56:24 -0500
committerMike Pagano <mpagano@gentoo.org>2018-12-17 16:56:24 -0500
commit5c15ccf351b68dbc491e2f8f38d309b6c184bfcb (patch)
treeee44b9d7c06284c3ad517dcbd84607bf6e1d3524 /1167_linux-4.4.168.patch
parentproj/linux-patchs: Linux patch 4.4.167 (diff)
downloadlinux-patches-5c15ccf351b68dbc491e2f8f38d309b6c184bfcb.tar.gz
linux-patches-5c15ccf351b68dbc491e2f8f38d309b6c184bfcb.tar.bz2
linux-patches-5c15ccf351b68dbc491e2f8f38d309b6c184bfcb.zip
proj/linux-patches: Linux patch 4.4.1684.4-169
Signed-off-by: Mike Pagano <mpagano@gentoo.org>
Diffstat (limited to '1167_linux-4.4.168.patch')
-rw-r--r--1167_linux-4.4.168.patch7825
1 files changed, 7825 insertions, 0 deletions
diff --git a/1167_linux-4.4.168.patch b/1167_linux-4.4.168.patch
new file mode 100644
index 00000000..a57a669e
--- /dev/null
+++ b/1167_linux-4.4.168.patch
@@ -0,0 +1,7825 @@
+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 <errno.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-
+-#include <sys/socket.h>
+-#include <sys/ioctl.h>
+-
+-#include <linux/if.h>
+-#include <linux/net_tstamp.h>
+-#include <linux/sockios.h>
+-
+-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 <patrick.ohly@intel.com>
+- *
+- * 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 <stdio.h>
+-#include <stdlib.h>
+-#include <errno.h>
+-#include <string.h>
+-
+-#include <sys/time.h>
+-#include <sys/socket.h>
+-#include <sys/select.h>
+-#include <sys/ioctl.h>
+-#include <arpa/inet.h>
+-#include <net/if.h>
+-
+-#include <asm/types.h>
+-#include <linux/net_tstamp.h>
+-#include <linux/errqueue.h>
+-
+-#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 <arpa/inet.h>
+-#include <asm/types.h>
+-#include <error.h>
+-#include <errno.h>
+-#include <inttypes.h>
+-#include <linux/errqueue.h>
+-#include <linux/if_ether.h>
+-#include <linux/net_tstamp.h>
+-#include <netdb.h>
+-#include <net/if.h>
+-#include <netinet/in.h>
+-#include <netinet/ip.h>
+-#include <netinet/udp.h>
+-#include <netinet/tcp.h>
+-#include <netpacket/packet.h>
+-#include <poll.h>
+-#include <stdarg.h>
+-#include <stdbool.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <sys/ioctl.h>
+-#include <sys/select.h>
+-#include <sys/socket.h>
+-#include <sys/time.h>
+-#include <sys/types.h>
+-#include <time.h>
+-#include <unistd.h>
+-
+-/* 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(&current->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,6 +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.
+@@ -203,10 +211,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+
+ #ifdef CONFIG_X86_32
+ #define __put_user_asm_u64(x, addr, err, errret) \
+- asm volatile(ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1: movl %%eax,0(%2)\n" \
+ "2: movl %%edx,4(%2)\n" \
+- "3: " ASM_CLAC "\n" \
++ "3:" \
+ ".section .fixup,\"ax\"\n" \
+ "4: movl %3,%0\n" \
+ " jmp 3b\n" \
+@@ -217,10 +225,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+ : "A" (x), "r" (addr), "i" (errret), "0" (err))
+
+ #define __put_user_asm_ex_u64(x, addr) \
+- asm volatile(ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1: movl %%eax,0(%1)\n" \
+ "2: movl %%edx,4(%1)\n" \
+- "3: " ASM_CLAC "\n" \
++ "3:" \
+ _ASM_EXTABLE_EX(1b, 2b) \
+ _ASM_EXTABLE_EX(2b, 3b) \
+ : : "A" (x), "r" (addr))
+@@ -314,6 +322,10 @@ do { \
+ } \
+ } while (0)
+
++/*
++ * This doesn't do __uaccess_begin/end - the exception handling
++ * around it must do that.
++ */
+ #define __put_user_size_ex(x, ptr, size) \
+ do { \
+ __chk_user_ptr(ptr); \
+@@ -368,9 +380,9 @@ do { \
+ } while (0)
+
+ #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
+- asm volatile(ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1: mov"itype" %2,%"rtype"1\n" \
+- "2: " ASM_CLAC "\n" \
++ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: mov %3,%0\n" \
+ " xor"itype" %"rtype"1,%"rtype"1\n" \
+@@ -380,6 +392,10 @@ do { \
+ : "=r" (err), ltype(x) \
+ : "m" (__m(addr)), "i" (errret), "0" (err))
+
++/*
++ * This doesn't do __uaccess_begin/end - the exception handling
++ * around it must do that.
++ */
+ #define __get_user_size_ex(x, ptr, size) \
+ do { \
+ __chk_user_ptr(ptr); \
+@@ -410,7 +426,9 @@ do { \
+ #define __put_user_nocheck(x, ptr, size) \
+ ({ \
+ int __pu_err; \
++ __uaccess_begin(); \
+ __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
++ __uaccess_end(); \
+ __builtin_expect(__pu_err, 0); \
+ })
+
+@@ -418,7 +436,9 @@ do { \
+ ({ \
+ int __gu_err; \
+ unsigned long __gu_val; \
++ __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); \
+ })
+@@ -433,9 +453,9 @@ struct __large_struct { unsigned long buf[100]; };
+ * aliasing issues.
+ */
+ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
+- asm volatile(ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1: mov"itype" %"rtype"1,%2\n" \
+- "2: " ASM_CLAC "\n" \
++ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: mov %3,%0\n" \
+ " jmp 2b\n" \
+@@ -455,11 +475,15 @@ struct __large_struct { unsigned long buf[100]; };
+ */
+ #define uaccess_try do { \
+ current_thread_info()->uaccess_err = 0; \
+- stac(); \
++ __uaccess_begin(); \
+ barrier();
+
++#define uaccess_try_nospec do { \
++ current_thread_info()->uaccess_err = 0; \
++ __uaccess_begin_nospec(); \
++
+ #define uaccess_catch(err) \
+- clac(); \
++ __uaccess_end(); \
+ (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
+ } while (0)
+
+@@ -522,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 { \
+@@ -557,12 +581,13 @@ extern void __cmpxchg_wrong_size(void)
+ __typeof__(ptr) __uval = (uval); \
+ __typeof__(*(ptr)) __old = (old); \
+ __typeof__(*(ptr)) __new = (new); \
++ __uaccess_begin_nospec(); \
+ switch (size) { \
+ case 1: \
+ { \
+- asm volatile("\t" ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1:\t" LOCK_PREFIX "cmpxchgb %4, %2\n" \
+- "2:\t" ASM_CLAC "\n" \
++ "2:\n" \
+ "\t.section .fixup, \"ax\"\n" \
+ "3:\tmov %3, %0\n" \
+ "\tjmp 2b\n" \
+@@ -576,9 +601,9 @@ extern void __cmpxchg_wrong_size(void)
+ } \
+ case 2: \
+ { \
+- asm volatile("\t" ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1:\t" LOCK_PREFIX "cmpxchgw %4, %2\n" \
+- "2:\t" ASM_CLAC "\n" \
++ "2:\n" \
+ "\t.section .fixup, \"ax\"\n" \
+ "3:\tmov %3, %0\n" \
+ "\tjmp 2b\n" \
+@@ -592,9 +617,9 @@ extern void __cmpxchg_wrong_size(void)
+ } \
+ case 4: \
+ { \
+- asm volatile("\t" ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n" \
+- "2:\t" ASM_CLAC "\n" \
++ "2:\n" \
+ "\t.section .fixup, \"ax\"\n" \
+ "3:\tmov %3, %0\n" \
+ "\tjmp 2b\n" \
+@@ -611,9 +636,9 @@ extern void __cmpxchg_wrong_size(void)
+ if (!IS_ENABLED(CONFIG_X86_64)) \
+ __cmpxchg_wrong_size(); \
+ \
+- asm volatile("\t" ASM_STAC "\n" \
++ asm volatile("\n" \
+ "1:\t" LOCK_PREFIX "cmpxchgq %4, %2\n" \
+- "2:\t" ASM_CLAC "\n" \
++ "2:\n" \
+ "\t.section .fixup, \"ax\"\n" \
+ "3:\tmov %3, %0\n" \
+ "\tjmp 2b\n" \
+@@ -628,6 +653,7 @@ extern void __cmpxchg_wrong_size(void)
+ default: \
+ __cmpxchg_wrong_size(); \
+ } \
++ __uaccess_end(); \
+ *__uval = __old; \
+ __ret; \
+ })
+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
+@@ -48,20 +48,28 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
+
+ switch (n) {
+ case 1:
++ __uaccess_begin_nospec();
+ __put_user_size(*(u8 *)from, (u8 __user *)to,
+ 1, ret, 1);
++ __uaccess_end();
+ return ret;
+ case 2:
++ __uaccess_begin_nospec();
+ __put_user_size(*(u16 *)from, (u16 __user *)to,
+ 2, ret, 2);
++ __uaccess_end();
+ return ret;
+ case 4:
++ __uaccess_begin_nospec();
+ __put_user_size(*(u32 *)from, (u32 __user *)to,
+ 4, ret, 4);
++ __uaccess_end();
+ return ret;
+ case 8:
++ __uaccess_begin_nospec();
+ __put_user_size(*(u64 *)from, (u64 __user *)to,
+ 8, ret, 8);
++ __uaccess_end();
+ return ret;
+ }
+ }
+@@ -103,13 +111,19 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+
+ switch (n) {
+ case 1:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u8 *)to, from, 1, ret, 1);
++ __uaccess_end();
+ return ret;
+ case 2:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u16 *)to, from, 2, ret, 2);
++ __uaccess_end();
+ return ret;
+ case 4:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u32 *)to, from, 4, ret, 4);
++ __uaccess_end();
+ return ret;
+ }
+ }
+@@ -148,13 +162,19 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
+
+ switch (n) {
+ case 1:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u8 *)to, from, 1, ret, 1);
++ __uaccess_end();
+ return ret;
+ case 2:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u16 *)to, from, 2, ret, 2);
++ __uaccess_end();
+ return ret;
+ case 4:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u32 *)to, from, 4, ret, 4);
++ __uaccess_end();
+ return ret;
+ }
+ }
+@@ -170,13 +190,19 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
+
+ switch (n) {
+ case 1:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u8 *)to, from, 1, ret, 1);
++ __uaccess_end();
+ return ret;
+ case 2:
++ __uaccess_begin_nospec();
+ __get_user_size(*(u16 *)to, from, 2, ret, 2);
++ __uaccess_end();
+ return ret;
+ case 4:
++ __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
+@@ -56,35 +56,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:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
++ case 1:
++ __uaccess_begin_nospec();
++ __get_user_asm(*(u8 *)dst, (u8 __user *)src,
+ ret, "b", "b", "=q", 1);
++ __uaccess_end();
+ return ret;
+- case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
++ case 2:
++ __uaccess_begin_nospec();
++ __get_user_asm(*(u16 *)dst, (u16 __user *)src,
+ ret, "w", "w", "=r", 2);
++ __uaccess_end();
+ return ret;
+- case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
++ case 4:
++ __uaccess_begin_nospec();
++ __get_user_asm(*(u32 *)dst, (u32 __user *)src,
+ ret, "l", "k", "=r", 4);
++ __uaccess_end();
+ return ret;
+- case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
++ case 8:
++ __uaccess_begin_nospec();
++ __get_user_asm(*(u64 *)dst, (u64 __user *)src,
+ ret, "q", "", "=r", 8);
++ __uaccess_end();
+ return ret;
+ case 10:
++ __uaccess_begin_nospec();
+ __get_user_asm(*(u64 *)dst, (u64 __user *)src,
+ ret, "q", "", "=r", 10);
+- if (unlikely(ret))
+- return ret;
+- __get_user_asm(*(u16 *)(8 + (char *)dst),
+- (u16 __user *)(8 + (char __user *)src),
+- ret, "w", "w", "=r", 2);
++ 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_nospec();
+ __get_user_asm(*(u64 *)dst, (u64 __user *)src,
+ ret, "q", "", "=r", 16);
+- if (unlikely(ret))
+- return ret;
+- __get_user_asm(*(u64 *)(8 + (char *)dst),
+- (u64 __user *)(8 + (char __user *)src),
+- ret, "q", "", "=r", 8);
++ 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);
+@@ -106,35 +120,51 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size)
+ if (!__builtin_constant_p(size))
+ return copy_user_generic((__force void *)dst, src, size);
+ switch (size) {
+- case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
++ case 1:
++ __uaccess_begin();
++ __put_user_asm(*(u8 *)src, (u8 __user *)dst,
+ ret, "b", "b", "iq", 1);
++ __uaccess_end();
+ return ret;
+- case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
++ case 2:
++ __uaccess_begin();
++ __put_user_asm(*(u16 *)src, (u16 __user *)dst,
+ ret, "w", "w", "ir", 2);
++ __uaccess_end();
+ return ret;
+- case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
++ case 4:
++ __uaccess_begin();
++ __put_user_asm(*(u32 *)src, (u32 __user *)dst,
+ ret, "l", "k", "ir", 4);
++ __uaccess_end();
+ return ret;
+- case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
++ case 8:
++ __uaccess_begin();
++ __put_user_asm(*(u64 *)src, (u64 __user *)dst,
+ ret, "q", "", "er", 8);
++ __uaccess_end();
+ return ret;
+ case 10:
++ __uaccess_begin();
+ __put_user_asm(*(u64 *)src, (u64 __user *)dst,
+ ret, "q", "", "er", 10);
+- if (unlikely(ret))
+- return ret;
+- asm("":::"memory");
+- __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
+- ret, "w", "w", "ir", 2);
++ if (likely(!ret)) {
++ asm("":::"memory");
++ __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
++ ret, "w", "w", "ir", 2);
++ }
++ __uaccess_end();
+ return ret;
+ case 16:
++ __uaccess_begin();
+ __put_user_asm(*(u64 *)src, (u64 __user *)dst,
+ ret, "q", "", "er", 16);
+- if (unlikely(ret))
+- return ret;
+- asm("":::"memory");
+- __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
+- ret, "q", "", "er", 8);
++ if (likely(!ret)) {
++ asm("":::"memory");
++ __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
++ ret, "q", "", "er", 8);
++ }
++ __uaccess_end();
+ return ret;
+ default:
+ return copy_user_generic((__force void *)dst, src, size);
+@@ -160,39 +190,47 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
+ switch (size) {
+ case 1: {
+ u8 tmp;
++ __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_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_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_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 <asm/desc.h>
+ #include <asm/debugreg.h>
+ #include <asm/kvm_para.h>
++#include <asm/microcode.h>
+ #include <asm/spec-ctrl.h>
+
+ #include <asm/virtext.h>
+@@ -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 <asm/kexec.h>
+ #include <asm/apic.h>
+ #include <asm/irq_remapping.h>
++#include <asm/microcode.h>
+ #include <asm/spec-ctrl.h>
+
+ #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(&current->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(&current->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(&current->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 <asm/xen/hypervisor.h>
+
+ #include <xen/xen.h>
++#include <xen/xen-ops.h>
+ #include <xen/page.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/memory.h>
+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 <linux/cache.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/mm.h>
+@@ -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 <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <sys/socket.h>
++#include <sys/ioctl.h>
++
++#include <linux/if.h>
++#include <linux/net_tstamp.h>
++#include <linux/sockios.h>
++
++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 <patrick.ohly@intel.com>
++ *
++ * 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 <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++
++#include <sys/time.h>
++#include <sys/socket.h>
++#include <sys/select.h>
++#include <sys/ioctl.h>
++#include <arpa/inet.h>
++#include <net/if.h>
++
++#include <asm/types.h>
++#include <linux/net_tstamp.h>
++#include <linux/errqueue.h>
++
++#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 <arpa/inet.h>
++#include <asm/types.h>
++#include <error.h>
++#include <errno.h>
++#include <inttypes.h>
++#include <linux/errqueue.h>
++#include <linux/if_ether.h>
++#include <linux/net_tstamp.h>
++#include <netdb.h>
++#include <net/if.h>
++#include <netinet/in.h>
++#include <netinet/ip.h>
++#include <netinet/udp.h>
++#include <netinet/tcp.h>
++#include <netpacket/packet.h>
++#include <poll.h>
++#include <stdarg.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <sys/select.h>
++#include <sys/socket.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <time.h>
++#include <unistd.h>
++
++/* 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(&current->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;
+