summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--3.12.4/1003_linux-3.12.4.patch4725
-rw-r--r--3.12.5/0000_README (renamed from 3.12.4/0000_README)6
-rw-r--r--3.12.5/4420_grsecurity-3.0-3.12.5-201312132204.patch (renamed from 3.12.4/4420_grsecurity-3.0-3.12.4-201312081754.patch)2468
-rw-r--r--3.12.5/4425_grsec_remove_EI_PAX.patch (renamed from 3.12.4/4425_grsec_remove_EI_PAX.patch)0
-rw-r--r--3.12.5/4427_force_XATTR_PAX_tmpfs.patch (renamed from 3.12.4/4427_force_XATTR_PAX_tmpfs.patch)0
-rw-r--r--3.12.5/4430_grsec-remove-localversion-grsec.patch (renamed from 3.12.4/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.12.5/4435_grsec-mute-warnings.patch (renamed from 3.12.4/4435_grsec-mute-warnings.patch)0
-rw-r--r--3.12.5/4440_grsec-remove-protected-paths.patch (renamed from 3.12.4/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--3.12.5/4450_grsec-kconfig-default-gids.patch (renamed from 3.12.4/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--3.12.5/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.12.4/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--3.12.5/4470_disable-compat_vdso.patch (renamed from 3.12.4/4470_disable-compat_vdso.patch)0
-rw-r--r--3.12.5/4475_emutramp_default_on.patch (renamed from 3.12.4/4475_emutramp_default_on.patch)0
-rw-r--r--3.2.53/0000_README2
-rw-r--r--3.2.53/4420_grsecurity-3.0-3.2.53-201312132200.patch (renamed from 3.2.53/4420_grsecurity-3.0-3.2.53-201312081752.patch)2375
14 files changed, 3945 insertions, 5631 deletions
diff --git a/3.12.4/1003_linux-3.12.4.patch b/3.12.4/1003_linux-3.12.4.patch
deleted file mode 100644
index 819cfed..0000000
--- a/3.12.4/1003_linux-3.12.4.patch
+++ /dev/null
@@ -1,4725 +0,0 @@
-diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
-index a46d785..7d8dc93 100644
---- a/Documentation/networking/ip-sysctl.txt
-+++ b/Documentation/networking/ip-sysctl.txt
-@@ -588,9 +588,6 @@ tcp_limit_output_bytes - INTEGER
- typical pfifo_fast qdiscs.
- tcp_limit_output_bytes limits the number of bytes on qdisc
- or device to reduce artificial RTT/cwnd and reduce bufferbloat.
-- Note: For GSO/TSO enabled flows, we try to have at least two
-- packets in flight. Reducing tcp_limit_output_bytes might also
-- reduce the size of individual GSO packet (64KB being the max)
- Default: 131072
-
- tcp_challenge_ack_limit - INTEGER
-diff --git a/Makefile b/Makefile
-index b28bc57..3b7165e 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 3
- PATCHLEVEL = 12
--SUBLEVEL = 3
-+SUBLEVEL = 4
- EXTRAVERSION =
- NAME = One Giant Leap for Frogkind
-
-diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
-index 516593e..26328e8 100644
---- a/arch/x86/net/bpf_jit_comp.c
-+++ b/arch/x86/net/bpf_jit_comp.c
-@@ -788,5 +788,7 @@ void bpf_jit_free(struct sk_filter *fp)
- if (fp->bpf_func != sk_run_filter) {
- INIT_WORK(&fp->work, bpf_jit_free_deferred);
- schedule_work(&fp->work);
-+ } else {
-+ kfree(fp);
- }
- }
-diff --git a/block/blk-core.c b/block/blk-core.c
-index 0c611d8..fce4b93 100644
---- a/block/blk-core.c
-+++ b/block/blk-core.c
-@@ -741,9 +741,17 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
-
- q->sg_reserved_size = INT_MAX;
-
-+ /* Protect q->elevator from elevator_change */
-+ mutex_lock(&q->sysfs_lock);
-+
- /* init elevator */
-- if (elevator_init(q, NULL))
-+ if (elevator_init(q, NULL)) {
-+ mutex_unlock(&q->sysfs_lock);
- return NULL;
-+ }
-+
-+ mutex_unlock(&q->sysfs_lock);
-+
- return q;
- }
- EXPORT_SYMBOL(blk_init_allocated_queue);
-diff --git a/block/elevator.c b/block/elevator.c
-index 2bcbd8c..b7ff286 100644
---- a/block/elevator.c
-+++ b/block/elevator.c
-@@ -186,6 +186,12 @@ int elevator_init(struct request_queue *q, char *name)
- struct elevator_type *e = NULL;
- int err;
-
-+ /*
-+ * q->sysfs_lock must be held to provide mutual exclusion between
-+ * elevator_switch() and here.
-+ */
-+ lockdep_assert_held(&q->sysfs_lock);
-+
- if (unlikely(q->elevator))
- return 0;
-
-@@ -959,7 +965,7 @@ fail_init:
- /*
- * Switch this queue to the given IO scheduler.
- */
--int elevator_change(struct request_queue *q, const char *name)
-+static int __elevator_change(struct request_queue *q, const char *name)
- {
- char elevator_name[ELV_NAME_MAX];
- struct elevator_type *e;
-@@ -981,6 +987,18 @@ int elevator_change(struct request_queue *q, const char *name)
-
- return elevator_switch(q, e);
- }
-+
-+int elevator_change(struct request_queue *q, const char *name)
-+{
-+ int ret;
-+
-+ /* Protect q->elevator from elevator_init() */
-+ mutex_lock(&q->sysfs_lock);
-+ ret = __elevator_change(q, name);
-+ mutex_unlock(&q->sysfs_lock);
-+
-+ return ret;
-+}
- EXPORT_SYMBOL(elevator_change);
-
- ssize_t elv_iosched_store(struct request_queue *q, const char *name,
-@@ -991,7 +1009,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
- if (!q->elevator)
- return count;
-
-- ret = elevator_change(q, name);
-+ ret = __elevator_change(q, name);
- if (!ret)
- return count;
-
-diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
-index 0262210..8502462 100644
---- a/crypto/algif_hash.c
-+++ b/crypto/algif_hash.c
-@@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
- struct hash_ctx *ctx = ask->private;
- int err;
-
-+ if (flags & MSG_SENDPAGE_NOTLAST)
-+ flags |= MSG_MORE;
-+
- lock_sock(sk);
- sg_init_table(ctx->sgl.sg, 1);
- sg_set_page(ctx->sgl.sg, page, size, offset);
-@@ -161,8 +164,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
- else if (len < ds)
- msg->msg_flags |= MSG_TRUNC;
-
-- msg->msg_namelen = 0;
--
- lock_sock(sk);
- if (ctx->more) {
- ctx->more = 0;
-diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
-index a1c4f0a..a19c027 100644
---- a/crypto/algif_skcipher.c
-+++ b/crypto/algif_skcipher.c
-@@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page,
- struct skcipher_sg_list *sgl;
- int err = -EINVAL;
-
-+ if (flags & MSG_SENDPAGE_NOTLAST)
-+ flags |= MSG_MORE;
-+
- lock_sock(sk);
- if (!ctx->more && ctx->used)
- goto unlock;
-@@ -432,7 +435,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
- long copied = 0;
-
- lock_sock(sk);
-- msg->msg_namelen = 0;
- for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
- iovlen--, iov++) {
- unsigned long seglen = iov->iov_len;
-diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
-index 272f009..1bdf104 100644
---- a/drivers/atm/idt77252.c
-+++ b/drivers/atm/idt77252.c
-@@ -3511,7 +3511,7 @@ static int init_card(struct atm_dev *dev)
- tmp = dev_get_by_name(&init_net, tname); /* jhs: was "tmp = dev_get(tname);" */
- if (tmp) {
- memcpy(card->atmdev->esi, tmp->dev_addr, 6);
--
-+ dev_put(tmp);
- printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
- }
- /*
-diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
-index c73fc2b..18c5b9b 100644
---- a/drivers/connector/cn_proc.c
-+++ b/drivers/connector/cn_proc.c
-@@ -32,11 +32,23 @@
- #include <linux/atomic.h>
- #include <linux/pid_namespace.h>
-
--#include <asm/unaligned.h>
--
- #include <linux/cn_proc.h>
-
--#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
-+/*
-+ * Size of a cn_msg followed by a proc_event structure. Since the
-+ * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we
-+ * add one 4-byte word to the size here, and then start the actual
-+ * cn_msg structure 4 bytes into the stack buffer. The result is that
-+ * the immediately following proc_event structure is aligned to 8 bytes.
-+ */
-+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4)
-+
-+/* See comment above; we test our assumption about sizeof struct cn_msg here. */
-+static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer)
-+{
-+ BUILD_BUG_ON(sizeof(struct cn_msg) != 20);
-+ return (struct cn_msg *)(buffer + 4);
-+}
-
- static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
- static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
-@@ -56,19 +68,19 @@ void proc_fork_connector(struct task_struct *task)
- {
- struct cn_msg *msg;
- struct proc_event *ev;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
- struct task_struct *parent;
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_FORK;
- rcu_read_lock();
- parent = rcu_dereference(task->real_parent);
-@@ -91,17 +103,17 @@ void proc_exec_connector(struct task_struct *task)
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_EXEC;
- ev->event_data.exec.process_pid = task->pid;
- ev->event_data.exec.process_tgid = task->tgid;
-@@ -117,14 +129,14 @@ void proc_id_connector(struct task_struct *task, int which_id)
- {
- struct cn_msg *msg;
- struct proc_event *ev;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
- const struct cred *cred;
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- ev->what = which_id;
-@@ -145,7 +157,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
- rcu_read_unlock();
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
-
- memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
- msg->ack = 0; /* not used */
-@@ -159,17 +171,17 @@ void proc_sid_connector(struct task_struct *task)
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_SID;
- ev->event_data.sid.process_pid = task->pid;
- ev->event_data.sid.process_tgid = task->tgid;
-@@ -186,17 +198,17 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_PTRACE;
- ev->event_data.ptrace.process_pid = task->pid;
- ev->event_data.ptrace.process_tgid = task->tgid;
-@@ -221,17 +233,17 @@ void proc_comm_connector(struct task_struct *task)
- struct cn_msg *msg;
- struct proc_event *ev;
- struct timespec ts;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_COMM;
- ev->event_data.comm.process_pid = task->pid;
- ev->event_data.comm.process_tgid = task->tgid;
-@@ -248,18 +260,18 @@ void proc_coredump_connector(struct task_struct *task)
- {
- struct cn_msg *msg;
- struct proc_event *ev;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_COREDUMP;
- ev->event_data.coredump.process_pid = task->pid;
- ev->event_data.coredump.process_tgid = task->tgid;
-@@ -275,18 +287,18 @@ void proc_exit_connector(struct task_struct *task)
- {
- struct cn_msg *msg;
- struct proc_event *ev;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- get_seq(&msg->seq, &ev->cpu);
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->what = PROC_EVENT_EXIT;
- ev->event_data.exit.process_pid = task->pid;
- ev->event_data.exit.process_tgid = task->tgid;
-@@ -312,18 +324,18 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
- {
- struct cn_msg *msg;
- struct proc_event *ev;
-- __u8 buffer[CN_PROC_MSG_SIZE];
-+ __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
- struct timespec ts;
-
- if (atomic_read(&proc_event_num_listeners) < 1)
- return;
-
-- msg = (struct cn_msg *)buffer;
-+ msg = buffer_to_cn_msg(buffer);
- ev = (struct proc_event *)msg->data;
- memset(&ev->event_data, 0, sizeof(ev->event_data));
- msg->seq = rcvd_seq;
- ktime_get_ts(&ts); /* get high res monotonic timestamp */
-- put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
-+ ev->timestamp_ns = timespec_to_ns(&ts);
- ev->cpu = -1;
- ev->what = PROC_EVENT_NONE;
- ev->event_data.ack.err = err;
-diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
-index 06022e3..615c5b2 100644
---- a/drivers/gpu/drm/radeon/r600_hdmi.c
-+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
-@@ -24,6 +24,7 @@
- * Authors: Christian König
- */
- #include <linux/hdmi.h>
-+#include <linux/gcd.h>
- #include <drm/drmP.h>
- #include <drm/radeon_drm.h>
- #include "radeon.h"
-@@ -57,35 +58,57 @@ enum r600_hdmi_iec_status_bits {
- static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
- /* 32kHz 44.1kHz 48kHz */
- /* Clock N CTS N CTS N CTS */
-- { 25175, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
-+ { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
- { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
- { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
- { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
- { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
- { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
-- { 74176, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */
-+ { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
- { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
-- { 148352, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */
-+ { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
- { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
-- { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */
- };
-
-+
- /*
-- * calculate CTS value if it's not found in the table
-+ * calculate CTS and N values if they are not found in the table
- */
--static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int N, int freq)
-+static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
- {
-- u64 n;
-- u32 d;
--
-- if (*CTS == 0) {
-- n = (u64)clock * (u64)N * 1000ULL;
-- d = 128 * freq;
-- do_div(n, d);
-- *CTS = n;
-- }
-- DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
-- N, *CTS, freq);
-+ int n, cts;
-+ unsigned long div, mul;
-+
-+ /* Safe, but overly large values */
-+ n = 128 * freq;
-+ cts = clock * 1000;
-+
-+ /* Smallest valid fraction */
-+ div = gcd(n, cts);
-+
-+ n /= div;
-+ cts /= div;
-+
-+ /*
-+ * The optimal N is 128*freq/1000. Calculate the closest larger
-+ * value that doesn't truncate any bits.
-+ */
-+ mul = ((128*freq/1000) + (n-1))/n;
-+
-+ n *= mul;
-+ cts *= mul;
-+
-+ /* Check that we are in spec (not always possible) */
-+ if (n < (128*freq/1500))
-+ printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
-+ if (n > (128*freq/300))
-+ printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
-+
-+ *N = n;
-+ *CTS = cts;
-+
-+ DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
-+ *N, *CTS, freq);
- }
-
- struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
-@@ -93,15 +116,16 @@ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
- struct radeon_hdmi_acr res;
- u8 i;
-
-- for (i = 0; r600_hdmi_predefined_acr[i].clock != clock &&
-- r600_hdmi_predefined_acr[i].clock != 0; i++)
-- ;
-- res = r600_hdmi_predefined_acr[i];
-+ /* Precalculated values for common clocks */
-+ for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) {
-+ if (r600_hdmi_predefined_acr[i].clock == clock)
-+ return r600_hdmi_predefined_acr[i];
-+ }
-
-- /* In case some CTS are missing */
-- r600_hdmi_calc_cts(clock, &res.cts_32khz, res.n_32khz, 32000);
-- r600_hdmi_calc_cts(clock, &res.cts_44_1khz, res.n_44_1khz, 44100);
-- r600_hdmi_calc_cts(clock, &res.cts_48khz, res.n_48khz, 48000);
-+ /* And odd clocks get manually calculated */
-+ r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
-+ r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
-+ r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
-
- return res;
- }
-diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
-index f042a6c..55e4920 100644
---- a/drivers/hid/hid-elo.c
-+++ b/drivers/hid/hid-elo.c
-@@ -181,7 +181,40 @@ fail:
- */
- static bool elo_broken_firmware(struct usb_device *dev)
- {
-- return use_fw_quirk && le16_to_cpu(dev->descriptor.bcdDevice) == 0x10d;
-+ struct usb_device *hub = dev->parent;
-+ struct usb_device *child = NULL;
-+ u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice);
-+ u16 child_vid, child_pid;
-+ int i;
-+
-+ if (!use_fw_quirk)
-+ return false;
-+ if (fw_lvl != 0x10d)
-+ return false;
-+
-+ /* iterate sibling devices of the touch controller */
-+ usb_hub_for_each_child(hub, i, child) {
-+ child_vid = le16_to_cpu(child->descriptor.idVendor);
-+ child_pid = le16_to_cpu(child->descriptor.idProduct);
-+
-+ /*
-+ * If one of the devices below is present attached as a sibling of
-+ * the touch controller then this is a newer IBM 4820 monitor that
-+ * does not need the IBM-requested workaround if fw level is
-+ * 0x010d - aka 'M'.
-+ * No other HW can have this combination.
-+ */
-+ if (child_vid==0x04b3) {
-+ switch (child_pid) {
-+ case 0x4676: /* 4820 21x Video */
-+ case 0x4677: /* 4820 51x Video */
-+ case 0x4678: /* 4820 2Lx Video */
-+ case 0x4679: /* 4820 5Lx Video */
-+ return false;
-+ }
-+ }
-+ }
-+ return true;
- }
-
- static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
-diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
-index 1bfd292..06eb45f 100644
---- a/drivers/hid/hid-lg.c
-+++ b/drivers/hid/hid-lg.c
-@@ -47,6 +47,7 @@
- #define DFP_RDESC_ORIG_SIZE 97
- #define FV_RDESC_ORIG_SIZE 130
- #define MOMO_RDESC_ORIG_SIZE 87
-+#define MOMO2_RDESC_ORIG_SIZE 87
-
- /* Fixed report descriptors for Logitech Driving Force (and Pro)
- * wheel controllers
-@@ -284,6 +285,54 @@ static __u8 momo_rdesc_fixed[] = {
- 0xC0 /* End Collection */
- };
-
-+static __u8 momo2_rdesc_fixed[] = {
-+0x05, 0x01, /* Usage Page (Desktop), */
-+0x09, 0x04, /* Usage (Joystik), */
-+0xA1, 0x01, /* Collection (Application), */
-+0xA1, 0x02, /* Collection (Logical), */
-+0x95, 0x01, /* Report Count (1), */
-+0x75, 0x0A, /* Report Size (10), */
-+0x15, 0x00, /* Logical Minimum (0), */
-+0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
-+0x35, 0x00, /* Physical Minimum (0), */
-+0x46, 0xFF, 0x03, /* Physical Maximum (1023), */
-+0x09, 0x30, /* Usage (X), */
-+0x81, 0x02, /* Input (Variable), */
-+0x95, 0x0A, /* Report Count (10), */
-+0x75, 0x01, /* Report Size (1), */
-+0x25, 0x01, /* Logical Maximum (1), */
-+0x45, 0x01, /* Physical Maximum (1), */
-+0x05, 0x09, /* Usage Page (Button), */
-+0x19, 0x01, /* Usage Minimum (01h), */
-+0x29, 0x0A, /* Usage Maximum (0Ah), */
-+0x81, 0x02, /* Input (Variable), */
-+0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
-+0x09, 0x00, /* Usage (00h), */
-+0x95, 0x04, /* Report Count (4), */
-+0x81, 0x02, /* Input (Variable), */
-+0x95, 0x01, /* Report Count (1), */
-+0x75, 0x08, /* Report Size (8), */
-+0x26, 0xFF, 0x00, /* Logical Maximum (255), */
-+0x46, 0xFF, 0x00, /* Physical Maximum (255), */
-+0x09, 0x01, /* Usage (01h), */
-+0x81, 0x02, /* Input (Variable), */
-+0x05, 0x01, /* Usage Page (Desktop), */
-+0x09, 0x31, /* Usage (Y), */
-+0x81, 0x02, /* Input (Variable), */
-+0x09, 0x32, /* Usage (Z), */
-+0x81, 0x02, /* Input (Variable), */
-+0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
-+0x09, 0x00, /* Usage (00h), */
-+0x81, 0x02, /* Input (Variable), */
-+0xC0, /* End Collection, */
-+0xA1, 0x02, /* Collection (Logical), */
-+0x09, 0x02, /* Usage (02h), */
-+0x95, 0x07, /* Report Count (7), */
-+0x91, 0x02, /* Output (Variable), */
-+0xC0, /* End Collection, */
-+0xC0 /* End Collection */
-+};
-+
- /*
- * Certain Logitech keyboards send in report #3 keys which are far
- * above the logical maximum described in descriptor. This extends
-@@ -343,6 +392,15 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
- }
- break;
-
-+ case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
-+ if (*rsize == MOMO2_RDESC_ORIG_SIZE) {
-+ hid_info(hdev,
-+ "fixing up Logitech Momo Racing Force (Black) report descriptor\n");
-+ rdesc = momo2_rdesc_fixed;
-+ *rsize = sizeof(momo2_rdesc_fixed);
-+ }
-+ break;
-+
- case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
- if (*rsize == FV_RDESC_ORIG_SIZE) {
- hid_info(hdev,
-diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
-index 15e9b57..40203ad 100644
---- a/drivers/iommu/intel-iommu.c
-+++ b/drivers/iommu/intel-iommu.c
-@@ -782,7 +782,11 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
- int offset;
-
- BUG_ON(!domain->pgd);
-- BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
-+
-+ if (addr_width < BITS_PER_LONG && pfn >> addr_width)
-+ /* Address beyond IOMMU's addressing capabilities. */
-+ return NULL;
-+
- parent = domain->pgd;
-
- while (level > 0) {
-diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
-index f71673d..b97d70b 100644
---- a/drivers/iommu/intel_irq_remapping.c
-+++ b/drivers/iommu/intel_irq_remapping.c
-@@ -525,12 +525,13 @@ static int __init intel_irq_remapping_supported(void)
- if (disable_irq_remap)
- return 0;
- if (irq_remap_broken) {
-- WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
-- "This system BIOS has enabled interrupt remapping\n"
-- "on a chipset that contains an erratum making that\n"
-- "feature unstable. To maintain system stability\n"
-- "interrupt remapping is being disabled. Please\n"
-- "contact your BIOS vendor for an update\n");
-+ printk(KERN_WARNING
-+ "This system BIOS has enabled interrupt remapping\n"
-+ "on a chipset that contains an erratum making that\n"
-+ "feature unstable. To maintain system stability\n"
-+ "interrupt remapping is being disabled. Please\n"
-+ "contact your BIOS vendor for an update\n");
-+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
- disable_irq_remap = 1;
- return 0;
- }
-diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
-index baf2686..02125e6 100644
---- a/drivers/isdn/isdnloop/isdnloop.c
-+++ b/drivers/isdn/isdnloop/isdnloop.c
-@@ -1083,8 +1083,10 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
- spin_unlock_irqrestore(&card->isdnloop_lock, flags);
- return -ENOMEM;
- }
-- for (i = 0; i < 3; i++)
-- strcpy(card->s0num[i], sdef.num[i]);
-+ for (i = 0; i < 3; i++) {
-+ strlcpy(card->s0num[i], sdef.num[i],
-+ sizeof(card->s0num[0]));
-+ }
- break;
- case ISDN_PTYPE_1TR6:
- if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
-@@ -1097,7 +1099,7 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
- spin_unlock_irqrestore(&card->isdnloop_lock, flags);
- return -ENOMEM;
- }
-- strcpy(card->s0num[0], sdef.num[0]);
-+ strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0]));
- card->s0num[1][0] = '\0';
- card->s0num[2][0] = '\0';
- break;
-diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
-index e47dcb9..5cefb47 100644
---- a/drivers/isdn/mISDN/socket.c
-+++ b/drivers/isdn/mISDN/socket.c
-@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- {
- struct sk_buff *skb;
- struct sock *sk = sock->sk;
-- struct sockaddr_mISDN *maddr;
-
- int copied, err;
-
-@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (!skb)
- return err;
-
-- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
-- msg->msg_namelen = sizeof(struct sockaddr_mISDN);
-- maddr = (struct sockaddr_mISDN *)msg->msg_name;
-+ if (msg->msg_name) {
-+ struct sockaddr_mISDN *maddr = msg->msg_name;
-+
- maddr->family = AF_ISDN;
- maddr->dev = _pms(sk)->dev->id;
- if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
-@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- maddr->sapi = _pms(sk)->ch.addr & 0xFF;
- maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
- }
-- } else {
-- if (msg->msg_namelen)
-- printk(KERN_WARNING "%s: too small namelen %d\n",
-- __func__, msg->msg_namelen);
-- msg->msg_namelen = 0;
-+ msg->msg_namelen = sizeof(*maddr);
- }
-
- copied = skb->len + MISDN_HEADER_LEN;
-diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
-index e4109f6..8a0665d 100644
---- a/drivers/md/raid5.c
-+++ b/drivers/md/raid5.c
-@@ -5214,15 +5214,18 @@ raid5_show_group_thread_cnt(struct mddev *mddev, char *page)
- return 0;
- }
-
--static int alloc_thread_groups(struct r5conf *conf, int cnt);
-+static int alloc_thread_groups(struct r5conf *conf, int cnt,
-+ int *group_cnt,
-+ int *worker_cnt_per_group,
-+ struct r5worker_group **worker_groups);
- static ssize_t
- raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
- {
- struct r5conf *conf = mddev->private;
- unsigned long new;
- int err;
-- struct r5worker_group *old_groups;
-- int old_group_cnt;
-+ struct r5worker_group *new_groups, *old_groups;
-+ int group_cnt, worker_cnt_per_group;
-
- if (len >= PAGE_SIZE)
- return -EINVAL;
-@@ -5238,17 +5241,19 @@ raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)
- mddev_suspend(mddev);
-
- old_groups = conf->worker_groups;
-- old_group_cnt = conf->worker_cnt_per_group;
--
- if (old_groups)
- flush_workqueue(raid5_wq);
-
-- conf->worker_groups = NULL;
-- err = alloc_thread_groups(conf, new);
-- if (err) {
-- conf->worker_groups = old_groups;
-- conf->worker_cnt_per_group = old_group_cnt;
-- } else {
-+ err = alloc_thread_groups(conf, new,
-+ &group_cnt, &worker_cnt_per_group,
-+ &new_groups);
-+ if (!err) {
-+ spin_lock_irq(&conf->device_lock);
-+ conf->group_cnt = group_cnt;
-+ conf->worker_cnt_per_group = worker_cnt_per_group;
-+ conf->worker_groups = new_groups;
-+ spin_unlock_irq(&conf->device_lock);
-+
- if (old_groups)
- kfree(old_groups[0].workers);
- kfree(old_groups);
-@@ -5278,33 +5283,36 @@ static struct attribute_group raid5_attrs_group = {
- .attrs = raid5_attrs,
- };
-
--static int alloc_thread_groups(struct r5conf *conf, int cnt)
-+static int alloc_thread_groups(struct r5conf *conf, int cnt,
-+ int *group_cnt,
-+ int *worker_cnt_per_group,
-+ struct r5worker_group **worker_groups)
- {
- int i, j;
- ssize_t size;
- struct r5worker *workers;
-
-- conf->worker_cnt_per_group = cnt;
-+ *worker_cnt_per_group = cnt;
- if (cnt == 0) {
-- conf->worker_groups = NULL;
-+ *group_cnt = 0;
-+ *worker_groups = NULL;
- return 0;
- }
-- conf->group_cnt = num_possible_nodes();
-+ *group_cnt = num_possible_nodes();
- size = sizeof(struct r5worker) * cnt;
-- workers = kzalloc(size * conf->group_cnt, GFP_NOIO);
-- conf->worker_groups = kzalloc(sizeof(struct r5worker_group) *
-- conf->group_cnt, GFP_NOIO);
-- if (!conf->worker_groups || !workers) {
-+ workers = kzalloc(size * *group_cnt, GFP_NOIO);
-+ *worker_groups = kzalloc(sizeof(struct r5worker_group) *
-+ *group_cnt, GFP_NOIO);
-+ if (!*worker_groups || !workers) {
- kfree(workers);
-- kfree(conf->worker_groups);
-- conf->worker_groups = NULL;
-+ kfree(*worker_groups);
- return -ENOMEM;
- }
-
-- for (i = 0; i < conf->group_cnt; i++) {
-+ for (i = 0; i < *group_cnt; i++) {
- struct r5worker_group *group;
-
-- group = &conf->worker_groups[i];
-+ group = &(*worker_groups)[i];
- INIT_LIST_HEAD(&group->handle_list);
- group->conf = conf;
- group->workers = workers + i * cnt;
-@@ -5462,6 +5470,8 @@ static struct r5conf *setup_conf(struct mddev *mddev)
- struct md_rdev *rdev;
- struct disk_info *disk;
- char pers_name[6];
-+ int group_cnt, worker_cnt_per_group;
-+ struct r5worker_group *new_group;
-
- if (mddev->new_level != 5
- && mddev->new_level != 4
-@@ -5496,7 +5506,12 @@ static struct r5conf *setup_conf(struct mddev *mddev)
- if (conf == NULL)
- goto abort;
- /* Don't enable multi-threading by default*/
-- if (alloc_thread_groups(conf, 0))
-+ if (!alloc_thread_groups(conf, 0, &group_cnt, &worker_cnt_per_group,
-+ &new_group)) {
-+ conf->group_cnt = group_cnt;
-+ conf->worker_cnt_per_group = worker_cnt_per_group;
-+ conf->worker_groups = new_group;
-+ } else
- goto abort;
- spin_lock_init(&conf->device_lock);
- seqcount_init(&conf->gen_lock);
-diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
-index e883bfe..dd8057d 100644
---- a/drivers/net/bonding/bond_main.c
-+++ b/drivers/net/bonding/bond_main.c
-@@ -3395,20 +3395,20 @@ static void bond_set_rx_mode(struct net_device *bond_dev)
- struct bonding *bond = netdev_priv(bond_dev);
- struct slave *slave;
-
-- ASSERT_RTNL();
--
-+ rcu_read_lock();
- if (USES_PRIMARY(bond->params.mode)) {
-- slave = rtnl_dereference(bond->curr_active_slave);
-+ slave = rcu_dereference(bond->curr_active_slave);
- if (slave) {
- dev_uc_sync(slave->dev, bond_dev);
- dev_mc_sync(slave->dev, bond_dev);
- }
- } else {
-- bond_for_each_slave(bond, slave) {
-+ bond_for_each_slave_rcu(bond, slave) {
- dev_uc_sync_multiple(slave->dev, bond_dev);
- dev_mc_sync_multiple(slave->dev, bond_dev);
- }
- }
-+ rcu_read_unlock();
- }
-
- static int bond_neigh_init(struct neighbour *n)
-diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
-index c29b836..b60f95b 100644
---- a/drivers/net/bonding/bond_sysfs.c
-+++ b/drivers/net/bonding/bond_sysfs.c
-@@ -587,8 +587,9 @@ static ssize_t bonding_store_arp_interval(struct device *d,
- goto out;
- }
- if (bond->params.mode == BOND_MODE_ALB ||
-- bond->params.mode == BOND_MODE_TLB) {
-- pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n",
-+ bond->params.mode == BOND_MODE_TLB ||
-+ bond->params.mode == BOND_MODE_8023AD) {
-+ pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
- bond->dev->name, bond->dev->name);
- ret = -EINVAL;
- goto out;
-@@ -759,6 +760,8 @@ static ssize_t bonding_store_downdelay(struct device *d,
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
-+ if (!rtnl_trylock())
-+ return restart_syscall();
- if (!(bond->params.miimon)) {
- pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
- bond->dev->name);
-@@ -792,6 +795,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
- }
-
- out:
-+ rtnl_unlock();
- return ret;
- }
- static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
-@@ -814,6 +818,8 @@ static ssize_t bonding_store_updelay(struct device *d,
- int new_value, ret = count;
- struct bonding *bond = to_bond(d);
-
-+ if (!rtnl_trylock())
-+ return restart_syscall();
- if (!(bond->params.miimon)) {
- pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
- bond->dev->name);
-@@ -847,6 +853,7 @@ static ssize_t bonding_store_updelay(struct device *d,
- }
-
- out:
-+ rtnl_unlock();
- return ret;
- }
- static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
-diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
-index 2c210ec..f2f6d85 100644
---- a/drivers/net/ethernet/marvell/mv643xx_eth.c
-+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
-@@ -2890,6 +2890,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
- PHY_INTERFACE_MODE_GMII);
- if (!mp->phy)
- err = -ENODEV;
-+ else
-+ phy_addr_set(mp, mp->phy->addr);
- } else if (pd->phy_addr != MV643XX_ETH_PHY_NONE) {
- mp->phy = phy_scan(mp, pd->phy_addr);
-
-diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
-index a071cda..0d087b0 100644
---- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
-+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
-@@ -264,6 +264,10 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
- mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
- mdev->port_cnt++;
-
-+ /* Initialize time stamp mechanism */
-+ if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
-+ mlx4_en_init_timestamp(mdev);
-+
- mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
- if (!dev->caps.comp_pool) {
- mdev->profile.prof[i].rx_ring_num =
-@@ -301,10 +305,6 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
- mdev->pndev[i] = NULL;
- }
-
-- /* Initialize time stamp mechanism */
-- if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_TS)
-- mlx4_en_init_timestamp(mdev);
--
- return mdev;
-
- err_mr:
-diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
-index d2e5919..0095af5 100644
---- a/drivers/net/ethernet/realtek/8139cp.c
-+++ b/drivers/net/ethernet/realtek/8139cp.c
-@@ -678,9 +678,6 @@ static void cp_tx (struct cp_private *cp)
- le32_to_cpu(txd->opts1) & 0xffff,
- PCI_DMA_TODEVICE);
-
-- bytes_compl += skb->len;
-- pkts_compl++;
--
- if (status & LastFrag) {
- if (status & (TxError | TxFIFOUnder)) {
- netif_dbg(cp, tx_err, cp->dev,
-@@ -702,6 +699,8 @@ static void cp_tx (struct cp_private *cp)
- netif_dbg(cp, tx_done, cp->dev,
- "tx done, slot %d\n", tx_tail);
- }
-+ bytes_compl += skb->len;
-+ pkts_compl++;
- dev_kfree_skb_irq(skb);
- }
-
-diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
-index 3397cee..fb3f8dc 100644
---- a/drivers/net/ethernet/realtek/r8169.c
-+++ b/drivers/net/ethernet/realtek/r8169.c
-@@ -3465,6 +3465,11 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
- rtl_writephy(tp, 0x14, 0x9065);
- rtl_writephy(tp, 0x14, 0x1065);
-
-+ /* Check ALDPS bit, disable it if enabled */
-+ rtl_writephy(tp, 0x1f, 0x0a43);
-+ if (rtl_readphy(tp, 0x10) & 0x0004)
-+ rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
-+
- rtl_writephy(tp, 0x1f, 0x0000);
- }
-
-diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
-index 98eedb9..fc3e25c 100644
---- a/drivers/net/ethernet/smsc/smc91x.h
-+++ b/drivers/net/ethernet/smsc/smc91x.h
-@@ -46,7 +46,8 @@
- defined(CONFIG_MACH_LITTLETON) ||\
- defined(CONFIG_MACH_ZYLONITE2) ||\
- defined(CONFIG_ARCH_VIPER) ||\
-- defined(CONFIG_MACH_STARGATE2)
-+ defined(CONFIG_MACH_STARGATE2) ||\
-+ defined(CONFIG_ARCH_VERSATILE)
-
- #include <asm/mach-types.h>
-
-@@ -154,6 +155,8 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
- #define SMC_outl(v, a, r) writel(v, (a) + (r))
- #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
- #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
-+#define SMC_insw(a, r, p, l) readsw((a) + (r), p, l)
-+#define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l)
- #define SMC_IRQ_FLAGS (-1) /* from resource */
-
- /* We actually can't write halfwords properly if not word aligned */
-@@ -206,23 +209,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
- #define RPC_LSA_DEFAULT RPC_LED_TX_RX
- #define RPC_LSB_DEFAULT RPC_LED_100_10
-
--#elif defined(CONFIG_ARCH_VERSATILE)
--
--#define SMC_CAN_USE_8BIT 1
--#define SMC_CAN_USE_16BIT 1
--#define SMC_CAN_USE_32BIT 1
--#define SMC_NOWAIT 1
--
--#define SMC_inb(a, r) readb((a) + (r))
--#define SMC_inw(a, r) readw((a) + (r))
--#define SMC_inl(a, r) readl((a) + (r))
--#define SMC_outb(v, a, r) writeb(v, (a) + (r))
--#define SMC_outw(v, a, r) writew(v, (a) + (r))
--#define SMC_outl(v, a, r) writel(v, (a) + (r))
--#define SMC_insl(a, r, p, l) readsl((a) + (r), p, l)
--#define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l)
--#define SMC_IRQ_FLAGS (-1) /* from resource */
--
- #elif defined(CONFIG_MN10300)
-
- /*
-diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
-index d022bf9..ad61d26 100644
---- a/drivers/net/ethernet/via/via-velocity.c
-+++ b/drivers/net/ethernet/via/via-velocity.c
-@@ -2172,16 +2172,13 @@ static int velocity_poll(struct napi_struct *napi, int budget)
- unsigned int rx_done;
- unsigned long flags;
-
-- spin_lock_irqsave(&vptr->lock, flags);
- /*
- * Do rx and tx twice for performance (taken from the VIA
- * out-of-tree driver).
- */
-- rx_done = velocity_rx_srv(vptr, budget / 2);
-- velocity_tx_srv(vptr);
-- rx_done += velocity_rx_srv(vptr, budget - rx_done);
-+ rx_done = velocity_rx_srv(vptr, budget);
-+ spin_lock_irqsave(&vptr->lock, flags);
- velocity_tx_srv(vptr);
--
- /* If budget not fully consumed, exit the polling mode */
- if (rx_done < budget) {
- napi_complete(napi);
-@@ -2342,6 +2339,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
- if (ret < 0)
- goto out_free_tmp_vptr_1;
-
-+ napi_disable(&vptr->napi);
-+
- spin_lock_irqsave(&vptr->lock, flags);
-
- netif_stop_queue(dev);
-@@ -2362,6 +2361,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
-
- velocity_give_many_rx_descs(vptr);
-
-+ napi_enable(&vptr->napi);
-+
- mac_enable_int(vptr->mac_regs);
- netif_start_queue(dev);
-
-diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
-index 9dccb1e..dc76670 100644
---- a/drivers/net/macvtap.c
-+++ b/drivers/net/macvtap.c
-@@ -628,6 +628,7 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
- const struct iovec *iv, unsigned long total_len,
- size_t count, int noblock)
- {
-+ int good_linear = SKB_MAX_HEAD(NET_IP_ALIGN);
- struct sk_buff *skb;
- struct macvlan_dev *vlan;
- unsigned long len = total_len;
-@@ -670,6 +671,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
-
- if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
- copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
-+ if (copylen > good_linear)
-+ copylen = good_linear;
- linear = copylen;
- if (iov_pages(iv, vnet_hdr_len + copylen, count)
- <= MAX_SKB_FRAGS)
-@@ -678,7 +681,10 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
-
- if (!zerocopy) {
- copylen = len;
-- linear = vnet_hdr.hdr_len;
-+ if (vnet_hdr.hdr_len > good_linear)
-+ linear = good_linear;
-+ else
-+ linear = vnet_hdr.hdr_len;
- }
-
- skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, copylen,
-diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
-index 5f66e30..82ee6ed 100644
---- a/drivers/net/ppp/pppoe.c
-+++ b/drivers/net/ppp/pppoe.c
-@@ -979,8 +979,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (error < 0)
- goto end;
-
-- m->msg_namelen = 0;
--
- if (skb) {
- total_len = min_t(size_t, total_len, skb->len);
- error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
-diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
-index 50e43e6..6327df2 100644
---- a/drivers/net/team/team.c
-+++ b/drivers/net/team/team.c
-@@ -1366,6 +1366,8 @@ static int team_user_linkup_option_get(struct team *team,
- return 0;
- }
-
-+static void __team_carrier_check(struct team *team);
-+
- static int team_user_linkup_option_set(struct team *team,
- struct team_gsetter_ctx *ctx)
- {
-@@ -1373,6 +1375,7 @@ static int team_user_linkup_option_set(struct team *team,
-
- port->user.linkup = ctx->data.bool_val;
- team_refresh_port_linkup(port);
-+ __team_carrier_check(port->team);
- return 0;
- }
-
-@@ -1392,6 +1395,7 @@ static int team_user_linkup_en_option_set(struct team *team,
-
- port->user.linkup_enabled = ctx->data.bool_val;
- team_refresh_port_linkup(port);
-+ __team_carrier_check(port->team);
- return 0;
- }
-
-diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index 7cb105c..782e38b 100644
---- a/drivers/net/tun.c
-+++ b/drivers/net/tun.c
-@@ -981,6 +981,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
- struct sk_buff *skb;
- size_t len = total_len, align = NET_SKB_PAD, linear;
- struct virtio_net_hdr gso = { 0 };
-+ int good_linear;
- int offset = 0;
- int copylen;
- bool zerocopy = false;
-@@ -1021,12 +1022,16 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
- return -EINVAL;
- }
-
-+ good_linear = SKB_MAX_HEAD(align);
-+
- if (msg_control) {
- /* There are 256 bytes to be copied in skb, so there is
- * enough room for skb expand head in case it is used.
- * The rest of the buffer is mapped from userspace.
- */
- copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN;
-+ if (copylen > good_linear)
-+ copylen = good_linear;
- linear = copylen;
- if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS)
- zerocopy = true;
-@@ -1034,7 +1039,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
-
- if (!zerocopy) {
- copylen = len;
-- linear = gso.hdr_len;
-+ if (gso.hdr_len > good_linear)
-+ linear = good_linear;
-+ else
-+ linear = gso.hdr_len;
- }
-
- skb = tun_alloc_skb(tfile, align, copylen, linear, noblock);
-diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
-index 90a429b..8494bb5 100644
---- a/drivers/net/usb/usbnet.c
-+++ b/drivers/net/usb/usbnet.c
-@@ -204,9 +204,6 @@ static void intr_complete (struct urb *urb)
- break;
- }
-
-- if (!netif_running (dev->net))
-- return;
--
- status = usb_submit_urb (urb, GFP_ATOMIC);
- if (status != 0)
- netif_err(dev, timer, dev->net,
-diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
-index fa33b5e..e3eb952 100644
---- a/drivers/net/wireless/rt2x00/rt2800.h
-+++ b/drivers/net/wireless/rt2x00/rt2800.h
-@@ -52,6 +52,7 @@
- * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
- * RF5592 2.4G/5G 2T2R
-+ * RF3070 2.4G 1T1R
- * RF5360 2.4G 1T1R
- * RF5370 2.4G 1T1R
- * RF5390 2.4G 1T1R
-@@ -70,6 +71,7 @@
- #define RF3322 0x000c
- #define RF3053 0x000d
- #define RF5592 0x000f
-+#define RF3070 0x3070
- #define RF3290 0x3290
- #define RF5360 0x5360
- #define RF5370 0x5370
-diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
-index 1400787..446eade 100644
---- a/drivers/net/wireless/rt2x00/rt2800lib.c
-+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
-@@ -3152,6 +3152,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
- case RF3322:
- rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
- break;
-+ case RF3070:
- case RF5360:
- case RF5370:
- case RF5372:
-@@ -3166,7 +3167,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
- rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
- }
-
-- if (rt2x00_rf(rt2x00dev, RF3290) ||
-+ if (rt2x00_rf(rt2x00dev, RF3070) ||
-+ rt2x00_rf(rt2x00dev, RF3290) ||
- rt2x00_rf(rt2x00dev, RF3322) ||
- rt2x00_rf(rt2x00dev, RF5360) ||
- rt2x00_rf(rt2x00dev, RF5370) ||
-@@ -4264,6 +4266,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
- rt2800_rfcsr_write(rt2x00dev, 7, rfcsr);
- break;
- case RF3053:
-+ case RF3070:
- case RF3290:
- case RF5360:
- case RF5370:
-@@ -7024,6 +7027,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
- case RF3022:
- case RF3052:
- case RF3053:
-+ case RF3070:
- case RF3290:
- case RF3320:
- case RF3322:
-@@ -7546,6 +7550,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
- rt2x00_rf(rt2x00dev, RF2020) ||
- rt2x00_rf(rt2x00dev, RF3021) ||
- rt2x00_rf(rt2x00dev, RF3022) ||
-+ rt2x00_rf(rt2x00dev, RF3070) ||
- rt2x00_rf(rt2x00dev, RF3290) ||
- rt2x00_rf(rt2x00dev, RF3320) ||
- rt2x00_rf(rt2x00dev, RF3322) ||
-@@ -7674,6 +7679,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
- case RF3320:
- case RF3052:
- case RF3053:
-+ case RF3070:
- case RF3290:
- case RF5360:
- case RF5370:
-diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
-index 900da4b..6255850 100644
---- a/drivers/net/xen-netback/netback.c
-+++ b/drivers/net/xen-netback/netback.c
-@@ -39,6 +39,7 @@
- #include <linux/udp.h>
-
- #include <net/tcp.h>
-+#include <net/ip6_checksum.h>
-
- #include <xen/xen.h>
- #include <xen/events.h>
-diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
-index ed0834e..ab69245 100644
---- a/drivers/usb/musb/davinci.c
-+++ b/drivers/usb/musb/davinci.c
-@@ -509,7 +509,7 @@ static u64 davinci_dmamask = DMA_BIT_MASK(32);
-
- static int davinci_probe(struct platform_device *pdev)
- {
-- struct resource musb_resources[2];
-+ struct resource musb_resources[3];
- struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev);
- struct platform_device *musb;
- struct davinci_glue *glue;
-@@ -567,6 +567,15 @@ static int davinci_probe(struct platform_device *pdev)
- musb_resources[1].end = pdev->resource[1].end;
- musb_resources[1].flags = pdev->resource[1].flags;
-
-+ /*
-+ * For DM6467 3 resources are passed. A placeholder for the 3rd
-+ * resource is always there, so it's safe to always copy it...
-+ */
-+ musb_resources[2].name = pdev->resource[2].name;
-+ musb_resources[2].start = pdev->resource[2].start;
-+ musb_resources[2].end = pdev->resource[2].end;
-+ musb_resources[2].flags = pdev->resource[2].flags;
-+
- ret = platform_device_add_resources(musb, musb_resources,
- ARRAY_SIZE(musb_resources));
- if (ret) {
-diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c
-index 6ad02f5..3dcf66f 100644
---- a/drivers/usb/wusbcore/wa-xfer.c
-+++ b/drivers/usb/wusbcore/wa-xfer.c
-@@ -91,7 +91,8 @@
- #include "wusbhc.h"
-
- enum {
-- WA_SEGS_MAX = 255,
-+ /* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */
-+ WA_SEGS_MAX = 128,
- };
-
- enum wa_seg_status {
-@@ -446,7 +447,7 @@ static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
- }
- xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
- xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length, xfer->seg_size);
-- if (xfer->segs >= WA_SEGS_MAX) {
-+ if (xfer->segs > WA_SEGS_MAX) {
- dev_err(dev, "BUG? ops, number of segments %d bigger than %d\n",
- (int)(urb->transfer_buffer_length / xfer->seg_size),
- WA_SEGS_MAX);
-diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
-index 6157f74..ec7fc87 100644
---- a/drivers/video/kyro/fbdev.c
-+++ b/drivers/video/kyro/fbdev.c
-@@ -625,15 +625,15 @@ static int kyrofb_ioctl(struct fb_info *info,
- }
- break;
- case KYRO_IOCTL_UVSTRIDE:
-- if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long)))
-+ if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride)))
- return -EFAULT;
- break;
- case KYRO_IOCTL_STRIDE:
-- if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long)))
-+ if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride)))
- return -EFAULT;
- break;
- case KYRO_IOCTL_OVERLAY_OFFSET:
-- if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long)))
-+ if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset)))
- return -EFAULT;
- break;
- }
-diff --git a/fs/aio.c b/fs/aio.c
-index 067e3d3..6efb7f6 100644
---- a/fs/aio.c
-+++ b/fs/aio.c
-@@ -36,10 +36,10 @@
- #include <linux/eventfd.h>
- #include <linux/blkdev.h>
- #include <linux/compat.h>
--#include <linux/anon_inodes.h>
- #include <linux/migrate.h>
- #include <linux/ramfs.h>
- #include <linux/percpu-refcount.h>
-+#include <linux/mount.h>
-
- #include <asm/kmap_types.h>
- #include <asm/uaccess.h>
-@@ -80,6 +80,8 @@ struct kioctx {
- struct percpu_ref users;
- atomic_t dead;
-
-+ struct percpu_ref reqs;
-+
- unsigned long user_id;
-
- struct __percpu kioctx_cpu *cpu;
-@@ -107,7 +109,6 @@ struct kioctx {
- struct page **ring_pages;
- long nr_pages;
-
-- struct rcu_head rcu_head;
- struct work_struct free_work;
-
- struct {
-@@ -152,12 +153,67 @@ unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio request
- static struct kmem_cache *kiocb_cachep;
- static struct kmem_cache *kioctx_cachep;
-
-+static struct vfsmount *aio_mnt;
-+
-+static const struct file_operations aio_ring_fops;
-+static const struct address_space_operations aio_ctx_aops;
-+
-+static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
-+{
-+ struct qstr this = QSTR_INIT("[aio]", 5);
-+ struct file *file;
-+ struct path path;
-+ struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb);
-+ if (IS_ERR(inode))
-+ return ERR_CAST(inode);
-+
-+ inode->i_mapping->a_ops = &aio_ctx_aops;
-+ inode->i_mapping->private_data = ctx;
-+ inode->i_size = PAGE_SIZE * nr_pages;
-+
-+ path.dentry = d_alloc_pseudo(aio_mnt->mnt_sb, &this);
-+ if (!path.dentry) {
-+ iput(inode);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ path.mnt = mntget(aio_mnt);
-+
-+ d_instantiate(path.dentry, inode);
-+ file = alloc_file(&path, FMODE_READ | FMODE_WRITE, &aio_ring_fops);
-+ if (IS_ERR(file)) {
-+ path_put(&path);
-+ return file;
-+ }
-+
-+ file->f_flags = O_RDWR;
-+ file->private_data = ctx;
-+ return file;
-+}
-+
-+static struct dentry *aio_mount(struct file_system_type *fs_type,
-+ int flags, const char *dev_name, void *data)
-+{
-+ static const struct dentry_operations ops = {
-+ .d_dname = simple_dname,
-+ };
-+ return mount_pseudo(fs_type, "aio:", NULL, &ops, 0xa10a10a1);
-+}
-+
- /* aio_setup
- * Creates the slab caches used by the aio routines, panic on
- * failure as this is done early during the boot sequence.
- */
- static int __init aio_setup(void)
- {
-+ static struct file_system_type aio_fs = {
-+ .name = "aio",
-+ .mount = aio_mount,
-+ .kill_sb = kill_anon_super,
-+ };
-+ aio_mnt = kern_mount(&aio_fs);
-+ if (IS_ERR(aio_mnt))
-+ panic("Failed to create aio fs mount.");
-+
- kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC);
- kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC);
-
-@@ -195,8 +251,10 @@ static void aio_free_ring(struct kioctx *ctx)
-
- put_aio_ring_file(ctx);
-
-- if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages)
-+ if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) {
- kfree(ctx->ring_pages);
-+ ctx->ring_pages = NULL;
-+ }
- }
-
- static int aio_ring_mmap(struct file *file, struct vm_area_struct *vma)
-@@ -283,16 +341,12 @@ static int aio_setup_ring(struct kioctx *ctx)
- if (nr_pages < 0)
- return -EINVAL;
-
-- file = anon_inode_getfile_private("[aio]", &aio_ring_fops, ctx, O_RDWR);
-+ file = aio_private_file(ctx, nr_pages);
- if (IS_ERR(file)) {
- ctx->aio_ring_file = NULL;
- return -EAGAIN;
- }
-
-- file->f_inode->i_mapping->a_ops = &aio_ctx_aops;
-- file->f_inode->i_mapping->private_data = ctx;
-- file->f_inode->i_size = PAGE_SIZE * (loff_t)nr_pages;
--
- for (i = 0; i < nr_pages; i++) {
- struct page *page;
- page = find_or_create_page(file->f_inode->i_mapping,
-@@ -313,8 +367,10 @@ static int aio_setup_ring(struct kioctx *ctx)
- if (nr_pages > AIO_RING_PAGES) {
- ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
- GFP_KERNEL);
-- if (!ctx->ring_pages)
-+ if (!ctx->ring_pages) {
-+ put_aio_ring_file(ctx);
- return -ENOMEM;
-+ }
- }
-
- ctx->mmap_size = nr_pages * PAGE_SIZE;
-@@ -412,26 +468,34 @@ static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb)
- return cancel(kiocb);
- }
-
--static void free_ioctx_rcu(struct rcu_head *head)
-+static void free_ioctx(struct work_struct *work)
- {
-- struct kioctx *ctx = container_of(head, struct kioctx, rcu_head);
-+ struct kioctx *ctx = container_of(work, struct kioctx, free_work);
-
-+ pr_debug("freeing %p\n", ctx);
-+
-+ aio_free_ring(ctx);
- free_percpu(ctx->cpu);
- kmem_cache_free(kioctx_cachep, ctx);
- }
-
-+static void free_ioctx_reqs(struct percpu_ref *ref)
-+{
-+ struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
-+
-+ INIT_WORK(&ctx->free_work, free_ioctx);
-+ schedule_work(&ctx->free_work);
-+}
-+
- /*
- * When this function runs, the kioctx has been removed from the "hash table"
- * and ctx->users has dropped to 0, so we know no more kiocbs can be submitted -
- * now it's safe to cancel any that need to be.
- */
--static void free_ioctx(struct work_struct *work)
-+static void free_ioctx_users(struct percpu_ref *ref)
- {
-- struct kioctx *ctx = container_of(work, struct kioctx, free_work);
-- struct aio_ring *ring;
-+ struct kioctx *ctx = container_of(ref, struct kioctx, users);
- struct kiocb *req;
-- unsigned cpu, avail;
-- DEFINE_WAIT(wait);
-
- spin_lock_irq(&ctx->ctx_lock);
-
-@@ -445,54 +509,8 @@ static void free_ioctx(struct work_struct *work)
-
- spin_unlock_irq(&ctx->ctx_lock);
-
-- for_each_possible_cpu(cpu) {
-- struct kioctx_cpu *kcpu = per_cpu_ptr(ctx->cpu, cpu);
--
-- atomic_add(kcpu->reqs_available, &ctx->reqs_available);
-- kcpu->reqs_available = 0;
-- }
--
-- while (1) {
-- prepare_to_wait(&ctx->wait, &wait, TASK_UNINTERRUPTIBLE);
--
-- ring = kmap_atomic(ctx->ring_pages[0]);
-- avail = (ring->head <= ring->tail)
-- ? ring->tail - ring->head
-- : ctx->nr_events - ring->head + ring->tail;
--
-- atomic_add(avail, &ctx->reqs_available);
-- ring->head = ring->tail;
-- kunmap_atomic(ring);
--
-- if (atomic_read(&ctx->reqs_available) >= ctx->nr_events - 1)
-- break;
--
-- schedule();
-- }
-- finish_wait(&ctx->wait, &wait);
--
-- WARN_ON(atomic_read(&ctx->reqs_available) > ctx->nr_events - 1);
--
-- aio_free_ring(ctx);
--
-- pr_debug("freeing %p\n", ctx);
--
-- /*
-- * Here the call_rcu() is between the wait_event() for reqs_active to
-- * hit 0, and freeing the ioctx.
-- *
-- * aio_complete() decrements reqs_active, but it has to touch the ioctx
-- * after to issue a wakeup so we use rcu.
-- */
-- call_rcu(&ctx->rcu_head, free_ioctx_rcu);
--}
--
--static void free_ioctx_ref(struct percpu_ref *ref)
--{
-- struct kioctx *ctx = container_of(ref, struct kioctx, users);
--
-- INIT_WORK(&ctx->free_work, free_ioctx);
-- schedule_work(&ctx->free_work);
-+ percpu_ref_kill(&ctx->reqs);
-+ percpu_ref_put(&ctx->reqs);
- }
-
- static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
-@@ -551,6 +569,16 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
- }
- }
-
-+static void aio_nr_sub(unsigned nr)
-+{
-+ spin_lock(&aio_nr_lock);
-+ if (WARN_ON(aio_nr - nr > aio_nr))
-+ aio_nr = 0;
-+ else
-+ aio_nr -= nr;
-+ spin_unlock(&aio_nr_lock);
-+}
-+
- /* ioctx_alloc
- * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed.
- */
-@@ -588,8 +616,11 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
-
- ctx->max_reqs = nr_events;
-
-- if (percpu_ref_init(&ctx->users, free_ioctx_ref))
-- goto out_freectx;
-+ if (percpu_ref_init(&ctx->users, free_ioctx_users))
-+ goto err;
-+
-+ if (percpu_ref_init(&ctx->reqs, free_ioctx_reqs))
-+ goto err;
-
- spin_lock_init(&ctx->ctx_lock);
- spin_lock_init(&ctx->completion_lock);
-@@ -600,10 +631,10 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
-
- ctx->cpu = alloc_percpu(struct kioctx_cpu);
- if (!ctx->cpu)
-- goto out_freeref;
-+ goto err;
-
- if (aio_setup_ring(ctx) < 0)
-- goto out_freepcpu;
-+ goto err;
-
- atomic_set(&ctx->reqs_available, ctx->nr_events - 1);
- ctx->req_batch = (ctx->nr_events - 1) / (num_possible_cpus() * 4);
-@@ -615,7 +646,8 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
- if (aio_nr + nr_events > (aio_max_nr * 2UL) ||
- aio_nr + nr_events < aio_nr) {
- spin_unlock(&aio_nr_lock);
-- goto out_cleanup;
-+ err = -EAGAIN;
-+ goto err_ctx;
- }
- aio_nr += ctx->max_reqs;
- spin_unlock(&aio_nr_lock);
-@@ -624,23 +656,20 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
-
- err = ioctx_add_table(ctx, mm);
- if (err)
-- goto out_cleanup_put;
-+ goto err_cleanup;
-
- pr_debug("allocated ioctx %p[%ld]: mm=%p mask=0x%x\n",
- ctx, ctx->user_id, mm, ctx->nr_events);
- return ctx;
-
--out_cleanup_put:
-- percpu_ref_put(&ctx->users);
--out_cleanup:
-- err = -EAGAIN;
-+err_cleanup:
-+ aio_nr_sub(ctx->max_reqs);
-+err_ctx:
- aio_free_ring(ctx);
--out_freepcpu:
-+err:
- free_percpu(ctx->cpu);
--out_freeref:
-+ free_percpu(ctx->reqs.pcpu_count);
- free_percpu(ctx->users.pcpu_count);
--out_freectx:
-- put_aio_ring_file(ctx);
- kmem_cache_free(kioctx_cachep, ctx);
- pr_debug("error allocating ioctx %d\n", err);
- return ERR_PTR(err);
-@@ -675,10 +704,7 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx)
- * -EAGAIN with no ioctxs actually in use (as far as userspace
- * could tell).
- */
-- spin_lock(&aio_nr_lock);
-- BUG_ON(aio_nr - ctx->max_reqs > aio_nr);
-- aio_nr -= ctx->max_reqs;
-- spin_unlock(&aio_nr_lock);
-+ aio_nr_sub(ctx->max_reqs);
-
- if (ctx->mmap_size)
- vm_munmap(ctx->mmap_base, ctx->mmap_size);
-@@ -810,6 +836,8 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx)
- if (unlikely(!req))
- goto out_put;
-
-+ percpu_ref_get(&ctx->reqs);
-+
- req->ki_ctx = ctx;
- return req;
- out_put:
-@@ -879,12 +907,6 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
- return;
- }
-
-- /*
-- * Take rcu_read_lock() in case the kioctx is being destroyed, as we
-- * need to issue a wakeup after incrementing reqs_available.
-- */
-- rcu_read_lock();
--
- if (iocb->ki_list.next) {
- unsigned long flags;
-
-@@ -959,7 +981,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2)
- if (waitqueue_active(&ctx->wait))
- wake_up(&ctx->wait);
-
-- rcu_read_unlock();
-+ percpu_ref_put(&ctx->reqs);
- }
- EXPORT_SYMBOL(aio_complete);
-
-@@ -1370,6 +1392,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
- return 0;
- out_put_req:
- put_reqs_available(ctx, 1);
-+ percpu_ref_put(&ctx->reqs);
- kiocb_free(req);
- return ret;
- }
-diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
-index 85c9618..22f9698 100644
---- a/fs/anon_inodes.c
-+++ b/fs/anon_inodes.c
-@@ -24,7 +24,6 @@
-
- static struct vfsmount *anon_inode_mnt __read_mostly;
- static struct inode *anon_inode_inode;
--static const struct file_operations anon_inode_fops;
-
- /*
- * anon_inodefs_dname() is called from d_path().
-@@ -39,51 +38,6 @@ static const struct dentry_operations anon_inodefs_dentry_operations = {
- .d_dname = anon_inodefs_dname,
- };
-
--/*
-- * nop .set_page_dirty method so that people can use .page_mkwrite on
-- * anon inodes.
-- */
--static int anon_set_page_dirty(struct page *page)
--{
-- return 0;
--};
--
--static const struct address_space_operations anon_aops = {
-- .set_page_dirty = anon_set_page_dirty,
--};
--
--/*
-- * A single inode exists for all anon_inode files. Contrary to pipes,
-- * anon_inode inodes have no associated per-instance data, so we need
-- * only allocate one of them.
-- */
--static struct inode *anon_inode_mkinode(struct super_block *s)
--{
-- struct inode *inode = new_inode_pseudo(s);
--
-- if (!inode)
-- return ERR_PTR(-ENOMEM);
--
-- inode->i_ino = get_next_ino();
-- inode->i_fop = &anon_inode_fops;
--
-- inode->i_mapping->a_ops = &anon_aops;
--
-- /*
-- * Mark the inode dirty from the very beginning,
-- * that way it will never be moved to the dirty
-- * list because mark_inode_dirty() will think
-- * that it already _is_ on the dirty list.
-- */
-- inode->i_state = I_DIRTY;
-- inode->i_mode = S_IRUSR | S_IWUSR;
-- inode->i_uid = current_fsuid();
-- inode->i_gid = current_fsgid();
-- inode->i_flags |= S_PRIVATE;
-- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-- return inode;
--}
--
- static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
- {
-@@ -92,7 +46,7 @@ static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type,
- &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC);
- if (!IS_ERR(root)) {
- struct super_block *s = root->d_sb;
-- anon_inode_inode = anon_inode_mkinode(s);
-+ anon_inode_inode = alloc_anon_inode(s);
- if (IS_ERR(anon_inode_inode)) {
- dput(root);
- deactivate_locked_super(s);
-@@ -134,7 +88,7 @@ struct file *anon_inode_getfile_private(const char *name,
- if (fops->owner && !try_module_get(fops->owner))
- return ERR_PTR(-ENOENT);
-
-- inode = anon_inode_mkinode(anon_inode_mnt->mnt_sb);
-+ inode = alloc_anon_inode(anon_inode_mnt->mnt_sb);
- if (IS_ERR(inode)) {
- file = ERR_PTR(-ENOMEM);
- goto err_module;
-diff --git a/fs/libfs.c b/fs/libfs.c
-index 3a3a9b5..193e0c2 100644
---- a/fs/libfs.c
-+++ b/fs/libfs.c
-@@ -993,3 +993,46 @@ EXPORT_SYMBOL_GPL(simple_attr_open);
- EXPORT_SYMBOL_GPL(simple_attr_release);
- EXPORT_SYMBOL_GPL(simple_attr_read);
- EXPORT_SYMBOL_GPL(simple_attr_write);
-+
-+/*
-+ * nop .set_page_dirty method so that people can use .page_mkwrite on
-+ * anon inodes.
-+ */
-+static int anon_set_page_dirty(struct page *page)
-+{
-+ return 0;
-+};
-+
-+/*
-+ * A single inode exists for all anon_inode files. Contrary to pipes,
-+ * anon_inode inodes have no associated per-instance data, so we need
-+ * only allocate one of them.
-+ */
-+struct inode *alloc_anon_inode(struct super_block *s)
-+{
-+ static const struct address_space_operations anon_aops = {
-+ .set_page_dirty = anon_set_page_dirty,
-+ };
-+ struct inode *inode = new_inode_pseudo(s);
-+
-+ if (!inode)
-+ return ERR_PTR(-ENOMEM);
-+
-+ inode->i_ino = get_next_ino();
-+ inode->i_mapping->a_ops = &anon_aops;
-+
-+ /*
-+ * Mark the inode dirty from the very beginning,
-+ * that way it will never be moved to the dirty
-+ * list because mark_inode_dirty() will think
-+ * that it already _is_ on the dirty list.
-+ */
-+ inode->i_state = I_DIRTY;
-+ inode->i_mode = S_IRUSR | S_IWUSR;
-+ inode->i_uid = current_fsuid();
-+ inode->i_gid = current_fsgid();
-+ inode->i_flags |= S_PRIVATE;
-+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-+ return inode;
-+}
-+EXPORT_SYMBOL(alloc_anon_inode);
-diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
-index 668e8f4..2e1e6c3 100644
---- a/fs/xfs/xfs_ioctl.c
-+++ b/fs/xfs/xfs_ioctl.c
-@@ -1717,6 +1717,12 @@ xfs_file_ioctl(
- if (mp->m_flags & XFS_MOUNT_RDONLY)
- return -XFS_ERROR(EROFS);
-
-+ if (!capable(CAP_SYS_ADMIN))
-+ return -EPERM;
-+
-+ if (mp->m_flags & XFS_MOUNT_RDONLY)
-+ return -XFS_ERROR(EROFS);
-+
- if (copy_from_user(&eofb, arg, sizeof(eofb)))
- return -XFS_ERROR(EFAULT);
-
-diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 3f40547..fefa7b0 100644
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -2562,6 +2562,7 @@ extern int simple_write_begin(struct file *file, struct address_space *mapping,
- extern int simple_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata);
-+extern struct inode *alloc_anon_inode(struct super_block *);
-
- extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags);
- extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
-diff --git a/include/linux/net.h b/include/linux/net.h
-index 4f27575..8bd9d92 100644
---- a/include/linux/net.h
-+++ b/include/linux/net.h
-@@ -163,6 +163,14 @@ struct proto_ops {
- #endif
- int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
- struct msghdr *m, size_t total_len);
-+ /* Notes for implementing recvmsg:
-+ * ===============================
-+ * msg->msg_namelen should get updated by the recvmsg handlers
-+ * iff msg_name != NULL. It is by default 0 to prevent
-+ * returning uninitialized memory to user space. The recvfrom
-+ * handlers can assume that msg.msg_name is either NULL or has
-+ * a minimum size of sizeof(struct sockaddr_storage).
-+ */
- int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
- struct msghdr *m, size_t total_len,
- int flags);
-diff --git a/include/linux/random.h b/include/linux/random.h
-index 6312dd9..bf9085e 100644
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -50,9 +50,9 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
- {
- u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
-
-- state->s1 = __seed(i, 1);
-- state->s2 = __seed(i, 7);
-- state->s3 = __seed(i, 15);
-+ state->s1 = __seed(i, 2);
-+ state->s2 = __seed(i, 8);
-+ state->s3 = __seed(i, 16);
- }
-
- #ifdef CONFIG_ARCH_RANDOM
-diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index c2d8933..f66f346 100644
---- a/include/linux/skbuff.h
-+++ b/include/linux/skbuff.h
-@@ -333,11 +333,6 @@ typedef unsigned int sk_buff_data_t;
- typedef unsigned char *sk_buff_data_t;
- #endif
-
--#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
-- defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
--#define NET_SKBUFF_NF_DEFRAG_NEEDED 1
--#endif
--
- /**
- * struct sk_buff - socket buffer
- * @next: Next buffer in list
-@@ -370,7 +365,6 @@ typedef unsigned char *sk_buff_data_t;
- * @protocol: Packet protocol from driver
- * @destructor: Destruct function
- * @nfct: Associated connection, if any
-- * @nfct_reasm: netfilter conntrack re-assembly pointer
- * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
- * @skb_iif: ifindex of device we arrived on
- * @tc_index: Traffic control index
-@@ -459,9 +453,6 @@ struct sk_buff {
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- struct nf_conntrack *nfct;
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-- struct sk_buff *nfct_reasm;
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- struct nf_bridge_info *nf_bridge;
- #endif
-@@ -2605,18 +2596,6 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
- atomic_inc(&nfct->use);
- }
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
--static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
--{
-- if (skb)
-- atomic_inc(&skb->users);
--}
--static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
--{
-- if (skb)
-- kfree_skb(skb);
--}
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
- {
-@@ -2635,10 +2614,6 @@ static inline void nf_reset(struct sk_buff *skb)
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-- nf_conntrack_put_reasm(skb->nfct_reasm);
-- skb->nfct_reasm = NULL;
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- nf_bridge_put(skb->nf_bridge);
- skb->nf_bridge = NULL;
-@@ -2660,10 +2635,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
- nf_conntrack_get(src->nfct);
- dst->nfctinfo = src->nfctinfo;
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-- dst->nfct_reasm = src->nfct_reasm;
-- nf_conntrack_get_reasm(src->nfct_reasm);
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- dst->nf_bridge = src->nf_bridge;
- nf_bridge_get(src->nf_bridge);
-@@ -2675,9 +2646,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
- #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
- nf_conntrack_put(dst->nfct);
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-- nf_conntrack_put_reasm(dst->nfct_reasm);
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- nf_bridge_put(dst->nf_bridge);
- #endif
-diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
-index 1855f0a..c557c6d 100644
---- a/include/linux/vm_event_item.h
-+++ b/include/linux/vm_event_item.h
-@@ -39,6 +39,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
- PAGEOUTRUN, ALLOCSTALL, PGROTATED,
- #ifdef CONFIG_NUMA_BALANCING
- NUMA_PTE_UPDATES,
-+ NUMA_HUGE_PTE_UPDATES,
- NUMA_HINT_FAULTS,
- NUMA_HINT_FAULTS_LOCAL,
- NUMA_PAGE_MIGRATE,
-diff --git a/include/net/ip.h b/include/net/ip.h
-index 5e52688..301f10c 100644
---- a/include/net/ip.h
-+++ b/include/net/ip.h
-@@ -464,7 +464,7 @@ extern int compat_ip_getsockopt(struct sock *sk, int level,
- int optname, char __user *optval, int __user *optlen);
- extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
-
--extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
-+extern int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
- extern void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
- __be16 port, u32 info, u8 *payload);
- extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
-diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
-index 9c4d37e..772252d 100644
---- a/include/net/ip_vs.h
-+++ b/include/net/ip_vs.h
-@@ -109,7 +109,6 @@ extern int ip_vs_conn_tab_size;
- struct ip_vs_iphdr {
- __u32 len; /* IPv4 simply where L4 starts
- IPv6 where L4 Transport Header starts */
-- __u32 thoff_reasm; /* Transport Header Offset in nfct_reasm skb */
- __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
- __s16 protocol;
- __s32 flags;
-@@ -117,34 +116,12 @@ struct ip_vs_iphdr {
- union nf_inet_addr daddr;
- };
-
--/* Dependency to module: nf_defrag_ipv6 */
--#if defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
--static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
--{
-- return skb->nfct_reasm;
--}
--static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
-- int len, void *buffer,
-- const struct ip_vs_iphdr *ipvsh)
--{
-- if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb)))
-- return skb_header_pointer(skb_nfct_reasm(skb),
-- ipvsh->thoff_reasm, len, buffer);
--
-- return skb_header_pointer(skb, offset, len, buffer);
--}
--#else
--static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
--{
-- return NULL;
--}
- static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
- int len, void *buffer,
- const struct ip_vs_iphdr *ipvsh)
- {
- return skb_header_pointer(skb, offset, len, buffer);
- }
--#endif
-
- static inline void
- ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr)
-@@ -171,19 +148,12 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
- (struct ipv6hdr *)skb_network_header(skb);
- iphdr->saddr.in6 = iph->saddr;
- iphdr->daddr.in6 = iph->daddr;
-- /* ipv6_find_hdr() updates len, flags, thoff_reasm */
-- iphdr->thoff_reasm = 0;
-+ /* ipv6_find_hdr() updates len, flags */
- iphdr->len = 0;
- iphdr->flags = 0;
- iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1,
- &iphdr->fragoffs,
- &iphdr->flags);
-- /* get proto from re-assembled packet and it's offset */
-- if (skb_nfct_reasm(skb))
-- iphdr->protocol = ipv6_find_hdr(skb_nfct_reasm(skb),
-- &iphdr->thoff_reasm,
-- -1, NULL, NULL);
--
- } else
- #endif
- {
-diff --git a/include/net/ipv6.h b/include/net/ipv6.h
-index bbf1c8f..1f96efd 100644
---- a/include/net/ipv6.h
-+++ b/include/net/ipv6.h
-@@ -802,8 +802,10 @@ extern int compat_ipv6_getsockopt(struct sock *sk,
- extern int ip6_datagram_connect(struct sock *sk,
- struct sockaddr *addr, int addr_len);
-
--extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
--extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
-+extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
-+ int *addr_len);
-+extern int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
-+ int *addr_len);
- extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
- u32 info, u8 *payload);
- extern void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
-diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
-index fd79c9a..17920d8 100644
---- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
-+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
-@@ -6,10 +6,7 @@ extern void nf_defrag_ipv6_enable(void);
- extern int nf_ct_frag6_init(void);
- extern void nf_ct_frag6_cleanup(void);
- extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
--extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-- struct net_device *in,
-- struct net_device *out,
-- int (*okfn)(struct sk_buff *));
-+extern void nf_ct_frag6_consume_orig(struct sk_buff *skb);
-
- struct inet_frags_ctl;
-
-diff --git a/include/net/ping.h b/include/net/ping.h
-index 5db0224..2b496e9 100644
---- a/include/net/ping.h
-+++ b/include/net/ping.h
-@@ -31,7 +31,8 @@
-
- /* Compatibility glue so we can support IPv6 when it's compiled as a module */
- struct pingv6_ops {
-- int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len);
-+ int (*ipv6_recv_error)(struct sock *sk, struct msghdr *msg, int len,
-+ int *addr_len);
- int (*ip6_datagram_recv_ctl)(struct sock *sk, struct msghdr *msg,
- struct sk_buff *skb);
- int (*icmpv6_err_convert)(u8 type, u8 code, int *err);
-diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
-index 9b82913..66f925d 100644
---- a/include/uapi/linux/pkt_sched.h
-+++ b/include/uapi/linux/pkt_sched.h
-@@ -759,13 +759,14 @@ enum {
-
- TCA_FQ_RATE_ENABLE, /* enable/disable rate limiting */
-
-- TCA_FQ_FLOW_DEFAULT_RATE,/* for sockets with unspecified sk_rate,
-- * use the following rate
-- */
-+ TCA_FQ_FLOW_DEFAULT_RATE,/* obsolete, do not use */
-
- TCA_FQ_FLOW_MAX_RATE, /* per flow max rate */
-
- TCA_FQ_BUCKETS_LOG, /* log2(number of buckets) */
-+
-+ TCA_FQ_FLOW_REFILL_DELAY, /* flow credit refill delay in usec */
-+
- __TCA_FQ_MAX
- };
-
-diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
-index bb22151..af8d1d4 100644
---- a/kernel/time/ntp.c
-+++ b/kernel/time/ntp.c
-@@ -475,6 +475,7 @@ static void sync_cmos_clock(struct work_struct *work)
- * called as close as possible to 500 ms before the new second starts.
- * This code is run on a timer. If the clock is set, that timer
- * may not expire at the correct time. Thus, we adjust...
-+ * We want the clock to be within a couple of ticks from the target.
- */
- if (!ntp_synced()) {
- /*
-@@ -485,7 +486,7 @@ static void sync_cmos_clock(struct work_struct *work)
- }
-
- getnstimeofday(&now);
-- if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
-+ if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec * 5) {
- struct timespec adjust = now;
-
- fail = -ENODEV;
-diff --git a/lib/random32.c b/lib/random32.c
-index 52280d5..01e8890 100644
---- a/lib/random32.c
-+++ b/lib/random32.c
-@@ -141,7 +141,7 @@ void prandom_seed(u32 entropy)
- */
- for_each_possible_cpu (i) {
- struct rnd_state *state = &per_cpu(net_rand_state, i);
-- state->s1 = __seed(state->s1 ^ entropy, 1);
-+ state->s1 = __seed(state->s1 ^ entropy, 2);
- }
- }
- EXPORT_SYMBOL(prandom_seed);
-@@ -158,9 +158,9 @@ static int __init prandom_init(void)
- struct rnd_state *state = &per_cpu(net_rand_state,i);
-
- #define LCG(x) ((x) * 69069) /* super-duper LCG */
-- state->s1 = __seed(LCG(i + jiffies), 1);
-- state->s2 = __seed(LCG(state->s1), 7);
-- state->s3 = __seed(LCG(state->s2), 15);
-+ state->s1 = __seed(LCG(i + jiffies), 2);
-+ state->s2 = __seed(LCG(state->s1), 8);
-+ state->s3 = __seed(LCG(state->s2), 16);
-
- /* "warm it up" */
- prandom_u32_state(state);
-@@ -187,9 +187,9 @@ static int __init prandom_reseed(void)
- u32 seeds[3];
-
- get_random_bytes(&seeds, sizeof(seeds));
-- state->s1 = __seed(seeds[0], 1);
-- state->s2 = __seed(seeds[1], 7);
-- state->s3 = __seed(seeds[2], 15);
-+ state->s1 = __seed(seeds[0], 2);
-+ state->s2 = __seed(seeds[1], 8);
-+ state->s3 = __seed(seeds[2], 16);
-
- /* mix it in */
- prandom_u32_state(state);
-diff --git a/mm/mprotect.c b/mm/mprotect.c
-index 412ba2b..6c3f56f 100644
---- a/mm/mprotect.c
-+++ b/mm/mprotect.c
-@@ -138,6 +138,7 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
- pmd_t *pmd;
- unsigned long next;
- unsigned long pages = 0;
-+ unsigned long nr_huge_updates = 0;
- bool all_same_node;
-
- pmd = pmd_offset(pud, addr);
-@@ -148,7 +149,8 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
- split_huge_page_pmd(vma, addr, pmd);
- else if (change_huge_pmd(vma, pmd, addr, newprot,
- prot_numa)) {
-- pages++;
-+ pages += HPAGE_PMD_NR;
-+ nr_huge_updates++;
- continue;
- }
- /* fall through */
-@@ -168,6 +170,9 @@ static inline unsigned long change_pmd_range(struct vm_area_struct *vma,
- change_pmd_protnuma(vma->vm_mm, addr, pmd);
- } while (pmd++, addr = next, addr != end);
-
-+ if (nr_huge_updates)
-+ count_vm_numa_events(NUMA_HUGE_PTE_UPDATES, nr_huge_updates);
-+
- return pages;
- }
-
-diff --git a/mm/vmstat.c b/mm/vmstat.c
-index 9bb3145..5a442a7 100644
---- a/mm/vmstat.c
-+++ b/mm/vmstat.c
-@@ -812,6 +812,7 @@ const char * const vmstat_text[] = {
-
- #ifdef CONFIG_NUMA_BALANCING
- "numa_pte_updates",
-+ "numa_huge_pte_updates",
- "numa_hint_faults",
- "numa_hint_faults_local",
- "numa_pages_migrated",
-diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
-index 7fee50d..7d424ac 100644
---- a/net/appletalk/ddp.c
-+++ b/net/appletalk/ddp.c
-@@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
- size_t size, int flags)
- {
- struct sock *sk = sock->sk;
-- struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
- struct ddpehdr *ddp;
- int copied = 0;
- int offset = 0;
-@@ -1764,14 +1763,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
- }
- err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
-
-- if (!err) {
-- if (sat) {
-- sat->sat_family = AF_APPLETALK;
-- sat->sat_port = ddp->deh_sport;
-- sat->sat_addr.s_node = ddp->deh_snode;
-- sat->sat_addr.s_net = ddp->deh_snet;
-- }
-- msg->msg_namelen = sizeof(*sat);
-+ if (!err && msg->msg_name) {
-+ struct sockaddr_at *sat = msg->msg_name;
-+ sat->sat_family = AF_APPLETALK;
-+ sat->sat_port = ddp->deh_sport;
-+ sat->sat_addr.s_node = ddp->deh_snode;
-+ sat->sat_addr.s_net = ddp->deh_snet;
-+ msg->msg_namelen = sizeof(*sat);
- }
-
- skb_free_datagram(sk, skb); /* Free the datagram. */
-diff --git a/net/atm/common.c b/net/atm/common.c
-index 737bef5..7b49100 100644
---- a/net/atm/common.c
-+++ b/net/atm/common.c
-@@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
- struct sk_buff *skb;
- int copied, error = -EINVAL;
-
-- msg->msg_namelen = 0;
--
- if (sock->state != SS_CONNECTED)
- return -ENOTCONN;
-
-diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
-index 4b4d2b7..78c474f 100644
---- a/net/ax25/af_ax25.c
-+++ b/net/ax25/af_ax25.c
-@@ -1636,11 +1636,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (msg->msg_namelen != 0) {
-- struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
-+ if (msg->msg_name) {
- ax25_digi digi;
- ax25_address src;
- const unsigned char *mac = skb_mac_header(skb);
-+ struct sockaddr_ax25 *sax = msg->msg_name;
-
- memset(sax, 0, sizeof(struct full_sockaddr_ax25));
- ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
-diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
-index 9096137..6629cdc 100644
---- a/net/bluetooth/af_bluetooth.c
-+++ b/net/bluetooth/af_bluetooth.c
-@@ -221,8 +221,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (flags & (MSG_OOB))
- return -EOPNOTSUPP;
-
-- msg->msg_namelen = 0;
--
- skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb) {
- if (sk->sk_shutdown & RCV_SHUTDOWN)
-@@ -287,8 +285,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
-- msg->msg_namelen = 0;
--
- BT_DBG("sk %p size %zu", sk, size);
-
- lock_sock(sk);
-diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
-index 9bd7d95..fa4bf66 100644
---- a/net/bluetooth/hci_sock.c
-+++ b/net/bluetooth/hci_sock.c
-@@ -752,8 +752,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (!skb)
- return err;
-
-- msg->msg_namelen = 0;
--
- copied = skb->len;
- if (len < copied) {
- msg->msg_flags |= MSG_TRUNC;
-diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
-index 30b3721..c1c6028 100644
---- a/net/bluetooth/rfcomm/sock.c
-+++ b/net/bluetooth/rfcomm/sock.c
-@@ -608,7 +608,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
- rfcomm_dlc_accept(d);
-- msg->msg_namelen = 0;
- return 0;
- }
-
-diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
-index 96bd388..d021e44 100644
---- a/net/bluetooth/sco.c
-+++ b/net/bluetooth/sco.c
-@@ -715,7 +715,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
- sco_conn_defer_accept(pi->conn->hcon, pi->setting);
- sk->sk_state = BT_CONFIG;
-- msg->msg_namelen = 0;
-
- release_sock(sk);
- return 0;
-diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
-index c41d5fb..547504c 100644
---- a/net/bridge/br_if.c
-+++ b/net/bridge/br_if.c
-@@ -172,6 +172,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
- del_nbp(p);
- }
-
-+ br_fdb_delete_by_port(br, NULL, 1);
-+
- del_timer_sync(&br->gc_timer);
-
- br_sysfs_delbr(br->dev);
-diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
-index 05a41c7..d6be3ed 100644
---- a/net/caif/caif_socket.c
-+++ b/net/caif/caif_socket.c
-@@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (m->msg_flags&MSG_OOB)
- goto read_error;
-
-- m->msg_namelen = 0;
--
- skb = skb_recv_datagram(sk, flags, 0 , &ret);
- if (!skb)
- goto read_error;
-@@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (flags&MSG_OOB)
- goto out;
-
-- msg->msg_namelen = 0;
--
- /*
- * Lock the socket to prevent queue disordering
- * while sleeps in memcpy_tomsg
-diff --git a/net/compat.c b/net/compat.c
-index 8903258..dd32e34 100644
---- a/net/compat.c
-+++ b/net/compat.c
-@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
- __get_user(kmsg->msg_flags, &umsg->msg_flags))
- return -EFAULT;
- if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
-- return -EINVAL;
-+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
- kmsg->msg_name = compat_ptr(tmp1);
- kmsg->msg_iov = compat_ptr(tmp2);
- kmsg->msg_control = compat_ptr(tmp3);
-@@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
- if (err < 0)
- return err;
- }
-- kern_msg->msg_name = kern_address;
-+ if (kern_msg->msg_name)
-+ kern_msg->msg_name = kern_address;
- } else
- kern_msg->msg_name = NULL;
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 3430b1e..3d13874 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -1691,13 +1691,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
- kfree_skb(skb);
- return NET_RX_DROP;
- }
-- skb->protocol = eth_type_trans(skb, dev);
-
-- /* eth_type_trans() can set pkt_type.
-- * call skb_scrub_packet() after it to clear pkt_type _after_ calling
-- * eth_type_trans().
-- */
- skb_scrub_packet(skb, true);
-+ skb->protocol = eth_type_trans(skb, dev);
-
- return netif_rx(skb);
- }
-@@ -4819,7 +4815,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
- {
- const struct net_device_ops *ops = dev->netdev_ops;
-
-- if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
-+ if (ops->ndo_change_rx_flags)
- ops->ndo_change_rx_flags(dev, flags);
- }
-
-diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
-index 2e65413..f409e0b 100644
---- a/net/core/fib_rules.c
-+++ b/net/core/fib_rules.c
-@@ -460,7 +460,8 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh)
- if (frh->action && (frh->action != rule->action))
- continue;
-
-- if (frh->table && (frh_get_table(frh, tb) != rule->table))
-+ if (frh_get_table(frh, tb) &&
-+ (frh_get_table(frh, tb) != rule->table))
- continue;
-
- if (tb[FRA_PRIORITY] &&
-diff --git a/net/core/iovec.c b/net/core/iovec.c
-index b77eeec..7d84ea1 100644
---- a/net/core/iovec.c
-+++ b/net/core/iovec.c
-@@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
- if (err < 0)
- return err;
- }
-- m->msg_name = address;
-+ if (m->msg_name)
-+ m->msg_name = address;
- } else {
- m->msg_name = NULL;
- }
-diff --git a/net/core/pktgen.c b/net/core/pktgen.c
-index 261357a..a797fff 100644
---- a/net/core/pktgen.c
-+++ b/net/core/pktgen.c
-@@ -2527,6 +2527,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,
- if (x) {
- int ret;
- __u8 *eth;
-+ struct iphdr *iph;
-+
- nhead = x->props.header_len - skb_headroom(skb);
- if (nhead > 0) {
- ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
-@@ -2548,6 +2550,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,
- eth = (__u8 *) skb_push(skb, ETH_HLEN);
- memcpy(eth, pkt_dev->hh, 12);
- *(u16 *) &eth[12] = protocol;
-+
-+ /* Update IPv4 header len as well as checksum value */
-+ iph = ip_hdr(skb);
-+ iph->tot_len = htons(skb->len - ETH_HLEN);
-+ ip_send_check(iph);
- }
- }
- return 1;
-diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index d81cff1..c28c7fe 100644
---- a/net/core/skbuff.c
-+++ b/net/core/skbuff.c
-@@ -580,9 +580,6 @@ static void skb_release_head_state(struct sk_buff *skb)
- #if IS_ENABLED(CONFIG_NF_CONNTRACK)
- nf_conntrack_put(skb->nfct);
- #endif
--#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
-- nf_conntrack_put_reasm(skb->nfct_reasm);
--#endif
- #ifdef CONFIG_BRIDGE_NETFILTER
- nf_bridge_put(skb->nf_bridge);
- #endif
-@@ -2758,6 +2755,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
- struct sk_buff *segs = NULL;
- struct sk_buff *tail = NULL;
- struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
-+ skb_frag_t *skb_frag = skb_shinfo(skb)->frags;
- unsigned int mss = skb_shinfo(skb)->gso_size;
- unsigned int doffset = skb->data - skb_mac_header(skb);
- unsigned int offset = doffset;
-@@ -2797,16 +2795,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
- if (hsize > len || !sg)
- hsize = len;
-
-- if (!hsize && i >= nfrags) {
-- BUG_ON(fskb->len != len);
-+ if (!hsize && i >= nfrags && skb_headlen(fskb) &&
-+ (skb_headlen(fskb) == len || sg)) {
-+ BUG_ON(skb_headlen(fskb) > len);
-+
-+ i = 0;
-+ nfrags = skb_shinfo(fskb)->nr_frags;
-+ skb_frag = skb_shinfo(fskb)->frags;
-+ pos += skb_headlen(fskb);
-+
-+ while (pos < offset + len) {
-+ BUG_ON(i >= nfrags);
-+
-+ size = skb_frag_size(skb_frag);
-+ if (pos + size > offset + len)
-+ break;
-+
-+ i++;
-+ pos += size;
-+ skb_frag++;
-+ }
-
-- pos += len;
- nskb = skb_clone(fskb, GFP_ATOMIC);
- fskb = fskb->next;
-
- if (unlikely(!nskb))
- goto err;
-
-+ if (unlikely(pskb_trim(nskb, len))) {
-+ kfree_skb(nskb);
-+ goto err;
-+ }
-+
- hsize = skb_end_offset(nskb);
- if (skb_cow_head(nskb, doffset + headroom)) {
- kfree_skb(nskb);
-@@ -2850,7 +2870,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
- nskb->data - tnl_hlen,
- doffset + tnl_hlen);
-
-- if (fskb != skb_shinfo(skb)->frag_list)
-+ if (nskb->len == len + doffset)
- goto perform_csum_check;
-
- if (!sg) {
-@@ -2868,8 +2888,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
-
- skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
-
-- while (pos < offset + len && i < nfrags) {
-- *frag = skb_shinfo(skb)->frags[i];
-+ while (pos < offset + len) {
-+ if (i >= nfrags) {
-+ BUG_ON(skb_headlen(fskb));
-+
-+ i = 0;
-+ nfrags = skb_shinfo(fskb)->nr_frags;
-+ skb_frag = skb_shinfo(fskb)->frags;
-+
-+ BUG_ON(!nfrags);
-+
-+ fskb = fskb->next;
-+ }
-+
-+ if (unlikely(skb_shinfo(nskb)->nr_frags >=
-+ MAX_SKB_FRAGS)) {
-+ net_warn_ratelimited(
-+ "skb_segment: too many frags: %u %u\n",
-+ pos, mss);
-+ goto err;
-+ }
-+
-+ *frag = *skb_frag;
- __skb_frag_ref(frag);
- size = skb_frag_size(frag);
-
-@@ -2882,6 +2922,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
-
- if (pos + size <= offset + len) {
- i++;
-+ skb_frag++;
- pos += size;
- } else {
- skb_frag_size_sub(frag, pos + size - (offset + len));
-@@ -2891,25 +2932,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
- frag++;
- }
-
-- if (pos < offset + len) {
-- struct sk_buff *fskb2 = fskb;
--
-- BUG_ON(pos + fskb->len != offset + len);
--
-- pos += fskb->len;
-- fskb = fskb->next;
--
-- if (fskb2->next) {
-- fskb2 = skb_clone(fskb2, GFP_ATOMIC);
-- if (!fskb2)
-- goto err;
-- } else
-- skb_get(fskb2);
--
-- SKB_FRAG_ASSERT(nskb);
-- skb_shinfo(nskb)->frag_list = fskb2;
-- }
--
- skip_fraglist:
- nskb->data_len = len - hsize;
- nskb->len += nskb->data_len;
-diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
-index ff41b4d..008f337 100644
---- a/net/ieee802154/6lowpan.c
-+++ b/net/ieee802154/6lowpan.c
-@@ -957,7 +957,7 @@ lowpan_process_data(struct sk_buff *skb)
- * Traffic class carried in-line
- * ECN + DSCP (1 byte), Flow Label is elided
- */
-- case 1: /* 10b */
-+ case 2: /* 10b */
- if (lowpan_fetch_skb_u8(skb, &tmp))
- goto drop;
-
-@@ -968,7 +968,7 @@ lowpan_process_data(struct sk_buff *skb)
- * Flow Label carried in-line
- * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
- */
-- case 2: /* 01b */
-+ case 1: /* 01b */
- if (lowpan_fetch_skb_u8(skb, &tmp))
- goto drop;
-
-diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
-index 581a595..1865fdf 100644
---- a/net/ieee802154/dgram.c
-+++ b/net/ieee802154/dgram.c
-@@ -315,9 +315,8 @@ static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
- if (saddr) {
- saddr->family = AF_IEEE802154;
- saddr->addr = mac_cb(skb)->sa;
-- }
-- if (addr_len)
- *addr_len = sizeof(*saddr);
-+ }
-
- if (flags & MSG_TRUNC)
- copied = skb->len;
-diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
-index b28e863..19e3637 100644
---- a/net/ipv4/datagram.c
-+++ b/net/ipv4/datagram.c
-@@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
- if (IS_ERR(rt)) {
- err = PTR_ERR(rt);
- if (err == -ENETUNREACH)
-- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
-+ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
- goto out;
- }
-
-diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
-index d9c4f11..23e6ab0 100644
---- a/net/ipv4/ip_sockglue.c
-+++ b/net/ipv4/ip_sockglue.c
-@@ -368,7 +368,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
- /*
- * Handle MSG_ERRQUEUE
- */
--int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
-+int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
- {
- struct sock_exterr_skb *serr;
- struct sk_buff *skb, *skb2;
-@@ -405,6 +405,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
- serr->addr_offset);
- sin->sin_port = serr->port;
- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *addr_len = sizeof(*sin);
- }
-
- memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
-diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
-index 63a6d6d..254f11c 100644
---- a/net/ipv4/ip_tunnel.c
-+++ b/net/ipv4/ip_tunnel.c
-@@ -454,6 +454,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
- tstats->rx_bytes += skb->len;
- u64_stats_update_end(&tstats->syncp);
-
-+ skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
-+
- if (tunnel->dev->type == ARPHRD_ETHER) {
- skb->protocol = eth_type_trans(skb, tunnel->dev);
- skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
-@@ -461,8 +463,6 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
- skb->dev = tunnel->dev;
- }
-
-- skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(tunnel->dev)));
--
- gro_cells_receive(&tunnel->gro_cells, skb);
- return 0;
-
-diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
-index 6e87f85..26847e1 100644
---- a/net/ipv4/ip_vti.c
-+++ b/net/ipv4/ip_vti.c
-@@ -190,6 +190,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
- if (!rt->dst.xfrm ||
- rt->dst.xfrm->props.mode != XFRM_MODE_TUNNEL) {
- dev->stats.tx_carrier_errors++;
-+ ip_rt_put(rt);
- goto tx_error_icmp;
- }
- tdev = rt->dst.dev;
-diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
-index d7d9882..c482f7c 100644
---- a/net/ipv4/ping.c
-+++ b/net/ipv4/ping.c
-@@ -769,7 +769,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- err = PTR_ERR(rt);
- rt = NULL;
- if (err == -ENETUNREACH)
-- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
-+ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
- goto out;
- }
-
-@@ -827,8 +827,6 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- {
- struct inet_sock *isk = inet_sk(sk);
- int family = sk->sk_family;
-- struct sockaddr_in *sin;
-- struct sockaddr_in6 *sin6;
- struct sk_buff *skb;
- int copied, err;
-
-@@ -838,19 +836,13 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- if (flags & MSG_OOB)
- goto out;
-
-- if (addr_len) {
-- if (family == AF_INET)
-- *addr_len = sizeof(*sin);
-- else if (family == AF_INET6 && addr_len)
-- *addr_len = sizeof(*sin6);
-- }
--
- if (flags & MSG_ERRQUEUE) {
- if (family == AF_INET) {
-- return ip_recv_error(sk, msg, len);
-+ return ip_recv_error(sk, msg, len, addr_len);
- #if IS_ENABLED(CONFIG_IPV6)
- } else if (family == AF_INET6) {
-- return pingv6_ops.ipv6_recv_error(sk, msg, len);
-+ return pingv6_ops.ipv6_recv_error(sk, msg, len,
-+ addr_len);
- #endif
- }
- }
-@@ -874,11 +866,15 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
-
- /* Copy the address and add cmsg data. */
- if (family == AF_INET) {
-- sin = (struct sockaddr_in *) msg->msg_name;
-- sin->sin_family = AF_INET;
-- sin->sin_port = 0 /* skb->h.uh->source */;
-- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
-- memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
-+
-+ if (sin) {
-+ sin->sin_family = AF_INET;
-+ sin->sin_port = 0 /* skb->h.uh->source */;
-+ sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
-+ memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *addr_len = sizeof(*sin);
-+ }
-
- if (isk->cmsg_flags)
- ip_cmsg_recv(msg, skb);
-@@ -887,17 +883,21 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- } else if (family == AF_INET6) {
- struct ipv6_pinfo *np = inet6_sk(sk);
- struct ipv6hdr *ip6 = ipv6_hdr(skb);
-- sin6 = (struct sockaddr_in6 *) msg->msg_name;
-- sin6->sin6_family = AF_INET6;
-- sin6->sin6_port = 0;
-- sin6->sin6_addr = ip6->saddr;
--
-- sin6->sin6_flowinfo = 0;
-- if (np->sndflow)
-- sin6->sin6_flowinfo = ip6_flowinfo(ip6);
--
-- sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
-- IP6CB(skb)->iif);
-+ struct sockaddr_in6 *sin6 =
-+ (struct sockaddr_in6 *)msg->msg_name;
-+
-+ if (sin6) {
-+ sin6->sin6_family = AF_INET6;
-+ sin6->sin6_port = 0;
-+ sin6->sin6_addr = ip6->saddr;
-+ sin6->sin6_flowinfo = 0;
-+ if (np->sndflow)
-+ sin6->sin6_flowinfo = ip6_flowinfo(ip6);
-+ sin6->sin6_scope_id =
-+ ipv6_iface_scope_id(&sin6->sin6_addr,
-+ IP6CB(skb)->iif);
-+ *addr_len = sizeof(*sin6);
-+ }
-
- if (inet6_sk(sk)->rxopt.all)
- pingv6_ops.ip6_datagram_recv_ctl(sk, msg, skb);
-diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
-index 193db03..7d3db78 100644
---- a/net/ipv4/raw.c
-+++ b/net/ipv4/raw.c
-@@ -694,11 +694,8 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- if (flags & MSG_OOB)
- goto out;
-
-- if (addr_len)
-- *addr_len = sizeof(*sin);
--
- if (flags & MSG_ERRQUEUE) {
-- err = ip_recv_error(sk, msg, len);
-+ err = ip_recv_error(sk, msg, len, addr_len);
- goto out;
- }
-
-@@ -724,6 +721,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
- sin->sin_port = 0;
- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *addr_len = sizeof(*sin);
- }
- if (inet->cmsg_flags)
- ip_cmsg_recv(msg, skb);
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 6011615..62290b5 100644
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1772,8 +1772,12 @@ local_input:
- rth->dst.error= -err;
- rth->rt_flags &= ~RTCF_LOCAL;
- }
-- if (do_cache)
-- rt_cache_route(&FIB_RES_NH(res), rth);
-+ if (do_cache) {
-+ if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
-+ rth->dst.flags |= DST_NOCACHE;
-+ rt_add_uncached_list(rth);
-+ }
-+ }
- skb_dst_set(skb, &rth->dst);
- err = 0;
- goto out;
-diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
-index 6e5617b..be5246e 100644
---- a/net/ipv4/tcp.c
-+++ b/net/ipv4/tcp.c
-@@ -806,12 +806,6 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
- xmit_size_goal = min_t(u32, gso_size,
- sk->sk_gso_max_size - 1 - hlen);
-
-- /* TSQ : try to have at least two segments in flight
-- * (one in NIC TX ring, another in Qdisc)
-- */
-- xmit_size_goal = min_t(u32, xmit_size_goal,
-- sysctl_tcp_limit_output_bytes >> 1);
--
- xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
-
- /* We try hard to avoid divides here */
-diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
-index b14266b..5031f68 100644
---- a/net/ipv4/tcp_ipv4.c
-+++ b/net/ipv4/tcp_ipv4.c
-@@ -177,7 +177,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
- if (IS_ERR(rt)) {
- err = PTR_ERR(rt);
- if (err == -ENETUNREACH)
-- IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
-+ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
- return err;
- }
-
-diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
-index 52f3c6b..3107114 100644
---- a/net/ipv4/tcp_metrics.c
-+++ b/net/ipv4/tcp_metrics.c
-@@ -659,10 +659,13 @@ void tcp_fastopen_cache_get(struct sock *sk, u16 *mss,
- void tcp_fastopen_cache_set(struct sock *sk, u16 mss,
- struct tcp_fastopen_cookie *cookie, bool syn_lost)
- {
-+ struct dst_entry *dst = __sk_dst_get(sk);
- struct tcp_metrics_block *tm;
-
-+ if (!dst)
-+ return;
- rcu_read_lock();
-- tm = tcp_get_metrics(sk, __sk_dst_get(sk), true);
-+ tm = tcp_get_metrics(sk, dst, true);
- if (tm) {
- struct tcp_fastopen_metrics *tfom = &tm->tcpm_fastopen;
-
-diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
-index 533c58a..910ab81 100644
---- a/net/ipv4/tcp_offload.c
-+++ b/net/ipv4/tcp_offload.c
-@@ -272,33 +272,32 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
- {
- const struct iphdr *iph = skb_gro_network_header(skb);
- __wsum wsum;
-- __sum16 sum;
-+
-+ /* Don't bother verifying checksum if we're going to flush anyway. */
-+ if (NAPI_GRO_CB(skb)->flush)
-+ goto skip_csum;
-+
-+ wsum = skb->csum;
-
- switch (skb->ip_summed) {
-+ case CHECKSUM_NONE:
-+ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
-+ 0);
-+
-+ /* fall through */
-+
- case CHECKSUM_COMPLETE:
- if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
-- skb->csum)) {
-+ wsum)) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- break;
- }
--flush:
-+
- NAPI_GRO_CB(skb)->flush = 1;
- return NULL;
--
-- case CHECKSUM_NONE:
-- wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
-- skb_gro_len(skb), IPPROTO_TCP, 0);
-- sum = csum_fold(skb_checksum(skb,
-- skb_gro_offset(skb),
-- skb_gro_len(skb),
-- wsum));
-- if (sum)
-- goto flush;
--
-- skb->ip_summed = CHECKSUM_UNNECESSARY;
-- break;
- }
-
-+skip_csum:
- return tcp_gro_receive(head, skb);
- }
-
-diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
-index d46f214..e912634 100644
---- a/net/ipv4/tcp_output.c
-+++ b/net/ipv4/tcp_output.c
-@@ -1875,8 +1875,12 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
- * - better RTT estimation and ACK scheduling
- * - faster recovery
- * - high rates
-+ * Alas, some drivers / subsystems require a fair amount
-+ * of queued bytes to ensure line rate.
-+ * One example is wifi aggregation (802.11 AMPDU)
- */
-- limit = max(skb->truesize, sk->sk_pacing_rate >> 10);
-+ limit = max_t(unsigned int, sysctl_tcp_limit_output_bytes,
-+ sk->sk_pacing_rate >> 10);
-
- if (atomic_read(&sk->sk_wmem_alloc) > limit) {
- set_bit(TSQ_THROTTLED, &tp->tsq_flags);
-@@ -3108,7 +3112,6 @@ void tcp_send_window_probe(struct sock *sk)
- {
- if (sk->sk_state == TCP_ESTABLISHED) {
- tcp_sk(sk)->snd_wl1 = tcp_sk(sk)->rcv_nxt - 1;
-- tcp_sk(sk)->snd_nxt = tcp_sk(sk)->write_seq;
- tcp_xmit_probe_skb(sk, 0);
- }
- }
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 0ca44df..5e2c2f1 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -973,7 +973,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- err = PTR_ERR(rt);
- rt = NULL;
- if (err == -ENETUNREACH)
-- IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
-+ IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
- goto out;
- }
-
-@@ -1072,6 +1072,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
- struct udp_sock *up = udp_sk(sk);
- int ret;
-
-+ if (flags & MSG_SENDPAGE_NOTLAST)
-+ flags |= MSG_MORE;
-+
- if (!up->pending) {
- struct msghdr msg = { .msg_flags = flags|MSG_MORE };
-
-@@ -1209,14 +1212,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- int is_udplite = IS_UDPLITE(sk);
- bool slow;
-
-- /*
-- * Check any passed addresses
-- */
-- if (addr_len)
-- *addr_len = sizeof(*sin);
--
- if (flags & MSG_ERRQUEUE)
-- return ip_recv_error(sk, msg, len);
-+ return ip_recv_error(sk, msg, len, addr_len);
-
- try_again:
- skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
-@@ -1276,6 +1273,7 @@ try_again:
- sin->sin_port = udp_hdr(skb)->source;
- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
- memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *addr_len = sizeof(*sin);
- }
- if (inet->cmsg_flags)
- ip_cmsg_recv(msg, skb);
-diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
-index ccde542..adf9983 100644
---- a/net/ipv4/xfrm4_policy.c
-+++ b/net/ipv4/xfrm4_policy.c
-@@ -104,10 +104,14 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
- const struct iphdr *iph = ip_hdr(skb);
- u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
- struct flowi4 *fl4 = &fl->u.ip4;
-+ int oif = 0;
-+
-+ if (skb_dst(skb))
-+ oif = skb_dst(skb)->dev->ifindex;
-
- memset(fl4, 0, sizeof(struct flowi4));
- fl4->flowi4_mark = skb->mark;
-- fl4->flowi4_oif = skb_dst(skb)->dev->ifindex;
-+ fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
-
- if (!ip_is_fragment(iph)) {
- switch (iph->protocol) {
-diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
-index 7c96100..8132b44 100644
---- a/net/ipv6/af_inet6.c
-+++ b/net/ipv6/af_inet6.c
-@@ -965,10 +965,10 @@ out:
-
- #ifdef CONFIG_SYSCTL
- sysctl_fail:
-- ipv6_packet_cleanup();
-+ pingv6_exit();
- #endif
- pingv6_fail:
-- pingv6_exit();
-+ ipv6_packet_cleanup();
- ipv6_packet_fail:
- tcpv6_exit();
- tcpv6_fail:
-diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
-index 48b6bd2..c66c6df 100644
---- a/net/ipv6/datagram.c
-+++ b/net/ipv6/datagram.c
-@@ -318,7 +318,7 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
- /*
- * Handle MSG_ERRQUEUE
- */
--int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
-+int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
- {
- struct ipv6_pinfo *np = inet6_sk(sk);
- struct sock_exterr_skb *serr;
-@@ -369,6 +369,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
- &sin->sin6_addr);
- sin->sin6_scope_id = 0;
- }
-+ *addr_len = sizeof(*sin);
- }
-
- memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
-@@ -377,6 +378,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
- if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
- sin->sin6_family = AF_INET6;
- sin->sin6_flowinfo = 0;
-+ sin->sin6_port = 0;
- if (skb->protocol == htons(ETH_P_IPV6)) {
- sin->sin6_addr = ipv6_hdr(skb)->saddr;
- if (np->rxopt.all)
-@@ -423,7 +425,8 @@ EXPORT_SYMBOL_GPL(ipv6_recv_error);
- /*
- * Handle IPV6_RECVPATHMTU
- */
--int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
-+int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
-+ int *addr_len)
- {
- struct ipv6_pinfo *np = inet6_sk(sk);
- struct sk_buff *skb;
-@@ -457,6 +460,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
- sin->sin6_port = 0;
- sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
- sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
-+ *addr_len = sizeof(*sin);
- }
-
- put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
-diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
-index 46e8843..f0ccdb7 100644
---- a/net/ipv6/ip6_flowlabel.c
-+++ b/net/ipv6/ip6_flowlabel.c
-@@ -453,8 +453,10 @@ static int mem_check(struct sock *sk)
- if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
- return 0;
-
-+ rcu_read_lock_bh();
- for_each_sk_fl_rcu(np, sfl)
- count++;
-+ rcu_read_unlock_bh();
-
- if (room <= 0 ||
- ((count >= FL_MAX_PER_SOCK ||
-diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
-index 91fb4e8..b6fa35e 100644
---- a/net/ipv6/ip6_output.c
-+++ b/net/ipv6/ip6_output.c
-@@ -116,8 +116,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
- }
- rcu_read_unlock_bh();
-
-- IP6_INC_STATS_BH(dev_net(dst->dev),
-- ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
-+ IP6_INC_STATS(dev_net(dst->dev),
-+ ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
- kfree_skb(skb);
- return -EINVAL;
- }
-@@ -125,7 +125,8 @@ static int ip6_finish_output2(struct sk_buff *skb)
- static int ip6_finish_output(struct sk_buff *skb)
- {
- if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
-- dst_allfrag(skb_dst(skb)))
-+ dst_allfrag(skb_dst(skb)) ||
-+ (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
- return ip6_fragment(skb, ip6_finish_output2);
- else
- return ip6_finish_output2(skb);
-diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
-index 583b77e..c1e11b5 100644
---- a/net/ipv6/ip6_tunnel.c
-+++ b/net/ipv6/ip6_tunnel.c
-@@ -1635,6 +1635,15 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
- return ip6_tnl_update(t, &p);
- }
-
-+static void ip6_tnl_dellink(struct net_device *dev, struct list_head *head)
-+{
-+ struct net *net = dev_net(dev);
-+ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
-+
-+ if (dev != ip6n->fb_tnl_dev)
-+ unregister_netdevice_queue(dev, head);
-+}
-+
- static size_t ip6_tnl_get_size(const struct net_device *dev)
- {
- return
-@@ -1699,6 +1708,7 @@ static struct rtnl_link_ops ip6_link_ops __read_mostly = {
- .validate = ip6_tnl_validate,
- .newlink = ip6_tnl_newlink,
- .changelink = ip6_tnl_changelink,
-+ .dellink = ip6_tnl_dellink,
- .get_size = ip6_tnl_get_size,
- .fill_info = ip6_tnl_fill_info,
- };
-@@ -1715,9 +1725,9 @@ static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
- .priority = 1,
- };
-
--static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
-+static void __net_exit ip6_tnl_destroy_tunnels(struct net *net)
- {
-- struct net *net = dev_net(ip6n->fb_tnl_dev);
-+ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
- struct net_device *dev, *aux;
- int h;
- struct ip6_tnl *t;
-@@ -1785,10 +1795,8 @@ err_alloc_dev:
-
- static void __net_exit ip6_tnl_exit_net(struct net *net)
- {
-- struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
--
- rtnl_lock();
-- ip6_tnl_destroy_tunnels(ip6n);
-+ ip6_tnl_destroy_tunnels(net);
- rtnl_unlock();
- }
-
-diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
-index d6e4dd8..83ab37c 100644
---- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
-+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
-@@ -169,63 +169,13 @@ out:
- return nf_conntrack_confirm(skb);
- }
-
--static unsigned int __ipv6_conntrack_in(struct net *net,
-- unsigned int hooknum,
-- struct sk_buff *skb,
-- const struct net_device *in,
-- const struct net_device *out,
-- int (*okfn)(struct sk_buff *))
--{
-- struct sk_buff *reasm = skb->nfct_reasm;
-- const struct nf_conn_help *help;
-- struct nf_conn *ct;
-- enum ip_conntrack_info ctinfo;
--
-- /* This packet is fragmented and has reassembled packet. */
-- if (reasm) {
-- /* Reassembled packet isn't parsed yet ? */
-- if (!reasm->nfct) {
-- unsigned int ret;
--
-- ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
-- if (ret != NF_ACCEPT)
-- return ret;
-- }
--
-- /* Conntrack helpers need the entire reassembled packet in the
-- * POST_ROUTING hook. In case of unconfirmed connections NAT
-- * might reassign a helper, so the entire packet is also
-- * required.
-- */
-- ct = nf_ct_get(reasm, &ctinfo);
-- if (ct != NULL && !nf_ct_is_untracked(ct)) {
-- help = nfct_help(ct);
-- if ((help && help->helper) || !nf_ct_is_confirmed(ct)) {
-- nf_conntrack_get_reasm(reasm);
-- NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
-- (struct net_device *)in,
-- (struct net_device *)out,
-- okfn, NF_IP6_PRI_CONNTRACK + 1);
-- return NF_DROP_ERR(-ECANCELED);
-- }
-- }
--
-- nf_conntrack_get(reasm->nfct);
-- skb->nfct = reasm->nfct;
-- skb->nfctinfo = reasm->nfctinfo;
-- return NF_ACCEPT;
-- }
--
-- return nf_conntrack_in(net, PF_INET6, hooknum, skb);
--}
--
- static unsigned int ipv6_conntrack_in(unsigned int hooknum,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *))
- {
-- return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
-+ return nf_conntrack_in(dev_net(in), PF_INET6, hooknum, skb);
- }
-
- static unsigned int ipv6_conntrack_local(unsigned int hooknum,
-@@ -239,7 +189,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
- net_notice_ratelimited("ipv6_conntrack_local: packet too short\n");
- return NF_ACCEPT;
- }
-- return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
-+ return nf_conntrack_in(dev_net(out), PF_INET6, hooknum, skb);
- }
-
- static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
-diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
-index dffdc1a..253566a 100644
---- a/net/ipv6/netfilter/nf_conntrack_reasm.c
-+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
-@@ -621,31 +621,16 @@ ret_orig:
- return skb;
- }
-
--void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
-- struct net_device *in, struct net_device *out,
-- int (*okfn)(struct sk_buff *))
-+void nf_ct_frag6_consume_orig(struct sk_buff *skb)
- {
- struct sk_buff *s, *s2;
-- unsigned int ret = 0;
-
- for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
-- nf_conntrack_put_reasm(s->nfct_reasm);
-- nf_conntrack_get_reasm(skb);
-- s->nfct_reasm = skb;
--
- s2 = s->next;
- s->next = NULL;
--
-- if (ret != -ECANCELED)
-- ret = NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s,
-- in, out, okfn,
-- NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
-- else
-- kfree_skb(s);
--
-+ consume_skb(s);
- s = s2;
- }
-- nf_conntrack_put_reasm(skb);
- }
-
- static int nf_ct_net_init(struct net *net)
-diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
-index aacd121..581dd9e 100644
---- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
-+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
-@@ -75,8 +75,11 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
- if (reasm == skb)
- return NF_ACCEPT;
-
-- nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in,
-- (struct net_device *)out, okfn);
-+ nf_ct_frag6_consume_orig(reasm);
-+
-+ NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, reasm,
-+ (struct net_device *) in, (struct net_device *) out,
-+ okfn, NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
-
- return NF_STOLEN;
- }
-diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
-index 18f19df..7856e96 100644
---- a/net/ipv6/ping.c
-+++ b/net/ipv6/ping.c
-@@ -57,7 +57,8 @@ static struct inet_protosw pingv6_protosw = {
-
-
- /* Compatibility glue so we can support IPv6 when it's compiled as a module */
--static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
-+static int dummy_ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
-+ int *addr_len)
- {
- return -EAFNOSUPPORT;
- }
-diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
-index a4ed241..430067c 100644
---- a/net/ipv6/raw.c
-+++ b/net/ipv6/raw.c
-@@ -466,14 +466,11 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
-- if (addr_len)
-- *addr_len=sizeof(*sin6);
--
- if (flags & MSG_ERRQUEUE)
-- return ipv6_recv_error(sk, msg, len);
-+ return ipv6_recv_error(sk, msg, len, addr_len);
-
- if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-- return ipv6_recv_rxpmtu(sk, msg, len);
-+ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
-
- skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb)
-@@ -507,6 +504,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
- sin6->sin6_flowinfo = 0;
- sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
- IP6CB(skb)->iif);
-+ *addr_len = sizeof(*sin6);
- }
-
- sock_recv_ts_and_drops(msg, sk, skb);
-diff --git a/net/ipv6/route.c b/net/ipv6/route.c
-index 04e17b3..77308af 100644
---- a/net/ipv6/route.c
-+++ b/net/ipv6/route.c
-@@ -731,8 +731,11 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
- prefix = &prefix_buf;
- }
-
-- rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
-- dev->ifindex);
-+ if (rinfo->prefix_len == 0)
-+ rt = rt6_get_dflt_router(gwaddr, dev);
-+ else
-+ rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
-+ gwaddr, dev->ifindex);
-
- if (rt && !lifetime) {
- ip6_del_rt(rt);
-diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
-index 1926945..b433884 100644
---- a/net/ipv6/sit.c
-+++ b/net/ipv6/sit.c
-@@ -1594,6 +1594,15 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
- #endif
- };
-
-+static void ipip6_dellink(struct net_device *dev, struct list_head *head)
-+{
-+ struct net *net = dev_net(dev);
-+ struct sit_net *sitn = net_generic(net, sit_net_id);
-+
-+ if (dev != sitn->fb_tunnel_dev)
-+ unregister_netdevice_queue(dev, head);
-+}
-+
- static struct rtnl_link_ops sit_link_ops __read_mostly = {
- .kind = "sit",
- .maxtype = IFLA_IPTUN_MAX,
-@@ -1605,6 +1614,7 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = {
- .changelink = ipip6_changelink,
- .get_size = ipip6_get_size,
- .fill_info = ipip6_fill_info,
-+ .dellink = ipip6_dellink,
- };
-
- static struct xfrm_tunnel sit_handler __read_mostly = {
-@@ -1619,9 +1629,10 @@ static struct xfrm_tunnel ipip_handler __read_mostly = {
- .priority = 2,
- };
-
--static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
-+static void __net_exit sit_destroy_tunnels(struct net *net,
-+ struct list_head *head)
- {
-- struct net *net = dev_net(sitn->fb_tunnel_dev);
-+ struct sit_net *sitn = net_generic(net, sit_net_id);
- struct net_device *dev, *aux;
- int prio;
-
-@@ -1696,11 +1707,10 @@ err_alloc_dev:
-
- static void __net_exit sit_exit_net(struct net *net)
- {
-- struct sit_net *sitn = net_generic(net, sit_net_id);
- LIST_HEAD(list);
-
- rtnl_lock();
-- sit_destroy_tunnels(sitn, &list);
-+ sit_destroy_tunnels(net, &list);
- unregister_netdevice_many(&list);
- rtnl_unlock();
- }
-diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
-index 2ec6bf6..a7a2384 100644
---- a/net/ipv6/tcpv6_offload.c
-+++ b/net/ipv6/tcpv6_offload.c
-@@ -37,34 +37,32 @@ static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
- {
- const struct ipv6hdr *iph = skb_gro_network_header(skb);
- __wsum wsum;
-- __sum16 sum;
-+
-+ /* Don't bother verifying checksum if we're going to flush anyway. */
-+ if (NAPI_GRO_CB(skb)->flush)
-+ goto skip_csum;
-+
-+ wsum = skb->csum;
-
- switch (skb->ip_summed) {
-+ case CHECKSUM_NONE:
-+ wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
-+ wsum);
-+
-+ /* fall through */
-+
- case CHECKSUM_COMPLETE:
- if (!tcp_v6_check(skb_gro_len(skb), &iph->saddr, &iph->daddr,
-- skb->csum)) {
-+ wsum)) {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- break;
- }
--flush:
-+
- NAPI_GRO_CB(skb)->flush = 1;
- return NULL;
--
-- case CHECKSUM_NONE:
-- wsum = ~csum_unfold(csum_ipv6_magic(&iph->saddr, &iph->daddr,
-- skb_gro_len(skb),
-- IPPROTO_TCP, 0));
-- sum = csum_fold(skb_checksum(skb,
-- skb_gro_offset(skb),
-- skb_gro_len(skb),
-- wsum));
-- if (sum)
-- goto flush;
--
-- skb->ip_summed = CHECKSUM_UNNECESSARY;
-- break;
- }
-
-+skip_csum:
- return tcp_gro_receive(head, skb);
- }
-
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index 1878609..3d2758d 100644
---- a/net/ipv6/udp.c
-+++ b/net/ipv6/udp.c
-@@ -374,14 +374,11 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
- int is_udp4;
- bool slow;
-
-- if (addr_len)
-- *addr_len = sizeof(struct sockaddr_in6);
--
- if (flags & MSG_ERRQUEUE)
-- return ipv6_recv_error(sk, msg, len);
-+ return ipv6_recv_error(sk, msg, len, addr_len);
-
- if (np->rxpmtu && np->rxopt.bits.rxpmtu)
-- return ipv6_recv_rxpmtu(sk, msg, len);
-+ return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
-
- try_again:
- skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
-@@ -462,7 +459,7 @@ try_again:
- ipv6_iface_scope_id(&sin6->sin6_addr,
- IP6CB(skb)->iif);
- }
--
-+ *addr_len = sizeof(*sin6);
- }
- if (is_udp4) {
- if (inet->cmsg_flags)
-diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
-index 6055951..34c6fff 100644
---- a/net/ipv6/udp_offload.c
-+++ b/net/ipv6/udp_offload.c
-@@ -88,7 +88,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
-
- /* Check if there is enough headroom to insert fragment header. */
- tnl_hlen = skb_tnl_header_len(skb);
-- if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) {
-+ if (skb->mac_header < (tnl_hlen + frag_hdr_sz)) {
- if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz))
- goto out;
- }
-diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
-index 08ed277..550b195 100644
---- a/net/ipv6/xfrm6_policy.c
-+++ b/net/ipv6/xfrm6_policy.c
-@@ -135,10 +135,14 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
- struct ipv6_opt_hdr *exthdr;
- const unsigned char *nh = skb_network_header(skb);
- u8 nexthdr = nh[IP6CB(skb)->nhoff];
-+ int oif = 0;
-+
-+ if (skb_dst(skb))
-+ oif = skb_dst(skb)->dev->ifindex;
-
- memset(fl6, 0, sizeof(struct flowi6));
- fl6->flowi6_mark = skb->mark;
-- fl6->flowi6_oif = skb_dst(skb)->dev->ifindex;
-+ fl6->flowi6_oif = reverse ? skb->skb_iif : oif;
-
- fl6->daddr = reverse ? hdr->saddr : hdr->daddr;
- fl6->saddr = reverse ? hdr->daddr : hdr->saddr;
-diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
-index 7a1e0fc..e096025 100644
---- a/net/ipx/af_ipx.c
-+++ b/net/ipx/af_ipx.c
-@@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (skb->tstamp.tv64)
- sk->sk_stamp = skb->tstamp;
-
-- msg->msg_namelen = sizeof(*sipx);
--
- if (sipx) {
- sipx->sipx_family = AF_IPX;
- sipx->sipx_port = ipx->ipx_source.sock;
-@@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
- sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net;
- sipx->sipx_type = ipx->ipx_type;
- sipx->sipx_zero = 0;
-+ msg->msg_namelen = sizeof(*sipx);
- }
- rc = copied;
-
-diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
-index 0578d4f..a5e62ef5 100644
---- a/net/irda/af_irda.c
-+++ b/net/irda/af_irda.c
-@@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
-
- IRDA_DEBUG(4, "%s()\n", __func__);
-
-- msg->msg_namelen = 0;
--
- skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
- flags & MSG_DONTWAIT, &err);
- if (!skb)
-@@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, noblock);
-
-- msg->msg_namelen = 0;
--
- do {
- int chunk;
- struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
-diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
-index 168aff5..c4b7218 100644
---- a/net/iucv/af_iucv.c
-+++ b/net/iucv/af_iucv.c
-@@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
- int err = 0;
- u32 offset;
-
-- msg->msg_namelen = 0;
--
- if ((sk->sk_state == IUCV_DISCONN) &&
- skb_queue_empty(&iucv->backlog_skb_q) &&
- skb_queue_empty(&sk->sk_receive_queue) &&
-diff --git a/net/key/af_key.c b/net/key/af_key.c
-index 911ef03..545f047 100644
---- a/net/key/af_key.c
-+++ b/net/key/af_key.c
-@@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
- goto out;
-
-- msg->msg_namelen = 0;
- skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
- if (skb == NULL)
- goto out;
-diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
-index 571db8d..da1a1ce 100644
---- a/net/l2tp/l2tp_ip.c
-+++ b/net/l2tp/l2tp_ip.c
-@@ -518,9 +518,6 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
- if (flags & MSG_OOB)
- goto out;
-
-- if (addr_len)
-- *addr_len = sizeof(*sin);
--
- skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb)
- goto out;
-@@ -543,6 +540,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
- sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
- sin->sin_port = 0;
- memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
-+ *addr_len = sizeof(*sin);
- }
- if (inet->cmsg_flags)
- ip_cmsg_recv(msg, skb);
-diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
-index b8a6039..e6e8408 100644
---- a/net/l2tp/l2tp_ip6.c
-+++ b/net/l2tp/l2tp_ip6.c
-@@ -665,7 +665,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
- *addr_len = sizeof(*lsa);
-
- if (flags & MSG_ERRQUEUE)
-- return ipv6_recv_error(sk, msg, len);
-+ return ipv6_recv_error(sk, msg, len, addr_len);
-
- skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb)
-diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
-index 8c46b27..44441c0 100644
---- a/net/l2tp/l2tp_ppp.c
-+++ b/net/l2tp/l2tp_ppp.c
-@@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (sk->sk_state & PPPOX_BOUND)
- goto end;
-
-- msg->msg_namelen = 0;
--
- err = 0;
- skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
- flags & MSG_DONTWAIT, &err);
-diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
-index 6cba486..7b01b9f 100644
---- a/net/llc/af_llc.c
-+++ b/net/llc/af_llc.c
-@@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
- int target; /* Read at least this many bytes */
- long timeo;
-
-- msg->msg_namelen = 0;
--
- lock_sock(sk);
- copied = -ENOTCONN;
- if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
-diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
-index 74fd00c..3581736 100644
---- a/net/netfilter/ipvs/ip_vs_core.c
-+++ b/net/netfilter/ipvs/ip_vs_core.c
-@@ -1139,12 +1139,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
- ip_vs_fill_iph_skb(af, skb, &iph);
- #ifdef CONFIG_IP_VS_IPV6
- if (af == AF_INET6) {
-- if (!iph.fragoffs && skb_nfct_reasm(skb)) {
-- struct sk_buff *reasm = skb_nfct_reasm(skb);
-- /* Save fw mark for coming frags */
-- reasm->ipvs_property = 1;
-- reasm->mark = skb->mark;
-- }
- if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
- int related;
- int verdict = ip_vs_out_icmp_v6(skb, &related,
-@@ -1614,12 +1608,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
-
- #ifdef CONFIG_IP_VS_IPV6
- if (af == AF_INET6) {
-- if (!iph.fragoffs && skb_nfct_reasm(skb)) {
-- struct sk_buff *reasm = skb_nfct_reasm(skb);
-- /* Save fw mark for coming frags. */
-- reasm->ipvs_property = 1;
-- reasm->mark = skb->mark;
-- }
- if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
- int related;
- int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum,
-@@ -1671,9 +1659,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
- /* sorry, all this trouble for a no-hit :) */
- IP_VS_DBG_PKT(12, af, pp, skb, 0,
- "ip_vs_in: packet continues traversal as normal");
-- if (iph.fragoffs && !skb_nfct_reasm(skb)) {
-+ if (iph.fragoffs) {
- /* Fragment that couldn't be mapped to a conn entry
-- * and don't have any pointer to a reasm skb
- * is missing module nf_defrag_ipv6
- */
- IP_VS_DBG_RL("Unhandled frag, load nf_defrag_ipv6\n");
-@@ -1756,38 +1743,6 @@ ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb,
- #ifdef CONFIG_IP_VS_IPV6
-
- /*
-- * AF_INET6 fragment handling
-- * Copy info from first fragment, to the rest of them.
-- */
--static unsigned int
--ip_vs_preroute_frag6(unsigned int hooknum, struct sk_buff *skb,
-- const struct net_device *in,
-- const struct net_device *out,
-- int (*okfn)(struct sk_buff *))
--{
-- struct sk_buff *reasm = skb_nfct_reasm(skb);
-- struct net *net;
--
-- /* Skip if not a "replay" from nf_ct_frag6_output or first fragment.
-- * ipvs_property is set when checking first fragment
-- * in ip_vs_in() and ip_vs_out().
-- */
-- if (reasm)
-- IP_VS_DBG(2, "Fragment recv prop:%d\n", reasm->ipvs_property);
-- if (!reasm || !reasm->ipvs_property)
-- return NF_ACCEPT;
--
-- net = skb_net(skb);
-- if (!net_ipvs(net)->enable)
-- return NF_ACCEPT;
--
-- /* Copy stored fw mark, saved in ip_vs_{in,out} */
-- skb->mark = reasm->mark;
--
-- return NF_ACCEPT;
--}
--
--/*
- * AF_INET6 handler in NF_INET_LOCAL_IN chain
- * Schedule and forward packets from remote clients
- */
-@@ -1924,14 +1879,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
- .priority = 100,
- },
- #ifdef CONFIG_IP_VS_IPV6
-- /* After mangle & nat fetch 2:nd fragment and following */
-- {
-- .hook = ip_vs_preroute_frag6,
-- .owner = THIS_MODULE,
-- .pf = NFPROTO_IPV6,
-- .hooknum = NF_INET_PRE_ROUTING,
-- .priority = NF_IP6_PRI_NAT_DST + 1,
-- },
- /* After packet filtering, change source only for VS/NAT */
- {
- .hook = ip_vs_reply6,
-diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c
-index 9ef22bd..bed5f70 100644
---- a/net/netfilter/ipvs/ip_vs_pe_sip.c
-+++ b/net/netfilter/ipvs/ip_vs_pe_sip.c
-@@ -65,7 +65,6 @@ static int get_callid(const char *dptr, unsigned int dataoff,
- static int
- ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
- {
-- struct sk_buff *reasm = skb_nfct_reasm(skb);
- struct ip_vs_iphdr iph;
- unsigned int dataoff, datalen, matchoff, matchlen;
- const char *dptr;
-@@ -79,15 +78,10 @@ ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb)
- /* todo: IPv6 fragments:
- * I think this only should be done for the first fragment. /HS
- */
-- if (reasm) {
-- skb = reasm;
-- dataoff = iph.thoff_reasm + sizeof(struct udphdr);
-- } else
-- dataoff = iph.len + sizeof(struct udphdr);
-+ dataoff = iph.len + sizeof(struct udphdr);
-
- if (dataoff >= skb->len)
- return -EINVAL;
-- /* todo: Check if this will mess-up the reasm skb !!! /HS */
- retc = skb_linearize(skb);
- if (retc < 0)
- return retc;
-diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
-index 8df7f64..6135635 100644
---- a/net/netlink/af_netlink.c
-+++ b/net/netlink/af_netlink.c
-@@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
- }
- #endif
-
-- msg->msg_namelen = 0;
--
- copied = data_skb->len;
- if (len < copied) {
- msg->msg_flags |= MSG_TRUNC;
-diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
-index 698814b..53c19a3 100644
---- a/net/netrom/af_netrom.c
-+++ b/net/netrom/af_netrom.c
-@@ -1179,10 +1179,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
- sax->sax25_family = AF_NETROM;
- skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
- AX25_ADDR_LEN);
-+ msg->msg_namelen = sizeof(*sax);
- }
-
-- msg->msg_namelen = sizeof(*sax);
--
- skb_free_datagram(sk, skb);
-
- release_sock(sk);
-diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
-index d308402..824c605 100644
---- a/net/nfc/llcp_sock.c
-+++ b/net/nfc/llcp_sock.c
-@@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- pr_debug("%p %zu\n", sk, len);
-
-- msg->msg_namelen = 0;
--
- lock_sock(sk);
-
- if (sk->sk_state == LLCP_CLOSED &&
-diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
-index 313bf1b..5d11f4a 100644
---- a/net/nfc/rawsock.c
-+++ b/net/nfc/rawsock.c
-@@ -241,8 +241,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (!skb)
- return rc;
-
-- msg->msg_namelen = 0;
--
- copied = skb->len;
- if (len < copied) {
- msg->msg_flags |= MSG_TRUNC;
-diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
-index 2e8286b..ba2548b 100644
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -244,11 +244,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
- static void register_prot_hook(struct sock *sk)
- {
- struct packet_sock *po = pkt_sk(sk);
-+
- if (!po->running) {
-- if (po->fanout)
-+ if (po->fanout) {
- __fanout_link(sk, po);
-- else
-+ } else {
- dev_add_pack(&po->prot_hook);
-+ rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
-+ }
-+
- sock_hold(sk);
- po->running = 1;
- }
-@@ -266,10 +270,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
- struct packet_sock *po = pkt_sk(sk);
-
- po->running = 0;
-- if (po->fanout)
-+ if (po->fanout) {
- __fanout_unlink(sk, po);
-- else
-+ } else {
- __dev_remove_pack(&po->prot_hook);
-+ RCU_INIT_POINTER(po->cached_dev, NULL);
-+ }
-+
- __sock_put(sk);
-
- if (sync) {
-@@ -432,9 +439,9 @@ static void prb_shutdown_retire_blk_timer(struct packet_sock *po,
-
- pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
-
-- spin_lock(&rb_queue->lock);
-+ spin_lock_bh(&rb_queue->lock);
- pkc->delete_blk_timer = 1;
-- spin_unlock(&rb_queue->lock);
-+ spin_unlock_bh(&rb_queue->lock);
-
- prb_del_retire_blk_timer(pkc);
- }
-@@ -2052,12 +2059,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
- return tp_len;
- }
-
-+static struct net_device *packet_cached_dev_get(struct packet_sock *po)
-+{
-+ struct net_device *dev;
-+
-+ rcu_read_lock();
-+ dev = rcu_dereference(po->cached_dev);
-+ if (dev)
-+ dev_hold(dev);
-+ rcu_read_unlock();
-+
-+ return dev;
-+}
-+
- static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
- {
- struct sk_buff *skb;
- struct net_device *dev;
- __be16 proto;
-- bool need_rls_dev = false;
- int err, reserve = 0;
- void *ph;
- struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
-@@ -2070,7 +2089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
- mutex_lock(&po->pg_vec_lock);
-
- if (saddr == NULL) {
-- dev = po->prot_hook.dev;
-+ dev = packet_cached_dev_get(po);
- proto = po->num;
- addr = NULL;
- } else {
-@@ -2084,19 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
- proto = saddr->sll_protocol;
- addr = saddr->sll_addr;
- dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
-- need_rls_dev = true;
- }
-
- err = -ENXIO;
- if (unlikely(dev == NULL))
- goto out;
--
-- reserve = dev->hard_header_len;
--
- err = -ENETDOWN;
- if (unlikely(!(dev->flags & IFF_UP)))
- goto out_put;
-
-+ reserve = dev->hard_header_len;
-+
- size_max = po->tx_ring.frame_size
- - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
-
-@@ -2173,8 +2190,7 @@ out_status:
- __packet_set_status(po, ph, status);
- kfree_skb(skb);
- out_put:
-- if (need_rls_dev)
-- dev_put(dev);
-+ dev_put(dev);
- out:
- mutex_unlock(&po->pg_vec_lock);
- return err;
-@@ -2212,7 +2228,6 @@ static int packet_snd(struct socket *sock,
- struct sk_buff *skb;
- struct net_device *dev;
- __be16 proto;
-- bool need_rls_dev = false;
- unsigned char *addr;
- int err, reserve = 0;
- struct virtio_net_hdr vnet_hdr = { 0 };
-@@ -2228,7 +2243,7 @@ static int packet_snd(struct socket *sock,
- */
-
- if (saddr == NULL) {
-- dev = po->prot_hook.dev;
-+ dev = packet_cached_dev_get(po);
- proto = po->num;
- addr = NULL;
- } else {
-@@ -2240,19 +2255,17 @@ static int packet_snd(struct socket *sock,
- proto = saddr->sll_protocol;
- addr = saddr->sll_addr;
- dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
-- need_rls_dev = true;
- }
-
- err = -ENXIO;
-- if (dev == NULL)
-+ if (unlikely(dev == NULL))
- goto out_unlock;
-- if (sock->type == SOCK_RAW)
-- reserve = dev->hard_header_len;
--
- err = -ENETDOWN;
-- if (!(dev->flags & IFF_UP))
-+ if (unlikely(!(dev->flags & IFF_UP)))
- goto out_unlock;
-
-+ if (sock->type == SOCK_RAW)
-+ reserve = dev->hard_header_len;
- if (po->has_vnet_hdr) {
- vnet_hdr_len = sizeof(vnet_hdr);
-
-@@ -2386,15 +2399,14 @@ static int packet_snd(struct socket *sock,
- if (err > 0 && (err = net_xmit_errno(err)) != 0)
- goto out_unlock;
-
-- if (need_rls_dev)
-- dev_put(dev);
-+ dev_put(dev);
-
- return len;
-
- out_free:
- kfree_skb(skb);
- out_unlock:
-- if (dev && need_rls_dev)
-+ if (dev)
- dev_put(dev);
- out:
- return err;
-@@ -2614,6 +2626,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
- po = pkt_sk(sk);
- sk->sk_family = PF_PACKET;
- po->num = proto;
-+ RCU_INIT_POINTER(po->cached_dev, NULL);
-
- sk->sk_destruct = packet_sock_destruct;
- sk_refcnt_debug_inc(sk);
-@@ -2660,7 +2673,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int copied, err;
-- struct sockaddr_ll *sll;
- int vnet_hdr_len = 0;
-
- err = -EINVAL;
-@@ -2744,22 +2756,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
- goto out_free;
- }
-
-- /*
-- * If the address length field is there to be filled in, we fill
-- * it in now.
-+ /* You lose any data beyond the buffer you gave. If it worries
-+ * a user program they can ask the device for its MTU
-+ * anyway.
- */
--
-- sll = &PACKET_SKB_CB(skb)->sa.ll;
-- if (sock->type == SOCK_PACKET)
-- msg->msg_namelen = sizeof(struct sockaddr_pkt);
-- else
-- msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
--
-- /*
-- * You lose any data beyond the buffer you gave. If it worries a
-- * user program they can ask the device for its MTU anyway.
-- */
--
- copied = skb->len;
- if (copied > len) {
- copied = len;
-@@ -2772,9 +2772,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- sock_recv_ts_and_drops(msg, sk, skb);
-
-- if (msg->msg_name)
-+ if (msg->msg_name) {
-+ /* If the address length field is there to be filled
-+ * in, we fill it in now.
-+ */
-+ if (sock->type == SOCK_PACKET) {
-+ msg->msg_namelen = sizeof(struct sockaddr_pkt);
-+ } else {
-+ struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
-+ msg->msg_namelen = sll->sll_halen +
-+ offsetof(struct sockaddr_ll, sll_addr);
-+ }
- memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
- msg->msg_namelen);
-+ }
-
- if (pkt_sk(sk)->auxdata) {
- struct tpacket_auxdata aux;
-diff --git a/net/packet/internal.h b/net/packet/internal.h
-index c4e4b45..1035fa2 100644
---- a/net/packet/internal.h
-+++ b/net/packet/internal.h
-@@ -113,6 +113,7 @@ struct packet_sock {
- unsigned int tp_loss:1;
- unsigned int tp_tx_has_off:1;
- unsigned int tp_tstamp;
-+ struct net_device __rcu *cached_dev;
- struct packet_type prot_hook ____cacheline_aligned_in_smp;
- };
-
-diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
-index 12c30f3..38946b2 100644
---- a/net/phonet/datagram.c
-+++ b/net/phonet/datagram.c
-@@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
- MSG_CMSG_COMPAT))
- goto out_nofree;
-
-- if (addr_len)
-- *addr_len = sizeof(sa);
--
- skb = skb_recv_datagram(sk, flags, noblock, &rval);
- if (skb == NULL)
- goto out_nofree;
-@@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
-
- rval = (flags & MSG_TRUNC) ? skb->len : copylen;
-
-- if (msg->msg_name != NULL)
-- memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
-+ if (msg->msg_name != NULL) {
-+ memcpy(msg->msg_name, &sa, sizeof(sa));
-+ *addr_len = sizeof(sa);
-+ }
-
- out:
- skb_free_datagram(sk, skb);
-diff --git a/net/rds/recv.c b/net/rds/recv.c
-index 9f0f17c..de339b2 100644
---- a/net/rds/recv.c
-+++ b/net/rds/recv.c
-@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
-
- rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
-
-- msg->msg_namelen = 0;
--
- if (msg_flags & MSG_OOB)
- goto out;
-
-diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
-index e98fcfb..33af772 100644
---- a/net/rose/af_rose.c
-+++ b/net/rose/af_rose.c
-@@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
- {
- struct sock *sk = sock->sk;
- struct rose_sock *rose = rose_sk(sk);
-- struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
- size_t copied;
- unsigned char *asmptr;
- struct sk_buff *skb;
-@@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (srose != NULL) {
-- memset(srose, 0, msg->msg_namelen);
-+ if (msg->msg_name) {
-+ struct sockaddr_rose *srose;
-+
-+ memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
-+ srose = msg->msg_name;
- srose->srose_family = AF_ROSE;
- srose->srose_addr = rose->dest_addr;
- srose->srose_call = rose->dest_call;
-diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c
-index 4b48687..898492a 100644
---- a/net/rxrpc/ar-recvmsg.c
-+++ b/net/rxrpc/ar-recvmsg.c
-@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
-
- /* copy the peer address and timestamp */
- if (!continue_call) {
-- if (msg->msg_name && msg->msg_namelen > 0)
-+ if (msg->msg_name) {
-+ size_t len =
-+ sizeof(call->conn->trans->peer->srx);
- memcpy(msg->msg_name,
-- &call->conn->trans->peer->srx,
-- sizeof(call->conn->trans->peer->srx));
-+ &call->conn->trans->peer->srx, len);
-+ msg->msg_namelen = len;
-+ }
- sock_recv_ts_and_drops(msg, &rx->sk, skb);
- }
-
-diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
-index a9dfdda..2e55f81 100644
---- a/net/sched/sch_fq.c
-+++ b/net/sched/sch_fq.c
-@@ -88,7 +88,7 @@ struct fq_sched_data {
- struct fq_flow internal; /* for non classified or high prio packets */
- u32 quantum;
- u32 initial_quantum;
-- u32 flow_default_rate;/* rate per flow : bytes per second */
-+ u32 flow_refill_delay;
- u32 flow_max_rate; /* optional max rate per flow */
- u32 flow_plimit; /* max packets per flow */
- struct rb_root *fq_root;
-@@ -115,6 +115,7 @@ static struct fq_flow detached, throttled;
- static void fq_flow_set_detached(struct fq_flow *f)
- {
- f->next = &detached;
-+ f->age = jiffies;
- }
-
- static bool fq_flow_is_detached(const struct fq_flow *f)
-@@ -209,21 +210,15 @@ static void fq_gc(struct fq_sched_data *q,
- }
- }
-
--static const u8 prio2band[TC_PRIO_MAX + 1] = {
-- 1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
--};
--
- static struct fq_flow *fq_classify(struct sk_buff *skb, struct fq_sched_data *q)
- {
- struct rb_node **p, *parent;
- struct sock *sk = skb->sk;
- struct rb_root *root;
- struct fq_flow *f;
-- int band;
-
- /* warning: no starvation prevention... */
-- band = prio2band[skb->priority & TC_PRIO_MAX];
-- if (unlikely(band == 0))
-+ if (unlikely((skb->priority & TC_PRIO_MAX) == TC_PRIO_CONTROL))
- return &q->internal;
-
- if (unlikely(!sk)) {
-@@ -372,17 +367,20 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
- }
-
- f->qlen++;
-- flow_queue_add(f, skb);
- if (skb_is_retransmit(skb))
- q->stat_tcp_retrans++;
- sch->qstats.backlog += qdisc_pkt_len(skb);
- if (fq_flow_is_detached(f)) {
- fq_flow_add_tail(&q->new_flows, f);
-- if (q->quantum > f->credit)
-- f->credit = q->quantum;
-+ if (time_after(jiffies, f->age + q->flow_refill_delay))
-+ f->credit = max_t(u32, f->credit, q->quantum);
- q->inactive_flows--;
- qdisc_unthrottled(sch);
- }
-+
-+ /* Note: this overwrites f->age */
-+ flow_queue_add(f, skb);
-+
- if (unlikely(f == &q->internal)) {
- q->stat_internal_packets++;
- qdisc_unthrottled(sch);
-@@ -460,7 +458,6 @@ begin:
- fq_flow_add_tail(&q->old_flows, f);
- } else {
- fq_flow_set_detached(f);
-- f->age = jiffies;
- q->inactive_flows++;
- }
- goto begin;
-@@ -614,6 +611,7 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
- [TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 },
- [TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
- [TCA_FQ_BUCKETS_LOG] = { .type = NLA_U32 },
-+ [TCA_FQ_FLOW_REFILL_DELAY] = { .type = NLA_U32 },
- };
-
- static int fq_change(struct Qdisc *sch, struct nlattr *opt)
-@@ -655,7 +653,8 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
- q->initial_quantum = nla_get_u32(tb[TCA_FQ_INITIAL_QUANTUM]);
-
- if (tb[TCA_FQ_FLOW_DEFAULT_RATE])
-- q->flow_default_rate = nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]);
-+ pr_warn_ratelimited("sch_fq: defrate %u ignored.\n",
-+ nla_get_u32(tb[TCA_FQ_FLOW_DEFAULT_RATE]));
-
- if (tb[TCA_FQ_FLOW_MAX_RATE])
- q->flow_max_rate = nla_get_u32(tb[TCA_FQ_FLOW_MAX_RATE]);
-@@ -669,6 +668,12 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt)
- err = -EINVAL;
- }
-
-+ if (tb[TCA_FQ_FLOW_REFILL_DELAY]) {
-+ u32 usecs_delay = nla_get_u32(tb[TCA_FQ_FLOW_REFILL_DELAY]) ;
-+
-+ q->flow_refill_delay = usecs_to_jiffies(usecs_delay);
-+ }
-+
- if (!err)
- err = fq_resize(q, fq_log);
-
-@@ -704,7 +709,7 @@ static int fq_init(struct Qdisc *sch, struct nlattr *opt)
- q->flow_plimit = 100;
- q->quantum = 2 * psched_mtu(qdisc_dev(sch));
- q->initial_quantum = 10 * psched_mtu(qdisc_dev(sch));
-- q->flow_default_rate = 0;
-+ q->flow_refill_delay = msecs_to_jiffies(40);
- q->flow_max_rate = ~0U;
- q->rate_enable = 1;
- q->new_flows.first = NULL;
-@@ -731,15 +736,16 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
- if (opts == NULL)
- goto nla_put_failure;
-
-- /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore,
-- * do not bother giving its value
-- */
-+ /* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore */
-+
- if (nla_put_u32(skb, TCA_FQ_PLIMIT, sch->limit) ||
- nla_put_u32(skb, TCA_FQ_FLOW_PLIMIT, q->flow_plimit) ||
- nla_put_u32(skb, TCA_FQ_QUANTUM, q->quantum) ||
- nla_put_u32(skb, TCA_FQ_INITIAL_QUANTUM, q->initial_quantum) ||
- nla_put_u32(skb, TCA_FQ_RATE_ENABLE, q->rate_enable) ||
- nla_put_u32(skb, TCA_FQ_FLOW_MAX_RATE, q->flow_max_rate) ||
-+ nla_put_u32(skb, TCA_FQ_FLOW_REFILL_DELAY,
-+ jiffies_to_usecs(q->flow_refill_delay)) ||
- nla_put_u32(skb, TCA_FQ_BUCKETS_LOG, q->fq_trees_log))
- goto nla_put_failure;
-
-diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
-index 1aaf1b6..6ddda28 100644
---- a/net/sched/sch_tbf.c
-+++ b/net/sched/sch_tbf.c
-@@ -21,6 +21,7 @@
- #include <net/netlink.h>
- #include <net/sch_generic.h>
- #include <net/pkt_sched.h>
-+#include <net/tcp.h>
-
-
- /* Simple Token Bucket Filter.
-@@ -117,6 +118,22 @@ struct tbf_sched_data {
- };
-
-
-+/*
-+ * Return length of individual segments of a gso packet,
-+ * including all headers (MAC, IP, TCP/UDP)
-+ */
-+static unsigned int skb_gso_seglen(const struct sk_buff *skb)
-+{
-+ unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb);
-+ const struct skb_shared_info *shinfo = skb_shinfo(skb);
-+
-+ if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
-+ hdr_len += tcp_hdrlen(skb);
-+ else
-+ hdr_len += sizeof(struct udphdr);
-+ return hdr_len + shinfo->gso_size;
-+}
-+
- /* GSO packet is too big, segment it so that tbf can transmit
- * each segment in time
- */
-@@ -136,12 +153,8 @@ static int tbf_segment(struct sk_buff *skb, struct Qdisc *sch)
- while (segs) {
- nskb = segs->next;
- segs->next = NULL;
-- if (likely(segs->len <= q->max_size)) {
-- qdisc_skb_cb(segs)->pkt_len = segs->len;
-- ret = qdisc_enqueue(segs, q->qdisc);
-- } else {
-- ret = qdisc_reshape_fail(skb, sch);
-- }
-+ qdisc_skb_cb(segs)->pkt_len = segs->len;
-+ ret = qdisc_enqueue(segs, q->qdisc);
- if (ret != NET_XMIT_SUCCESS) {
- if (net_xmit_drop_count(ret))
- sch->qstats.drops++;
-@@ -163,7 +176,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
- int ret;
-
- if (qdisc_pkt_len(skb) > q->max_size) {
-- if (skb_is_gso(skb))
-+ if (skb_is_gso(skb) && skb_gso_seglen(skb) <= q->max_size)
- return tbf_segment(skb, sch);
- return qdisc_reshape_fail(skb, sch);
- }
-@@ -316,6 +329,11 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
- if (max_size < 0)
- goto done;
-
-+ if (max_size < psched_mtu(qdisc_dev(sch)))
-+ pr_warn_ratelimited("sch_tbf: burst %u is lower than device %s mtu (%u) !\n",
-+ max_size, qdisc_dev(sch)->name,
-+ psched_mtu(qdisc_dev(sch)));
-+
- if (q->qdisc != &noop_qdisc) {
- err = fifo_set_limit(q->qdisc, qopt->limit);
- if (err)
-diff --git a/net/socket.c b/net/socket.c
-index c226ace..e83c416 100644
---- a/net/socket.c
-+++ b/net/socket.c
-@@ -221,12 +221,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
- int err;
- int len;
-
-+ BUG_ON(klen > sizeof(struct sockaddr_storage));
- err = get_user(len, ulen);
- if (err)
- return err;
- if (len > klen)
- len = klen;
-- if (len < 0 || len > sizeof(struct sockaddr_storage))
-+ if (len < 0)
- return -EINVAL;
- if (len) {
- if (audit_sockaddr(klen, kaddr))
-@@ -1840,8 +1841,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
- msg.msg_iov = &iov;
- iov.iov_len = size;
- iov.iov_base = ubuf;
-- msg.msg_name = (struct sockaddr *)&address;
-- msg.msg_namelen = sizeof(address);
-+ /* Save some cycles and don't copy the address if not needed */
-+ msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
-+ /* We assume all kernel code knows the size of sockaddr_storage */
-+ msg.msg_namelen = 0;
- if (sock->file->f_flags & O_NONBLOCK)
- flags |= MSG_DONTWAIT;
- err = sock_recvmsg(sock, &msg, size, flags);
-@@ -1970,7 +1973,7 @@ static int copy_msghdr_from_user(struct msghdr *kmsg,
- if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
- return -EFAULT;
- if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
-- return -EINVAL;
-+ kmsg->msg_namelen = sizeof(struct sockaddr_storage);
- return 0;
- }
-
-@@ -2221,16 +2224,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
- goto out;
- }
-
-- /*
-- * Save the user-mode address (verify_iovec will change the
-- * kernel msghdr to use the kernel address space)
-+ /* Save the user-mode address (verify_iovec will change the
-+ * kernel msghdr to use the kernel address space)
- */
--
- uaddr = (__force void __user *)msg_sys->msg_name;
- uaddr_len = COMPAT_NAMELEN(msg);
-- if (MSG_CMSG_COMPAT & flags) {
-+ if (MSG_CMSG_COMPAT & flags)
- err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-- } else
-+ else
- err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
- if (err < 0)
- goto out_freeiov;
-@@ -2239,6 +2240,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
- cmsg_ptr = (unsigned long)msg_sys->msg_control;
- msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
-
-+ /* We assume all kernel code knows the size of sockaddr_storage */
-+ msg_sys->msg_namelen = 0;
-+
- if (sock->file->f_flags & O_NONBLOCK)
- flags |= MSG_DONTWAIT;
- err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
-diff --git a/net/tipc/socket.c b/net/tipc/socket.c
-index 6cc7ddd..dffdbea 100644
---- a/net/tipc/socket.c
-+++ b/net/tipc/socket.c
-@@ -984,9 +984,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
- goto exit;
- }
-
-- /* will be updated in set_orig_addr() if needed */
-- m->msg_namelen = 0;
--
- timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
- restart:
-
-@@ -1095,9 +1092,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
- goto exit;
- }
-
-- /* will be updated in set_orig_addr() if needed */
-- m->msg_namelen = 0;
--
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
- timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
-diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index c1f403b..01625cc 100644
---- a/net/unix/af_unix.c
-+++ b/net/unix/af_unix.c
-@@ -1754,7 +1754,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
- {
- struct unix_sock *u = unix_sk(sk);
-
-- msg->msg_namelen = 0;
- if (u->addr) {
- msg->msg_namelen = u->addr->len;
- memcpy(msg->msg_name, u->addr->name, u->addr->len);
-@@ -1778,8 +1777,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (flags&MSG_OOB)
- goto out;
-
-- msg->msg_namelen = 0;
--
- err = mutex_lock_interruptible(&u->readlock);
- if (err) {
- err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
-@@ -1924,8 +1921,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
- target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
-
-- msg->msg_namelen = 0;
--
- /* Lock the socket to prevent queue disordering
- * while sleeps in memcpy_tomsg
- */
-diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
-index 545c08b..5adfd94 100644
---- a/net/vmw_vsock/af_vsock.c
-+++ b/net/vmw_vsock/af_vsock.c
-@@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
- vsk = vsock_sk(sk);
- err = 0;
-
-- msg->msg_namelen = 0;
--
- lock_sock(sk);
-
- if (sk->sk_state != SS_CONNECTED) {
-diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
-index 9d69866..687360d 100644
---- a/net/vmw_vsock/vmci_transport.c
-+++ b/net/vmw_vsock/vmci_transport.c
-@@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
- if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
- return -EOPNOTSUPP;
-
-- msg->msg_namelen = 0;
--
- /* Retrieve the head sk_buff from the socket's receive queue. */
- err = 0;
- skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
-diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
-index 45a3ab5..7622789 100644
---- a/net/x25/af_x25.c
-+++ b/net/x25/af_x25.c
-@@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
- if (sx25) {
- sx25->sx25_family = AF_X25;
- sx25->sx25_addr = x25->dest_addr;
-+ msg->msg_namelen = sizeof(*sx25);
- }
-
-- msg->msg_namelen = sizeof(struct sockaddr_x25);
--
- x25_check_rbuf(sk);
- rc = copied;
- out_free_dgram:
diff --git a/3.12.4/0000_README b/3.12.5/0000_README
index 3cb0775..374fa29 100644
--- a/3.12.4/0000_README
+++ b/3.12.5/0000_README
@@ -2,11 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1003_linux-3.12.4.patch
-From: http://www.kernel.org
-Desc: Linux 3.12.4
-
-Patch: 4420_grsecurity-3.0-3.12.4-201312081754.patch
+Patch: 4420_grsecurity-3.0-3.12.5-201312132204.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.12.4/4420_grsecurity-3.0-3.12.4-201312081754.patch b/3.12.5/4420_grsecurity-3.0-3.12.5-201312132204.patch
index fa9c2c7..013a53f 100644
--- a/3.12.4/4420_grsecurity-3.0-3.12.4-201312081754.patch
+++ b/3.12.5/4420_grsecurity-3.0-3.12.5-201312132204.patch
@@ -281,7 +281,7 @@ index fcbb736..5508d8c 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 3b7165e..9112a63 100644
+index 986f3cd..8691deb 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -1968,7 +1968,7 @@ index 5689c18..eea12f9 100644
#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
-index be956db..c8f25e2 100644
+index 1571d12..b8a9b43 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -33,6 +33,9 @@
@@ -4123,7 +4123,7 @@ index f123d6e..04bf569 100644
return __arm_ioremap_caller(phys_addr, size, mtype,
__builtin_return_address(0));
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
-index 0c63562..7128a90 100644
+index 304661d..53a6b19 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -59,6 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
@@ -7242,7 +7242,7 @@ index 2a625fb..9908930 100644
DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
me->arch.unwind_section, table, end, gp);
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
-index 5dfd248..64914ac 100644
+index 0d3a9d4..44975d0 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -33,9 +33,11 @@
@@ -7266,29 +7266,26 @@ index 5dfd248..64914ac 100644
return vm_unmapped_area(&info);
}
-@@ -61,10 +64,11 @@ static int get_offset(struct address_space *mapping)
- return (unsigned long) mapping >> 8;
+@@ -69,15 +72,17 @@ static unsigned long shared_align_offset(struct file *filp, unsigned long pgoff)
}
--static unsigned long get_shared_area(struct address_space *mapping,
-- unsigned long addr, unsigned long len, unsigned long pgoff)
-+static unsigned long get_shared_area(struct file *filp, struct address_space *mapping,
-+ unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+ static unsigned long get_shared_area(struct file *filp, unsigned long addr,
+- unsigned long len, unsigned long pgoff)
++ unsigned long len, unsigned long pgoff, unsigned long flags)
{
struct vm_unmapped_area_info info;
+ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
info.flags = 0;
info.length = len;
-@@ -72,6 +76,7 @@ static unsigned long get_shared_area(struct address_space *mapping,
+ info.low_limit = PAGE_ALIGN(addr);
info.high_limit = TASK_SIZE;
info.align_mask = PAGE_MASK & (SHMLBA - 1);
- info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
+ info.threadstack_offset = offset;
+ info.align_offset = shared_align_offset(filp, pgoff);
return vm_unmapped_area(&info);
}
-
-@@ -86,15 +91,22 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+@@ -93,13 +98,20 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
return -EINVAL;
return addr;
}
@@ -7303,16 +7300,13 @@ index 5dfd248..64914ac 100644
+
+ }
+
- if (filp) {
-- addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
-+ addr = get_shared_area(filp, filp->f_mapping, addr, len, pgoff, flags);
- } else if(flags & MAP_SHARED) {
-- addr = get_shared_area(NULL, addr, len, pgoff);
-+ addr = get_shared_area(filp, NULL, addr, len, pgoff, flags);
- } else {
+ if (filp || (flags & MAP_SHARED))
+- addr = get_shared_area(filp, addr, len, pgoff);
++ addr = get_shared_area(filp, addr, len, pgoff, flags);
+ else
- addr = get_unshared_area(addr, len);
-+ addr = get_unshared_area(filp, addr, len, flags);
- }
++ addr = get_unshared_area(addr, len, flags);
+
return addr;
}
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
@@ -11748,10 +11742,10 @@ index 78d91af..8ceb94b 100644
This option helps catch unintended modifications to loadable
kernel module's text and read-only data. It also prevents execution
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
-index 41250fb..863762e 100644
+index eda00f9..c511701 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
-@@ -46,14 +46,12 @@ ifeq ($(CONFIG_X86_32),y)
+@@ -49,14 +49,12 @@ ifeq ($(CONFIG_X86_32),y)
# CPU-specific tuning. Anything which can be shared with UML should go here.
include $(srctree)/arch/x86/Makefile_32.cpu
KBUILD_CFLAGS += $(cflags-y)
@@ -11767,7 +11761,7 @@ index 41250fb..863762e 100644
KBUILD_AFLAGS += -m64
KBUILD_CFLAGS += -m64
-@@ -83,6 +81,9 @@ else
+@@ -89,6 +87,9 @@ else
KBUILD_CFLAGS += -maccumulate-outgoing-args
endif
@@ -11777,7 +11771,7 @@ index 41250fb..863762e 100644
ifdef CONFIG_CC_STACKPROTECTOR
cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
-@@ -241,3 +242,12 @@ define archhelp
+@@ -247,3 +248,12 @@ define archhelp
echo ' FDINITRD=file initrd for the booted kernel'
echo ' kvmconfig - Enable additional options for guest kernel support'
endef
@@ -12159,7 +12153,7 @@ index 43eda28..5ab5fdb 100644
unsigned int v;
diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
-index 9105655..5e37f27 100644
+index 9105655..41779c1 100644
--- a/arch/x86/crypto/aes-x86_64-asm_64.S
+++ b/arch/x86/crypto/aes-x86_64-asm_64.S
@@ -8,6 +8,8 @@
@@ -12175,13 +12169,13 @@ index 9105655..5e37f27 100644
je B192; \
leaq 32(r9),r9;
-+#define ret pax_force_retaddr 0, 1; ret
++#define ret pax_force_retaddr; ret
+
#define epilogue(FUNC,r1,r2,r3,r4,r5,r6,r7,r8,r9) \
movq r1,r2; \
movq r3,r4; \
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
-index 477e9d7..3ab339f 100644
+index 477e9d7..c92c7d8 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -31,6 +31,7 @@
@@ -12192,19 +12186,240 @@ index 477e9d7..3ab339f 100644
#ifdef __x86_64__
.data
-@@ -1441,6 +1442,7 @@ _return_T_done_decrypt:
+@@ -205,7 +206,7 @@ enc: .octa 0x2
+ * num_initial_blocks = b mod 4
+ * encrypt the initial num_initial_blocks blocks and apply ghash on
+ * the ciphertext
+-* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
++* %r10, %r11, %r15, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+ * are clobbered
+ * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+ */
+@@ -214,8 +215,8 @@ enc: .octa 0x2
+ .macro INITIAL_BLOCKS_DEC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \
+ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ mov arg7, %r10 # %r10 = AAD
+- mov arg8, %r12 # %r12 = aadLen
+- mov %r12, %r11
++ mov arg8, %r15 # %r15 = aadLen
++ mov %r15, %r11
+ pxor %xmm\i, %xmm\i
+ _get_AAD_loop\num_initial_blocks\operation:
+ movd (%r10), \TMP1
+@@ -223,15 +224,15 @@ _get_AAD_loop\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+- sub $4, %r12
++ sub $4, %r15
+ jne _get_AAD_loop\num_initial_blocks\operation
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+- mov $16, %r12
++ mov $16, %r15
+ _get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+- sub $4, %r12
+- cmp %r11, %r12
++ sub $4, %r15
++ cmp %r11, %r15
+ jne _get_AAD_loop2\num_initial_blocks\operation
+ _get_AAD_loop2_done\num_initial_blocks\operation:
+ movdqa SHUF_MASK(%rip), %xmm14
+@@ -443,7 +444,7 @@ _initial_blocks_done\num_initial_blocks\operation:
+ * num_initial_blocks = b mod 4
+ * encrypt the initial num_initial_blocks blocks and apply ghash on
+ * the ciphertext
+-* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
++* %r10, %r11, %r15, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+ * are clobbered
+ * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+ */
+@@ -452,8 +453,8 @@ _initial_blocks_done\num_initial_blocks\operation:
+ .macro INITIAL_BLOCKS_ENC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \
+ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ mov arg7, %r10 # %r10 = AAD
+- mov arg8, %r12 # %r12 = aadLen
+- mov %r12, %r11
++ mov arg8, %r15 # %r15 = aadLen
++ mov %r15, %r11
+ pxor %xmm\i, %xmm\i
+ _get_AAD_loop\num_initial_blocks\operation:
+ movd (%r10), \TMP1
+@@ -461,15 +462,15 @@ _get_AAD_loop\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+- sub $4, %r12
++ sub $4, %r15
+ jne _get_AAD_loop\num_initial_blocks\operation
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+- mov $16, %r12
++ mov $16, %r15
+ _get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+- sub $4, %r12
+- cmp %r11, %r12
++ sub $4, %r15
++ cmp %r11, %r15
+ jne _get_AAD_loop2\num_initial_blocks\operation
+ _get_AAD_loop2_done\num_initial_blocks\operation:
+ movdqa SHUF_MASK(%rip), %xmm14
+@@ -1269,7 +1270,7 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
+ *
+ *****************************************************************************/
+ ENTRY(aesni_gcm_dec)
+- push %r12
++ push %r15
+ push %r13
+ push %r14
+ mov %rsp, %r14
+@@ -1279,8 +1280,8 @@ ENTRY(aesni_gcm_dec)
+ */
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp # align rsp to 64 bytes
+- mov %arg6, %r12
+- movdqu (%r12), %xmm13 # %xmm13 = HashKey
++ mov %arg6, %r15
++ movdqu (%r15), %xmm13 # %xmm13 = HashKey
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+@@ -1308,10 +1309,10 @@ ENTRY(aesni_gcm_dec)
+ movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly)
+ mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext
+ and $-16, %r13 # %r13 = %r13 - (%r13 mod 16)
+- mov %r13, %r12
+- and $(3<<4), %r12
++ mov %r13, %r15
++ and $(3<<4), %r15
+ jz _initial_num_blocks_is_0_decrypt
+- cmp $(2<<4), %r12
++ cmp $(2<<4), %r15
+ jb _initial_num_blocks_is_1_decrypt
+ je _initial_num_blocks_is_2_decrypt
+ _initial_num_blocks_is_3_decrypt:
+@@ -1361,16 +1362,16 @@ _zero_cipher_left_decrypt:
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte block
+- lea SHIFT_MASK+16(%rip), %r12
+- sub %r13, %r12
++ lea SHIFT_MASK+16(%rip), %r15
++ sub %r13, %r15
+ # adjust the shuffle mask pointer to be able to shift 16-%r13 bytes
+ # (%r13 is the number of bytes in plaintext mod 16)
+- movdqu (%r12), %xmm2 # get the appropriate shuffle mask
++ movdqu (%r15), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes
+
+ movdqa %xmm1, %xmm2
+ pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn)
+- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
++ movdqu ALL_F-SHIFT_MASK(%r15), %xmm1
+ # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm2
+@@ -1399,9 +1400,9 @@ _less_than_8_bytes_left_decrypt:
+ sub $1, %r13
+ jne _less_than_8_bytes_left_decrypt
+ _multiple_of_16_bytes_decrypt:
+- mov arg8, %r12 # %r13 = aadLen (number of bytes)
+- shl $3, %r12 # convert into number of bits
+- movd %r12d, %xmm15 # len(A) in %xmm15
++ mov arg8, %r15 # %r13 = aadLen (number of bytes)
++ shl $3, %r15 # convert into number of bits
++ movd %r15d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+@@ -1440,7 +1441,8 @@ _return_T_done_decrypt:
+ mov %r14, %rsp
pop %r14
pop %r13
- pop %r12
-+ pax_force_retaddr 0, 1
+- pop %r12
++ pop %r15
++ pax_force_retaddr
ret
ENDPROC(aesni_gcm_dec)
-@@ -1705,6 +1707,7 @@ _return_T_done_encrypt:
+@@ -1529,7 +1531,7 @@ ENDPROC(aesni_gcm_dec)
+ * poly = x^128 + x^127 + x^126 + x^121 + 1
+ ***************************************************************************/
+ ENTRY(aesni_gcm_enc)
+- push %r12
++ push %r15
+ push %r13
+ push %r14
+ mov %rsp, %r14
+@@ -1539,8 +1541,8 @@ ENTRY(aesni_gcm_enc)
+ #
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp
+- mov %arg6, %r12
+- movdqu (%r12), %xmm13
++ mov %arg6, %r15
++ movdqu (%r15), %xmm13
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+@@ -1564,13 +1566,13 @@ ENTRY(aesni_gcm_enc)
+ movdqa %xmm13, HashKey(%rsp)
+ mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly)
+ and $-16, %r13
+- mov %r13, %r12
++ mov %r13, %r15
+
+ # Encrypt first few blocks
+
+- and $(3<<4), %r12
++ and $(3<<4), %r15
+ jz _initial_num_blocks_is_0_encrypt
+- cmp $(2<<4), %r12
++ cmp $(2<<4), %r15
+ jb _initial_num_blocks_is_1_encrypt
+ je _initial_num_blocks_is_2_encrypt
+ _initial_num_blocks_is_3_encrypt:
+@@ -1623,14 +1625,14 @@ _zero_cipher_left_encrypt:
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks
+- lea SHIFT_MASK+16(%rip), %r12
+- sub %r13, %r12
++ lea SHIFT_MASK+16(%rip), %r15
++ sub %r13, %r15
+ # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
+ # (%r13 is the number of bytes in plaintext mod 16)
+- movdqu (%r12), %xmm2 # get the appropriate shuffle mask
++ movdqu (%r15), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte
+ pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn)
+- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
++ movdqu ALL_F-SHIFT_MASK(%r15), %xmm1
+ # get the appropriate mask to mask out top 16-r13 bytes of xmm0
+ pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0
+ movdqa SHUF_MASK(%rip), %xmm10
+@@ -1663,9 +1665,9 @@ _less_than_8_bytes_left_encrypt:
+ sub $1, %r13
+ jne _less_than_8_bytes_left_encrypt
+ _multiple_of_16_bytes_encrypt:
+- mov arg8, %r12 # %r12 = addLen (number of bytes)
+- shl $3, %r12
+- movd %r12d, %xmm15 # len(A) in %xmm15
++ mov arg8, %r15 # %r15 = addLen (number of bytes)
++ shl $3, %r15
++ movd %r15d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+@@ -1704,7 +1706,8 @@ _return_T_done_encrypt:
+ mov %r14, %rsp
pop %r14
pop %r13
- pop %r12
-+ pax_force_retaddr 0, 1
+- pop %r12
++ pop %r15
++ pax_force_retaddr
ret
ENDPROC(aesni_gcm_enc)
@@ -12212,7 +12427,7 @@ index 477e9d7..3ab339f 100644
pxor %xmm1, %xmm0
movaps %xmm0, (TKEYP)
add $0x10, TKEYP
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_key_expansion_128)
ENDPROC(_key_expansion_256a)
@@ -12220,7 +12435,7 @@ index 477e9d7..3ab339f 100644
shufps $0b01001110, %xmm2, %xmm1
movaps %xmm1, 0x10(TKEYP)
add $0x20, TKEYP
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_key_expansion_192a)
@@ -12228,7 +12443,7 @@ index 477e9d7..3ab339f 100644
movaps %xmm0, (TKEYP)
add $0x10, TKEYP
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_key_expansion_192b)
@@ -12236,7 +12451,7 @@ index 477e9d7..3ab339f 100644
pxor %xmm1, %xmm2
movaps %xmm2, (TKEYP)
add $0x10, TKEYP
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_key_expansion_256b)
@@ -12244,7 +12459,7 @@ index 477e9d7..3ab339f 100644
#ifndef __x86_64__
popl KEYP
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_set_key)
@@ -12252,7 +12467,7 @@ index 477e9d7..3ab339f 100644
popl KLEN
popl KEYP
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_enc)
@@ -12260,7 +12475,7 @@ index 477e9d7..3ab339f 100644
AESENC KEY STATE
movaps 0x70(TKEYP), KEY
AESENCLAST KEY STATE
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_enc1)
@@ -12268,7 +12483,7 @@ index 477e9d7..3ab339f 100644
AESENCLAST KEY STATE2
AESENCLAST KEY STATE3
AESENCLAST KEY STATE4
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_enc4)
@@ -12276,7 +12491,7 @@ index 477e9d7..3ab339f 100644
popl KLEN
popl KEYP
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_dec)
@@ -12284,7 +12499,7 @@ index 477e9d7..3ab339f 100644
AESDEC KEY STATE
movaps 0x70(TKEYP), KEY
AESDECLAST KEY STATE
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_dec1)
@@ -12292,7 +12507,7 @@ index 477e9d7..3ab339f 100644
AESDECLAST KEY STATE2
AESDECLAST KEY STATE3
AESDECLAST KEY STATE4
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_dec4)
@@ -12300,7 +12515,7 @@ index 477e9d7..3ab339f 100644
popl KEYP
popl LEN
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_ecb_enc)
@@ -12308,7 +12523,7 @@ index 477e9d7..3ab339f 100644
popl KEYP
popl LEN
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_ecb_dec)
@@ -12316,7 +12531,7 @@ index 477e9d7..3ab339f 100644
popl LEN
popl IVP
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_cbc_enc)
@@ -12324,7 +12539,7 @@ index 477e9d7..3ab339f 100644
popl LEN
popl IVP
#endif
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_cbc_dec)
@@ -12332,7 +12547,7 @@ index 477e9d7..3ab339f 100644
mov $1, TCTR_LOW
MOVQ_R64_XMM TCTR_LOW INC
MOVQ_R64_XMM CTR TCTR_LOW
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_inc_init)
@@ -12340,7 +12555,7 @@ index 477e9d7..3ab339f 100644
.Linc_low:
movaps CTR, IV
PSHUFB_XMM BSWAP_MASK IV
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret
ENDPROC(_aesni_inc)
@@ -12348,7 +12563,7 @@ index 477e9d7..3ab339f 100644
.Lctr_enc_ret:
movups IV, (IVP)
.Lctr_enc_just_ret:
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_ctr_enc)
@@ -12356,12 +12571,12 @@ index 477e9d7..3ab339f 100644
pxor INC, STATE4
movdqu STATE4, 0x70(OUTP)
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(aesni_xts_crypt8)
diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S b/arch/x86/crypto/blowfish-x86_64-asm_64.S
-index 246c670..4d1ed00 100644
+index 246c670..466e2d6 100644
--- a/arch/x86/crypto/blowfish-x86_64-asm_64.S
+++ b/arch/x86/crypto/blowfish-x86_64-asm_64.S
@@ -21,6 +21,7 @@
@@ -12376,11 +12591,11 @@ index 246c670..4d1ed00 100644
jnz .L__enc_xor;
write_block();
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__enc_xor:
xor_block();
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__blowfish_enc_blk)
@@ -12388,7 +12603,7 @@ index 246c670..4d1ed00 100644
movq %r11, %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(blowfish_dec_blk)
@@ -12396,7 +12611,7 @@ index 246c670..4d1ed00 100644
popq %rbx;
popq %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__enc_xor4:
@@ -12404,7 +12619,7 @@ index 246c670..4d1ed00 100644
popq %rbx;
popq %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__blowfish_enc_blk_4way)
@@ -12412,11 +12627,11 @@ index 246c670..4d1ed00 100644
popq %rbx;
popq %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(blowfish_dec_blk_4way)
diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
-index ce71f92..2dd5b1e 100644
+index ce71f92..1dce7ec 100644
--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
@@ -16,6 +16,7 @@
@@ -12431,7 +12646,7 @@ index ce71f92..2dd5b1e 100644
roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
%xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15,
%rcx, (%r9));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
@@ -12439,7 +12654,7 @@ index ce71f92..2dd5b1e 100644
roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3,
%xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11,
%rax, (%r9));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
@@ -12447,7 +12662,7 @@ index ce71f92..2dd5b1e 100644
%xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
%xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
.align 8
@@ -12455,7 +12670,7 @@ index ce71f92..2dd5b1e 100644
%xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
%xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
.align 8
@@ -12463,7 +12678,7 @@ index ce71f92..2dd5b1e 100644
%xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
%xmm8, %rsi);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ecb_enc_16way)
@@ -12471,7 +12686,7 @@ index ce71f92..2dd5b1e 100644
%xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
%xmm8, %rsi);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ecb_dec_16way)
@@ -12479,7 +12694,7 @@ index ce71f92..2dd5b1e 100644
%xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
%xmm8, %rsi);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_cbc_dec_16way)
@@ -12487,7 +12702,7 @@ index ce71f92..2dd5b1e 100644
%xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
%xmm8, %rsi);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ctr_16way)
@@ -12495,12 +12710,12 @@ index ce71f92..2dd5b1e 100644
%xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
%xmm8, %rsi);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_xts_crypt_16way)
diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
-index 0e0b886..8fc756a 100644
+index 0e0b886..5a3123c 100644
--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
@@ -11,6 +11,7 @@
@@ -12515,7 +12730,7 @@ index 0e0b886..8fc756a 100644
roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15,
%rcx, (%r9));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
@@ -12523,7 +12738,7 @@ index 0e0b886..8fc756a 100644
roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3,
%ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11,
%rax, (%r9));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
@@ -12531,7 +12746,7 @@ index 0e0b886..8fc756a 100644
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
.align 8
@@ -12539,7 +12754,7 @@ index 0e0b886..8fc756a 100644
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
-+ pax_force_retaddr_bts
++ pax_force_retaddr
ret;
.align 8
@@ -12547,7 +12762,7 @@ index 0e0b886..8fc756a 100644
vzeroupper;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ecb_enc_32way)
@@ -12555,7 +12770,7 @@ index 0e0b886..8fc756a 100644
vzeroupper;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ecb_dec_32way)
@@ -12563,7 +12778,7 @@ index 0e0b886..8fc756a 100644
vzeroupper;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_cbc_dec_32way)
@@ -12571,7 +12786,7 @@ index 0e0b886..8fc756a 100644
vzeroupper;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_ctr_32way)
@@ -12579,12 +12794,12 @@ index 0e0b886..8fc756a 100644
vzeroupper;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_xts_crypt_32way)
diff --git a/arch/x86/crypto/camellia-x86_64-asm_64.S b/arch/x86/crypto/camellia-x86_64-asm_64.S
-index 310319c..ce174a4 100644
+index 310319c..db3d7b5 100644
--- a/arch/x86/crypto/camellia-x86_64-asm_64.S
+++ b/arch/x86/crypto/camellia-x86_64-asm_64.S
@@ -21,6 +21,7 @@
@@ -12599,14 +12814,14 @@ index 310319c..ce174a4 100644
enc_outunpack(mov, RT1);
movq RRBP, %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__enc_xor:
enc_outunpack(xor, RT1);
movq RRBP, %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__camellia_enc_blk)
@@ -12614,7 +12829,7 @@ index 310319c..ce174a4 100644
dec_outunpack();
movq RRBP, %rbp;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_dec_blk)
@@ -12622,7 +12837,7 @@ index 310319c..ce174a4 100644
movq RRBP, %rbp;
popq %rbx;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__enc2_xor:
@@ -12630,7 +12845,7 @@ index 310319c..ce174a4 100644
movq RRBP, %rbp;
popq %rbx;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__camellia_enc_blk_2way)
@@ -12638,11 +12853,11 @@ index 310319c..ce174a4 100644
movq RRBP, %rbp;
movq RXOR, %rbx;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(camellia_dec_blk_2way)
diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
-index c35fd5d..c1ee236 100644
+index c35fd5d..2d8c7db 100644
--- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
@@ -24,6 +24,7 @@
@@ -12657,7 +12872,7 @@ index c35fd5d..c1ee236 100644
outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__cast5_enc_blk16)
@@ -12665,7 +12880,7 @@ index c35fd5d..c1ee236 100644
outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__skip_dec:
@@ -12685,23 +12900,103 @@ index c35fd5d..c1ee236 100644
ret;
ENDPROC(cast5_ecb_dec_16way)
-@@ -469,6 +474,7 @@ ENTRY(cast5_cbc_dec_16way)
+@@ -430,10 +435,10 @@ ENTRY(cast5_cbc_dec_16way)
+ * %rdx: src
+ */
- popq %r12;
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ vmovdqu (0*16)(%rdx), RL1;
+ vmovdqu (1*16)(%rdx), RR1;
+@@ -447,16 +452,16 @@ ENTRY(cast5_cbc_dec_16way)
+ call __cast5_dec_blk16;
+
+ /* xor with src */
+- vmovq (%r12), RX;
++ vmovq (%r14), RX;
+ vpshufd $0x4f, RX, RX;
+ vpxor RX, RR1, RR1;
+- vpxor 0*16+8(%r12), RL1, RL1;
+- vpxor 1*16+8(%r12), RR2, RR2;
+- vpxor 2*16+8(%r12), RL2, RL2;
+- vpxor 3*16+8(%r12), RR3, RR3;
+- vpxor 4*16+8(%r12), RL3, RL3;
+- vpxor 5*16+8(%r12), RR4, RR4;
+- vpxor 6*16+8(%r12), RL4, RL4;
++ vpxor 0*16+8(%r14), RL1, RL1;
++ vpxor 1*16+8(%r14), RR2, RR2;
++ vpxor 2*16+8(%r14), RL2, RL2;
++ vpxor 3*16+8(%r14), RR3, RR3;
++ vpxor 4*16+8(%r14), RL3, RL3;
++ vpxor 5*16+8(%r14), RR4, RR4;
++ vpxor 6*16+8(%r14), RL4, RL4;
+
+ vmovdqu RR1, (0*16)(%r11);
+ vmovdqu RL1, (1*16)(%r11);
+@@ -467,8 +472,9 @@ ENTRY(cast5_cbc_dec_16way)
+ vmovdqu RR4, (6*16)(%r11);
+ vmovdqu RL4, (7*16)(%r11);
+
+- popq %r12;
++ popq %r14;
+ pax_force_retaddr
ret;
ENDPROC(cast5_cbc_dec_16way)
-@@ -542,5 +548,6 @@ ENTRY(cast5_ctr_16way)
+@@ -480,10 +486,10 @@ ENTRY(cast5_ctr_16way)
+ * %rcx: iv (big endian, 64bit)
+ */
- popq %r12;
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ vpcmpeqd RTMP, RTMP, RTMP;
+ vpsrldq $8, RTMP, RTMP; /* low: -1, high: 0 */
+@@ -523,14 +529,14 @@ ENTRY(cast5_ctr_16way)
+ call __cast5_enc_blk16;
+
+ /* dst = src ^ iv */
+- vpxor (0*16)(%r12), RR1, RR1;
+- vpxor (1*16)(%r12), RL1, RL1;
+- vpxor (2*16)(%r12), RR2, RR2;
+- vpxor (3*16)(%r12), RL2, RL2;
+- vpxor (4*16)(%r12), RR3, RR3;
+- vpxor (5*16)(%r12), RL3, RL3;
+- vpxor (6*16)(%r12), RR4, RR4;
+- vpxor (7*16)(%r12), RL4, RL4;
++ vpxor (0*16)(%r14), RR1, RR1;
++ vpxor (1*16)(%r14), RL1, RL1;
++ vpxor (2*16)(%r14), RR2, RR2;
++ vpxor (3*16)(%r14), RL2, RL2;
++ vpxor (4*16)(%r14), RR3, RR3;
++ vpxor (5*16)(%r14), RL3, RL3;
++ vpxor (6*16)(%r14), RR4, RR4;
++ vpxor (7*16)(%r14), RL4, RL4;
+ vmovdqu RR1, (0*16)(%r11);
+ vmovdqu RL1, (1*16)(%r11);
+ vmovdqu RR2, (2*16)(%r11);
+@@ -540,7 +546,8 @@ ENTRY(cast5_ctr_16way)
+ vmovdqu RR4, (6*16)(%r11);
+ vmovdqu RL4, (7*16)(%r11);
+
+- popq %r12;
++ popq %r14;
+ pax_force_retaddr
ret;
ENDPROC(cast5_ctr_16way)
diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
-index e3531f8..18ded3a 100644
+index e3531f8..e123f35 100644
--- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
@@ -24,6 +24,7 @@
@@ -12716,7 +13011,7 @@ index e3531f8..18ded3a 100644
outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__cast6_enc_blk8)
@@ -12724,7 +13019,7 @@ index e3531f8..18ded3a 100644
outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__cast6_dec_blk8)
@@ -12744,17 +13039,52 @@ index e3531f8..18ded3a 100644
ret;
ENDPROC(cast6_ecb_dec_8way)
-@@ -399,6 +404,7 @@ ENTRY(cast6_cbc_dec_8way)
+@@ -386,19 +391,20 @@ ENTRY(cast6_cbc_dec_8way)
+ * %rdx: src
+ */
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
- popq %r12;
+ load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ call __cast6_dec_blk8;
+
+- store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_cbc_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+ pax_force_retaddr
ret;
ENDPROC(cast6_cbc_dec_8way)
-@@ -424,6 +430,7 @@ ENTRY(cast6_ctr_8way)
+@@ -410,20 +416,21 @@ ENTRY(cast6_ctr_8way)
+ * %rcx: iv (little endian, 128bit)
+ */
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2,
+ RD2, RX, RKR, RKM);
+
+ call __cast6_enc_blk8;
- popq %r12;
+- store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_ctr_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+ pax_force_retaddr
ret;
@@ -12776,7 +13106,7 @@ index e3531f8..18ded3a 100644
ret;
ENDPROC(cast6_xts_dec_8way)
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
-index dbc4339..3d868c5 100644
+index dbc4339..de6e120 100644
--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
@@ -45,6 +45,7 @@
@@ -12791,7 +13121,7 @@ index dbc4339..3d868c5 100644
popq %rsi
popq %rdi
popq %rbx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
################################################################
@@ -12839,7 +13169,7 @@ index 586f41a..d02851e 100644
ret
ENDPROC(clmul_ghash_setkey)
diff --git a/arch/x86/crypto/salsa20-x86_64-asm_64.S b/arch/x86/crypto/salsa20-x86_64-asm_64.S
-index 9279e0b..9270820 100644
+index 9279e0b..c4b3d2c 100644
--- a/arch/x86/crypto/salsa20-x86_64-asm_64.S
+++ b/arch/x86/crypto/salsa20-x86_64-asm_64.S
@@ -1,4 +1,5 @@
@@ -12852,7 +13182,7 @@ index 9279e0b..9270820 100644
add %r11,%rsp
mov %rdi,%rax
mov %rsi,%rdx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
# bytesatleast65:
._bytesatleast65:
@@ -13056,7 +13386,7 @@ index acc066c..1559cc4 100644
ret;
ENDPROC(serpent_dec_blk_8way)
diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S
-index a410950..3356d42 100644
+index a410950..9dfe7ad 100644
--- a/arch/x86/crypto/sha1_ssse3_asm.S
+++ b/arch/x86/crypto/sha1_ssse3_asm.S
@@ -29,6 +29,7 @@
@@ -13067,16 +13397,35 @@ index a410950..3356d42 100644
#define CTX %rdi // arg1
#define BUF %rsi // arg2
-@@ -104,6 +105,7 @@
- pop %r12
+@@ -75,9 +76,9 @@
+
+ push %rbx
+ push %rbp
+- push %r12
++ push %r14
+
+- mov %rsp, %r12
++ mov %rsp, %r14
+ sub $64, %rsp # allocate workspace
+ and $~15, %rsp # align stack
+
+@@ -99,11 +100,12 @@
+ xor %rax, %rax
+ rep stosq
+
+- mov %r12, %rsp # deallocate workspace
++ mov %r14, %rsp # deallocate workspace
+
+- pop %r12
++ pop %r14
pop %rbp
pop %rbx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(\name)
diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S
-index 642f156..4ab07b9 100644
+index 642f156..51a513c 100644
--- a/arch/x86/crypto/sha256-avx-asm.S
+++ b/arch/x86/crypto/sha256-avx-asm.S
@@ -49,6 +49,7 @@
@@ -13091,12 +13440,12 @@ index 642f156..4ab07b9 100644
popq %r13
popq %rbp
popq %rbx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha256_transform_avx)
diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S
-index 9e86944..2e7f95a 100644
+index 9e86944..3795e6a 100644
--- a/arch/x86/crypto/sha256-avx2-asm.S
+++ b/arch/x86/crypto/sha256-avx2-asm.S
@@ -50,6 +50,7 @@
@@ -13111,12 +13460,12 @@ index 9e86944..2e7f95a 100644
popq %r12
popq %rbp
popq %rbx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha256_transform_rorx)
diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S
-index f833b74..c36ed14 100644
+index f833b74..8c62a9e 100644
--- a/arch/x86/crypto/sha256-ssse3-asm.S
+++ b/arch/x86/crypto/sha256-ssse3-asm.S
@@ -47,6 +47,7 @@
@@ -13131,12 +13480,12 @@ index f833b74..c36ed14 100644
popq %rbp
popq %rbx
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha256_transform_ssse3)
diff --git a/arch/x86/crypto/sha512-avx-asm.S b/arch/x86/crypto/sha512-avx-asm.S
-index 974dde9..4533d34 100644
+index 974dde9..a823ff9 100644
--- a/arch/x86/crypto/sha512-avx-asm.S
+++ b/arch/x86/crypto/sha512-avx-asm.S
@@ -49,6 +49,7 @@
@@ -13151,12 +13500,12 @@ index 974dde9..4533d34 100644
mov frame_RSPSAVE(%rsp), %rsp
nowork:
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha512_transform_avx)
diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S
-index 568b961..061ef1d 100644
+index 568b961..ed20c37 100644
--- a/arch/x86/crypto/sha512-avx2-asm.S
+++ b/arch/x86/crypto/sha512-avx2-asm.S
@@ -51,6 +51,7 @@
@@ -13171,12 +13520,12 @@ index 568b961..061ef1d 100644
# Restore Stack Pointer
mov frame_RSPSAVE(%rsp), %rsp
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha512_transform_rorx)
diff --git a/arch/x86/crypto/sha512-ssse3-asm.S b/arch/x86/crypto/sha512-ssse3-asm.S
-index fb56855..e23914f 100644
+index fb56855..6edd768 100644
--- a/arch/x86/crypto/sha512-ssse3-asm.S
+++ b/arch/x86/crypto/sha512-ssse3-asm.S
@@ -48,6 +48,7 @@
@@ -13191,12 +13540,12 @@ index fb56855..e23914f 100644
mov frame_RSPSAVE(%rsp), %rsp
nowork:
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(sha512_transform_ssse3)
diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
-index 0505813..63b1d00 100644
+index 0505813..b067311 100644
--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
@@ -24,6 +24,7 @@
@@ -13211,7 +13560,7 @@ index 0505813..63b1d00 100644
outunpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2);
outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__twofish_enc_blk8)
@@ -13219,7 +13568,7 @@ index 0505813..63b1d00 100644
outunpack_blocks(RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2);
outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__twofish_dec_blk8)
@@ -13227,7 +13576,7 @@ index 0505813..63b1d00 100644
store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(twofish_ecb_enc_8way)
@@ -13235,23 +13584,58 @@ index 0505813..63b1d00 100644
store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(twofish_ecb_dec_8way)
-@@ -383,6 +388,7 @@ ENTRY(twofish_cbc_dec_8way)
+@@ -370,19 +375,20 @@ ENTRY(twofish_cbc_dec_8way)
+ * %rdx: src
+ */
- popq %r12;
+- pushq %r12;
++ pushq %r14;
-+ pax_force_retaddr 0, 1
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_8way(%rdx, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+ call __twofish_dec_blk8;
+
+- store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_cbc_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+
++ pax_force_retaddr
ret;
ENDPROC(twofish_cbc_dec_8way)
-@@ -408,6 +414,7 @@ ENTRY(twofish_ctr_8way)
+@@ -394,20 +400,21 @@ ENTRY(twofish_ctr_8way)
+ * %rcx: iv (little endian, 128bit)
+ */
- popq %r12;
+- pushq %r12;
++ pushq %r14;
-+ pax_force_retaddr 0, 1
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2,
+ RD2, RX0, RX1, RY0);
+
+ call __twofish_enc_blk8;
+
+- store_ctr_8way(%r12, %r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
++ store_ctr_8way(%r14, %r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+- popq %r12;
++ popq %r14;
+
++ pax_force_retaddr
ret;
ENDPROC(twofish_ctr_8way)
@@ -13259,7 +13643,7 @@ index 0505813..63b1d00 100644
/* dst <= regs xor IVs(in dst) */
store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(twofish_xts_enc_8way)
@@ -13267,11 +13651,11 @@ index 0505813..63b1d00 100644
/* dst <= regs xor IVs(in dst) */
store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(twofish_xts_dec_8way)
diff --git a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
-index 1c3b7ce..b365c5e 100644
+index 1c3b7ce..02f578d 100644
--- a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
+++ b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
@@ -21,6 +21,7 @@
@@ -13286,7 +13670,7 @@ index 1c3b7ce..b365c5e 100644
popq %r13;
popq %r14;
popq %r15;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
.L__enc_xor3:
@@ -13294,7 +13678,7 @@ index 1c3b7ce..b365c5e 100644
popq %r13;
popq %r14;
popq %r15;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(__twofish_enc_blk_3way)
@@ -13302,11 +13686,11 @@ index 1c3b7ce..b365c5e 100644
popq %r13;
popq %r14;
popq %r15;
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret;
ENDPROC(twofish_dec_blk_3way)
diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S b/arch/x86/crypto/twofish-x86_64-asm_64.S
-index a039d21..29e7615 100644
+index a039d21..524b8b2 100644
--- a/arch/x86/crypto/twofish-x86_64-asm_64.S
+++ b/arch/x86/crypto/twofish-x86_64-asm_64.S
@@ -22,6 +22,7 @@
@@ -13321,7 +13705,7 @@ index a039d21..29e7615 100644
popq R1
movq $1,%rax
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(twofish_enc_blk)
@@ -13329,7 +13713,7 @@ index a039d21..29e7615 100644
popq R1
movq $1,%rax
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
ENDPROC(twofish_dec_blk)
diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
@@ -13399,7 +13783,7 @@ index 665a730..8e7a67a 100644
err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
-index 4299eb0..904b82a 100644
+index 4299eb0..c0687a7 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -15,8 +15,10 @@
@@ -13413,6 +13797,24 @@ index 4299eb0..904b82a 100644
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
#include <linux/elf-em.h>
+@@ -62,12 +64,12 @@
+ */
+ .macro LOAD_ARGS32 offset, _r9=0
+ .if \_r9
+- movl \offset+16(%rsp),%r9d
++ movl \offset+R9(%rsp),%r9d
+ .endif
+- movl \offset+40(%rsp),%ecx
+- movl \offset+48(%rsp),%edx
+- movl \offset+56(%rsp),%esi
+- movl \offset+64(%rsp),%edi
++ movl \offset+RCX(%rsp),%ecx
++ movl \offset+RDX(%rsp),%edx
++ movl \offset+RSI(%rsp),%esi
++ movl \offset+RDI(%rsp),%edi
+ movl %eax,%eax /* zero extension */
+ .endm
+
@@ -96,6 +98,32 @@ ENTRY(native_irq_enable_sysexit)
ENDPROC(native_irq_enable_sysexit)
#endif
@@ -13514,7 +13916,7 @@ index 4299eb0..904b82a 100644
CFI_REMEMBER_STATE
jnz sysenter_tracesys
cmpq $(IA32_NR_syscalls-1),%rax
-@@ -162,12 +209,15 @@ sysenter_do_call:
+@@ -162,15 +209,18 @@ sysenter_do_call:
sysenter_dispatch:
call *ia32_sys_call_table(,%rax,8)
movq %rax,RAX-ARGOFFSET(%rsp)
@@ -13530,8 +13932,13 @@ index 4299eb0..904b82a 100644
+ pax_erase_kstack
+ andl $~TS_COMPAT,TI_status(%r11)
/* clear IF, that popfq doesn't enable interrupts early */
- andl $~0x200,EFLAGS-R11(%rsp)
- movl RIP-R11(%rsp),%edx /* User %eip */
+- andl $~0x200,EFLAGS-R11(%rsp)
+- movl RIP-R11(%rsp),%edx /* User %eip */
++ andl $~X86_EFLAGS_IF,EFLAGS(%rsp)
++ movl RIP(%rsp),%edx /* User %eip */
+ CFI_REGISTER rip,rdx
+ RESTORE_ARGS 0,24,0,0,0,0
+ xorq %r8,%r8
@@ -193,6 +243,9 @@ sysexit_from_sys_call:
movl %eax,%esi /* 2nd arg: syscall number */
movl $AUDIT_ARCH_I386,%edi /* 1st arg: audit arch */
@@ -13640,7 +14047,7 @@ index 4299eb0..904b82a 100644
CFI_REMEMBER_STATE
jnz cstar_tracesys
cmpq $IA32_NR_syscalls-1,%rax
-@@ -319,12 +395,15 @@ cstar_do_call:
+@@ -319,13 +395,16 @@ cstar_do_call:
cstar_dispatch:
call *ia32_sys_call_table(,%rax,8)
movq %rax,RAX-ARGOFFSET(%rsp)
@@ -13652,12 +14059,14 @@ index 4299eb0..904b82a 100644
jnz sysretl_audit
sysretl_from_sys_call:
- andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+- RESTORE_ARGS 0,-ARG_SKIP,0,0,0
+ pax_exit_kernel_user
+ pax_erase_kstack
+ andl $~TS_COMPAT,TI_status(%r11)
- RESTORE_ARGS 0,-ARG_SKIP,0,0,0
++ RESTORE_ARGS 0,-ORIG_RAX,0,0,0
movl RIP-ARGOFFSET(%rsp),%ecx
CFI_REGISTER rip,rcx
+ movl EFLAGS-ARGOFFSET(%rsp),%r11d
@@ -352,7 +431,7 @@ sysretl_audit:
cstar_tracesys:
@@ -13747,7 +14156,7 @@ index 8e0ceec..af13504 100644
SET_GID(gid, from_kgid_munged(current_user_ns(), stat->gid));
if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h
-index 372231c..a5aa1a1 100644
+index 372231c..51b537d 100644
--- a/arch/x86/include/asm/alternative-asm.h
+++ b/arch/x86/include/asm/alternative-asm.h
@@ -18,6 +18,45 @@
@@ -13773,13 +14182,13 @@ index 372231c..a5aa1a1 100644
+ .if \reload
+ pax_set_fptr_mask
+ .endif
-+ orq %r10,\rip(%rsp)
++ orq %r12,\rip(%rsp)
+ .endm
+ .macro pax_force_fptr ptr
-+ orq %r10,\ptr
++ orq %r12,\ptr
+ .endm
+ .macro pax_set_fptr_mask
-+ movabs $0x8000000000000000,%r10
++ movabs $0x8000000000000000,%r12
+ .endm
+#endif
+#else
@@ -14881,6 +15290,178 @@ index 9863ee3..4a1f8e1 100644
else if (pg_flags == _PGMT_WC)
return _PAGE_CACHE_WC;
else if (pg_flags == _PGMT_UC_MINUS)
+diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
+index 0fa6750..cb7b2c3 100644
+--- a/arch/x86/include/asm/calling.h
++++ b/arch/x86/include/asm/calling.h
+@@ -80,103 +80,113 @@ For 32-bit we have the following conventions - kernel is built with
+ #define RSP 152
+ #define SS 160
+
+-#define ARGOFFSET R11
+-#define SWFRAME ORIG_RAX
++#define ARGOFFSET R15
+
+ .macro SAVE_ARGS addskip=0, save_rcx=1, save_r891011=1
+- subq $9*8+\addskip, %rsp
+- CFI_ADJUST_CFA_OFFSET 9*8+\addskip
+- movq_cfi rdi, 8*8
+- movq_cfi rsi, 7*8
+- movq_cfi rdx, 6*8
++ subq $ORIG_RAX-ARGOFFSET+\addskip, %rsp
++ CFI_ADJUST_CFA_OFFSET ORIG_RAX-ARGOFFSET+\addskip
++ movq_cfi rdi, RDI
++ movq_cfi rsi, RSI
++ movq_cfi rdx, RDX
+
+ .if \save_rcx
+- movq_cfi rcx, 5*8
++ movq_cfi rcx, RCX
+ .endif
+
+- movq_cfi rax, 4*8
++ movq_cfi rax, RAX
+
+ .if \save_r891011
+- movq_cfi r8, 3*8
+- movq_cfi r9, 2*8
+- movq_cfi r10, 1*8
+- movq_cfi r11, 0*8
++ movq_cfi r8, R8
++ movq_cfi r9, R9
++ movq_cfi r10, R10
++ movq_cfi r11, R11
+ .endif
+
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq_cfi r12, R12
++#endif
++
+ .endm
+
+-#define ARG_SKIP (9*8)
++#define ARG_SKIP ORIG_RAX
+
+ .macro RESTORE_ARGS rstor_rax=1, addskip=0, rstor_rcx=1, rstor_r11=1, \
+ rstor_r8910=1, rstor_rdx=1
++
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq_cfi_restore R12, r12
++#endif
++
+ .if \rstor_r11
+- movq_cfi_restore 0*8, r11
++ movq_cfi_restore R11, r11
+ .endif
+
+ .if \rstor_r8910
+- movq_cfi_restore 1*8, r10
+- movq_cfi_restore 2*8, r9
+- movq_cfi_restore 3*8, r8
++ movq_cfi_restore R10, r10
++ movq_cfi_restore R9, r9
++ movq_cfi_restore R8, r8
+ .endif
+
+ .if \rstor_rax
+- movq_cfi_restore 4*8, rax
++ movq_cfi_restore RAX, rax
+ .endif
+
+ .if \rstor_rcx
+- movq_cfi_restore 5*8, rcx
++ movq_cfi_restore RCX, rcx
+ .endif
+
+ .if \rstor_rdx
+- movq_cfi_restore 6*8, rdx
++ movq_cfi_restore RDX, rdx
+ .endif
+
+- movq_cfi_restore 7*8, rsi
+- movq_cfi_restore 8*8, rdi
++ movq_cfi_restore RSI, rsi
++ movq_cfi_restore RDI, rdi
+
+- .if ARG_SKIP+\addskip > 0
+- addq $ARG_SKIP+\addskip, %rsp
+- CFI_ADJUST_CFA_OFFSET -(ARG_SKIP+\addskip)
++ .if ORIG_RAX+\addskip > 0
++ addq $ORIG_RAX+\addskip, %rsp
++ CFI_ADJUST_CFA_OFFSET -(ORIG_RAX+\addskip)
+ .endif
+ .endm
+
+- .macro LOAD_ARGS offset, skiprax=0
+- movq \offset(%rsp), %r11
+- movq \offset+8(%rsp), %r10
+- movq \offset+16(%rsp), %r9
+- movq \offset+24(%rsp), %r8
+- movq \offset+40(%rsp), %rcx
+- movq \offset+48(%rsp), %rdx
+- movq \offset+56(%rsp), %rsi
+- movq \offset+64(%rsp), %rdi
++ .macro LOAD_ARGS skiprax=0
++ movq R11(%rsp), %r11
++ movq R10(%rsp), %r10
++ movq R9(%rsp), %r9
++ movq R8(%rsp), %r8
++ movq RCX(%rsp), %rcx
++ movq RDX(%rsp), %rdx
++ movq RSI(%rsp), %rsi
++ movq RDI(%rsp), %rdi
+ .if \skiprax
+ .else
+- movq \offset+72(%rsp), %rax
++ movq RAX(%rsp), %rax
+ .endif
+ .endm
+
+-#define REST_SKIP (6*8)
+-
+ .macro SAVE_REST
+- subq $REST_SKIP, %rsp
+- CFI_ADJUST_CFA_OFFSET REST_SKIP
+- movq_cfi rbx, 5*8
+- movq_cfi rbp, 4*8
+- movq_cfi r12, 3*8
+- movq_cfi r13, 2*8
+- movq_cfi r14, 1*8
+- movq_cfi r15, 0*8
++ movq_cfi rbx, RBX
++ movq_cfi rbp, RBP
++
++#ifndef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq_cfi r12, R12
++#endif
++
++ movq_cfi r13, R13
++ movq_cfi r14, R14
++ movq_cfi r15, R15
+ .endm
+
+ .macro RESTORE_REST
+- movq_cfi_restore 0*8, r15
+- movq_cfi_restore 1*8, r14
+- movq_cfi_restore 2*8, r13
+- movq_cfi_restore 3*8, r12
+- movq_cfi_restore 4*8, rbp
+- movq_cfi_restore 5*8, rbx
+- addq $REST_SKIP, %rsp
+- CFI_ADJUST_CFA_OFFSET -(REST_SKIP)
++ movq_cfi_restore R15, r15
++ movq_cfi_restore R14, r14
++ movq_cfi_restore R13, r13
++
++#ifndef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq_cfi_restore R12, r12
++#endif
++
++ movq_cfi_restore RBP, rbp
++ movq_cfi_restore RBX, rbx
+ .endm
+
+ .macro SAVE_ALL
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index f50de69..2b0a458 100644
--- a/arch/x86/include/asm/checksum_32.h
@@ -18961,6 +19542,18 @@ index bbae024..e1528f9 100644
#define BIOS_END 0x00100000
#define BIOS_ROM_BASE 0xffe00000
+diff --git a/arch/x86/include/uapi/asm/ptrace-abi.h b/arch/x86/include/uapi/asm/ptrace-abi.h
+index 7b0a55a..ad115bf 100644
+--- a/arch/x86/include/uapi/asm/ptrace-abi.h
++++ b/arch/x86/include/uapi/asm/ptrace-abi.h
+@@ -49,7 +49,6 @@
+ #define EFLAGS 144
+ #define RSP 152
+ #define SS 160
+-#define ARGOFFSET R11
+ #endif /* __ASSEMBLY__ */
+
+ /* top of stack page */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index a5408b9..5133813 100644
--- a/arch/x86/kernel/Makefile
@@ -21406,7 +21999,7 @@ index f0dcb0c..9f39b80 100644
/*
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index b077f4c..feb26c1 100644
+index b077f4c..8e0df9f 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -59,6 +59,8 @@
@@ -21924,27 +22517,84 @@ index b077f4c..feb26c1 100644
.macro TRACE_IRQS_IRETQ offset=ARGOFFSET
#ifdef CONFIG_TRACE_IRQFLAGS
-@@ -375,8 +808,8 @@ ENDPROC(native_usergs_sysret64)
+@@ -320,7 +753,7 @@ ENDPROC(native_usergs_sysret64)
+ .endm
+
+ .macro TRACE_IRQS_IRETQ_DEBUG offset=ARGOFFSET
+- bt $9,EFLAGS-\offset(%rsp) /* interrupts off? */
++ bt $X86_EFLAGS_IF_BIT,EFLAGS-\offset(%rsp) /* interrupts off? */
+ jnc 1f
+ TRACE_IRQS_ON_DEBUG
+ 1:
+@@ -358,27 +791,6 @@ ENDPROC(native_usergs_sysret64)
+ movq \tmp,R11+\offset(%rsp)
.endm
- .macro UNFAKE_STACK_FRAME
+- .macro FAKE_STACK_FRAME child_rip
+- /* push in order ss, rsp, eflags, cs, rip */
+- xorl %eax, %eax
+- pushq_cfi $__KERNEL_DS /* ss */
+- /*CFI_REL_OFFSET ss,0*/
+- pushq_cfi %rax /* rsp */
+- CFI_REL_OFFSET rsp,0
+- pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED) /* eflags - interrupts on */
+- /*CFI_REL_OFFSET rflags,0*/
+- pushq_cfi $__KERNEL_CS /* cs */
+- /*CFI_REL_OFFSET cs,0*/
+- pushq_cfi \child_rip /* rip */
+- CFI_REL_OFFSET rip,0
+- pushq_cfi %rax /* orig rax */
+- .endm
+-
+- .macro UNFAKE_STACK_FRAME
- addq $8*6, %rsp
- CFI_ADJUST_CFA_OFFSET -(6*8)
-+ addq $8*6 + ARG_SKIP, %rsp
-+ CFI_ADJUST_CFA_OFFSET -(6*8 + ARG_SKIP)
- .endm
-
+- .endm
+-
/*
-@@ -463,7 +896,7 @@ ENDPROC(native_usergs_sysret64)
+ * initial frame state for interrupts (and exceptions without error code)
+ */
+@@ -445,25 +857,26 @@ ENDPROC(native_usergs_sysret64)
+ /* save partial stack frame */
+ .macro SAVE_ARGS_IRQ
+ cld
+- /* start from rbp in pt_regs and jump over */
+- movq_cfi rdi, (RDI-RBP)
+- movq_cfi rsi, (RSI-RBP)
+- movq_cfi rdx, (RDX-RBP)
+- movq_cfi rcx, (RCX-RBP)
+- movq_cfi rax, (RAX-RBP)
+- movq_cfi r8, (R8-RBP)
+- movq_cfi r9, (R9-RBP)
+- movq_cfi r10, (R10-RBP)
+- movq_cfi r11, (R11-RBP)
++ /* start from r15 in pt_regs and jump over */
++ movq_cfi rdi, RDI
++ movq_cfi rsi, RSI
++ movq_cfi rdx, RDX
++ movq_cfi rcx, RCX
++ movq_cfi rax, RAX
++ movq_cfi r8, R8
++ movq_cfi r9, R9
++ movq_cfi r10, R10
++ movq_cfi r11, R11
++ movq_cfi r12, R12
+
+ /* Save rbp so that we can unwind from get_irq_regs() */
+- movq_cfi rbp, 0
++ movq_cfi rbp, RBP
+
+ /* Save previous stack value */
movq %rsp, %rsi
- leaq -RBP(%rsp),%rdi /* arg1 for handler */
+- leaq -RBP(%rsp),%rdi /* arg1 for handler */
- testl $3, CS-RBP(%rsi)
-+ testb $3, CS-RBP(%rsi)
++ movq %rsp,%rdi /* arg1 for handler */
++ testb $3, CS(%rsi)
je 1f
SWAPGS
/*
-@@ -514,9 +947,10 @@ ENTRY(save_paranoid)
+@@ -514,9 +927,10 @@ ENTRY(save_paranoid)
js 1f /* negative -> in kernel */
SWAPGS
xorl %ebx,%ebx
@@ -21957,7 +22607,7 @@ index b077f4c..feb26c1 100644
.popsection
/*
-@@ -538,7 +972,7 @@ ENTRY(ret_from_fork)
+@@ -538,7 +952,7 @@ ENTRY(ret_from_fork)
RESTORE_REST
@@ -21966,7 +22616,15 @@ index b077f4c..feb26c1 100644
jz 1f
testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET
-@@ -556,7 +990,7 @@ ENTRY(ret_from_fork)
+@@ -548,15 +962,13 @@ ENTRY(ret_from_fork)
+ jmp ret_from_sys_call # go to the SYSRET fastpath
+
+ 1:
+- subq $REST_SKIP, %rsp # leave space for volatiles
+- CFI_ADJUST_CFA_OFFSET REST_SKIP
+ movq %rbp, %rdi
+ call *%rbx
+ movl $0, RAX(%rsp)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -21975,7 +22633,7 @@ index b077f4c..feb26c1 100644
/*
* System call entry. Up to 6 arguments in registers are supported.
-@@ -593,7 +1027,7 @@ END(ret_from_fork)
+@@ -593,7 +1005,7 @@ END(ret_from_fork)
ENTRY(system_call)
CFI_STARTPROC simple
CFI_SIGNAL_FRAME
@@ -21984,7 +22642,7 @@ index b077f4c..feb26c1 100644
CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK
-@@ -606,16 +1040,23 @@ GLOBAL(system_call_after_swapgs)
+@@ -606,16 +1018,23 @@ GLOBAL(system_call_after_swapgs)
movq %rsp,PER_CPU_VAR(old_rsp)
movq PER_CPU_VAR(kernel_stack),%rsp
@@ -22010,16 +22668,7 @@ index b077f4c..feb26c1 100644
jnz tracesys
system_call_fastpath:
#if __SYSCALL_MASK == ~0
-@@ -625,7 +1066,7 @@ system_call_fastpath:
- cmpl $__NR_syscall_max,%eax
- #endif
- ja badsys
-- movq %r10,%rcx
-+ movq R10-ARGOFFSET(%rsp),%rcx
- call *sys_call_table(,%rax,8) # XXX: rip relative
- movq %rax,RAX-ARGOFFSET(%rsp)
- /*
-@@ -639,10 +1080,13 @@ sysret_check:
+@@ -639,10 +1058,13 @@ sysret_check:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
@@ -22034,15 +22683,7 @@ index b077f4c..feb26c1 100644
/*
* sysretq will re-enable interrupts:
*/
-@@ -694,14 +1138,18 @@ badsys:
- * jump back to the normal fast path.
- */
- auditsys:
-- movq %r10,%r9 /* 6th arg: 4th syscall arg */
-+ movq R10-ARGOFFSET(%rsp),%r9 /* 6th arg: 4th syscall arg */
- movq %rdx,%r8 /* 5th arg: 3rd syscall arg */
- movq %rsi,%rcx /* 4th arg: 2nd syscall arg */
- movq %rdi,%rdx /* 3rd arg: 1st syscall arg */
+@@ -701,6 +1123,9 @@ auditsys:
movq %rax,%rsi /* 2nd arg: syscall number */
movl $AUDIT_ARCH_X86_64,%edi /* 1st arg: audit arch */
call __audit_syscall_entry
@@ -22050,11 +22691,9 @@ index b077f4c..feb26c1 100644
+ pax_erase_kstack
+
LOAD_ARGS 0 /* reload call-clobbered registers */
-+ pax_set_fptr_mask
jmp system_call_fastpath
- /*
-@@ -722,7 +1170,7 @@ sysret_audit:
+@@ -722,7 +1147,7 @@ sysret_audit:
/* Do syscall tracing */
tracesys:
#ifdef CONFIG_AUDITSYSCALL
@@ -22063,7 +22702,7 @@ index b077f4c..feb26c1 100644
jz auditsys
#endif
SAVE_REST
-@@ -730,12 +1178,16 @@ tracesys:
+@@ -730,12 +1155,15 @@ tracesys:
FIXUP_TOP_OF_STACK %rdi
movq %rsp,%rdi
call syscall_trace_enter
@@ -22075,21 +22714,12 @@ index b077f4c..feb26c1 100644
* We don't reload %rax because syscall_trace_enter() returned
* the value it wants us to use in the table lookup.
*/
- LOAD_ARGS ARGOFFSET, 1
-+ pax_set_fptr_mask
+- LOAD_ARGS ARGOFFSET, 1
++ LOAD_ARGS 1
RESTORE_REST
#if __SYSCALL_MASK == ~0
cmpq $__NR_syscall_max,%rax
-@@ -744,7 +1196,7 @@ tracesys:
- cmpl $__NR_syscall_max,%eax
- #endif
- ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */
-- movq %r10,%rcx /* fixup for C */
-+ movq R10-ARGOFFSET(%rsp),%rcx /* fixup for C */
- call *sys_call_table(,%rax,8)
- movq %rax,RAX-ARGOFFSET(%rsp)
- /* Use IRET because user could have changed frame */
-@@ -765,7 +1217,9 @@ GLOBAL(int_with_check)
+@@ -765,7 +1193,9 @@ GLOBAL(int_with_check)
andl %edi,%edx
jnz int_careful
andl $~TS_COMPAT,TI_status(%rcx)
@@ -22100,7 +22730,7 @@ index b077f4c..feb26c1 100644
/* Either reschedule or signal or syscall exit tracking needed. */
/* First do a reschedule test. */
-@@ -811,7 +1265,7 @@ int_restore_rest:
+@@ -811,7 +1241,7 @@ int_restore_rest:
TRACE_IRQS_OFF
jmp int_with_check
CFI_ENDPROC
@@ -22109,19 +22739,20 @@ index b077f4c..feb26c1 100644
.macro FORK_LIKE func
ENTRY(stub_\func)
-@@ -824,9 +1278,10 @@ ENTRY(stub_\func)
+@@ -824,9 +1254,10 @@ ENTRY(stub_\func)
DEFAULT_FRAME 0 8 /* offset 8: return address */
call sys_\func
RESTORE_TOP_OF_STACK %r11, 8
+- ret $REST_SKIP /* pop extended registers */
+ pax_force_retaddr
- ret $REST_SKIP /* pop extended registers */
++ ret
CFI_ENDPROC
-END(stub_\func)
+ENDPROC(stub_\func)
.endm
.macro FIXED_FRAME label,func
-@@ -836,9 +1291,10 @@ ENTRY(\label)
+@@ -836,9 +1267,10 @@ ENTRY(\label)
FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET
call \func
RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET
@@ -22133,19 +22764,27 @@ index b077f4c..feb26c1 100644
.endm
FORK_LIKE clone
-@@ -855,9 +1311,10 @@ ENTRY(ptregscall_common)
- movq_cfi_restore R12+8, r12
- movq_cfi_restore RBP+8, rbp
- movq_cfi_restore RBX+8, rbx
-+ pax_force_retaddr
- ret $REST_SKIP /* pop extended registers */
- CFI_ENDPROC
+@@ -846,19 +1278,6 @@ END(\label)
+ FORK_LIKE vfork
+ FIXED_FRAME stub_iopl, sys_iopl
+
+-ENTRY(ptregscall_common)
+- DEFAULT_FRAME 1 8 /* offset 8: return address */
+- RESTORE_TOP_OF_STACK %r11, 8
+- movq_cfi_restore R15+8, r15
+- movq_cfi_restore R14+8, r14
+- movq_cfi_restore R13+8, r13
+- movq_cfi_restore R12+8, r12
+- movq_cfi_restore RBP+8, rbp
+- movq_cfi_restore RBX+8, rbx
+- ret $REST_SKIP /* pop extended registers */
+- CFI_ENDPROC
-END(ptregscall_common)
-+ENDPROC(ptregscall_common)
-
+-
ENTRY(stub_execve)
CFI_STARTPROC
-@@ -870,7 +1327,7 @@ ENTRY(stub_execve)
+ addq $8, %rsp
+@@ -870,7 +1289,7 @@ ENTRY(stub_execve)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -22154,7 +22793,7 @@ index b077f4c..feb26c1 100644
/*
* sigreturn is special because it needs to restore all registers on return.
-@@ -887,7 +1344,7 @@ ENTRY(stub_rt_sigreturn)
+@@ -887,7 +1306,7 @@ ENTRY(stub_rt_sigreturn)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -22163,7 +22802,7 @@ index b077f4c..feb26c1 100644
#ifdef CONFIG_X86_X32_ABI
ENTRY(stub_x32_rt_sigreturn)
-@@ -901,7 +1358,7 @@ ENTRY(stub_x32_rt_sigreturn)
+@@ -901,7 +1320,7 @@ ENTRY(stub_x32_rt_sigreturn)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -22172,7 +22811,7 @@ index b077f4c..feb26c1 100644
ENTRY(stub_x32_execve)
CFI_STARTPROC
-@@ -915,7 +1372,7 @@ ENTRY(stub_x32_execve)
+@@ -915,7 +1334,7 @@ ENTRY(stub_x32_execve)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -22181,7 +22820,7 @@ index b077f4c..feb26c1 100644
#endif
-@@ -952,7 +1409,7 @@ vector=vector+1
+@@ -952,7 +1371,7 @@ vector=vector+1
2: jmp common_interrupt
.endr
CFI_ENDPROC
@@ -22190,9 +22829,14 @@ index b077f4c..feb26c1 100644
.previous
END(interrupt)
-@@ -972,6 +1429,16 @@ END(interrupt)
- subq $ORIG_RAX-RBP, %rsp
- CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
+@@ -969,9 +1388,19 @@ END(interrupt)
+ /* 0(%rsp): ~(interrupt number) */
+ .macro interrupt func
+ /* reserve pt_regs for scratch regs and rbp */
+- subq $ORIG_RAX-RBP, %rsp
+- CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
++ subq $ORIG_RAX, %rsp
++ CFI_ADJUST_CFA_OFFSET ORIG_RAX
SAVE_ARGS_IRQ
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+ testb $3, CS(%rdi)
@@ -22207,7 +22851,17 @@ index b077f4c..feb26c1 100644
call \func
.endm
-@@ -1004,7 +1471,7 @@ ret_from_intr:
+@@ -997,14 +1426,14 @@ ret_from_intr:
+
+ /* Restore saved previous stack */
+ popq %rsi
+- CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */
+- leaq ARGOFFSET-RBP(%rsi), %rsp
++ CFI_DEF_CFA rsi,SS+8 /* reg/off reset after def_cfa_expr */
++ movq %rsi, %rsp
+ CFI_DEF_CFA_REGISTER rsp
+- CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET
++ CFI_ADJUST_CFA_OFFSET -ARGOFFSET
exit_intr:
GET_THREAD_INFO(%rcx)
@@ -22216,7 +22870,7 @@ index b077f4c..feb26c1 100644
je retint_kernel
/* Interrupt came from user space */
-@@ -1026,12 +1493,16 @@ retint_swapgs: /* return to user-space */
+@@ -1026,12 +1455,16 @@ retint_swapgs: /* return to user-space */
* The iretq could re-enable interrupts:
*/
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -22233,7 +22887,7 @@ index b077f4c..feb26c1 100644
/*
* The iretq could re-enable interrupts:
*/
-@@ -1114,7 +1585,7 @@ ENTRY(retint_kernel)
+@@ -1114,7 +1547,7 @@ ENTRY(retint_kernel)
#endif
CFI_ENDPROC
@@ -22242,7 +22896,7 @@ index b077f4c..feb26c1 100644
/*
* End of kprobes section
*/
-@@ -1132,7 +1603,7 @@ ENTRY(\sym)
+@@ -1132,7 +1565,7 @@ ENTRY(\sym)
interrupt \do_sym
jmp ret_from_intr
CFI_ENDPROC
@@ -22251,7 +22905,7 @@ index b077f4c..feb26c1 100644
.endm
#ifdef CONFIG_TRACING
-@@ -1215,12 +1686,22 @@ ENTRY(\sym)
+@@ -1215,12 +1648,22 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
@@ -22275,7 +22929,7 @@ index b077f4c..feb26c1 100644
.endm
.macro paranoidzeroentry sym do_sym
-@@ -1233,15 +1714,25 @@ ENTRY(\sym)
+@@ -1233,15 +1676,25 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF
@@ -22299,11 +22953,11 @@ index b077f4c..feb26c1 100644
.endm
-#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
-+#define INIT_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r12)
++#define INIT_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r13)
.macro paranoidzeroentry_ist sym do_sym ist
ENTRY(\sym)
INTR_FRAME
-@@ -1252,14 +1743,30 @@ ENTRY(\sym)
+@@ -1252,14 +1705,30 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF_DEBUG
@@ -22320,10 +22974,10 @@ index b077f4c..feb26c1 100644
movq %rsp,%rdi /* pt_regs pointer */
xorl %esi,%esi /* no error code */
+#ifdef CONFIG_SMP
-+ imul $TSS_size, PER_CPU_VAR(cpu_number), %r12d
-+ lea init_tss(%r12), %r12
++ imul $TSS_size, PER_CPU_VAR(cpu_number), %r13d
++ lea init_tss(%r13), %r13
+#else
-+ lea init_tss(%rip), %r12
++ lea init_tss(%rip), %r13
+#endif
subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
call \do_sym
@@ -22335,7 +22989,7 @@ index b077f4c..feb26c1 100644
.endm
.macro errorentry sym do_sym
-@@ -1271,13 +1778,23 @@ ENTRY(\sym)
+@@ -1271,13 +1740,23 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
@@ -22360,7 +23014,7 @@ index b077f4c..feb26c1 100644
.endm
/* error code is on the stack already */
-@@ -1291,13 +1808,23 @@ ENTRY(\sym)
+@@ -1291,13 +1770,23 @@ ENTRY(\sym)
call save_paranoid
DEFAULT_FRAME 0
TRACE_IRQS_OFF
@@ -22385,7 +23039,7 @@ index b077f4c..feb26c1 100644
.endm
zeroentry divide_error do_divide_error
-@@ -1327,9 +1854,10 @@ gs_change:
+@@ -1327,9 +1816,10 @@ gs_change:
2: mfence /* workaround */
SWAPGS
popfq_cfi
@@ -22397,7 +23051,7 @@ index b077f4c..feb26c1 100644
_ASM_EXTABLE(gs_change,bad_gs)
.section .fixup,"ax"
-@@ -1357,9 +1885,10 @@ ENTRY(call_softirq)
+@@ -1357,9 +1847,10 @@ ENTRY(call_softirq)
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
decl PER_CPU_VAR(irq_count)
@@ -22409,7 +23063,7 @@ index b077f4c..feb26c1 100644
#ifdef CONFIG_XEN
zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
-@@ -1397,7 +1926,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
+@@ -1397,7 +1888,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
decl PER_CPU_VAR(irq_count)
jmp error_exit
CFI_ENDPROC
@@ -22418,7 +23072,7 @@ index b077f4c..feb26c1 100644
/*
* Hypervisor uses this for application faults while it executes.
-@@ -1456,7 +1985,7 @@ ENTRY(xen_failsafe_callback)
+@@ -1456,7 +1947,7 @@ ENTRY(xen_failsafe_callback)
SAVE_ALL
jmp error_exit
CFI_ENDPROC
@@ -22427,7 +23081,7 @@ index b077f4c..feb26c1 100644
apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
xen_hvm_callback_vector xen_evtchn_do_upcall
-@@ -1508,18 +2037,33 @@ ENTRY(paranoid_exit)
+@@ -1508,18 +1999,33 @@ ENTRY(paranoid_exit)
DEFAULT_FRAME
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF_DEBUG
@@ -22463,7 +23117,7 @@ index b077f4c..feb26c1 100644
jmp irq_return
paranoid_userspace:
GET_THREAD_INFO(%rcx)
-@@ -1548,7 +2092,7 @@ paranoid_schedule:
+@@ -1548,7 +2054,7 @@ paranoid_schedule:
TRACE_IRQS_OFF
jmp paranoid_userspace
CFI_ENDPROC
@@ -22472,7 +23126,7 @@ index b077f4c..feb26c1 100644
/*
* Exception entry point. This expects an error code/orig_rax on the stack.
-@@ -1575,12 +2119,13 @@ ENTRY(error_entry)
+@@ -1575,12 +2081,13 @@ ENTRY(error_entry)
movq_cfi r14, R14+8
movq_cfi r15, R15+8
xorl %ebx,%ebx
@@ -22487,7 +23141,7 @@ index b077f4c..feb26c1 100644
ret
/*
-@@ -1607,7 +2152,7 @@ bstep_iret:
+@@ -1607,7 +2114,7 @@ bstep_iret:
movq %rcx,RIP+8(%rsp)
jmp error_swapgs
CFI_ENDPROC
@@ -22496,7 +23150,7 @@ index b077f4c..feb26c1 100644
/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
-@@ -1618,7 +2163,7 @@ ENTRY(error_exit)
+@@ -1618,7 +2125,7 @@ ENTRY(error_exit)
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
GET_THREAD_INFO(%rcx)
@@ -22505,7 +23159,7 @@ index b077f4c..feb26c1 100644
jne retint_kernel
LOCKDEP_SYS_EXIT_IRQ
movl TI_flags(%rcx),%edx
-@@ -1627,7 +2172,7 @@ ENTRY(error_exit)
+@@ -1627,7 +2134,7 @@ ENTRY(error_exit)
jnz retint_careful
jmp retint_swapgs
CFI_ENDPROC
@@ -22514,7 +23168,7 @@ index b077f4c..feb26c1 100644
/*
* Test if a given stack is an NMI stack or not.
-@@ -1685,9 +2230,11 @@ ENTRY(nmi)
+@@ -1685,9 +2192,11 @@ ENTRY(nmi)
* If %cs was not the kernel segment, then the NMI triggered in user
* space, which means it is definitely not nested.
*/
@@ -22527,7 +23181,7 @@ index b077f4c..feb26c1 100644
/*
* Check the special variable on the stack to see if NMIs are
* executing.
-@@ -1721,8 +2268,7 @@ nested_nmi:
+@@ -1721,8 +2230,7 @@ nested_nmi:
1:
/* Set up the interrupted NMIs stack to jump to repeat_nmi */
@@ -22537,7 +23191,7 @@ index b077f4c..feb26c1 100644
CFI_ADJUST_CFA_OFFSET 1*8
leaq -10*8(%rsp), %rdx
pushq_cfi $__KERNEL_DS
-@@ -1740,6 +2286,7 @@ nested_nmi_out:
+@@ -1740,6 +2248,7 @@ nested_nmi_out:
CFI_RESTORE rdx
/* No need to check faults here */
@@ -22545,17 +23199,29 @@ index b077f4c..feb26c1 100644
INTERRUPT_RETURN
CFI_RESTORE_STATE
-@@ -1856,6 +2403,8 @@ end_repeat_nmi:
+@@ -1852,9 +2361,11 @@ end_repeat_nmi:
+ * NMI itself takes a page fault, the page fault that was preempted
+ * will read the information from the NMI page fault and not the
+ * origin fault. Save it off and restore it if it changes.
+- * Use the r12 callee-saved register.
++ * Use the r13 callee-saved register.
*/
- movq %cr2, %r12
-
-+ pax_enter_kernel_nmi
+- movq %cr2, %r12
++ movq %cr2, %r13
+
++ pax_enter_kernel_nmi
+
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
movq %rsp,%rdi
- movq $-1,%rsi
-@@ -1868,26 +2417,31 @@ end_repeat_nmi:
- movq %r12, %cr2
+@@ -1863,31 +2374,36 @@ end_repeat_nmi:
+
+ /* Did the NMI take a page fault? Restore cr2 if it did */
+ movq %cr2, %rcx
+- cmpq %rcx, %r12
++ cmpq %rcx, %r13
+ je 1f
+- movq %r12, %cr2
++ movq %r13, %cr2
1:
- testl %ebx,%ebx /* swapgs needed? */
@@ -26670,7 +27336,7 @@ index b110fe6..d9c19f2 100644
out:
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
-index 5439117..d08f3d4 100644
+index 5439117..f4d21f7 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -55,7 +55,7 @@
@@ -26682,6 +27348,117 @@ index 5439117..d08f3d4 100644
#define APIC_LVT_NUM 6
/* 14 is the version for Xeon and Pentium 8.4.8*/
+@@ -143,6 +143,8 @@ static inline int kvm_apic_id(struct kvm_lapic *apic)
+ return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
+ }
+
++#define KVM_X2APIC_CID_BITS 0
++
+ static void recalculate_apic_map(struct kvm *kvm)
+ {
+ struct kvm_apic_map *new, *old = NULL;
+@@ -180,7 +182,8 @@ static void recalculate_apic_map(struct kvm *kvm)
+ if (apic_x2apic_mode(apic)) {
+ new->ldr_bits = 32;
+ new->cid_shift = 16;
+- new->cid_mask = new->lid_mask = 0xffff;
++ new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1;
++ new->lid_mask = 0xffff;
+ } else if (kvm_apic_sw_enabled(apic) &&
+ !new->cid_mask /* flat mode */ &&
+ kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
+@@ -841,7 +844,8 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
+ ASSERT(apic != NULL);
+
+ /* if initial count is 0, current count should also be 0 */
+- if (kvm_apic_get_reg(apic, APIC_TMICT) == 0)
++ if (kvm_apic_get_reg(apic, APIC_TMICT) == 0 ||
++ apic->lapic_timer.period == 0)
+ return 0;
+
+ remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
+@@ -1691,7 +1695,6 @@ static void apic_sync_pv_eoi_from_guest(struct kvm_vcpu *vcpu,
+ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
+ {
+ u32 data;
+- void *vapic;
+
+ if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention))
+ apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic);
+@@ -1699,9 +1702,8 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
+ if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention))
+ return;
+
+- vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
+- data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
+- kunmap_atomic(vapic);
++ kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
++ sizeof(u32));
+
+ apic_set_tpr(vcpu->arch.apic, data & 0xff);
+ }
+@@ -1737,7 +1739,6 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
+ u32 data, tpr;
+ int max_irr, max_isr;
+ struct kvm_lapic *apic = vcpu->arch.apic;
+- void *vapic;
+
+ apic_sync_pv_eoi_to_guest(vcpu, apic);
+
+@@ -1753,18 +1754,24 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
+ max_isr = 0;
+ data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24);
+
+- vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
+- *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data;
+- kunmap_atomic(vapic);
++ kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data,
++ sizeof(u32));
+ }
+
+-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
++int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
+ {
+- vcpu->arch.apic->vapic_addr = vapic_addr;
+- if (vapic_addr)
++ if (vapic_addr) {
++ if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
++ &vcpu->arch.apic->vapic_cache,
++ vapic_addr, sizeof(u32)))
++ return -EINVAL;
+ __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
+- else
++ } else {
+ __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention);
++ }
++
++ vcpu->arch.apic->vapic_addr = vapic_addr;
++ return 0;
+ }
+
+ int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
+index c730ac9..c8b0d0d 100644
+--- a/arch/x86/kvm/lapic.h
++++ b/arch/x86/kvm/lapic.h
+@@ -34,7 +34,7 @@ struct kvm_lapic {
+ */
+ void *regs;
+ gpa_t vapic_addr;
+- struct page *vapic_page;
++ struct gfn_to_hva_cache vapic_cache;
+ unsigned long pending_events;
+ unsigned int sipi_vector;
+ };
+@@ -76,7 +76,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data);
+ void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset);
+ void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector);
+
+-void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
++int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
+ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
+ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
+
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index ad75d77..a679d32 100644
--- a/arch/x86/kvm/paging_tmpl.h
@@ -26883,7 +27660,7 @@ index 2b2fce1..da76be4 100644
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index e5ca72a..83d5177 100644
+index e5ca72a..0f30b12 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1779,8 +1779,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
@@ -26906,7 +27683,17 @@ index e5ca72a..83d5177 100644
if (copy_to_user(user_msr_list->indices, &msrs_to_save,
num_msrs_to_save * sizeof(u32)))
goto out;
-@@ -5462,7 +5464,7 @@ static struct notifier_block pvclock_gtod_notifier = {
+@@ -3192,8 +3194,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
+ r = -EFAULT;
+ if (copy_from_user(&va, argp, sizeof va))
+ goto out;
+- r = 0;
+- kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
++ r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
+ break;
+ }
+ case KVM_X86_SETUP_MCE: {
+@@ -5462,7 +5463,7 @@ static struct notifier_block pvclock_gtod_notifier = {
};
#endif
@@ -26915,6 +27702,64 @@ index e5ca72a..83d5177 100644
{
int r;
struct kvm_x86_ops *ops = opaque;
+@@ -5718,36 +5719,6 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu)
+ !kvm_event_needs_reinjection(vcpu);
+ }
+
+-static int vapic_enter(struct kvm_vcpu *vcpu)
+-{
+- struct kvm_lapic *apic = vcpu->arch.apic;
+- struct page *page;
+-
+- if (!apic || !apic->vapic_addr)
+- return 0;
+-
+- page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
+- if (is_error_page(page))
+- return -EFAULT;
+-
+- vcpu->arch.apic->vapic_page = page;
+- return 0;
+-}
+-
+-static void vapic_exit(struct kvm_vcpu *vcpu)
+-{
+- struct kvm_lapic *apic = vcpu->arch.apic;
+- int idx;
+-
+- if (!apic || !apic->vapic_addr)
+- return;
+-
+- idx = srcu_read_lock(&vcpu->kvm->srcu);
+- kvm_release_page_dirty(apic->vapic_page);
+- mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
+- srcu_read_unlock(&vcpu->kvm->srcu, idx);
+-}
+-
+ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
+ {
+ int max_irr, tpr;
+@@ -6047,11 +6018,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
+ struct kvm *kvm = vcpu->kvm;
+
+ vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
+- r = vapic_enter(vcpu);
+- if (r) {
+- srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
+- return r;
+- }
+
+ r = 1;
+ while (r > 0) {
+@@ -6110,8 +6076,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
+
+ srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
+
+- vapic_exit(vcpu);
+-
+ return r;
+ }
+
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index bdf8532..f63c587 100644
--- a/arch/x86/lguest/boot.c
@@ -27719,7 +28564,7 @@ index 1e572c5..2a162cd 100644
CFI_ENDPROC
diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
-index 176cca6..1166c50 100644
+index 176cca6..e0d658e 100644
--- a/arch/x86/lib/copy_page_64.S
+++ b/arch/x86/lib/copy_page_64.S
@@ -9,6 +9,7 @@ copy_page_rep:
@@ -27730,74 +28575,68 @@ index 176cca6..1166c50 100644
ret
CFI_ENDPROC
ENDPROC(copy_page_rep)
-@@ -20,12 +21,14 @@ ENDPROC(copy_page_rep)
-
- ENTRY(copy_page)
- CFI_STARTPROC
-- subq $2*8, %rsp
-- CFI_ADJUST_CFA_OFFSET 2*8
-+ subq $3*8, %rsp
-+ CFI_ADJUST_CFA_OFFSET 3*8
+@@ -24,8 +25,8 @@ ENTRY(copy_page)
+ CFI_ADJUST_CFA_OFFSET 2*8
movq %rbx, (%rsp)
CFI_REL_OFFSET rbx, 0
- movq %r12, 1*8(%rsp)
- CFI_REL_OFFSET r12, 1*8
-+ movq %r13, 2*8(%rsp)
-+ CFI_REL_OFFSET r13, 2*8
+- movq %r12, 1*8(%rsp)
+- CFI_REL_OFFSET r12, 1*8
++ movq %r13, 1*8(%rsp)
++ CFI_REL_OFFSET r13, 1*8
movl $(4096/64)-5, %ecx
.p2align 4
-@@ -36,7 +39,7 @@ ENTRY(copy_page)
- movq 0x8*2(%rsi), %rdx
- movq 0x8*3(%rsi), %r8
+@@ -38,7 +39,7 @@ ENTRY(copy_page)
movq 0x8*4(%rsi), %r9
-- movq 0x8*5(%rsi), %r10
-+ movq 0x8*5(%rsi), %r13
+ movq 0x8*5(%rsi), %r10
movq 0x8*6(%rsi), %r11
- movq 0x8*7(%rsi), %r12
+- movq 0x8*7(%rsi), %r12
++ movq 0x8*7(%rsi), %r13
+
+ prefetcht0 5*64(%rsi)
-@@ -47,7 +50,7 @@ ENTRY(copy_page)
- movq %rdx, 0x8*2(%rdi)
- movq %r8, 0x8*3(%rdi)
+@@ -49,7 +50,7 @@ ENTRY(copy_page)
movq %r9, 0x8*4(%rdi)
-- movq %r10, 0x8*5(%rdi)
-+ movq %r13, 0x8*5(%rdi)
+ movq %r10, 0x8*5(%rdi)
movq %r11, 0x8*6(%rdi)
- movq %r12, 0x8*7(%rdi)
+- movq %r12, 0x8*7(%rdi)
++ movq %r13, 0x8*7(%rdi)
-@@ -66,7 +69,7 @@ ENTRY(copy_page)
- movq 0x8*2(%rsi), %rdx
- movq 0x8*3(%rsi), %r8
+ leaq 64 (%rsi), %rsi
+ leaq 64 (%rdi), %rdi
+@@ -68,7 +69,7 @@ ENTRY(copy_page)
movq 0x8*4(%rsi), %r9
-- movq 0x8*5(%rsi), %r10
-+ movq 0x8*5(%rsi), %r13
+ movq 0x8*5(%rsi), %r10
movq 0x8*6(%rsi), %r11
- movq 0x8*7(%rsi), %r12
+- movq 0x8*7(%rsi), %r12
++ movq 0x8*7(%rsi), %r13
-@@ -75,7 +78,7 @@ ENTRY(copy_page)
- movq %rdx, 0x8*2(%rdi)
- movq %r8, 0x8*3(%rdi)
+ movq %rax, 0x8*0(%rdi)
+ movq %rbx, 0x8*1(%rdi)
+@@ -77,7 +78,7 @@ ENTRY(copy_page)
movq %r9, 0x8*4(%rdi)
-- movq %r10, 0x8*5(%rdi)
-+ movq %r13, 0x8*5(%rdi)
+ movq %r10, 0x8*5(%rdi)
movq %r11, 0x8*6(%rdi)
- movq %r12, 0x8*7(%rdi)
+- movq %r12, 0x8*7(%rdi)
++ movq %r13, 0x8*7(%rdi)
-@@ -87,8 +90,11 @@ ENTRY(copy_page)
+ leaq 64(%rdi), %rdi
+ leaq 64(%rsi), %rsi
+@@ -85,10 +86,11 @@ ENTRY(copy_page)
+
+ movq (%rsp), %rbx
CFI_RESTORE rbx
- movq 1*8(%rsp), %r12
- CFI_RESTORE r12
-- addq $2*8, %rsp
-- CFI_ADJUST_CFA_OFFSET -2*8
-+ movq 2*8(%rsp), %r13
+- movq 1*8(%rsp), %r12
+- CFI_RESTORE r12
++ movq 1*8(%rsp), %r13
+ CFI_RESTORE r13
-+ addq $3*8, %rsp
-+ CFI_ADJUST_CFA_OFFSET -3*8
+ addq $2*8, %rsp
+ CFI_ADJUST_CFA_OFFSET -2*8
+ pax_force_retaddr
ret
.Lcopy_page_end:
CFI_ENDPROC
-@@ -99,7 +105,7 @@ ENDPROC(copy_page)
+@@ -99,7 +101,7 @@ ENDPROC(copy_page)
#include <asm/cpufeature.h>
@@ -27807,7 +28646,7 @@ index 176cca6..1166c50 100644
.byte (copy_page_rep - copy_page) - (2f - 1b) /* offset */
2:
diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
-index a30ca15..6b3f4e1 100644
+index a30ca15..407412b 100644
--- a/arch/x86/lib/copy_user_64.S
+++ b/arch/x86/lib/copy_user_64.S
@@ -18,31 +18,7 @@
@@ -27904,30 +28743,6 @@ index a30ca15..6b3f4e1 100644
ASM_STAC
cmpl $8,%edx
jb 20f /* less then 8 bytes, go to byte copy loop */
-@@ -141,19 +72,19 @@ ENTRY(copy_user_generic_unrolled)
- jz 17f
- 1: movq (%rsi),%r8
- 2: movq 1*8(%rsi),%r9
--3: movq 2*8(%rsi),%r10
-+3: movq 2*8(%rsi),%rax
- 4: movq 3*8(%rsi),%r11
- 5: movq %r8,(%rdi)
- 6: movq %r9,1*8(%rdi)
--7: movq %r10,2*8(%rdi)
-+7: movq %rax,2*8(%rdi)
- 8: movq %r11,3*8(%rdi)
- 9: movq 4*8(%rsi),%r8
- 10: movq 5*8(%rsi),%r9
--11: movq 6*8(%rsi),%r10
-+11: movq 6*8(%rsi),%rax
- 12: movq 7*8(%rsi),%r11
- 13: movq %r8,4*8(%rdi)
- 14: movq %r9,5*8(%rdi)
--15: movq %r10,6*8(%rdi)
-+15: movq %rax,6*8(%rdi)
- 16: movq %r11,7*8(%rdi)
- leaq 64(%rsi),%rsi
- leaq 64(%rdi),%rdi
@@ -180,6 +111,8 @@ ENTRY(copy_user_generic_unrolled)
jnz 21b
23: xor %eax,%eax
@@ -27972,7 +28787,7 @@ index a30ca15..6b3f4e1 100644
.section .fixup,"ax"
diff --git a/arch/x86/lib/copy_user_nocache_64.S b/arch/x86/lib/copy_user_nocache_64.S
-index 6a4f43c..55d26f2 100644
+index 6a4f43c..c70fb52 100644
--- a/arch/x86/lib/copy_user_nocache_64.S
+++ b/arch/x86/lib/copy_user_nocache_64.S
@@ -8,6 +8,7 @@
@@ -28008,30 +28823,6 @@ index 6a4f43c..55d26f2 100644
ASM_STAC
cmpl $8,%edx
jb 20f /* less then 8 bytes, go to byte copy loop */
-@@ -59,19 +71,19 @@ ENTRY(__copy_user_nocache)
- jz 17f
- 1: movq (%rsi),%r8
- 2: movq 1*8(%rsi),%r9
--3: movq 2*8(%rsi),%r10
-+3: movq 2*8(%rsi),%rax
- 4: movq 3*8(%rsi),%r11
- 5: movnti %r8,(%rdi)
- 6: movnti %r9,1*8(%rdi)
--7: movnti %r10,2*8(%rdi)
-+7: movnti %rax,2*8(%rdi)
- 8: movnti %r11,3*8(%rdi)
- 9: movq 4*8(%rsi),%r8
- 10: movq 5*8(%rsi),%r9
--11: movq 6*8(%rsi),%r10
-+11: movq 6*8(%rsi),%rax
- 12: movq 7*8(%rsi),%r11
- 13: movnti %r8,4*8(%rdi)
- 14: movnti %r9,5*8(%rdi)
--15: movnti %r10,6*8(%rdi)
-+15: movnti %rax,6*8(%rdi)
- 16: movnti %r11,7*8(%rdi)
- leaq 64(%rsi),%rsi
- leaq 64(%rdi),%rdi
@@ -98,7 +110,9 @@ ENTRY(__copy_user_nocache)
jnz 21b
23: xorl %eax,%eax
@@ -28043,7 +28834,7 @@ index 6a4f43c..55d26f2 100644
.section .fixup,"ax"
diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S
-index 2419d5f..953ee51 100644
+index 2419d5f..fe52d0e 100644
--- a/arch/x86/lib/csum-copy_64.S
+++ b/arch/x86/lib/csum-copy_64.S
@@ -9,6 +9,7 @@
@@ -28054,11 +28845,62 @@ index 2419d5f..953ee51 100644
/*
* Checksum copy with exception handling.
+@@ -56,8 +57,8 @@ ENTRY(csum_partial_copy_generic)
+ CFI_ADJUST_CFA_OFFSET 7*8
+ movq %rbx, 2*8(%rsp)
+ CFI_REL_OFFSET rbx, 2*8
+- movq %r12, 3*8(%rsp)
+- CFI_REL_OFFSET r12, 3*8
++ movq %r15, 3*8(%rsp)
++ CFI_REL_OFFSET r15, 3*8
+ movq %r14, 4*8(%rsp)
+ CFI_REL_OFFSET r14, 4*8
+ movq %r13, 5*8(%rsp)
+@@ -72,16 +73,16 @@ ENTRY(csum_partial_copy_generic)
+ movl %edx, %ecx
+
+ xorl %r9d, %r9d
+- movq %rcx, %r12
++ movq %rcx, %r15
+
+- shrq $6, %r12
++ shrq $6, %r15
+ jz .Lhandle_tail /* < 64 */
+
+ clc
+
+ /* main loop. clear in 64 byte blocks */
+ /* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
+- /* r11: temp3, rdx: temp4, r12 loopcnt */
++ /* r11: temp3, rdx: temp4, r15 loopcnt */
+ /* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */
+ .p2align 4
+ .Lloop:
+@@ -115,7 +116,7 @@ ENTRY(csum_partial_copy_generic)
+ adcq %r14, %rax
+ adcq %r13, %rax
+
+- decl %r12d
++ decl %r15d
+
+ dest
+ movq %rbx, (%rsi)
+@@ -210,8 +211,8 @@ ENTRY(csum_partial_copy_generic)
+ .Lende:
+ movq 2*8(%rsp), %rbx
+ CFI_RESTORE rbx
+- movq 3*8(%rsp), %r12
+- CFI_RESTORE r12
++ movq 3*8(%rsp), %r15
++ CFI_RESTORE r15
+ movq 4*8(%rsp), %r14
+ CFI_RESTORE r14
+ movq 5*8(%rsp), %r13
@@ -220,6 +221,7 @@ ENTRY(csum_partial_copy_generic)
CFI_RESTORE rbp
addq $7*8, %rsp
CFI_ADJUST_CFA_OFFSET -7*8
-+ pax_force_retaddr 0, 1
++ pax_force_retaddr
ret
CFI_RESTORE_STATE
@@ -28298,7 +29140,7 @@ index 05a95e7..326f2fa 100644
CFI_ENDPROC
ENDPROC(__iowrite32_copy)
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
-index 56313a3..9b59269 100644
+index 56313a3..0db417e 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -24,7 +24,7 @@
@@ -28332,48 +29174,9 @@ index 56313a3..9b59269 100644
ret
.Lmemcpy_e_e:
.previous
-@@ -76,13 +78,13 @@ ENTRY(memcpy)
- */
- movq 0*8(%rsi), %r8
- movq 1*8(%rsi), %r9
-- movq 2*8(%rsi), %r10
-+ movq 2*8(%rsi), %rcx
- movq 3*8(%rsi), %r11
- leaq 4*8(%rsi), %rsi
-
- movq %r8, 0*8(%rdi)
- movq %r9, 1*8(%rdi)
-- movq %r10, 2*8(%rdi)
-+ movq %rcx, 2*8(%rdi)
- movq %r11, 3*8(%rdi)
- leaq 4*8(%rdi), %rdi
- jae .Lcopy_forward_loop
-@@ -105,12 +107,12 @@ ENTRY(memcpy)
- subq $0x20, %rdx
- movq -1*8(%rsi), %r8
- movq -2*8(%rsi), %r9
-- movq -3*8(%rsi), %r10
-+ movq -3*8(%rsi), %rcx
- movq -4*8(%rsi), %r11
- leaq -4*8(%rsi), %rsi
- movq %r8, -1*8(%rdi)
- movq %r9, -2*8(%rdi)
-- movq %r10, -3*8(%rdi)
-+ movq %rcx, -3*8(%rdi)
- movq %r11, -4*8(%rdi)
- leaq -4*8(%rdi), %rdi
- jae .Lcopy_backward_loop
-@@ -130,12 +132,13 @@ ENTRY(memcpy)
- */
- movq 0*8(%rsi), %r8
- movq 1*8(%rsi), %r9
-- movq -2*8(%rsi, %rdx), %r10
-+ movq -2*8(%rsi, %rdx), %rcx
- movq -1*8(%rsi, %rdx), %r11
- movq %r8, 0*8(%rdi)
+@@ -136,6 +138,7 @@ ENTRY(memcpy)
movq %r9, 1*8(%rdi)
-- movq %r10, -2*8(%rdi, %rdx)
-+ movq %rcx, -2*8(%rdi, %rdx)
+ movq %r10, -2*8(%rdi, %rdx)
movq %r11, -1*8(%rdi, %rdx)
+ pax_force_retaddr
retq
@@ -28404,121 +29207,9 @@ index 56313a3..9b59269 100644
CFI_ENDPROC
ENDPROC(memcpy)
diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
-index 65268a6..5aa7815 100644
+index 65268a6..dd1de11 100644
--- a/arch/x86/lib/memmove_64.S
+++ b/arch/x86/lib/memmove_64.S
-@@ -61,13 +61,13 @@ ENTRY(memmove)
- 5:
- sub $0x20, %rdx
- movq 0*8(%rsi), %r11
-- movq 1*8(%rsi), %r10
-+ movq 1*8(%rsi), %rcx
- movq 2*8(%rsi), %r9
- movq 3*8(%rsi), %r8
- leaq 4*8(%rsi), %rsi
-
- movq %r11, 0*8(%rdi)
-- movq %r10, 1*8(%rdi)
-+ movq %rcx, 1*8(%rdi)
- movq %r9, 2*8(%rdi)
- movq %r8, 3*8(%rdi)
- leaq 4*8(%rdi), %rdi
-@@ -81,10 +81,10 @@ ENTRY(memmove)
- 4:
- movq %rdx, %rcx
- movq -8(%rsi, %rdx), %r11
-- lea -8(%rdi, %rdx), %r10
-+ lea -8(%rdi, %rdx), %r9
- shrq $3, %rcx
- rep movsq
-- movq %r11, (%r10)
-+ movq %r11, (%r9)
- jmp 13f
- .Lmemmove_end_forward:
-
-@@ -95,14 +95,14 @@ ENTRY(memmove)
- 7:
- movq %rdx, %rcx
- movq (%rsi), %r11
-- movq %rdi, %r10
-+ movq %rdi, %r9
- leaq -8(%rsi, %rdx), %rsi
- leaq -8(%rdi, %rdx), %rdi
- shrq $3, %rcx
- std
- rep movsq
- cld
-- movq %r11, (%r10)
-+ movq %r11, (%r9)
- jmp 13f
-
- /*
-@@ -127,13 +127,13 @@ ENTRY(memmove)
- 8:
- subq $0x20, %rdx
- movq -1*8(%rsi), %r11
-- movq -2*8(%rsi), %r10
-+ movq -2*8(%rsi), %rcx
- movq -3*8(%rsi), %r9
- movq -4*8(%rsi), %r8
- leaq -4*8(%rsi), %rsi
-
- movq %r11, -1*8(%rdi)
-- movq %r10, -2*8(%rdi)
-+ movq %rcx, -2*8(%rdi)
- movq %r9, -3*8(%rdi)
- movq %r8, -4*8(%rdi)
- leaq -4*8(%rdi), %rdi
-@@ -151,11 +151,11 @@ ENTRY(memmove)
- * Move data from 16 bytes to 31 bytes.
- */
- movq 0*8(%rsi), %r11
-- movq 1*8(%rsi), %r10
-+ movq 1*8(%rsi), %rcx
- movq -2*8(%rsi, %rdx), %r9
- movq -1*8(%rsi, %rdx), %r8
- movq %r11, 0*8(%rdi)
-- movq %r10, 1*8(%rdi)
-+ movq %rcx, 1*8(%rdi)
- movq %r9, -2*8(%rdi, %rdx)
- movq %r8, -1*8(%rdi, %rdx)
- jmp 13f
-@@ -167,9 +167,9 @@ ENTRY(memmove)
- * Move data from 8 bytes to 15 bytes.
- */
- movq 0*8(%rsi), %r11
-- movq -1*8(%rsi, %rdx), %r10
-+ movq -1*8(%rsi, %rdx), %r9
- movq %r11, 0*8(%rdi)
-- movq %r10, -1*8(%rdi, %rdx)
-+ movq %r9, -1*8(%rdi, %rdx)
- jmp 13f
- 10:
- cmpq $4, %rdx
-@@ -178,9 +178,9 @@ ENTRY(memmove)
- * Move data from 4 bytes to 7 bytes.
- */
- movl (%rsi), %r11d
-- movl -4(%rsi, %rdx), %r10d
-+ movl -4(%rsi, %rdx), %r9d
- movl %r11d, (%rdi)
-- movl %r10d, -4(%rdi, %rdx)
-+ movl %r9d, -4(%rdi, %rdx)
- jmp 13f
- 11:
- cmp $2, %rdx
-@@ -189,9 +189,9 @@ ENTRY(memmove)
- * Move data from 2 bytes to 3 bytes.
- */
- movw (%rsi), %r11w
-- movw -2(%rsi, %rdx), %r10w
-+ movw -2(%rsi, %rdx), %r9w
- movw %r11w, (%rdi)
-- movw %r10w, -2(%rdi, %rdx)
-+ movw %r9w, -2(%rdi, %rdx)
- jmp 13f
- 12:
- cmp $1, %rdx
@@ -202,14 +202,16 @@ ENTRY(memmove)
movb (%rsi), %r11b
movb %r11b, (%rdi)
@@ -28538,7 +29229,7 @@ index 65268a6..5aa7815 100644
.Lmemmove_end_forward_efs:
.previous
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
-index 2dcb380..50a78bc 100644
+index 2dcb380..2eb79fe 100644
--- a/arch/x86/lib/memset_64.S
+++ b/arch/x86/lib/memset_64.S
@@ -16,7 +16,7 @@
@@ -28574,21 +29265,10 @@ index 2dcb380..50a78bc 100644
ret
.Lmemset_e_e:
.previous
-@@ -59,7 +61,7 @@
- ENTRY(memset)
- ENTRY(__memset)
- CFI_STARTPROC
-- movq %rdi,%r10
-+ movq %rdi,%r11
-
- /* expand byte value */
- movzbl %sil,%ecx
-@@ -117,7 +119,8 @@ ENTRY(__memset)
- jnz .Lloop_1
+@@ -118,6 +120,7 @@ ENTRY(__memset)
.Lende:
-- movq %r10,%rax
-+ movq %r11,%rax
+ movq %r10,%rax
+ pax_force_retaddr
ret
@@ -28913,7 +29593,7 @@ index c9f2d9b..e7fd2c0 100644
from += 64;
to += 64;
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
-index f6d13ee..aca5f0b 100644
+index f6d13ee..d789440 100644
--- a/arch/x86/lib/msr-reg.S
+++ b/arch/x86/lib/msr-reg.S
@@ -3,6 +3,7 @@
@@ -28924,34 +29604,8 @@ index f6d13ee..aca5f0b 100644
#ifdef CONFIG_X86_64
/*
-@@ -16,7 +17,7 @@ ENTRY(\op\()_safe_regs)
- CFI_STARTPROC
- pushq_cfi %rbx
- pushq_cfi %rbp
-- movq %rdi, %r10 /* Save pointer */
-+ movq %rdi, %r9 /* Save pointer */
- xorl %r11d, %r11d /* Return value */
- movl (%rdi), %eax
- movl 4(%rdi), %ecx
-@@ -27,16 +28,17 @@ ENTRY(\op\()_safe_regs)
- movl 28(%rdi), %edi
- CFI_REMEMBER_STATE
- 1: \op
--2: movl %eax, (%r10)
-+2: movl %eax, (%r9)
- movl %r11d, %eax /* Return value */
-- movl %ecx, 4(%r10)
-- movl %edx, 8(%r10)
-- movl %ebx, 12(%r10)
-- movl %ebp, 20(%r10)
-- movl %esi, 24(%r10)
-- movl %edi, 28(%r10)
-+ movl %ecx, 4(%r9)
-+ movl %edx, 8(%r9)
-+ movl %ebx, 12(%r9)
-+ movl %ebp, 20(%r9)
-+ movl %esi, 24(%r9)
-+ movl %edi, 28(%r9)
+@@ -37,6 +38,7 @@ ENTRY(\op\()_safe_regs)
+ movl %edi, 28(%r10)
popq_cfi %rbp
popq_cfi %rbx
+ pax_force_retaddr
@@ -29221,7 +29875,7 @@ index 5dff5f0..cadebf4 100644
CFI_ENDPROC
ENDPROC(call_rwsem_downgrade_wake)
diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S
-index a63efd6..ccecad8 100644
+index a63efd6..8149fbe 100644
--- a/arch/x86/lib/thunk_64.S
+++ b/arch/x86/lib/thunk_64.S
@@ -8,6 +8,7 @@
@@ -29232,10 +29886,30 @@ index a63efd6..ccecad8 100644
/* rdi: arg1 ... normal C conventions. rax is saved/restored. */
.macro THUNK name, func, put_ret_addr_in_rdi=0
-@@ -41,5 +42,6 @@
- SAVE_ARGS
+@@ -15,11 +16,11 @@
+ \name:
+ CFI_STARTPROC
+
+- /* this one pushes 9 elems, the next one would be %rIP */
+- SAVE_ARGS
++ /* this one pushes 15+1 elems, the next one would be %rIP */
++ SAVE_ARGS 8
+
+ .if \put_ret_addr_in_rdi
+- movq_cfi_restore 9*8, rdi
++ movq_cfi_restore RIP, rdi
+ .endif
+
+ call \func
+@@ -38,8 +39,9 @@
+
+ /* SAVE_ARGS below is used only for the .cfi directives it contains. */
+ CFI_STARTPROC
+- SAVE_ARGS
++ SAVE_ARGS 8
restore:
- RESTORE_ARGS
+- RESTORE_ARGS
++ RESTORE_ARGS 1,8
+ pax_force_retaddr
ret
CFI_ENDPROC
@@ -30698,7 +31372,7 @@ index 3aaeffc..42ea9fb 100644
+ return ret ? -EFAULT : 0;
+}
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
-index dd74e46..7d26398 100644
+index dd74e46..0970b01 100644
--- a/arch/x86/mm/gup.c
+++ b/arch/x86/mm/gup.c
@@ -255,7 +255,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
@@ -30710,6 +31384,17 @@ index dd74e46..7d26398 100644
(void __user *)start, len)))
return 0;
+@@ -331,6 +331,10 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ goto slow_irqon;
+ #endif
+
++ if (unlikely(!__access_ok(write ? VERIFY_WRITE : VERIFY_READ,
++ (void __user *)start, len)))
++ return 0;
++
+ /*
+ * XXX: batch / limit 'nr', to avoid large irq off latency
+ * needs some instrumenting to determine the common sizes used by
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 4500142..53a363c 100644
--- a/arch/x86/mm/highmem_32.c
@@ -34858,10 +35543,10 @@ index 81a94a3..b711c74 100644
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
-index db6dfcf..770d1f0 100644
+index ab58556..ed19dd2 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
-@@ -4113,7 +4113,7 @@ int ata_sas_port_init(struct ata_port *ap)
+@@ -4114,7 +4114,7 @@ int ata_sas_port_init(struct ata_port *ap)
if (rc)
return rc;
@@ -37581,7 +38266,7 @@ index f897d51..15da295 100644
if (policy->cpu != 0)
return -ENODEV;
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
-index d75040d..4738ca5 100644
+index 22c07fb..9dff5ac 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -252,7 +252,7 @@ static int poll_idle(struct cpuidle_device *dev,
@@ -37981,10 +38666,10 @@ index 5145fa3..0d3babd 100644
return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
}
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
-index 8a7432a..28fb839 100644
+index 8c5a61a..cf07bd0 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
-@@ -452,7 +452,7 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
+@@ -456,7 +456,7 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
static int
create_efivars_bin_attributes(void)
{
@@ -45864,7 +46549,7 @@ index c9382d6..6619864 100644
error = bus_register(&fcoe_bus_type);
if (error)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
-index df0c3c7..b00e1d0 100644
+index 3cafe0d..f1e87f8 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -42,7 +42,7 @@
@@ -45886,10 +46571,10 @@ index df0c3c7..b00e1d0 100644
/* These three are default values which can be overridden */
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
-index 891c86b..dd1224a0 100644
+index 0eb0940..3ca9b79 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
-@@ -578,7 +578,7 @@ static inline u32 next_command(struct ctlr_info *h, u8 q)
+@@ -579,7 +579,7 @@ static inline u32 next_command(struct ctlr_info *h, u8 q)
unsigned long flags;
if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
@@ -45898,7 +46583,7 @@ index 891c86b..dd1224a0 100644
if ((rq->head[rq->current_entry] & 1) == rq->wraparound) {
a = rq->head[rq->current_entry];
-@@ -3444,7 +3444,7 @@ static void start_io(struct ctlr_info *h)
+@@ -3445,7 +3445,7 @@ static void start_io(struct ctlr_info *h)
while (!list_empty(&h->reqQ)) {
c = list_entry(h->reqQ.next, struct CommandList, list);
/* can't do anything if fifo is full */
@@ -45907,7 +46592,7 @@ index 891c86b..dd1224a0 100644
dev_warn(&h->pdev->dev, "fifo full\n");
break;
}
-@@ -3466,7 +3466,7 @@ static void start_io(struct ctlr_info *h)
+@@ -3467,7 +3467,7 @@ static void start_io(struct ctlr_info *h)
/* Tell the controller execute command */
spin_unlock_irqrestore(&h->lock, flags);
@@ -45916,7 +46601,7 @@ index 891c86b..dd1224a0 100644
spin_lock_irqsave(&h->lock, flags);
}
spin_unlock_irqrestore(&h->lock, flags);
-@@ -3474,17 +3474,17 @@ static void start_io(struct ctlr_info *h)
+@@ -3475,17 +3475,17 @@ static void start_io(struct ctlr_info *h)
static inline unsigned long get_next_completion(struct ctlr_info *h, u8 q)
{
@@ -45937,7 +46622,7 @@ index 891c86b..dd1224a0 100644
(h->interrupts_enabled == 0);
}
-@@ -4386,7 +4386,7 @@ static int hpsa_pci_init(struct ctlr_info *h)
+@@ -4387,7 +4387,7 @@ static int hpsa_pci_init(struct ctlr_info *h)
if (prod_index < 0)
return -ENODEV;
h->product_name = products[prod_index].product_name;
@@ -45946,7 +46631,7 @@ index 891c86b..dd1224a0 100644
pci_disable_link_state(h->pdev, PCIE_LINK_STATE_L0S |
PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
-@@ -4668,7 +4668,7 @@ static void controller_lockup_detected(struct ctlr_info *h)
+@@ -4669,7 +4669,7 @@ static void controller_lockup_detected(struct ctlr_info *h)
assert_spin_locked(&lockup_detector_lock);
remove_ctlr_from_lockup_detector_list(h);
@@ -45955,7 +46640,7 @@ index 891c86b..dd1224a0 100644
spin_lock_irqsave(&h->lock, flags);
h->lockup_detected = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
spin_unlock_irqrestore(&h->lock, flags);
-@@ -4845,7 +4845,7 @@ reinit_after_soft_reset:
+@@ -4846,7 +4846,7 @@ reinit_after_soft_reset:
}
/* make sure the board interrupts are off */
@@ -45964,7 +46649,7 @@ index 891c86b..dd1224a0 100644
if (hpsa_request_irq(h, do_hpsa_intr_msi, do_hpsa_intr_intx))
goto clean2;
-@@ -4879,7 +4879,7 @@ reinit_after_soft_reset:
+@@ -4880,7 +4880,7 @@ reinit_after_soft_reset:
* fake ones to scoop up any residual completions.
*/
spin_lock_irqsave(&h->lock, flags);
@@ -45973,7 +46658,7 @@ index 891c86b..dd1224a0 100644
spin_unlock_irqrestore(&h->lock, flags);
free_irqs(h);
rc = hpsa_request_irq(h, hpsa_msix_discard_completions,
-@@ -4898,9 +4898,9 @@ reinit_after_soft_reset:
+@@ -4899,9 +4899,9 @@ reinit_after_soft_reset:
dev_info(&h->pdev->dev, "Board READY.\n");
dev_info(&h->pdev->dev,
"Waiting for stale completions to drain.\n");
@@ -45985,7 +46670,7 @@ index 891c86b..dd1224a0 100644
rc = controller_reset_failed(h->cfgtable);
if (rc)
-@@ -4921,7 +4921,7 @@ reinit_after_soft_reset:
+@@ -4922,7 +4922,7 @@ reinit_after_soft_reset:
}
/* Turn the interrupts on so we can service requests */
@@ -45994,7 +46679,7 @@ index 891c86b..dd1224a0 100644
hpsa_hba_inquiry(h);
hpsa_register_scsi(h); /* hook ourselves into SCSI subsystem */
-@@ -4976,7 +4976,7 @@ static void hpsa_shutdown(struct pci_dev *pdev)
+@@ -4977,7 +4977,7 @@ static void hpsa_shutdown(struct pci_dev *pdev)
* To write all data in the battery backed cache to disks
*/
hpsa_flush_cache(h);
@@ -46003,7 +46688,7 @@ index 891c86b..dd1224a0 100644
hpsa_free_irqs_and_disable_msix(h);
}
-@@ -5144,7 +5144,7 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 use_short_tags)
+@@ -5145,7 +5145,7 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 use_short_tags)
return;
}
/* Change the access methods to the performant access methods */
@@ -46171,7 +46856,7 @@ index 5879929..32b241d 100644
}
EXPORT_SYMBOL(fc_exch_update_stats);
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
-index 161c98e..6d563b3 100644
+index d289583..b745eec 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -554,7 +554,7 @@ static struct ata_port_operations sas_sata_ops = {
@@ -46412,7 +47097,7 @@ index 7f0af4f..193ac3e 100644
unsigned long flags;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
-index 1eb7b028..b2a6080 100644
+index a38f71b..f3bc572 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -200,8 +200,8 @@ static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
@@ -46456,7 +47141,7 @@ index 1eb7b028..b2a6080 100644
pinstance->num_hrrq;
if (request_size) {
-@@ -4483,7 +4483,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
+@@ -4484,7 +4484,7 @@ static void pmcraid_worker_function(struct work_struct *workp)
pinstance = container_of(workp, struct pmcraid_instance, worker_q);
/* add resources only after host is added into system */
@@ -46465,7 +47150,7 @@ index 1eb7b028..b2a6080 100644
return;
fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
-@@ -5310,8 +5310,8 @@ static int pmcraid_init_instance(struct pci_dev *pdev, struct Scsi_Host *host,
+@@ -5311,8 +5311,8 @@ static int pmcraid_init_instance(struct pci_dev *pdev, struct Scsi_Host *host,
init_waitqueue_head(&pinstance->reset_wait_q);
atomic_set(&pinstance->outstanding_cmds, 0);
@@ -46476,7 +47161,7 @@ index 1eb7b028..b2a6080 100644
INIT_LIST_HEAD(&pinstance->free_res_q);
INIT_LIST_HEAD(&pinstance->used_res_q);
-@@ -6024,7 +6024,7 @@ static int pmcraid_probe(struct pci_dev *pdev,
+@@ -6025,7 +6025,7 @@ static int pmcraid_probe(struct pci_dev *pdev,
/* Schedule worker thread to handle CCN and take care of adding and
* removing devices to OS
*/
@@ -46780,10 +47465,10 @@ index f379c7f..e8fc69c 100644
transport_setup_device(&rport->dev);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index 5693f6d7..b0bf05a 100644
+index 2634d69..fcf7a81 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
-@@ -2934,7 +2934,7 @@ static int sd_probe(struct device *dev)
+@@ -2940,7 +2940,7 @@ static int sd_probe(struct device *dev)
sdkp->disk = gd;
sdkp->index = index;
atomic_set(&sdkp->openers, 0);
@@ -47728,10 +48413,10 @@ index c0f76da..d974c32 100644
dlci_get(dlci->gsm->dlci[0]);
mux_get(dlci->gsm);
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
-index ff58293..71c87bc 100644
+index 4d6f430..0810fa9 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
-@@ -2502,6 +2502,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
+@@ -2504,6 +2504,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
{
*ops = tty_ldisc_N_TTY;
ops->owner = NULL;
@@ -52899,7 +53584,7 @@ index 89dec7f..361b0d75 100644
fd_offset + ex.a_text);
if (error != N_DATADDR(ex)) {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 4c94a79..f428019 100644
+index 4c94a79..2610454 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -34,6 +34,7 @@
@@ -53415,15 +54100,20 @@ index 4c94a79..f428019 100644
struct elfhdr elf_ex;
struct elfhdr interp_elf_ex;
} *loc;
-+ unsigned long pax_task_size = TASK_SIZE;
++ unsigned long pax_task_size;
loc = kmalloc(sizeof(*loc), GFP_KERNEL);
if (!loc) {
-@@ -723,11 +1068,81 @@ static int load_elf_binary(struct linux_binprm *bprm)
+@@ -723,11 +1068,82 @@ static int load_elf_binary(struct linux_binprm *bprm)
goto out_free_dentry;
/* OK, This is the point of no return */
- current->mm->def_flags = def_flags;
++ current->mm->def_flags = 0;
+
+ /* Do this immediately, since STACK_TOP as used in setup_arg_pages
+ may depend on the personality. */
+ SET_PERSONALITY(loc->elf_ex);
+
+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
+ current->mm->pax_flags = 0UL;
@@ -53442,8 +54132,6 @@ index 4c94a79..f428019 100644
+ current->mm->delta_stack = 0UL;
+#endif
+
-+ current->mm->def_flags = 0;
-+
+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
+ if (0 > pax_parse_pax_flags(&loc->elf_ex, elf_phdata, bprm->file)) {
+ send_sig(SIGKILL, current, 0);
@@ -53471,19 +54159,17 @@ index 4c94a79..f428019 100644
+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
+ pax_task_size = SEGMEXEC_TASK_SIZE;
+ current->mm->def_flags |= VM_NOHUGEPAGE;
-+ }
++ } else
+#endif
+
++ pax_task_size = TASK_SIZE;
++
+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
+ put_cpu();
+ }
+#endif
-
- /* Do this immediately, since STACK_TOP as used in setup_arg_pages
- may depend on the personality. */
- SET_PERSONALITY(loc->elf_ex);
+
+#ifdef CONFIG_PAX_ASLR
+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
@@ -53502,7 +54188,7 @@ index 4c94a79..f428019 100644
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
current->personality |= READ_IMPLIES_EXEC;
-@@ -817,6 +1232,20 @@ static int load_elf_binary(struct linux_binprm *bprm)
+@@ -817,6 +1233,20 @@ static int load_elf_binary(struct linux_binprm *bprm)
#else
load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
#endif
@@ -53523,7 +54209,7 @@ index 4c94a79..f428019 100644
}
error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
-@@ -849,9 +1278,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
+@@ -849,9 +1279,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
* allowed task size. Note that p_filesz must always be
* <= p_memsz so it is only necessary to check p_memsz.
*/
@@ -53536,7 +54222,7 @@ index 4c94a79..f428019 100644
/* set_brk can never work. Avoid overflows. */
send_sig(SIGKILL, current, 0);
retval = -EINVAL;
-@@ -890,17 +1319,45 @@ static int load_elf_binary(struct linux_binprm *bprm)
+@@ -890,17 +1320,45 @@ static int load_elf_binary(struct linux_binprm *bprm)
goto out_free_dentry;
}
if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
@@ -53588,7 +54274,7 @@ index 4c94a79..f428019 100644
load_bias);
if (!IS_ERR((void *)elf_entry)) {
/*
-@@ -1122,7 +1579,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
+@@ -1122,7 +1580,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
* Decide what to dump of a segment, part, all or none.
*/
static unsigned long vma_dump_size(struct vm_area_struct *vma,
@@ -53597,7 +54283,7 @@ index 4c94a79..f428019 100644
{
#define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
-@@ -1160,7 +1617,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
+@@ -1160,7 +1618,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
if (vma->vm_file == NULL)
return 0;
@@ -53606,7 +54292,7 @@ index 4c94a79..f428019 100644
goto whole;
/*
-@@ -1385,9 +1842,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
+@@ -1385,9 +1843,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
{
elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
int i = 0;
@@ -53618,7 +54304,7 @@ index 4c94a79..f428019 100644
fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
}
-@@ -1396,7 +1853,7 @@ static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
+@@ -1396,7 +1854,7 @@ static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
{
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -53627,7 +54313,7 @@ index 4c94a79..f428019 100644
set_fs(old_fs);
fill_note(note, "CORE", NT_SIGINFO, sizeof(*csigdata), csigdata);
}
-@@ -2023,14 +2480,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+@@ -2023,14 +2481,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
}
static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
@@ -53644,7 +54330,7 @@ index 4c94a79..f428019 100644
return size;
}
-@@ -2123,7 +2580,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2123,7 +2581,7 @@ static int elf_core_dump(struct coredump_params *cprm)
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
@@ -53653,7 +54339,7 @@ index 4c94a79..f428019 100644
offset += elf_core_extra_data_size();
e_shoff = offset;
-@@ -2137,10 +2594,12 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2137,10 +2595,12 @@ static int elf_core_dump(struct coredump_params *cprm)
offset = dataoff;
size += sizeof(*elf);
@@ -53666,7 +54352,7 @@ index 4c94a79..f428019 100644
if (size > cprm->limit
|| !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
goto end_coredump;
-@@ -2154,7 +2613,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2154,7 +2614,7 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
@@ -53675,7 +54361,7 @@ index 4c94a79..f428019 100644
phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
-@@ -2165,6 +2624,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2165,6 +2625,7 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_align = ELF_EXEC_PAGESIZE;
size += sizeof(phdr);
@@ -53683,7 +54369,7 @@ index 4c94a79..f428019 100644
if (size > cprm->limit
|| !dump_write(cprm->file, &phdr, sizeof(phdr)))
goto end_coredump;
-@@ -2189,7 +2649,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2189,7 +2650,7 @@ static int elf_core_dump(struct coredump_params *cprm)
unsigned long addr;
unsigned long end;
@@ -53692,7 +54378,7 @@ index 4c94a79..f428019 100644
for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
struct page *page;
-@@ -2198,6 +2658,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2198,6 +2659,7 @@ static int elf_core_dump(struct coredump_params *cprm)
page = get_dump_page(addr);
if (page) {
void *kaddr = kmap(page);
@@ -53700,7 +54386,7 @@ index 4c94a79..f428019 100644
stop = ((size += PAGE_SIZE) > cprm->limit) ||
!dump_write(cprm->file, kaddr,
PAGE_SIZE);
-@@ -2215,6 +2676,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2215,6 +2677,7 @@ static int elf_core_dump(struct coredump_params *cprm)
if (e_phnum == PN_XNUM) {
size += sizeof(*shdr4extnum);
@@ -53708,7 +54394,7 @@ index 4c94a79..f428019 100644
if (size > cprm->limit
|| !dump_write(cprm->file, shdr4extnum,
sizeof(*shdr4extnum)))
-@@ -2235,6 +2697,167 @@ out:
+@@ -2235,6 +2698,167 @@ out:
#endif /* CONFIG_ELF_CORE */
@@ -54070,6 +54756,19 @@ index e913328..a34fb36 100644
/* Wake up anybody who may be waiting on this transaction */
wake_up(&root->fs_info->transaction_wait);
wake_up(&root->fs_info->transaction_blocked_wait);
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 79f057c..e14e1f7 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -3375,7 +3375,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
+ btrfs_set_token_file_extent_type(leaf, fi,
+ BTRFS_FILE_EXTENT_REG,
+ &token);
+- if (em->block_start == 0)
++ if (em->block_start == EXTENT_MAP_HOLE)
+ skip_csum = true;
+ }
+
diff --git a/fs/buffer.c b/fs/buffer.c
index 6024877..7bd000a 100644
--- a/fs/buffer.c
@@ -54433,6 +55132,28 @@ index c8e03f8..75362f6 100644
#endif
GLOBAL_EXTERN atomic_t smBufAllocCount;
GLOBAL_EXTERN atomic_t midCount;
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 7ddddf2..2e12dbc 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -1900,10 +1900,14 @@ static int cifs_writepages(struct address_space *mapping,
+ index = mapping->writeback_index; /* Start from prev offset */
+ end = -1;
+ } else {
+- index = wbc->range_start >> PAGE_CACHE_SHIFT;
+- end = wbc->range_end >> PAGE_CACHE_SHIFT;
+- if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
++ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) {
+ range_whole = true;
++ index = 0;
++ end = ULONG_MAX;
++ } else {
++ index = wbc->range_start >> PAGE_CACHE_SHIFT;
++ end = wbc->range_end >> PAGE_CACHE_SHIFT;
++ }
+ scanned = true;
+ }
+ retry:
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 7e36ceb..109252f 100644
--- a/fs/cifs/link.c
@@ -55069,9 +55790,18 @@ index 9bdeca1..2a9b08d 100644
EXPORT_SYMBOL(dump_write);
diff --git a/fs/dcache.c b/fs/dcache.c
-index 89f9671..5977a84 100644
+index 89f9671..d2dce57 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
+@@ -1570,7 +1570,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
+ */
+ dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
+ if (name->len > DNAME_INLINE_LEN-1) {
+- dname = kmalloc(name->len + 1, GFP_KERNEL);
++ dname = kmalloc(round_up(name->len + 1, sizeof(unsigned long)), GFP_KERNEL);
+ if (!dname) {
+ kmem_cache_free(dentry_cache, dentry);
+ return NULL;
@@ -2893,6 +2893,7 @@ static int prepend_path(const struct path *path,
restart:
bptr = *buffer;
@@ -59289,7 +60019,7 @@ index d420331..2dbb3fd 100644
}
putname(tmp);
diff --git a/fs/pipe.c b/fs/pipe.c
-index d2c45e1..009fe1c 100644
+index 0e0752e..7cfdd50 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -56,7 +56,7 @@ unsigned int pipe_min_size = PAGE_SIZE;
@@ -59370,7 +60100,16 @@ index d2c45e1..009fe1c 100644
mask |= POLLERR;
}
-@@ -734,17 +734,17 @@ pipe_release(struct inode *inode, struct file *file)
+@@ -731,7 +731,7 @@ static void put_pipe_info(struct inode *inode, struct pipe_inode_info *pipe)
+ int kill = 0;
+
+ spin_lock(&inode->i_lock);
+- if (!--pipe->files) {
++ if (atomic_dec_and_test(&pipe->files)) {
+ inode->i_pipe = NULL;
+ kill = 1;
+ }
+@@ -748,11 +748,11 @@ pipe_release(struct inode *inode, struct file *file)
__pipe_lock(pipe);
if (file->f_mode & FMODE_READ)
@@ -59385,14 +60124,7 @@ index d2c45e1..009fe1c 100644
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM | POLLERR | POLLHUP);
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
- }
- spin_lock(&inode->i_lock);
-- if (!--pipe->files) {
-+ if (atomic_dec_and_test(&pipe->files)) {
- inode->i_pipe = NULL;
- kill = 1;
- }
-@@ -811,7 +811,7 @@ void free_pipe_info(struct pipe_inode_info *pipe)
+@@ -817,7 +817,7 @@ void free_pipe_info(struct pipe_inode_info *pipe)
kfree(pipe);
}
@@ -59401,7 +60133,7 @@ index d2c45e1..009fe1c 100644
/*
* pipefs_dname() is called from d_path().
-@@ -841,8 +841,9 @@ static struct inode * get_pipe_inode(void)
+@@ -847,8 +847,9 @@ static struct inode * get_pipe_inode(void)
goto fail_iput;
inode->i_pipe = pipe;
@@ -59413,7 +60145,7 @@ index d2c45e1..009fe1c 100644
inode->i_fop = &pipefifo_fops;
/*
-@@ -1022,17 +1023,17 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -1027,17 +1028,17 @@ static int fifo_open(struct inode *inode, struct file *filp)
spin_lock(&inode->i_lock);
if (inode->i_pipe) {
pipe = inode->i_pipe;
@@ -59434,7 +60166,7 @@ index d2c45e1..009fe1c 100644
spin_unlock(&inode->i_lock);
free_pipe_info(pipe);
pipe = inode->i_pipe;
-@@ -1057,10 +1058,10 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -1062,10 +1063,10 @@ static int fifo_open(struct inode *inode, struct file *filp)
* opened, even when there is no process writing the FIFO.
*/
pipe->r_counter++;
@@ -59447,7 +60179,7 @@ index d2c45e1..009fe1c 100644
if ((filp->f_flags & O_NONBLOCK)) {
/* suppress POLLHUP until we have
* seen a writer */
-@@ -1079,14 +1080,14 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -1084,14 +1085,14 @@ static int fifo_open(struct inode *inode, struct file *filp)
* errno=ENXIO when there is no process reading the FIFO.
*/
ret = -ENXIO;
@@ -59465,7 +60197,7 @@ index d2c45e1..009fe1c 100644
if (wait_for_partner(pipe, &pipe->r_counter))
goto err_wr;
}
-@@ -1100,11 +1101,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -1105,11 +1106,11 @@ static int fifo_open(struct inode *inode, struct file *filp)
* the process can at least talk to itself.
*/
@@ -59480,7 +60212,7 @@ index d2c45e1..009fe1c 100644
wake_up_partner(pipe);
break;
-@@ -1118,20 +1119,20 @@ static int fifo_open(struct inode *inode, struct file *filp)
+@@ -1123,13 +1124,13 @@ static int fifo_open(struct inode *inode, struct file *filp)
return 0;
err_rd:
@@ -59496,14 +60228,6 @@ index d2c45e1..009fe1c 100644
wake_up_interruptible(&pipe->wait);
ret = -ERESTARTSYS;
goto err;
-
- err:
- spin_lock(&inode->i_lock);
-- if (!--pipe->files) {
-+ if (atomic_dec_and_test(&pipe->files)) {
- inode->i_pipe = NULL;
- kill = 1;
- }
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 15af622..0e9f4467 100644
--- a/fs/proc/Kconfig
@@ -67113,10 +67837,10 @@ index 0000000..25f54ef
+};
diff --git a/grsecurity/gracl_policy.c b/grsecurity/gracl_policy.c
new file mode 100644
-index 0000000..36e293f
+index 0000000..361a099
--- /dev/null
+++ b/grsecurity/gracl_policy.c
-@@ -0,0 +1,1777 @@
+@@ -0,0 +1,1782 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -67576,12 +68300,12 @@ index 0000000..36e293f
+ printk(KERN_ALERT "Obtained real root device=%d, inode=%lu\n", __get_dev(gr_real_root.dentry), gr_real_root.dentry->d_inode->i_ino);
+#endif
+
-+ fakefs_obj_rw = acl_alloc(sizeof(struct acl_object_label));
++ fakefs_obj_rw = kzalloc(sizeof(struct acl_object_label), GFP_KERNEL);
+ if (fakefs_obj_rw == NULL)
+ return 1;
+ fakefs_obj_rw->mode = GR_FIND | GR_READ | GR_WRITE;
+
-+ fakefs_obj_rwx = acl_alloc(sizeof(struct acl_object_label));
++ fakefs_obj_rwx = kzalloc(sizeof(struct acl_object_label), GFP_KERNEL);
+ if (fakefs_obj_rwx == NULL)
+ return 1;
+ fakefs_obj_rwx->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
@@ -67659,6 +68383,11 @@ index 0000000..36e293f
+ } while_each_thread(task2, task);
+ read_unlock(&tasklist_lock);
+
++ kfree(fakefs_obj_rw);
++ fakefs_obj_rw = NULL;
++ kfree(fakefs_obj_rwx);
++ fakefs_obj_rwx = NULL;
++
+ /* release the reference to the real root dentry and vfsmount */
+ path_put(&gr_real_root);
+ memset(&gr_real_root, 0, sizeof(gr_real_root));
@@ -73989,7 +74718,7 @@ index 0bc7275..4ccbf11 100644
unsigned int offset, size_t len);
diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 5f8f176..62a0556 100644
+index 094ddd0..f1dfcd3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -745,6 +745,7 @@ struct efivar_operations {
@@ -74001,7 +74730,7 @@ index 5f8f176..62a0556 100644
struct efivars {
/*
diff --git a/include/linux/elf.h b/include/linux/elf.h
-index 40a3c0e..4c45a38 100644
+index 40a3c0e0..4c45a38 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -24,6 +24,7 @@ extern Elf32_Dyn _DYNAMIC [];
@@ -77195,7 +77924,7 @@ index cc7494a..1e27036 100644
extern bool qid_valid(struct kqid qid);
diff --git a/include/linux/random.h b/include/linux/random.h
-index bf9085e..128eade 100644
+index bf9085e..1e8bbcf 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -10,9 +10,19 @@
@@ -77220,11 +77949,23 @@ index bf9085e..128eade 100644
extern void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes);
-@@ -33,6 +43,11 @@ void prandom_seed(u32 seed);
+@@ -23,16 +33,21 @@ extern int random_int_secret_init(void);
+ extern const struct file_operations random_fops, urandom_fops;
+ #endif
+
+-unsigned int get_random_int(void);
++unsigned int __intentional_overflow(-1) get_random_int(void);
+ unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
+
+-u32 prandom_u32(void);
++u32 prandom_u32(void) __intentional_overflow(-1);
+ void prandom_bytes(void *buf, int nbytes);
+ void prandom_seed(u32 seed);
+
u32 prandom_u32_state(struct rnd_state *);
void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
-+static inline unsigned long pax_get_random_long(void)
++static inline unsigned long __intentional_overflow(-1) pax_get_random_long(void)
+{
+ return prandom_u32() + (sizeof(long) > 4 ? (unsigned long)prandom_u32() << 32 : 0);
+}
@@ -81824,7 +82565,7 @@ index 086fe73..72c1122 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index c3a1a55..e32b4a98 100644
+index c3a1a55..1b8cfce 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -81847,6 +82588,15 @@ index c3a1a55..e32b4a98 100644
/*
* The futex address must be "naturally" aligned.
*/
+@@ -288,7 +294,7 @@ again:
+ put_page(page);
+ /* serialize against __split_huge_page_splitting() */
+ local_irq_disable();
+- if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) {
++ if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
+ page_head = compound_head(page);
+ /*
+ * page_head is valid pointer but we must pin
@@ -441,7 +447,7 @@ static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr,
static int get_futex_value_locked(u32 *dest, u32 __user *from)
@@ -85664,7 +86414,7 @@ index 88c9c65..7497ebc 100644
.clock_get = alarm_clock_get,
.timer_create = alarm_timer_create,
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
-index 947ba25..20cbade 100644
+index 5cf6c70..ac341b0 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -15,6 +15,7 @@
@@ -87232,7 +87982,7 @@ index ae4846f..b0acebe 100644
send_sig(SIGXFSZ, current, 0);
return -EFBIG;
diff --git a/mm/fremap.c b/mm/fremap.c
-index 5bff081..d8189a9 100644
+index 5bff081..00bd91e 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -163,6 +163,11 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
@@ -87247,6 +87997,15 @@ index 5bff081..d8189a9 100644
/*
* Make sure the vma is shared, that it supports prefaulting,
* and that the remapped range is valid and fully within
+@@ -218,6 +223,8 @@ get_write_lock:
+ BUG_ON(addr != start);
+ err = 0;
+ }
++ vm_flags = vma->vm_flags;
++ vma = NULL;
+ goto out;
+ }
+ mutex_lock(&mapping->i_mmap_mutex);
diff --git a/mm/highmem.c b/mm/highmem.c
index b32b70c..e512eb0 100644
--- a/mm/highmem.c
@@ -94303,7 +95062,7 @@ index 4b85e6f..22f9ac9 100644
syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) {
/* Has it gone just too far? */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index 5e2c2f1..6473c22 100644
+index f60b1ee..40b401c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -87,6 +87,7 @@
@@ -94354,7 +95113,7 @@ index 5e2c2f1..6473c22 100644
daddr = inet->inet_daddr;
dport = inet->inet_dport;
/* Open fast path for connected socket.
-@@ -1141,7 +1158,7 @@ static unsigned int first_packet_length(struct sock *sk)
+@@ -1144,7 +1161,7 @@ static unsigned int first_packet_length(struct sock *sk)
IS_UDPLITE(sk));
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
IS_UDPLITE(sk));
@@ -94363,7 +95122,7 @@ index 5e2c2f1..6473c22 100644
__skb_unlink(skb, rcvq);
__skb_queue_tail(&list_kill, skb);
}
-@@ -1221,6 +1238,10 @@ try_again:
+@@ -1224,6 +1241,10 @@ try_again:
if (!skb)
goto out;
@@ -94374,7 +95133,7 @@ index 5e2c2f1..6473c22 100644
ulen = skb->len - sizeof(struct udphdr);
copied = len;
if (copied > ulen)
-@@ -1254,7 +1275,7 @@ try_again:
+@@ -1257,7 +1278,7 @@ try_again:
if (unlikely(err)) {
trace_kfree_skb(skb, udp_recvmsg);
if (!peeked) {
@@ -94383,7 +95142,7 @@ index 5e2c2f1..6473c22 100644
UDP_INC_STATS_USER(sock_net(sk),
UDP_MIB_INERRORS, is_udplite);
}
-@@ -1542,7 +1563,7 @@ csum_error:
+@@ -1545,7 +1566,7 @@ csum_error:
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
drop:
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
@@ -94392,7 +95151,7 @@ index 5e2c2f1..6473c22 100644
kfree_skb(skb);
return -1;
}
-@@ -1561,7 +1582,7 @@ static void flush_stack(struct sock **stack, unsigned int count,
+@@ -1564,7 +1585,7 @@ static void flush_stack(struct sock **stack, unsigned int count,
skb1 = (i == final) ? skb : skb_clone(skb, GFP_ATOMIC);
if (!skb1) {
@@ -94401,7 +95160,7 @@ index 5e2c2f1..6473c22 100644
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
IS_UDPLITE(sk));
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
-@@ -1733,6 +1754,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
+@@ -1736,6 +1757,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
goto csum_error;
UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
@@ -94411,7 +95170,7 @@ index 5e2c2f1..6473c22 100644
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
/*
-@@ -2165,7 +2189,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
+@@ -2168,7 +2192,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
0, sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp,
@@ -96851,7 +97610,7 @@ index 6b36561..4f21064 100644
table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
diff --git a/net/socket.c b/net/socket.c
-index e83c416..17afbfa 100644
+index e83c416..9169305 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
@@ -97053,6 +97812,15 @@ index e83c416..17afbfa 100644
/* user mode address pointers */
struct sockaddr __user *uaddr;
+@@ -2227,7 +2293,7 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
+ /* Save the user-mode address (verify_iovec will change the
+ * kernel msghdr to use the kernel address space)
+ */
+- uaddr = (__force void __user *)msg_sys->msg_name;
++ uaddr = (void __force_user *)msg_sys->msg_name;
+ uaddr_len = COMPAT_NAMELEN(msg);
+ if (MSG_CMSG_COMPAT & flags)
+ err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
@@ -2985,7 +3051,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -101544,10 +102312,10 @@ index 0000000..568b360
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..698da67
+index 0000000..a25306b
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,471 @@
+@@ -0,0 +1,474 @@
+/*
+ * Copyright 2011-2013 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
@@ -101693,21 +102461,21 @@ index 0000000..698da67
+}
+
+/*
-+ * add special KERNEXEC instrumentation: reload %r10 after it has been clobbered
++ * add special KERNEXEC instrumentation: reload %r12 after it has been clobbered
+ */
+static void kernexec_reload_fptr_mask(gimple_stmt_iterator *gsi)
+{
+ gimple asm_movabs_stmt;
+
-+ // build asm volatile("movabs $0x8000000000000000, %%r10\n\t" : : : );
-+ asm_movabs_stmt = gimple_build_asm_vec("movabs $0x8000000000000000, %%r10\n\t", NULL, NULL, NULL, NULL);
++ // build asm volatile("movabs $0x8000000000000000, %%r12\n\t" : : : );
++ asm_movabs_stmt = gimple_build_asm_vec("movabs $0x8000000000000000, %%r12\n\t", NULL, NULL, NULL, NULL);
+ gimple_asm_set_volatile(asm_movabs_stmt, true);
+ gsi_insert_after(gsi, asm_movabs_stmt, GSI_CONTINUE_LINKING);
+ update_stmt(asm_movabs_stmt);
+}
+
+/*
-+ * find all asm() stmts that clobber r10 and add a reload of r10
++ * find all asm() stmts that clobber r12 and add a reload of r12
+ */
+static unsigned int execute_kernexec_reload(void)
+{
@@ -101718,7 +102486,7 @@ index 0000000..698da67
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
-+ // gimple match: __asm__ ("" : : : "r10");
++ // gimple match: __asm__ ("" : : : "r12");
+ gimple asm_stmt;
+ size_t nclobbers;
+
@@ -101727,11 +102495,11 @@ index 0000000..698da67
+ if (gimple_code(asm_stmt) != GIMPLE_ASM)
+ continue;
+
-+ // ... clobbering r10
++ // ... clobbering r12
+ nclobbers = gimple_asm_nclobbers(asm_stmt);
+ while (nclobbers--) {
+ tree op = gimple_asm_clobber_op(asm_stmt, nclobbers);
-+ if (strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "r10"))
++ if (strcmp(TREE_STRING_POINTER(TREE_VALUE(op)), "r12"))
+ continue;
+ kernexec_reload_fptr_mask(&gsi);
+//print_gimple_stmt(stderr, asm_stmt, 0, TDF_LINENO);
@@ -101814,7 +102582,7 @@ index 0000000..698da67
+#endif
+ new_fptr = make_ssa_name(new_fptr, NULL);
+
-+ // build asm volatile("orq %%r10, %0\n\t" : "=r"(new_fptr) : "0"(old_fptr));
++ // build asm volatile("orq %%r12, %0\n\t" : "=r"(new_fptr) : "0"(old_fptr));
+ input = build_tree_list(NULL_TREE, build_string(1, "0"));
+ input = chainon(NULL_TREE, build_tree_list(input, old_fptr));
+ output = build_tree_list(NULL_TREE, build_string(2, "=r"));
@@ -101826,7 +102594,7 @@ index 0000000..698da67
+ vec_safe_push(inputs, input);
+ vec_safe_push(outputs, output);
+#endif
-+ asm_or_stmt = gimple_build_asm_vec("orq %%r10, %0\n\t", inputs, outputs, NULL, NULL);
++ asm_or_stmt = gimple_build_asm_vec("orq %%r12, %0\n\t", inputs, outputs, NULL, NULL);
+ SSA_NAME_DEF_STMT(new_fptr) = asm_or_stmt;
+ gimple_asm_set_volatile(asm_or_stmt, true);
+ gsi_insert_before(gsi, asm_or_stmt, GSI_SAME_STMT);
@@ -101906,19 +102674,19 @@ index 0000000..698da67
+ emit_insn_before(btsq, insn);
+}
+
-+// add special KERNEXEC instrumentation: orq %r10,(%rsp) just before retn
++// add special KERNEXEC instrumentation: orq %r12,(%rsp) just before retn
+static void kernexec_instrument_retaddr_or(rtx insn)
+{
+ rtx orq;
+ rtvec argvec, constraintvec, labelvec;
+ int line;
+
-+ // create asm volatile("orq %%r10,(%%rsp)":::)
++ // create asm volatile("orq %%r12,(%%rsp)":::)
+ argvec = rtvec_alloc(0);
+ constraintvec = rtvec_alloc(0);
+ labelvec = rtvec_alloc(0);
+ line = expand_location(RTL_LOCATION(insn)).line;
-+ orq = gen_rtx_ASM_OPERANDS(VOIDmode, "orq %%r10,(%%rsp)", empty_string, 0, argvec, constraintvec, labelvec, line);
++ orq = gen_rtx_ASM_OPERANDS(VOIDmode, "orq %%r12,(%%rsp)", empty_string, 0, argvec, constraintvec, labelvec, line);
+ MEM_VOLATILE_P(orq) = 1;
+// RTX_FRAME_RELATED_P(orq) = 1; // not for ASM_OPERANDS
+ emit_insn_before(orq, insn);
@@ -101931,6 +102699,9 @@ index 0000000..698da67
+{
+ rtx insn;
+
++// if (stack_realign_drap)
++// inform(DECL_SOURCE_LOCATION(current_function_decl), "drap detected in %s\n", IDENTIFIER_POINTER(DECL_NAME(current_function_decl)));
++
+ // 1. find function returns
+ for (insn = get_insns(); insn; insn = NEXT_INSN(insn)) {
+ // rtl match: (jump_insn 41 40 42 2 (return) fptr.c:42 634 {return_internal} (nil))
@@ -102002,7 +102773,7 @@ index 0000000..698da67
+ } else if (!strcmp(argv[i].value, "or")) {
+ kernexec_instrument_fptr = kernexec_instrument_fptr_or;
+ kernexec_instrument_retaddr = kernexec_instrument_retaddr_or;
-+ fix_register("r10", 1, 1);
++ fix_register("r12", 1, 1);
+ } else
+ error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value);
+ continue;
@@ -102362,10 +103133,10 @@ index 0000000..679b9ef
+}
diff --git a/tools/gcc/size_overflow_hash.data b/tools/gcc/size_overflow_hash.data
new file mode 100644
-index 0000000..3a5b4b5
+index 0000000..7dad2cd
--- /dev/null
+++ b/tools/gcc/size_overflow_hash.data
-@@ -0,0 +1,7687 @@
+@@ -0,0 +1,7690 @@
+intel_fake_agp_alloc_by_type_1 intel_fake_agp_alloc_by_type 1 1 NULL
+ocfs2_get_refcount_tree_3 ocfs2_get_refcount_tree 0 3 NULL
+batadv_orig_node_del_if_4 batadv_orig_node_del_if 2 4 NULL
@@ -102380,8 +103151,8 @@ index 0000000..3a5b4b5
+snd_korg1212_copy_to_92 snd_korg1212_copy_to 6 92 NULL
+load_msg_95 load_msg 2 95 NULL
+device_flush_iotlb_115 device_flush_iotlb 2-3 115 NULL
-+ipath_verbs_send_117 ipath_verbs_send 5-3 117 NULL nohasharray
-+write_all_supers_117 write_all_supers 0 117 &ipath_verbs_send_117
++write_all_supers_117 write_all_supers 0 117 NULL nohasharray
++ipath_verbs_send_117 ipath_verbs_send 5-3 117 &write_all_supers_117
+init_q_132 init_q 4 132 NULL
+ocfs2_local_alloc_slide_window_134 ocfs2_local_alloc_slide_window 0 134 NULL
+memstick_alloc_host_142 memstick_alloc_host 1 142 NULL
@@ -103375,8 +104146,8 @@ index 0000000..3a5b4b5
+usb_allocate_stream_buffers_8964 usb_allocate_stream_buffers 3 8964 NULL
+qib_qsfp_dump_8966 qib_qsfp_dump 0-3 8966 NULL
+venus_mkdir_8967 venus_mkdir 4 8967 NULL
-+seq_open_net_8968 seq_open_net 4 8968 NULL nohasharray
-+vol_cdev_read_8968 vol_cdev_read 3 8968 &seq_open_net_8968
++vol_cdev_read_8968 vol_cdev_read 3 8968 NULL nohasharray
++seq_open_net_8968 seq_open_net 4 8968 &vol_cdev_read_8968
+bio_integrity_get_tag_8974 bio_integrity_get_tag 3 8974 NULL
+btrfs_alloc_free_block_8986 btrfs_alloc_free_block 3-8 8986 NULL
+jbd2_journal_blocks_per_page_9004 jbd2_journal_blocks_per_page 0 9004 NULL
@@ -103789,8 +104560,8 @@ index 0000000..3a5b4b5
+shash_compat_setkey_12267 shash_compat_setkey 3 12267 NULL
+add_sctp_bind_addr_12269 add_sctp_bind_addr 3 12269 NULL
+note_last_dentry_12285 note_last_dentry 3 12285 NULL
-+il_dbgfs_nvm_read_12288 il_dbgfs_nvm_read 3 12288 NULL nohasharray
-+roundup_to_multiple_of_64_12288 roundup_to_multiple_of_64 0-1 12288 &il_dbgfs_nvm_read_12288
++roundup_to_multiple_of_64_12288 roundup_to_multiple_of_64 0-1 12288 NULL nohasharray
++il_dbgfs_nvm_read_12288 il_dbgfs_nvm_read 3 12288 &roundup_to_multiple_of_64_12288
+wrap_min_12303 wrap_min 0-1-2 12303 NULL
+bt_sock_recvmsg_12316 bt_sock_recvmsg 4 12316 NULL
+pcbit_writecmd_12332 pcbit_writecmd 2 12332 NULL
@@ -104049,8 +104820,8 @@ index 0000000..3a5b4b5
+efx_mdio_check_mmds_14486 efx_mdio_check_mmds 2 14486 NULL nohasharray
+ieee80211_if_read_dot11MeshGateAnnouncementProtocol_14486 ieee80211_if_read_dot11MeshGateAnnouncementProtocol 3 14486 &efx_mdio_check_mmds_14486
+ocfs2_debug_read_14507 ocfs2_debug_read 3 14507 NULL
-+ep0_write_14536 ep0_write 3 14536 NULL nohasharray
-+dataflash_read_user_otp_14536 dataflash_read_user_otp 3-2 14536 &ep0_write_14536
++dataflash_read_user_otp_14536 dataflash_read_user_otp 3-2 14536 NULL nohasharray
++ep0_write_14536 ep0_write 3 14536 &dataflash_read_user_otp_14536
+register_trace_sched_switch_14545 register_trace_sched_switch 0 14545 NULL
+picolcd_debug_eeprom_read_14549 picolcd_debug_eeprom_read 3 14549 NULL
+drm_vmalloc_dma_14550 drm_vmalloc_dma 1 14550 NULL
@@ -104086,8 +104857,8 @@ index 0000000..3a5b4b5
+keys_proc_write_14792 keys_proc_write 3 14792 NULL
+ext4_kvmalloc_14796 ext4_kvmalloc 1 14796 NULL
+__kfifo_in_14797 __kfifo_in 3-0 14797 NULL
-+hpet_readl_14801 hpet_readl 0 14801 NULL nohasharray
-+snd_als300_gcr_read_14801 snd_als300_gcr_read 0 14801 &hpet_readl_14801
++snd_als300_gcr_read_14801 snd_als300_gcr_read 0 14801 NULL nohasharray
++hpet_readl_14801 hpet_readl 0 14801 &snd_als300_gcr_read_14801
+changed_cb_14819 changed_cb 0 14819 NULL
+do_tune_cpucache_14828 do_tune_cpucache 2 14828 NULL
+mrp_attr_create_14853 mrp_attr_create 3 14853 NULL
@@ -104778,8 +105549,8 @@ index 0000000..3a5b4b5
+cpulist_scnprintf_20648 cpulist_scnprintf 2-0 20648 NULL
+oz_add_farewell_20652 oz_add_farewell 5 20652 NULL
+oz_cdev_read_20659 oz_cdev_read 3 20659 NULL
-+snd_hdsp_playback_copy_20676 snd_hdsp_playback_copy 5 20676 NULL nohasharray
-+btrfs_qgroup_reserve_20676 btrfs_qgroup_reserve 0 20676 &snd_hdsp_playback_copy_20676
++btrfs_qgroup_reserve_20676 btrfs_qgroup_reserve 0 20676 NULL nohasharray
++snd_hdsp_playback_copy_20676 snd_hdsp_playback_copy 5 20676 &btrfs_qgroup_reserve_20676
+get_user_page_nowait_20682 get_user_page_nowait 3 20682 NULL nohasharray
+dvb_dmxdev_buffer_read_20682 dvb_dmxdev_buffer_read 0-4 20682 &get_user_page_nowait_20682
+cpumask_size_20683 cpumask_size 0 20683 NULL
@@ -105444,8 +106215,8 @@ index 0000000..3a5b4b5
+read_sb_page_26119 read_sb_page 5 26119 NULL
+__fswab64_26155 __fswab64 0 26155 NULL
+copy_oldmem_page_26164 copy_oldmem_page 3 26164 NULL
-+gfs2_xattr_acl_get_26166 gfs2_xattr_acl_get 0 26166 NULL nohasharray
-+ath6kl_roam_table_read_26166 ath6kl_roam_table_read 3 26166 &gfs2_xattr_acl_get_26166
++ath6kl_roam_table_read_26166 ath6kl_roam_table_read 3 26166 NULL nohasharray
++gfs2_xattr_acl_get_26166 gfs2_xattr_acl_get 0 26166 &ath6kl_roam_table_read_26166
+disk_devt_26180 disk_devt 0 26180 NULL
+cgroup_setxattr_26188 cgroup_setxattr 4 26188 NULL
+ieee80211_if_fmt_dot11MeshTTL_26198 ieee80211_if_fmt_dot11MeshTTL 3 26198 NULL
@@ -105771,8 +106542,8 @@ index 0000000..3a5b4b5
+xz_dec_init_29029 xz_dec_init 2 29029 NULL
+i915_gem_object_bind_to_vm_29035 i915_gem_object_bind_to_vm 0 29035 NULL
+ieee80211_if_read_ht_opmode_29044 ieee80211_if_read_ht_opmode 3 29044 NULL
-+ProcessGetHostMibs_29049 ProcessGetHostMibs 0 29049 NULL nohasharray
-+rxrpc_sendmsg_29049 rxrpc_sendmsg 4 29049 &ProcessGetHostMibs_29049
++rxrpc_sendmsg_29049 rxrpc_sendmsg 4 29049 NULL nohasharray
++ProcessGetHostMibs_29049 ProcessGetHostMibs 0 29049 &rxrpc_sendmsg_29049
+btrfs_root_bytenr_29058 btrfs_root_bytenr 0 29058 NULL
+iso_packets_buffer_init_29061 iso_packets_buffer_init 3-4 29061 NULL
+roundup_64_29066 roundup_64 2-0-1 29066 NULL
@@ -105875,7 +106646,8 @@ index 0000000..3a5b4b5
+lov_ost_pool_extend_29914 lov_ost_pool_extend 2 29914 NULL
+write_file_queue_29922 write_file_queue 3 29922 NULL
+ext4_xattr_set_acl_29930 ext4_xattr_set_acl 4 29930 NULL
-+__btrfs_getxattr_29947 __btrfs_getxattr 0 29947 NULL
++__btrfs_getxattr_29947 __btrfs_getxattr 0 29947 NULL nohasharray
++ipv6_recv_error_29947 ipv6_recv_error 3 29947 &__btrfs_getxattr_29947
+diva_os_get_context_size_29983 diva_os_get_context_size 0 29983 NULL
+arch_setup_dmar_msi_29992 arch_setup_dmar_msi 1 29992 NULL
+vmci_host_setup_notify_30002 vmci_host_setup_notify 2 30002 NULL
@@ -106382,8 +107154,8 @@ index 0000000..3a5b4b5
+av7110_vbi_write_34384 av7110_vbi_write 3 34384 NULL
+usbvision_v4l2_read_34386 usbvision_v4l2_read 3 34386 NULL
+read_rbu_image_type_34387 read_rbu_image_type 6 34387 NULL
-+iwl_calib_set_34400 iwl_calib_set 3 34400 NULL nohasharray
-+ivtv_read_pos_34400 ivtv_read_pos 3 34400 &iwl_calib_set_34400
++ivtv_read_pos_34400 ivtv_read_pos 3 34400 NULL nohasharray
++iwl_calib_set_34400 iwl_calib_set 3 34400 &ivtv_read_pos_34400
+wd_exp_mode_write_34407 wd_exp_mode_write 3 34407 NULL
+nl80211_send_disassoc_34424 nl80211_send_disassoc 4 34424 NULL
+security_socket_create_34439 security_socket_create 0 34439 NULL
@@ -106393,13 +107165,13 @@ index 0000000..3a5b4b5
+i2o_parm_field_get_34477 i2o_parm_field_get 5 34477 NULL
+ocfs2_block_group_clear_bits_34484 ocfs2_block_group_clear_bits 0 34484 NULL
+security_inode_permission_34488 security_inode_permission 0 34488 NULL
-+SyS_pwritev_34494 SyS_pwritev 3 34494 NULL nohasharray
-+__ffs64_34494 __ffs64 1-0 34494 &SyS_pwritev_34494
++__ffs64_34494 __ffs64 1-0 34494 NULL nohasharray
++SyS_pwritev_34494 SyS_pwritev 3 34494 &__ffs64_34494
+qp_alloc_res_34496 qp_alloc_res 5 34496 NULL
+lu_buf_check_and_alloc_34505 lu_buf_check_and_alloc 2 34505 NULL
+snd_pcm_hw_param_value_34525 snd_pcm_hw_param_value 0 34525 NULL
-+ext4_fallocate_34537 ext4_fallocate 4-3 34537 NULL nohasharray
-+tracing_stats_read_34537 tracing_stats_read 3 34537 &ext4_fallocate_34537
++tracing_stats_read_34537 tracing_stats_read 3 34537 NULL nohasharray
++ext4_fallocate_34537 ext4_fallocate 4-3 34537 &tracing_stats_read_34537
+hugetlbfs_read_actor_34547 hugetlbfs_read_actor 4-5-2-0 34547 NULL
+dbBackSplit_34561 dbBackSplit 0 34561 NULL
+alloc_ieee80211_rsl_34564 alloc_ieee80211_rsl 1 34564 NULL nohasharray
@@ -106412,8 +107184,8 @@ index 0000000..3a5b4b5
+cw1200_queue_init_34599 cw1200_queue_init 4 34599 &ceph_msgpool_init_34599
+__add_prelim_ref_34600 __add_prelim_ref 0 34600 NULL
+brcmf_cfg80211_mgmt_tx_34608 brcmf_cfg80211_mgmt_tx 7 34608 NULL
-+__jffs2_ref_totlen_34609 __jffs2_ref_totlen 0 34609 NULL nohasharray
-+mtd_write_34609 mtd_write 0 34609 &__jffs2_ref_totlen_34609
++mtd_write_34609 mtd_write 0 34609 NULL nohasharray
++__jffs2_ref_totlen_34609 __jffs2_ref_totlen 0 34609 &mtd_write_34609
+apei_get_nvs_resources_34616 apei_get_nvs_resources 0 34616 NULL
+__cfg80211_disconnected_34622 __cfg80211_disconnected 3 34622 NULL
+cnic_alloc_dma_34641 cnic_alloc_dma 3 34641 NULL
@@ -106876,11 +107648,11 @@ index 0000000..3a5b4b5
+snd_pcm_playback_rewind_38249 snd_pcm_playback_rewind 0-2 38249 NULL
+from_dblock_38256 from_dblock 0-1 38256 NULL
+vmci_qp_broker_set_page_store_38260 vmci_qp_broker_set_page_store 3-2 38260 NULL
-+SYSC_msgrcv_38268 SYSC_msgrcv 3 38268 NULL nohasharray
-+ieee80211_if_read_auto_open_plinks_38268 ieee80211_if_read_auto_open_plinks 3 38268 &SYSC_msgrcv_38268 nohasharray
-+mthca_alloc_icm_table_38268 mthca_alloc_icm_table 4-3 38268 &ieee80211_if_read_auto_open_plinks_38268
-+xfs_bmdr_to_bmbt_38275 xfs_bmdr_to_bmbt 5 38275 NULL nohasharray
-+xfs_bmbt_to_bmdr_38275 xfs_bmbt_to_bmdr 3 38275 &xfs_bmdr_to_bmbt_38275
++ieee80211_if_read_auto_open_plinks_38268 ieee80211_if_read_auto_open_plinks 3 38268 NULL nohasharray
++SYSC_msgrcv_38268 SYSC_msgrcv 3 38268 &ieee80211_if_read_auto_open_plinks_38268 nohasharray
++mthca_alloc_icm_table_38268 mthca_alloc_icm_table 4-3 38268 &SYSC_msgrcv_38268
++xfs_bmbt_to_bmdr_38275 xfs_bmbt_to_bmdr 3 38275 NULL nohasharray
++xfs_bmdr_to_bmbt_38275 xfs_bmdr_to_bmbt 5 38275 &xfs_bmbt_to_bmdr_38275
+ftdi_process_packet_38281 ftdi_process_packet 4 38281 NULL
+gpa_to_gfn_38291 gpa_to_gfn 0-1 38291 NULL
+ucma_query_path_38305 ucma_query_path 3 38305 NULL
@@ -106953,8 +107725,8 @@ index 0000000..3a5b4b5
+ext3_trim_all_free_38929 ext3_trim_all_free 4-3-2 38929 NULL
+il_dbgfs_sram_write_38942 il_dbgfs_sram_write 3 38942 NULL
+__ath6kl_wmi_send_mgmt_cmd_38971 __ath6kl_wmi_send_mgmt_cmd 7 38971 NULL
-+C_SYSC_preadv64_38977 C_SYSC_preadv64 3 38977 NULL nohasharray
-+usb_maxpacket_38977 usb_maxpacket 0 38977 &C_SYSC_preadv64_38977
++usb_maxpacket_38977 usb_maxpacket 0 38977 NULL nohasharray
++C_SYSC_preadv64_38977 C_SYSC_preadv64 3 38977 &usb_maxpacket_38977
+OSDSetBlock_38986 OSDSetBlock 2-4 38986 NULL
+lpfc_idiag_extacc_write_38998 lpfc_idiag_extacc_write 3 38998 NULL
+udf_new_block_38999 udf_new_block 4 38999 NULL
@@ -107019,8 +107791,8 @@ index 0000000..3a5b4b5
+ext_depth_39607 ext_depth 0 39607 NULL
+nfs_idmap_get_key_39616 nfs_idmap_get_key 2 39616 NULL
+sdio_readb_39618 sdio_readb 0 39618 NULL
-+set_dev_class_39645 set_dev_class 4 39645 NULL nohasharray
-+dm_exception_table_init_39645 dm_exception_table_init 2 39645 &set_dev_class_39645
++dm_exception_table_init_39645 dm_exception_table_init 2 39645 NULL nohasharray
++set_dev_class_39645 set_dev_class 4 39645 &dm_exception_table_init_39645
+snd_rme32_capture_copy_39653 snd_rme32_capture_copy 5 39653 NULL
+tcp_try_rmem_schedule_39657 tcp_try_rmem_schedule 3 39657 NULL
+kvm_read_guest_cached_39666 kvm_read_guest_cached 4 39666 NULL
@@ -107463,8 +108235,8 @@ index 0000000..3a5b4b5
+usb_alloc_urb_43436 usb_alloc_urb 1 43436 NULL
+ath6kl_wmi_roam_tbl_event_rx_43440 ath6kl_wmi_roam_tbl_event_rx 3 43440 NULL
+ocfs2_rotate_tree_left_43442 ocfs2_rotate_tree_left 0 43442 NULL
-+usemap_size_43443 usemap_size 0-2-1 43443 NULL nohasharray
-+usb_string_43443 usb_string 0 43443 &usemap_size_43443
++usb_string_43443 usb_string 0 43443 NULL nohasharray
++usemap_size_43443 usemap_size 0-2-1 43443 &usb_string_43443
+get_vm_area_size_43444 get_vm_area_size 0 43444 NULL
+nvme_trans_device_id_page_43466 nvme_trans_device_id_page 4 43466 NULL
+calculate_discard_block_size_43480 calculate_discard_block_size 0 43480 NULL nohasharray
@@ -107534,6 +108306,7 @@ index 0000000..3a5b4b5
+xlog_recover_add_to_cont_trans_44102 xlog_recover_add_to_cont_trans 4 44102 NULL
+skb_frag_dma_map_44112 skb_frag_dma_map 0 44112 NULL
+tracing_set_trace_read_44122 tracing_set_trace_read 3 44122 NULL
++hwif_to_node_44127 hwif_to_node 0 44127 NULL
+SyS_process_vm_writev_44129 SyS_process_vm_writev 3-5 44129 NULL
+vmw_gmr_bind_44130 vmw_gmr_bind 3 44130 NULL
+lookup_extent_data_ref_44136 lookup_extent_data_ref 0 44136 NULL
@@ -107579,7 +108352,6 @@ index 0000000..3a5b4b5
+osst_do_scsi_44410 osst_do_scsi 4 44410 NULL
+check_user_page_hwpoison_44412 check_user_page_hwpoison 1 44412 NULL
+ieee80211_if_read_rc_rateidx_mcs_mask_5ghz_44423 ieee80211_if_read_rc_rateidx_mcs_mask_5ghz 3 44423 NULL
-+prandom_u32_state_44445 prandom_u32_state 0 44445 NULL
+iwl_dbgfs_bf_params_write_44450 iwl_dbgfs_bf_params_write 3 44450 NULL
+write_file_debug_44476 write_file_debug 3 44476 NULL
+btrfs_chunk_item_size_44478 btrfs_chunk_item_size 0-1 44478 NULL
@@ -107743,6 +108515,7 @@ index 0000000..3a5b4b5
+ll_max_readahead_mb_seq_write_45815 ll_max_readahead_mb_seq_write 3 45815 NULL
+fm_v4l2_init_video_device_45821 fm_v4l2_init_video_device 2 45821 NULL
+memcg_update_cache_size_45828 memcg_update_cache_size 2 45828 NULL
++ipv6_recv_rxpmtu_45830 ipv6_recv_rxpmtu 3 45830 NULL
+task_state_char_45839 task_state_char 1 45839 NULL
+__ip_select_ident_45851 __ip_select_ident 3 45851 NULL
+x509_process_extension_45854 x509_process_extension 5 45854 NULL
@@ -107771,8 +108544,8 @@ index 0000000..3a5b4b5
+dma_tx_errors_read_46060 dma_tx_errors_read 3 46060 &__ocfs2_move_extent_46060
+sel_commit_bools_write_46077 sel_commit_bools_write 3 46077 NULL
+arizona_set_irq_wake_46101 arizona_set_irq_wake 2 46101 NULL
-+memcg_update_array_size_46111 memcg_update_array_size 1 46111 NULL nohasharray
-+il3945_ucode_general_stats_read_46111 il3945_ucode_general_stats_read 3 46111 &memcg_update_array_size_46111
++il3945_ucode_general_stats_read_46111 il3945_ucode_general_stats_read 3 46111 NULL nohasharray
++memcg_update_array_size_46111 memcg_update_array_size 1 46111 &il3945_ucode_general_stats_read_46111
+C_SYSC_writev_46113 C_SYSC_writev 3 46113 NULL
+mlx4_ib_alloc_fast_reg_page_list_46119 mlx4_ib_alloc_fast_reg_page_list 2 46119 NULL
+paging32_walk_addr_nested_46121 paging32_walk_addr_nested 3 46121 NULL
@@ -107792,8 +108565,8 @@ index 0000000..3a5b4b5
+mpi_read_raw_data_46248 mpi_read_raw_data 2 46248 NULL
+ReadReg_46277 ReadReg 0 46277 NULL
+sg_proc_write_dressz_46316 sg_proc_write_dressz 3 46316 NULL
-+__hwahc_dev_set_key_46328 __hwahc_dev_set_key 5 46328 NULL nohasharray
-+compat_SyS_readv_46328 compat_SyS_readv 3 46328 &__hwahc_dev_set_key_46328
++compat_SyS_readv_46328 compat_SyS_readv 3 46328 NULL nohasharray
++__hwahc_dev_set_key_46328 __hwahc_dev_set_key 5 46328 &compat_SyS_readv_46328
+iwl_dbgfs_chain_noise_read_46355 iwl_dbgfs_chain_noise_read 3 46355 NULL
+smk_write_direct_46363 smk_write_direct 3 46363 NULL
+__iommu_calculate_agaw_46366 __iommu_calculate_agaw 2 46366 NULL
@@ -108011,8 +108784,8 @@ index 0000000..3a5b4b5
+set_discoverable_48141 set_discoverable 4 48141 NULL
+dn_fib_count_nhs_48145 dn_fib_count_nhs 0 48145 NULL
+get_cur_inode_state_48149 get_cur_inode_state 0 48149 NULL
-+_add_to_r4w_48152 _add_to_r4w 4 48152 NULL nohasharray
-+bitmap_onto_48152 bitmap_onto 4 48152 &_add_to_r4w_48152
++bitmap_onto_48152 bitmap_onto 4 48152 NULL nohasharray
++_add_to_r4w_48152 _add_to_r4w 4 48152 &bitmap_onto_48152
+isr_dma1_done_read_48159 isr_dma1_done_read 3 48159 NULL
+c4iw_id_table_alloc_48163 c4iw_id_table_alloc 3 48163 NULL
+ocfs2_find_next_zero_bit_unaligned_48170 ocfs2_find_next_zero_bit_unaligned 2-3 48170 NULL nohasharray
@@ -108093,8 +108866,8 @@ index 0000000..3a5b4b5
+vc_do_resize_48842 vc_do_resize 4-3 48842 NULL
+comedi_buf_write_alloc_48846 comedi_buf_write_alloc 0-2 48846 NULL
+suspend_dtim_interval_write_48854 suspend_dtim_interval_write 3 48854 NULL
-+C_SYSC_pwritev64_48864 C_SYSC_pwritev64 3 48864 NULL nohasharray
-+viafb_dvp1_proc_write_48864 viafb_dvp1_proc_write 3 48864 &C_SYSC_pwritev64_48864
++viafb_dvp1_proc_write_48864 viafb_dvp1_proc_write 3 48864 NULL nohasharray
++C_SYSC_pwritev64_48864 C_SYSC_pwritev64 3 48864 &viafb_dvp1_proc_write_48864
+__ffs_ep0_read_events_48868 __ffs_ep0_read_events 3 48868 NULL
+ext2_alloc_branch_48889 ext2_alloc_branch 4 48889 NULL
+crypto_cipher_ctxsize_48890 crypto_cipher_ctxsize 0 48890 NULL
@@ -108349,8 +109122,8 @@ index 0000000..3a5b4b5
+dpcm_show_state_50827 dpcm_show_state 0 50827 NULL
+acpi_ev_install_gpe_block_50829 acpi_ev_install_gpe_block 2 50829 NULL
+SetArea_50835 SetArea 4 50835 NULL nohasharray
-+create_mem_extents_50835 create_mem_extents 0 50835 &SetArea_50835 nohasharray
-+mask_from_50835 mask_from 0-1-2 50835 &create_mem_extents_50835
++mask_from_50835 mask_from 0-1-2 50835 &SetArea_50835 nohasharray
++create_mem_extents_50835 create_mem_extents 0 50835 &mask_from_50835
+videobuf_dma_init_user_50839 videobuf_dma_init_user 3-4 50839 NULL
+btrfs_search_slot_for_read_50843 btrfs_search_slot_for_read 0 50843 NULL
+self_check_write_50856 self_check_write 0-5 50856 NULL
@@ -108441,8 +109214,8 @@ index 0000000..3a5b4b5
+load_pdptrs_51541 load_pdptrs 3 51541 NULL
+__alloc_eip_netdev_51549 __alloc_eip_netdev 1 51549 NULL
+ixgb_get_eeprom_len_51586 ixgb_get_eeprom_len 0 51586 NULL
-+get_cur_path_51589 get_cur_path 0 51589 NULL nohasharray
-+snd_interval_refine_first_51589 snd_interval_refine_first 0 51589 &get_cur_path_51589
++snd_interval_refine_first_51589 snd_interval_refine_first 0 51589 NULL nohasharray
++get_cur_path_51589 get_cur_path 0 51589 &snd_interval_refine_first_51589
+aac_convert_sgraw2_51598 aac_convert_sgraw2 4 51598 NULL
+table_size_to_number_of_entries_51613 table_size_to_number_of_entries 0-1 51613 NULL
+extent_fiemap_51621 extent_fiemap 3 51621 NULL
@@ -108478,8 +109251,8 @@ index 0000000..3a5b4b5
+get_indirect_ea_51869 get_indirect_ea 4 51869 NULL
+user_read_51881 user_read 3 51881 NULL
+dbAdjCtl_51888 dbAdjCtl 0 51888 NULL
-+SyS_mq_timedsend_51896 SyS_mq_timedsend 3 51896 NULL nohasharray
-+virt_to_phys_51896 virt_to_phys 0 51896 &SyS_mq_timedsend_51896
++virt_to_phys_51896 virt_to_phys 0 51896 NULL nohasharray
++SyS_mq_timedsend_51896 SyS_mq_timedsend 3 51896 &virt_to_phys_51896
+commit_fs_roots_51898 commit_fs_roots 0 51898 NULL
+wmi_set_ie_51919 wmi_set_ie 3 51919 NULL
+dbg_status_buf_51930 dbg_status_buf 2 51930 NULL
@@ -108689,8 +109462,8 @@ index 0000000..3a5b4b5
+nr_sendmsg_53656 nr_sendmsg 4 53656 NULL
+fuse_fill_write_pages_53682 fuse_fill_write_pages 0-4 53682 NULL
+v4l2_event_subscribe_53687 v4l2_event_subscribe 3 53687 NULL
-+bdev_logical_block_size_53690 bdev_logical_block_size 0 53690 NULL nohasharray
-+igb_alloc_q_vector_53690 igb_alloc_q_vector 6-4 53690 &bdev_logical_block_size_53690
++igb_alloc_q_vector_53690 igb_alloc_q_vector 6-4 53690 NULL nohasharray
++bdev_logical_block_size_53690 bdev_logical_block_size 0 53690 &igb_alloc_q_vector_53690
+find_overflow_devnum_53711 find_overflow_devnum 0 53711 NULL
+bio_integrity_split_53714 bio_integrity_split 3 53714 NULL
+__ocfs2_resv_find_window_53721 __ocfs2_resv_find_window 3 53721 NULL
@@ -108891,8 +109664,8 @@ index 0000000..3a5b4b5
+lov_get_stripecnt_55297 lov_get_stripecnt 0-3 55297 NULL
+gsm_control_modem_55303 gsm_control_modem 3 55303 NULL
+wimax_msg_len_55304 wimax_msg_len 0 55304 NULL
-+__get_vm_area_node_55305 __get_vm_area_node 6 55305 NULL nohasharray
-+qp_alloc_guest_work_55305 qp_alloc_guest_work 5-3 55305 &__get_vm_area_node_55305
++qp_alloc_guest_work_55305 qp_alloc_guest_work 5-3 55305 NULL nohasharray
++__get_vm_area_node_55305 __get_vm_area_node 6 55305 &qp_alloc_guest_work_55305
+__vxge_hw_vpath_initialize_55328 __vxge_hw_vpath_initialize 2 55328 NULL
+do_shmat_55336 do_shmat 5 55336 NULL
+vme_user_read_55338 vme_user_read 3 55338 NULL
@@ -109075,8 +109848,8 @@ index 0000000..3a5b4b5
+__bitmap_clear_bits_56912 __bitmap_clear_bits 3 56912 NULL
+strcspn_56913 strcspn 0 56913 NULL
+__kfifo_out_56927 __kfifo_out 0-3 56927 NULL
-+CopyBufferToControlPacket_56933 CopyBufferToControlPacket 0 56933 NULL nohasharray
-+journal_init_revoke_56933 journal_init_revoke 2 56933 &CopyBufferToControlPacket_56933
++journal_init_revoke_56933 journal_init_revoke 2 56933 NULL nohasharray
++CopyBufferToControlPacket_56933 CopyBufferToControlPacket 0 56933 &journal_init_revoke_56933
+nouveau_xtensa_create__56952 nouveau_xtensa_create_ 8 56952 NULL
+diva_get_driver_info_56967 diva_get_driver_info 0 56967 NULL
+nouveau_device_create__56984 nouveau_device_create_ 6 56984 NULL
@@ -109192,8 +109965,8 @@ index 0000000..3a5b4b5
+kiblnd_create_tx_pool_57846 kiblnd_create_tx_pool 2 57846 NULL
+process_all_new_xattrs_57881 process_all_new_xattrs 0 57881 NULL
+xt_alloc_table_info_57903 xt_alloc_table_info 1 57903 NULL
-+iio_read_first_n_kfifo_57910 iio_read_first_n_kfifo 2 57910 NULL nohasharray
-+atomic_add_return_unchecked_57910 atomic_add_return_unchecked 0-1 57910 &iio_read_first_n_kfifo_57910
++atomic_add_return_unchecked_57910 atomic_add_return_unchecked 0-1 57910 NULL nohasharray
++iio_read_first_n_kfifo_57910 iio_read_first_n_kfifo 2 57910 &atomic_add_return_unchecked_57910
+memcg_caches_array_size_57918 memcg_caches_array_size 0-1 57918 NULL
+twl_i2c_write_57923 twl_i2c_write 3-4 57923 NULL
+__snd_gf1_look16_57925 __snd_gf1_look16 0 57925 NULL
@@ -109432,8 +110205,8 @@ index 0000000..3a5b4b5
+xlog_bread_offset_60030 xlog_bread_offset 3 60030 NULL
+bio_integrity_hw_sectors_60039 bio_integrity_hw_sectors 0-2 60039 NULL
+do_ip6t_set_ctl_60040 do_ip6t_set_ctl 4 60040 NULL
-+vcs_size_60050 vcs_size 0 60050 NULL nohasharray
-+pin_2_irq_60050 pin_2_irq 0-3 60050 &vcs_size_60050
++pin_2_irq_60050 pin_2_irq 0-3 60050 NULL nohasharray
++vcs_size_60050 vcs_size 0 60050 &pin_2_irq_60050
+gru_alloc_gts_60056 gru_alloc_gts 3-2 60056 NULL
+open_cur_inode_file_60057 open_cur_inode_file 0 60057 NULL
+compat_writev_60063 compat_writev 3 60063 NULL
@@ -109662,6 +110435,7 @@ index 0000000..3a5b4b5
+ipath_user_sdma_pin_pages_62100 ipath_user_sdma_pin_pages 3-5-4 62100 NULL
+jffs2_security_setxattr_62107 jffs2_security_setxattr 4 62107 NULL
+btrfs_direct_IO_62114 btrfs_direct_IO 4 62114 NULL
++ip_recv_error_62117 ip_recv_error 3 62117 NULL
+generic_block_fiemap_62122 generic_block_fiemap 4 62122 NULL
+llc_ui_header_len_62131 llc_ui_header_len 0 62131 NULL
+qib_diag_write_62133 qib_diag_write 3 62133 NULL nohasharray
@@ -110055,10 +110829,10 @@ index 0000000..3a5b4b5
+nvme_trans_standard_inquiry_page_65526 nvme_trans_standard_inquiry_page 4 65526 NULL
diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c
new file mode 100644
-index 0000000..a3f9702
+index 0000000..c1967f6
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin.c
-@@ -0,0 +1,3870 @@
+@@ -0,0 +1,3922 @@
+/*
+ * Copyright 2011, 2012, 2013 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
@@ -110119,6 +110893,10 @@ index 0000000..a3f9702
+#define MIN_CHECK true
+#define MAX_CHECK false
+
++#define TURN_OFF_ASM_STR "# size_overflow MARK_TURN_OFF\n\t"
++#define YES_ASM_STR "# size_overflow MARK_YES\n\t"
++#define OK_ASM_STR "# size_overflow\n\t"
++
+#if BUILDING_GCC_VERSION == 4005
+#define DECL_CHAIN(NODE) (TREE_CHAIN(DECL_MINIMAL_CHECK(NODE)))
+#endif
@@ -110184,7 +110962,7 @@ index 0000000..a3f9702
+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3);
+
+static struct plugin_info size_overflow_plugin_info = {
-+ .version = "20131203beta",
++ .version = "20131211beta",
+ .help = "no-size-overflow\tturn off size overflow checking\n",
+};
+
@@ -111670,7 +112448,7 @@ index 0000000..a3f9702
+ break;
+ case DImode:
+ if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode))
-+ new_type = intDI_type_node;
++ new_type = TYPE_UNSIGNED(type) ? unsigned_intDI_type_node : intDI_type_node;
+ else
+ new_type = intTI_type_node;
+ break;
@@ -112252,36 +113030,43 @@ index 0000000..a3f9702
+ return false;
+}
+
++static const char *get_asm_string(const_gimple stmt)
++{
++ if (!stmt)
++ return NULL;
++ if (gimple_code(stmt) != GIMPLE_ASM)
++ return NULL;
++
++ return gimple_asm_string(stmt);
++}
++
+static bool is_size_overflow_intentional_asm_turn_off(const_gimple stmt)
+{
+ const char *str;
+
-+ if (!stmt)
++ str = get_asm_string(stmt);
++ if (!str)
+ return false;
-+
-+ str = gimple_asm_string(stmt);
-+ return !strcmp(str, "# size_overflow MARK_TURN_OFF\n\t");
++ return !strcmp(str, TURN_OFF_ASM_STR);
+}
+
+static bool is_size_overflow_intentional_asm_yes(const_gimple stmt)
+{
+ const char *str;
+
-+ if (!stmt)
++ str = get_asm_string(stmt);
++ if (!str)
+ return false;
-+
-+ str = gimple_asm_string(stmt);
-+ return !strcmp(str, "# size_overflow MARK_YES\n\t");
++ return !strcmp(str, YES_ASM_STR);
+}
+
+static bool is_size_overflow_asm(const_gimple stmt)
+{
+ const char *str;
+
-+ if (!stmt)
++ str = get_asm_string(stmt);
++ if (!str)
+ return false;
-+
-+ str = gimple_asm_string(stmt);
+ return !strncmp(str, "# size_overflow", 15);
+}
+
@@ -112370,8 +113155,6 @@ index 0000000..a3f9702
+ */
+static bool is_intentional_attribute_from_gimple(struct interesting_node *cur_node)
+{
-+ const_tree input, output;
-+
+ if (!cur_node->intentional_mark_from_gimple)
+ return false;
+
@@ -112383,10 +113166,6 @@ index 0000000..a3f9702
+ // skip param decls
+ if (gimple_asm_noutputs(cur_node->intentional_mark_from_gimple) == 0)
+ return true;
-+ input = gimple_asm_input_op(cur_node->intentional_mark_from_gimple, 0);
-+ output = gimple_asm_output_op(cur_node->intentional_mark_from_gimple, 0);
-+
-+ replace_size_overflow_asm_with_assign(cur_node->intentional_mark_from_gimple, TREE_VALUE(output), TREE_VALUE(input));
+ return true;
+}
+
@@ -112399,6 +113178,9 @@ index 0000000..a3f9702
+{
+ const_tree fndecl;
+
++ if (is_intentional_attribute_from_gimple(cur_node))
++ return;
++
+ if (is_turn_off_intentional_attr(DECL_ORIGIN(current_function_decl))) {
+ cur_node->intentional_attr_cur_fndecl = MARK_TURN_OFF;
+ return;
@@ -112423,9 +113205,6 @@ index 0000000..a3f9702
+ else if (is_yes_intentional_attr(fndecl, cur_node->num))
+ cur_node->intentional_attr_decl = MARK_YES;
+
-+ if (is_intentional_attribute_from_gimple(cur_node))
-+ return;
-+
+ cur_node->intentional_attr_cur_fndecl = search_last_nodes_intentional(cur_node);
+ print_missing_intentional(cur_node->intentional_attr_decl, cur_node->intentional_attr_cur_fndecl, cur_node->fndecl, cur_node->num);
+}
@@ -112511,13 +113290,8 @@ index 0000000..a3f9702
+// a size_overflow asm stmt in the control flow doesn't stop the recursion
+static void handle_asm_stmt(struct pointer_set_t *visited, struct interesting_node *cur_node, tree lhs, const_gimple stmt)
+{
-+ const_tree asm_lhs;
-+
+ if (!is_size_overflow_asm(stmt))
-+ return walk_use_def(visited, cur_node, SSA_NAME_VAR(lhs));
-+
-+ asm_lhs = gimple_asm_input_op(stmt, 0);
-+ walk_use_def(visited, cur_node, TREE_VALUE(asm_lhs));
++ walk_use_def(visited, cur_node, SSA_NAME_VAR(lhs));
+}
+
+/* collect the parm_decls and fndecls (for checking a missing size_overflow attribute (ret or arg) or intentional_overflow)
@@ -112578,39 +113352,58 @@ index 0000000..a3f9702
+ pointer_set_destroy(visited);
+}
+
-+/* This function calls the main recursion function (expand) that duplicates the stmts. Before that it checks the intentional_overflow attribute and asm stmts,
-+ * it decides whether the duplication is necessary or not and it searches for missing size_overflow attributes. After expand() it changes the orig node to the duplicated node
-+ * in the original stmt (first stmt) and it inserts the overflow check for the arg of the callee or for the return value.
-+ * If there is a mark_turn_off intentional attribute on the caller or the callee then there is no duplication and missing size_overflow attribute check anywhere.
++enum precond {
++ NO_ATTRIBUTE_SEARCH, NO_CHECK_INSERT, NONE
++};
++
++/* If there is a mark_turn_off intentional attribute on the caller or the callee then there is no duplication and missing size_overflow attribute check anywhere.
+ * There is only missing size_overflow attribute checking if the intentional_overflow attribute is the mark_no type.
+ * Stmt duplication is unnecessary if there are no binary/ternary assignements or if the unary assignment isn't a cast.
+ * It skips the possible error codes too. If the def_stmts trace back to a constant and there are no binary/ternary assigments then we assume that it is some kind of error code.
+ */
-+static struct next_cgraph_node *handle_interesting_stmt(struct next_cgraph_node *cnodes, struct interesting_node *cur_node, struct cgraph_node *caller_node)
++static enum precond check_preconditions(struct interesting_node *cur_node)
+{
-+ struct pointer_set_t *visited;
+ bool interesting_conditions[3] = {false, false, false};
-+ tree new_node, orig_node = cur_node->node;
+
+ set_last_nodes(cur_node);
+
+ check_intentional_attribute_ipa(cur_node);
+ if (cur_node->intentional_attr_decl == MARK_TURN_OFF || cur_node->intentional_attr_cur_fndecl == MARK_TURN_OFF)
-+ return cnodes;
++ return NO_ATTRIBUTE_SEARCH;
+
+ search_interesting_conditions(cur_node, interesting_conditions);
+
+ // error code
+ if (interesting_conditions[CAST] && interesting_conditions[FROM_CONST] && !interesting_conditions[NOT_UNARY])
-+ return cnodes;
++ return NO_ATTRIBUTE_SEARCH;
+
-+ cnodes = search_overflow_attribute(cnodes, cur_node);
++ // unnecessary overflow check
++ if (!interesting_conditions[CAST] && !interesting_conditions[NOT_UNARY])
++ return NO_CHECK_INSERT;
+
+ if (cur_node->intentional_attr_cur_fndecl != MARK_NO)
++ return NO_CHECK_INSERT;
++
++ return NONE;
++}
++
++/* This function calls the main recursion function (expand) that duplicates the stmts. Before that it checks the intentional_overflow attribute and asm stmts,
++ * it decides whether the duplication is necessary or not and it searches for missing size_overflow attributes. After expand() it changes the orig node to the duplicated node
++ * in the original stmt (first stmt) and it inserts the overflow check for the arg of the callee or for the return value.
++ */
++static struct next_cgraph_node *handle_interesting_stmt(struct next_cgraph_node *cnodes, struct interesting_node *cur_node, struct cgraph_node *caller_node)
++{
++ enum precond ret;
++ struct pointer_set_t *visited;
++ tree new_node, orig_node = cur_node->node;
++
++ ret = check_preconditions(cur_node);
++ if (ret == NO_ATTRIBUTE_SEARCH)
+ return cnodes;
+
-+ // unnecessary overflow check
-+ if (!interesting_conditions[CAST] && !interesting_conditions[NOT_UNARY])
++ cnodes = search_overflow_attribute(cnodes, cur_node);
++
++ if (ret == NO_CHECK_INSERT)
+ return cnodes;
+
+ visited = pointer_set_create();
@@ -112822,9 +113615,6 @@ index 0000000..a3f9702
+ imm_use_iterator imm_iter;
+ unsigned int argnum;
+
-+ if (is_size_overflow_intentional_asm_turn_off(intentional_asm))
-+ return head;
-+
+ gcc_assert(TREE_CODE(node) == SSA_NAME);
+
+ if (pointer_set_insert(visited, node))
@@ -112879,8 +113669,6 @@ index 0000000..a3f9702
+ gimple_stmt_iterator gsi;
+ tree input, output;
+
-+ if (gimple_code(stmt) != GIMPLE_ASM)
-+ return;
+ if (!is_size_overflow_asm(stmt))
+ return;
+
@@ -112913,13 +113701,19 @@ index 0000000..a3f9702
+
+ gcc_assert(gimple_asm_ninputs(stmt) == 1);
+
++ if (gimple_asm_noutputs(stmt) == 0 && is_size_overflow_intentional_asm_turn_off(stmt))
++ return head;
++
+ if (gimple_asm_noutputs(stmt) == 0) {
-+ const_tree input = gimple_asm_input_op(stmt, 0);
++ const_tree input;
++
++ if (!is_size_overflow_intentional_asm_turn_off(stmt))
++ return head;
+
++ input = gimple_asm_input_op(stmt, 0);
+ remove_size_overflow_asm(stmt);
+ if (is_gimple_constant(TREE_VALUE(input)))
+ return head;
-+
+ visited = pointer_set_create();
+ head = get_interesting_ret_or_call(visited, head, TREE_VALUE(input), intentional_asm);
+ pointer_set_destroy(visited);
@@ -113326,6 +114120,9 @@ index 0000000..a3f9702
+ case GIMPLE_NOP:
+ return search_intentional(visited, SSA_NAME_VAR(lhs));
+ case GIMPLE_ASM:
++ if (is_size_overflow_intentional_asm_turn_off(def_stmt))
++ return MARK_TURN_OFF;
++ return MARK_NO;
+ case GIMPLE_CALL:
+ return MARK_NO;
+ case GIMPLE_PHI:
@@ -113347,10 +114144,9 @@ index 0000000..a3f9702
+}
+
+// Check the intentional_overflow attribute and create the asm comment string for the size_overflow asm stmt.
-+static const char *check_intentional_attribute_gimple(const_tree arg, const_gimple stmt, unsigned int argnum)
++static enum mark check_intentional_attribute_gimple(const_tree arg, const_gimple stmt, unsigned int argnum)
+{
+ const_tree fndecl;
-+ const char *asm_str;
+ struct pointer_set_t *visited;
+ enum mark cur_fndecl_attr, decl_attr = MARK_NO;
+
@@ -113360,7 +114156,7 @@ index 0000000..a3f9702
+ else if (is_yes_intentional_attr(fndecl, argnum))
+ decl_attr = MARK_YES;
+ else if (is_turn_off_intentional_attr(fndecl) || is_turn_off_intentional_attr(DECL_ORIGIN(current_function_decl))) {
-+ return "# size_overflow MARK_TURN_OFF\n\t";
++ return MARK_TURN_OFF;
+ }
+
+ visited = pointer_set_create();
@@ -113369,18 +114165,13 @@ index 0000000..a3f9702
+
+ switch (cur_fndecl_attr) {
+ case MARK_NO:
-+ asm_str = "# size_overflow\n\t";
-+ break;
++ return MARK_NO;
+ case MARK_TURN_OFF:
-+ asm_str = "# size_overflow MARK_TURN_OFF\n\t";
-+ break;
++ return MARK_TURN_OFF;
+ default:
-+ asm_str = "# size_overflow MARK_YES\n\t";
+ print_missing_intentional(decl_attr, cur_fndecl_attr, fndecl, argnum);
-+ break;
++ return MARK_YES;
+ }
-+
-+ return asm_str;
+}
+
+static void check_missing_size_overflow_attribute(tree var)
@@ -113516,6 +114307,21 @@ index 0000000..a3f9702
+ update_stmt(stmt);
+}
+
++static const char *convert_mark_to_str(enum mark mark)
++{
++ switch (mark) {
++ case MARK_NO:
++ return OK_ASM_STR;
++ case MARK_YES:
++ case MARK_NOT_INTENTIONAL:
++ return YES_ASM_STR;
++ case MARK_TURN_OFF:
++ return TURN_OFF_ASM_STR;
++ }
++
++ gcc_unreachable();
++}
++
+/* Create the input of the size_overflow asm stmt.
+ * When the arg of the callee function is a parm_decl it creates this kind of size_overflow asm stmt:
+ * __asm__("# size_overflow MARK_YES" : : "rm" size_1(D));
@@ -113529,6 +114335,8 @@ index 0000000..a3f9702
+ return;
+ }
+
++ gcc_assert(!is_size_overflow_intentional_asm_turn_off(asm_data->def_stmt));
++
+ asm_data->input = create_new_var(TREE_TYPE(asm_data->output));
+ asm_data->input = make_ssa_name(asm_data->input, asm_data->def_stmt);
+
@@ -113541,7 +114349,11 @@ index 0000000..a3f9702
+ create_output_from_phi(stmt, argnum, asm_data);
+ break;
+ case GIMPLE_NOP: {
-+ const char *str = check_intentional_attribute_gimple(asm_data->output, stmt, argnum);
++ enum mark mark;
++ const char *str;
++
++ mark = check_intentional_attribute_gimple(asm_data->output, stmt, argnum);
++ str = convert_mark_to_str(mark);
+
+ asm_data->input = asm_data->output;
+ asm_data->output = NULL;
@@ -113571,19 +114383,24 @@ index 0000000..a3f9702
+{
+ struct asm_data asm_data;
+ const char *str;
++ enum mark mark;
+
+ if (is_gimple_constant(output_node))
+ return;
+
++ asm_data.output = output_node;
++ mark = check_intentional_attribute_gimple(asm_data.output, stmt, argnum);
++ if (mark == MARK_TURN_OFF)
++ return;
++
+ search_missing_size_overflow_attribute_gimple(stmt, argnum);
+
-+ asm_data.output = output_node;
+ asm_data.def_stmt = get_def_stmt(asm_data.output);
+ create_asm_input(stmt, argnum, &asm_data);
+ if (asm_data.input == NULL_TREE)
+ return;
+
-+ str = check_intentional_attribute_gimple(asm_data.output, stmt, argnum);
++ str = convert_mark_to_str(mark);
+ create_asm_stmt(str, build_string(1, "0"), build_string(3, "=rm"), &asm_data);
+}
+
@@ -113680,16 +114497,22 @@ index 0000000..a3f9702
+ if (mark != MARK_TURN_OFF)
+ return false;
+
-+ asm_data.input = gimple_call_lhs(stmt);
-+ if (asm_data.input == NULL_TREE) {
++ asm_data.def_stmt = stmt;
++ asm_data.output = gimple_call_lhs(stmt);
++
++ if (asm_data.output == NULL_TREE) {
+ asm_data.input = gimple_call_arg(stmt, 0);
+ if (is_gimple_constant(asm_data.input))
+ return false;
++ asm_data.output = NULL;
++ create_asm_stmt(TURN_OFF_ASM_STR, build_string(2, "rm"), NULL, &asm_data);
++ return true;
+ }
+
-+ asm_data.output = NULL;
-+ asm_data.def_stmt = stmt;
-+ create_asm_stmt("# size_overflow MARK_TURN_OFF\n\t", build_string(2, "rm"), NULL, &asm_data);
++ create_asm_input(stmt, 0, &asm_data);
++ gcc_assert(asm_data.input != NULL_TREE);
++
++ create_asm_stmt(TURN_OFF_ASM_STR, build_string(1, "0"), build_string(3, "=rm"), &asm_data);
+ return true;
+}
+
@@ -113739,6 +114562,9 @@ index 0000000..a3f9702
+ for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
+ gimple stmt = gsi_stmt(gsi);
+
++ if (is_size_overflow_asm(stmt))
++ continue;
++
+ if (is_gimple_call(stmt))
+ handle_interesting_function(stmt);
+ else if (gimple_code(stmt) == GIMPLE_RETURN)
@@ -114588,7 +115414,7 @@ index 96b919d..c49bb74 100644
+
#endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
-index 1cf9ccb..b9236e2 100644
+index 1cf9ccb..4a8abb5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -75,12 +75,17 @@ LIST_HEAD(vm_list);
@@ -114629,7 +115455,17 @@ index 1cf9ccb..b9236e2 100644
.release = kvm_vcpu_release,
.unlocked_ioctl = kvm_vcpu_ioctl,
#ifdef CONFIG_COMPAT
-@@ -2550,7 +2555,7 @@ static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma)
+@@ -1893,6 +1898,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
+ int r;
+ struct kvm_vcpu *vcpu, *v;
+
++ if (id >= KVM_MAX_VCPUS)
++ return -EINVAL;
++
+ vcpu = kvm_arch_vcpu_create(kvm, id);
+ if (IS_ERR(vcpu))
+ return PTR_ERR(vcpu);
+@@ -2550,7 +2558,7 @@ static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
@@ -114638,7 +115474,7 @@ index 1cf9ccb..b9236e2 100644
.release = kvm_vm_release,
.unlocked_ioctl = kvm_vm_ioctl,
#ifdef CONFIG_COMPAT
-@@ -2651,7 +2656,7 @@ out:
+@@ -2651,7 +2659,7 @@ out:
return r;
}
@@ -114647,7 +115483,7 @@ index 1cf9ccb..b9236e2 100644
.unlocked_ioctl = kvm_dev_ioctl,
.compat_ioctl = kvm_dev_ioctl,
.llseek = noop_llseek,
-@@ -2677,7 +2682,7 @@ static void hardware_enable_nolock(void *junk)
+@@ -2677,7 +2685,7 @@ static void hardware_enable_nolock(void *junk)
if (r) {
cpumask_clear_cpu(cpu, cpus_hardware_enabled);
@@ -114656,7 +115492,7 @@ index 1cf9ccb..b9236e2 100644
printk(KERN_INFO "kvm: enabling virtualization on "
"CPU%d failed\n", cpu);
}
-@@ -2731,10 +2736,10 @@ static int hardware_enable_all(void)
+@@ -2731,10 +2739,10 @@ static int hardware_enable_all(void)
kvm_usage_count++;
if (kvm_usage_count == 1) {
@@ -114669,7 +115505,7 @@ index 1cf9ccb..b9236e2 100644
hardware_disable_all_nolock();
r = -EBUSY;
}
-@@ -3168,7 +3173,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
+@@ -3168,7 +3176,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
kvm_arch_vcpu_put(vcpu);
}
@@ -114678,7 +115514,7 @@ index 1cf9ccb..b9236e2 100644
struct module *module)
{
int r;
-@@ -3215,7 +3220,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -3215,7 +3223,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
if (!vcpu_align)
vcpu_align = __alignof__(struct kvm_vcpu);
kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, vcpu_align,
@@ -114687,7 +115523,7 @@ index 1cf9ccb..b9236e2 100644
if (!kvm_vcpu_cache) {
r = -ENOMEM;
goto out_free_3;
-@@ -3225,9 +3230,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -3225,9 +3233,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
if (r)
goto out_free;
@@ -114699,7 +115535,7 @@ index 1cf9ccb..b9236e2 100644
r = misc_register(&kvm_dev);
if (r) {
-@@ -3237,9 +3244,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -3237,9 +3247,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
register_syscore_ops(&kvm_syscore_ops);
diff --git a/3.12.4/4425_grsec_remove_EI_PAX.patch b/3.12.5/4425_grsec_remove_EI_PAX.patch
index cf65d90..cf65d90 100644
--- a/3.12.4/4425_grsec_remove_EI_PAX.patch
+++ b/3.12.5/4425_grsec_remove_EI_PAX.patch
diff --git a/3.12.4/4427_force_XATTR_PAX_tmpfs.patch b/3.12.5/4427_force_XATTR_PAX_tmpfs.patch
index 23e60cd..23e60cd 100644
--- a/3.12.4/4427_force_XATTR_PAX_tmpfs.patch
+++ b/3.12.5/4427_force_XATTR_PAX_tmpfs.patch
diff --git a/3.12.4/4430_grsec-remove-localversion-grsec.patch b/3.12.5/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.12.4/4430_grsec-remove-localversion-grsec.patch
+++ b/3.12.5/4430_grsec-remove-localversion-grsec.patch
diff --git a/3.12.4/4435_grsec-mute-warnings.patch b/3.12.5/4435_grsec-mute-warnings.patch
index ed941d5..ed941d5 100644
--- a/3.12.4/4435_grsec-mute-warnings.patch
+++ b/3.12.5/4435_grsec-mute-warnings.patch
diff --git a/3.12.4/4440_grsec-remove-protected-paths.patch b/3.12.5/4440_grsec-remove-protected-paths.patch
index 05710b1..05710b1 100644
--- a/3.12.4/4440_grsec-remove-protected-paths.patch
+++ b/3.12.5/4440_grsec-remove-protected-paths.patch
diff --git a/3.12.4/4450_grsec-kconfig-default-gids.patch b/3.12.5/4450_grsec-kconfig-default-gids.patch
index aa9d567..aa9d567 100644
--- a/3.12.4/4450_grsec-kconfig-default-gids.patch
+++ b/3.12.5/4450_grsec-kconfig-default-gids.patch
diff --git a/3.12.4/4465_selinux-avc_audit-log-curr_ip.patch b/3.12.5/4465_selinux-avc_audit-log-curr_ip.patch
index 6490fca..6490fca 100644
--- a/3.12.4/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/3.12.5/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/3.12.4/4470_disable-compat_vdso.patch b/3.12.5/4470_disable-compat_vdso.patch
index 209dfae..209dfae 100644
--- a/3.12.4/4470_disable-compat_vdso.patch
+++ b/3.12.5/4470_disable-compat_vdso.patch
diff --git a/3.12.4/4475_emutramp_default_on.patch b/3.12.5/4475_emutramp_default_on.patch
index 30f6978..30f6978 100644
--- a/3.12.4/4475_emutramp_default_on.patch
+++ b/3.12.5/4475_emutramp_default_on.patch
diff --git a/3.2.53/0000_README b/3.2.53/0000_README
index 3a69687..09b1794 100644
--- a/3.2.53/0000_README
+++ b/3.2.53/0000_README
@@ -130,7 +130,7 @@ Patch: 1052_linux-3.2.53.patch
From: http://www.kernel.org
Desc: Linux 3.2.53
-Patch: 4420_grsecurity-3.0-3.2.53-201312081752.patch
+Patch: 4420_grsecurity-3.0-3.2.53-201312132200.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.53/4420_grsecurity-3.0-3.2.53-201312081752.patch b/3.2.53/4420_grsecurity-3.0-3.2.53-201312132200.patch
index eb4e1a1..e78690c 100644
--- a/3.2.53/4420_grsecurity-3.0-3.2.53-201312081752.patch
+++ b/3.2.53/4420_grsecurity-3.0-3.2.53-201312132200.patch
@@ -3386,6 +3386,18 @@ index c539c68..c95d3db 100644
{
.notifier_call = err_inject_cpu_callback,
};
+diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
+index 782c3a35..3540c5e 100644
+--- a/arch/ia64/kernel/irq_ia64.c
++++ b/arch/ia64/kernel/irq_ia64.c
+@@ -23,7 +23,6 @@
+ #include <linux/ioport.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/ptrace.h>
+-#include <linux/random.h> /* for rand_initialize_irq() */
+ #include <linux/signal.h>
+ #include <linux/smp.h>
+ #include <linux/threads.h>
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 9b97303..69464a9 100644
--- a/arch/ia64/kernel/mca.c
@@ -23358,7 +23370,7 @@ index f5302da..6ee193e 100644
/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
-index 54abb40..a192606 100644
+index 54abb40..fbcaf81 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -53,7 +53,7 @@
@@ -23370,6 +23382,15 @@ index 54abb40..a192606 100644
#define APIC_LVT_NUM 6
/* 14 is the version for Xeon and Pentium 8.4.8*/
+@@ -537,7 +537,7 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
+ ASSERT(apic != NULL);
+
+ /* if initial count is 0, current count should also be 0 */
+- if (apic_get_reg(apic, APIC_TMICT) == 0)
++ if (apic_get_reg(apic, APIC_TMICT) == 0 || apic->lapic_timer.period == 0)
+ return 0;
+
+ remaining = hrtimer_get_remaining(&apic->lapic_timer.timer);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index f1b36cf..af8a124 100644
--- a/arch/x86/kvm/mmu.c
@@ -33713,51 +33734,365 @@ index da3cfee..a5a6606 100644
*ppos = i;
diff --git a/drivers/char/random.c b/drivers/char/random.c
-index c244f0e..255f226 100644
+index c244f0e..bb09210 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
-@@ -269,8 +269,13 @@
+@@ -255,10 +255,8 @@
+ #include <linux/fips.h>
+ #include <linux/ptrace.h>
+ #include <linux/kmemcheck.h>
+-
+-#ifdef CONFIG_GENERIC_HARDIRQS
+-# include <linux/irq.h>
+-#endif
++#include <linux/workqueue.h>
++#include <linux/irq.h>
+
+ #include <asm/processor.h>
+ #include <asm/uaccess.h>
+@@ -266,129 +264,151 @@
+ #include <asm/irq_regs.h>
+ #include <asm/io.h>
+
++#define CREATE_TRACE_POINTS
++#include <trace/events/random.h>
++
/*
* Configuration information
*/
+-#define INPUT_POOL_WORDS 128
+-#define OUTPUT_POOL_WORDS 32
+-#define SEC_XFER_SIZE 512
+-#define EXTRACT_SIZE 10
+#ifdef CONFIG_GRKERNSEC_RANDNET
-+#define INPUT_POOL_WORDS 512
-+#define OUTPUT_POOL_WORDS 128
++#define INPUT_POOL_SHIFT 14
++#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
++#define OUTPUT_POOL_SHIFT 12
++#define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5))
+#else
- #define INPUT_POOL_WORDS 128
- #define OUTPUT_POOL_WORDS 32
++#define INPUT_POOL_SHIFT 12
++#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5))
++#define OUTPUT_POOL_SHIFT 10
++#define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5))
+#endif
- #define SEC_XFER_SIZE 512
- #define EXTRACT_SIZE 10
++#define SEC_XFER_SIZE 512
++#define EXTRACT_SIZE 10
+
+ #define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
+
+ /*
++ * To allow fractional bits to be tracked, the entropy_count field is
++ * denominated in units of 1/8th bits.
++ *
++ * 2*(ENTROPY_SHIFT + log2(poolbits)) must <= 31, or the multiply in
++ * credit_entropy_bits() needs to be 64 bits wide.
++ */
++#define ENTROPY_SHIFT 3
++#define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT)
++
++/*
+ * The minimum number of bits of entropy before we wake up a read on
+ * /dev/random. Should be enough to do a significant reseed.
+ */
+-static int random_read_wakeup_thresh = 64;
++static int random_read_wakeup_bits = 64;
+
+ /*
+ * If the entropy count falls under this number of bits, then we
+ * should wake up processes which are selecting or polling on write
+ * access to /dev/random.
+ */
+-static int random_write_wakeup_thresh = 128;
++static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS;
+
+ /*
+- * When the input pool goes over trickle_thresh, start dropping most
+- * samples to avoid wasting CPU time and reduce lock contention.
++ * The minimum number of seconds between urandom pool reseeding. We
++ * do this to limit the amount of entropy that can be drained from the
++ * input pool even if there are heavy demands on /dev/urandom.
+ */
+-
+-static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
+-
+-static DEFINE_PER_CPU(int, trickle_count);
++static int random_min_urandom_seed = 60;
-@@ -310,10 +315,17 @@ static struct poolinfo {
- int poolwords;
+ /*
+- * A pool of size .poolwords is stirred with a primitive polynomial
+- * of degree .poolwords over GF(2). The taps for various sizes are
+- * defined below. They are chosen to be evenly spaced (minimum RMS
+- * distance from evenly spaced; the numbers in the comments are a
+- * scaled squared error sum) except for the last tap, which is 1 to
+- * get the twisting happening as fast as possible.
++ * Originally, we used a primitive polynomial of degree .poolwords
++ * over GF(2). The taps for various sizes are defined below. They
++ * were chosen to be evenly spaced except for the last tap, which is 1
++ * to get the twisting happening as fast as possible.
++ *
++ * For the purposes of better mixing, we use the CRC-32 polynomial as
++ * well to make a (modified) twisted Generalized Feedback Shift
++ * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR
++ * generators. ACM Transactions on Modeling and Computer Simulation
++ * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted
++ * GFSR generators II. ACM Transactions on Modeling and Computer
++ * Simulation 4:254-266)
++ *
++ * Thanks to Colin Plumb for suggesting this.
++ *
++ * The mixing operation is much less sensitive than the output hash,
++ * where we use SHA-1. All that we want of mixing operation is that
++ * it be a good non-cryptographic hash; i.e. it not produce collisions
++ * when fed "random" data of the sort we expect to see. As long as
++ * the pool state differs for different inputs, we have preserved the
++ * input entropy and done a good job. The fact that an intelligent
++ * attacker can construct inputs that will produce controlled
++ * alterations to the pool's state is not important because we don't
++ * consider such inputs to contribute any randomness. The only
++ * property we need with respect to them is that the attacker can't
++ * increase his/her knowledge of the pool's state. Since all
++ * additions are reversible (knowing the final state and the input,
++ * you can reconstruct the initial state), if an attacker has any
++ * uncertainty about the initial state, he/she can only shuffle that
++ * uncertainty about, but never cause any collisions (which would
++ * decrease the uncertainty).
++ *
++ * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and
++ * Videau in their paper, "The Linux Pseudorandom Number Generator
++ * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their
++ * paper, they point out that we are not using a true Twisted GFSR,
++ * since Matsumoto & Kurita used a trinomial feedback polynomial (that
++ * is, with only three taps, instead of the six that we are using).
++ * As a result, the resulting polynomial is neither primitive nor
++ * irreducible, and hence does not have a maximal period over
++ * GF(2**32). They suggest a slight change to the generator
++ * polynomial which improves the resulting TGFSR polynomial to be
++ * irreducible, which we have made here.
+ */
+ static struct poolinfo {
+- int poolwords;
++ int poolbitshift, poolwords, poolbytes, poolbits, poolfracbits;
++#define S(x) ilog2(x)+5, (x), (x)*4, (x)*32, (x) << (ENTROPY_SHIFT+5)
int tap1, tap2, tap3, tap4, tap5;
} poolinfo_table[] = {
+- /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
+- { 128, 103, 76, 51, 25, 1 },
+- /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
+- { 32, 26, 20, 14, 7, 1 },
+#ifdef CONFIG_GRKERNSEC_RANDNET
-+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
-+ { 512, 411, 308, 208, 104, 1 },
-+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
-+ { 128, 103, 76, 51, 25, 1 },
++ /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
++ { S(512), 411, 308, 208, 104, 1 },
++ /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
++ /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
++ { S(128), 104, 76, 51, 25, 1 },
+#else
- /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
- { 128, 103, 76, 51, 25, 1 },
- /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
- { 32, 26, 20, 14, 7, 1 },
++ /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */
++ /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */
++ { S(128), 104, 76, 51, 25, 1 },
++ /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */
++ /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */
++ { S(32), 26, 19, 14, 7, 1 },
+#endif
#if 0
/* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
- { 2048, 1638, 1231, 819, 411, 1 },
-@@ -434,6 +446,7 @@ struct entropy_store {
+- { 2048, 1638, 1231, 819, 411, 1 },
++ { S(2048), 1638, 1231, 819, 411, 1 },
+
+ /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
+- { 1024, 817, 615, 412, 204, 1 },
++ { S(1024), 817, 615, 412, 204, 1 },
+
+ /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
+- { 1024, 819, 616, 410, 207, 2 },
++ { S(1024), 819, 616, 410, 207, 2 },
+
+ /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
+- { 512, 411, 308, 208, 104, 1 },
++ { S(512), 411, 308, 208, 104, 1 },
+
+ /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
+- { 512, 409, 307, 206, 102, 2 },
++ { S(512), 409, 307, 206, 102, 2 },
+ /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
+- { 512, 409, 309, 205, 103, 2 },
++ { S(512), 409, 309, 205, 103, 2 },
+
+ /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
+- { 256, 205, 155, 101, 52, 1 },
++ { S(256), 205, 155, 101, 52, 1 },
+
+ /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
+- { 128, 103, 78, 51, 27, 2 },
++ { S(128), 103, 78, 51, 27, 2 },
+
+ /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
+- { 64, 52, 39, 26, 14, 1 },
++ { S(64), 52, 39, 26, 14, 1 },
+ #endif
+ };
+
+-#define POOLBITS poolwords*32
+-#define POOLBYTES poolwords*4
+-
+-/*
+- * For the purposes of better mixing, we use the CRC-32 polynomial as
+- * well to make a twisted Generalized Feedback Shift Reigster
+- *
+- * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM
+- * Transactions on Modeling and Computer Simulation 2(3):179-194.
+- * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators
+- * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266)
+- *
+- * Thanks to Colin Plumb for suggesting this.
+- *
+- * We have not analyzed the resultant polynomial to prove it primitive;
+- * in fact it almost certainly isn't. Nonetheless, the irreducible factors
+- * of a random large-degree polynomial over GF(2) are more than large enough
+- * that periodicity is not a concern.
+- *
+- * The input hash is much less sensitive than the output hash. All
+- * that we want of it is that it be a good non-cryptographic hash;
+- * i.e. it not produce collisions when fed "random" data of the sort
+- * we expect to see. As long as the pool state differs for different
+- * inputs, we have preserved the input entropy and done a good job.
+- * The fact that an intelligent attacker can construct inputs that
+- * will produce controlled alterations to the pool's state is not
+- * important because we don't consider such inputs to contribute any
+- * randomness. The only property we need with respect to them is that
+- * the attacker can't increase his/her knowledge of the pool's state.
+- * Since all additions are reversible (knowing the final state and the
+- * input, you can reconstruct the initial state), if an attacker has
+- * any uncertainty about the initial state, he/she can only shuffle
+- * that uncertainty about, but never cause any collisions (which would
+- * decrease the uncertainty).
+- *
+- * The chosen system lets the state of the pool be (essentially) the input
+- * modulo the generator polymnomial. Now, for random primitive polynomials,
+- * this is a universal class of hash functions, meaning that the chance
+- * of a collision is limited by the attacker's knowledge of the generator
+- * polynomail, so if it is chosen at random, an attacker can never force
+- * a collision. Here, we use a fixed polynomial, but we *can* assume that
+- * ###--> it is unknown to the processes generating the input entropy. <-###
+- * Because of this important property, this is a good, collision-resistant
+- * hash; hash collisions will occur no more often than chance.
+- */
+-
+ /*
+ * Static global variables
+ */
+@@ -396,21 +416,6 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
+ static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
+ static struct fasync_struct *fasync;
+
+-#if 0
+-static int debug;
+-module_param(debug, bool, 0644);
+-#define DEBUG_ENT(fmt, arg...) do { \
+- if (debug) \
+- printk(KERN_DEBUG "random %04d %04d %04d: " \
+- fmt,\
+- input_pool.entropy_count,\
+- blocking_pool.entropy_count,\
+- nonblocking_pool.entropy_count,\
+- ## arg); } while (0)
+-#else
+-#define DEBUG_ENT(fmt, arg...) do {} while (0)
+-#endif
+-
+ /**********************************************************************
+ *
+ * OS independent entropy store. Here are the functions which handle
+@@ -421,22 +426,26 @@ module_param(debug, bool, 0644);
+ struct entropy_store;
+ struct entropy_store {
+ /* read-only data: */
+- struct poolinfo *poolinfo;
++ const struct poolinfo *poolinfo;
+ __u32 *pool;
+ const char *name;
+ struct entropy_store *pull;
+- int limit;
++ struct work_struct push_work;
+
+ /* read-write data: */
++ unsigned long last_pulled;
+ spinlock_t lock;
+- unsigned add_ptr;
+- unsigned input_rotate;
++ unsigned short add_ptr;
++ unsigned short input_rotate;
int entropy_count;
int entropy_total;
unsigned int initialized:1;
-+ bool last_data_init;
++ unsigned int limit:1;
++ unsigned int last_data_init:1;
__u8 last_data[EXTRACT_SIZE];
};
-@@ -524,8 +537,8 @@ static void __mix_pool_bytes(struct entropy_store *r, const void *in,
- input_rotate += i ? 7 : 14;
++static void push_to_pool(struct work_struct *work);
+ static __u32 input_pool_data[INPUT_POOL_WORDS];
+ static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
+ static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+@@ -445,7 +454,7 @@ static struct entropy_store input_pool = {
+ .poolinfo = &poolinfo_table[0],
+ .name = "input",
+ .limit = 1,
+- .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
++ .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
+ .pool = input_pool_data
+ };
+
+@@ -454,16 +463,20 @@ static struct entropy_store blocking_pool = {
+ .name = "blocking",
+ .limit = 1,
+ .pull = &input_pool,
+- .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
+- .pool = blocking_pool_data
++ .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock),
++ .pool = blocking_pool_data,
++ .push_work = __WORK_INITIALIZER(blocking_pool.push_work,
++ push_to_pool),
+ };
+
+ static struct entropy_store nonblocking_pool = {
+ .poolinfo = &poolinfo_table[1],
+ .name = "nonblocking",
+ .pull = &input_pool,
+- .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
+- .pool = nonblocking_pool_data
++ .lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock),
++ .pool = nonblocking_pool_data,
++ .push_work = __WORK_INITIALIZER(nonblocking_pool.push_work,
++ push_to_pool),
+ };
+
+ static __u32 const twist_table[8] = {
+@@ -480,8 +493,8 @@ static __u32 const twist_table[8] = {
+ * it's cheap to do so and helps slightly in the expected case where
+ * the entropy is concentrated in the low-order bits.
+ */
+-static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+- int nbytes, __u8 out[64])
++static void _mix_pool_bytes(struct entropy_store *r, const void *in,
++ int nbytes, __u8 out[64])
+ {
+ unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
+ int input_rotate;
+@@ -501,7 +514,7 @@ static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+
+ /* mix one byte at a time to simplify size handling and churn faster */
+ while (nbytes--) {
+- w = rol32(*bytes++, input_rotate & 31);
++ w = rol32(*bytes++, input_rotate);
+ i = (i - 1) & wordmask;
+
+ /* XOR in the various taps */
+@@ -521,11 +534,11 @@ static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+ * rotation, so that successive passes spread the
+ * input bits across the pool evenly.
+ */
+- input_rotate += i ? 7 : 14;
++ input_rotate = (input_rotate + (i ? 7 : 14)) & 31;
}
- ACCESS_ONCE(r->input_rotate) = input_rotate;
@@ -33767,51 +34102,608 @@ index c244f0e..255f226 100644
smp_wmb();
if (out)
-@@ -877,6 +890,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
- int reserved)
+@@ -533,13 +546,21 @@ static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+ ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
+ }
+
++static void __mix_pool_bytes(struct entropy_store *r, const void *in,
++ int nbytes, __u8 out[64])
++{
++ trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_);
++ _mix_pool_bytes(r, in, nbytes, out);
++}
++
+ static void mix_pool_bytes(struct entropy_store *r, const void *in,
+- int nbytes, __u8 out[64])
++ int nbytes, __u8 out[64])
{
unsigned long flags;
-+ int wakeup_write = 0;
- /* Hold lock while accounting */
++ trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
spin_lock_irqsave(&r->lock, flags);
-@@ -906,10 +920,8 @@ retry:
- goto retry;
- }
+- __mix_pool_bytes(r, in, nbytes, out);
++ _mix_pool_bytes(r, in, nbytes, out);
+ spin_unlock_irqrestore(&r->lock, flags);
+ }
+
+@@ -556,58 +577,151 @@ struct fast_pool {
+ * collector. It's hardcoded for an 128 bit pool and assumes that any
+ * locks that might be needed are taken by the caller.
+ */
+-static void fast_mix(struct fast_pool *f, const void *in, int nbytes)
++static void fast_mix(struct fast_pool *f, __u32 input[4])
+ {
+- const char *bytes = in;
+ __u32 w;
+- unsigned i = f->count;
+ unsigned input_rotate = f->rotate;
+
+- while (nbytes--) {
+- w = rol32(*bytes++, input_rotate & 31) ^ f->pool[i & 3] ^
+- f->pool[(i + 1) & 3];
+- f->pool[i & 3] = (w >> 3) ^ twist_table[w & 7];
+- input_rotate += (i++ & 3) ? 7 : 14;
+- }
+- f->count = i;
++ w = rol32(input[0], input_rotate) ^ f->pool[0] ^ f->pool[3];
++ f->pool[0] = (w >> 3) ^ twist_table[w & 7];
++ input_rotate = (input_rotate + 14) & 31;
++ w = rol32(input[1], input_rotate) ^ f->pool[1] ^ f->pool[0];
++ f->pool[1] = (w >> 3) ^ twist_table[w & 7];
++ input_rotate = (input_rotate + 7) & 31;
++ w = rol32(input[2], input_rotate) ^ f->pool[2] ^ f->pool[1];
++ f->pool[2] = (w >> 3) ^ twist_table[w & 7];
++ input_rotate = (input_rotate + 7) & 31;
++ w = rol32(input[3], input_rotate) ^ f->pool[3] ^ f->pool[2];
++ f->pool[3] = (w >> 3) ^ twist_table[w & 7];
++ input_rotate = (input_rotate + 7) & 31;
++
+ f->rotate = input_rotate;
++ f->count++;
+ }
+
+ /*
+- * Credit (or debit) the entropy store with n bits of entropy
++ * Credit (or debit) the entropy store with n bits of entropy.
++ * Use credit_entropy_bits_safe() if the value comes from userspace
++ * or otherwise should be checked for extreme values.
+ */
+ static void credit_entropy_bits(struct entropy_store *r, int nbits)
+ {
+ int entropy_count, orig;
++ const int pool_size = r->poolinfo->poolfracbits;
++ int nfrac = nbits << ENTROPY_SHIFT;
+
+ if (!nbits)
+ return;
+
+- DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
+ retry:
+ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+- entropy_count += nbits;
++ if (nfrac < 0) {
++ /* Debit */
++ entropy_count += nfrac;
++ } else {
++ /*
++ * Credit: we have to account for the possibility of
++ * overwriting already present entropy. Even in the
++ * ideal case of pure Shannon entropy, new contributions
++ * approach the full value asymptotically:
++ *
++ * entropy <- entropy + (pool_size - entropy) *
++ * (1 - exp(-add_entropy/pool_size))
++ *
++ * For add_entropy <= pool_size/2 then
++ * (1 - exp(-add_entropy/pool_size)) >=
++ * (add_entropy/pool_size)*0.7869...
++ * so we can approximate the exponential with
++ * 3/4*add_entropy/pool_size and still be on the
++ * safe side by adding at most pool_size/2 at a time.
++ *
++ * The use of pool_size-2 in the while statement is to
++ * prevent rounding artifacts from making the loop
++ * arbitrarily long; this limits the loop to log2(pool_size)*2
++ * turns no matter how large nbits is.
++ */
++ int pnfrac = nfrac;
++ const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2;
++ /* The +2 corresponds to the /4 in the denominator */
++
++ do {
++ unsigned int anfrac = min(pnfrac, pool_size/2);
++ unsigned int add =
++ ((pool_size - entropy_count)*anfrac*3) >> s;
++
++ entropy_count += add;
++ pnfrac -= anfrac;
++ } while (unlikely(entropy_count < pool_size-2 && pnfrac));
++ }
++
+ if (entropy_count < 0) {
+- DEBUG_ENT("negative entropy/overflow\n");
++ pr_warn("random: negative entropy/overflow: pool %s count %d\n",
++ r->name, entropy_count);
++ WARN_ON(1);
+ entropy_count = 0;
+- } else if (entropy_count > r->poolinfo->POOLBITS)
+- entropy_count = r->poolinfo->POOLBITS;
++ } else if (entropy_count > pool_size)
++ entropy_count = pool_size;
+ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+ goto retry;
+
+- if (!r->initialized && nbits > 0) {
+- r->entropy_total += nbits;
+- if (r->entropy_total > 128)
+- r->initialized = 1;
++ r->entropy_total += nbits;
++ if (!r->initialized && r->entropy_total > 128) {
++ r->initialized = 1;
++ r->entropy_total = 0;
++ if (r == &nonblocking_pool) {
++ prandom_reseed_late();
++ pr_notice("random: %s pool is initialized\n", r->name);
++ }
+ }
+
+- /* should we wake readers? */
+- if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
+- wake_up_interruptible(&random_read_wait);
+- kill_fasync(&fasync, SIGIO, POLL_IN);
++ trace_credit_entropy_bits(r->name, nbits,
++ entropy_count >> ENTROPY_SHIFT,
++ r->entropy_total, _RET_IP_);
++
++ if (r == &input_pool) {
++ int entropy_bits = entropy_count >> ENTROPY_SHIFT;
++
++ /* should we wake readers? */
++ if (entropy_bits >= random_read_wakeup_bits) {
++ wake_up_interruptible(&random_read_wait);
++ kill_fasync(&fasync, SIGIO, POLL_IN);
++ }
++ /* If the input pool is getting full, send some
++ * entropy to the two output pools, flipping back and
++ * forth between them, until the output pools are 75%
++ * full.
++ */
++ if (entropy_bits > random_write_wakeup_bits &&
++ r->initialized &&
++ r->entropy_total >= 2*random_read_wakeup_bits) {
++ static struct entropy_store *last = &blocking_pool;
++ struct entropy_store *other = &blocking_pool;
++
++ if (last == &blocking_pool)
++ other = &nonblocking_pool;
++ if (other->entropy_count <=
++ 3 * other->poolinfo->poolfracbits / 4)
++ last = other;
++ if (last->entropy_count <=
++ 3 * last->poolinfo->poolfracbits / 4) {
++ schedule_work(&last->push_work);
++ r->entropy_total = 0;
++ }
++ }
+ }
+ }
+
++static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
++{
++ const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
++
++ /* Cap the value to avoid overflows */
++ nbits = min(nbits, nbits_max);
++ nbits = max(nbits, -nbits_max);
++
++ credit_entropy_bits(r, nbits);
++}
++
+ /*********************************************************************
+ *
+ * Entropy input management
+@@ -621,42 +735,7 @@ struct timer_rand_state {
+ unsigned dont_count_entropy:1;
+ };
+
+-#ifndef CONFIG_GENERIC_HARDIRQS
+-
+-static struct timer_rand_state *irq_timer_state[NR_IRQS];
+-
+-static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+-{
+- return irq_timer_state[irq];
+-}
+-
+-static void set_timer_rand_state(unsigned int irq,
+- struct timer_rand_state *state)
+-{
+- irq_timer_state[irq] = state;
+-}
+-
+-#else
+-
+-static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+-{
+- struct irq_desc *desc;
+-
+- desc = irq_to_desc(irq);
+-
+- return desc->timer_rand_state;
+-}
+-
+-static void set_timer_rand_state(unsigned int irq,
+- struct timer_rand_state *state)
+-{
+- struct irq_desc *desc;
+-
+- desc = irq_to_desc(irq);
+-
+- desc->timer_rand_state = state;
+-}
+-#endif
++#define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, };
+
+ /*
+ * Add device- or boot-specific data to the input and nonblocking
+@@ -669,15 +748,22 @@ static void set_timer_rand_state(unsigned int irq,
+ void add_device_randomness(const void *buf, unsigned int size)
+ {
+ unsigned long time = random_get_entropy() ^ jiffies;
++ unsigned long flags;
+
+- mix_pool_bytes(&input_pool, buf, size, NULL);
+- mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
+- mix_pool_bytes(&nonblocking_pool, buf, size, NULL);
+- mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL);
++ trace_add_device_randomness(size, _RET_IP_);
++ spin_lock_irqsave(&input_pool.lock, flags);
++ _mix_pool_bytes(&input_pool, buf, size, NULL);
++ _mix_pool_bytes(&input_pool, &time, sizeof(time), NULL);
++ spin_unlock_irqrestore(&input_pool.lock, flags);
++
++ spin_lock_irqsave(&nonblocking_pool.lock, flags);
++ _mix_pool_bytes(&nonblocking_pool, buf, size, NULL);
++ _mix_pool_bytes(&nonblocking_pool, &time, sizeof(time), NULL);
++ spin_unlock_irqrestore(&nonblocking_pool.lock, flags);
+ }
+ EXPORT_SYMBOL(add_device_randomness);
+
+-static struct timer_rand_state input_timer_state;
++static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE;
+
+ /*
+ * This function adds entropy to the entropy "pool" by using timing
+@@ -691,6 +777,7 @@ static struct timer_rand_state input_timer_state;
+ */
+ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
+ {
++ struct entropy_store *r;
+ struct {
+ long jiffies;
+ unsigned cycles;
+@@ -699,15 +786,12 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
+ long delta, delta2, delta3;
+
+ preempt_disable();
+- /* if over the trickle threshold, use only 1 in 4096 samples */
+- if (input_pool.entropy_count > trickle_thresh &&
+- ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff))
+- goto out;
+
+ sample.jiffies = jiffies;
+ sample.cycles = random_get_entropy();
+ sample.num = num;
+- mix_pool_bytes(&input_pool, &sample, sizeof(sample), NULL);
++ r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
++ mix_pool_bytes(r, &sample, sizeof(sample), NULL);
+
+ /*
+ * Calculate number of bits of randomness we probably added.
+@@ -741,10 +825,8 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
+ * Round down by 1 bit on general principles,
+ * and limit entropy entimate to 12 bits.
+ */
+- credit_entropy_bits(&input_pool,
+- min_t(int, fls(delta>>1), 11));
++ credit_entropy_bits(r, min_t(int, fls(delta>>1), 11));
+ }
+-out:
+ preempt_enable();
+ }
+
+@@ -757,10 +839,10 @@ void add_input_randomness(unsigned int type, unsigned int code,
+ if (value == last_value)
+ return;
+
+- DEBUG_ENT("input event\n");
+ last_value = value;
+ add_timer_randomness(&input_timer_state,
+ (type << 4) ^ code ^ (code >> 4) ^ value);
++ trace_add_input_randomness(ENTROPY_BITS(&input_pool));
+ }
+ EXPORT_SYMBOL_GPL(add_input_randomness);
+
+@@ -772,20 +854,21 @@ void add_interrupt_randomness(int irq, int irq_flags)
+ struct fast_pool *fast_pool = &__get_cpu_var(irq_randomness);
+ struct pt_regs *regs = get_irq_regs();
+ unsigned long now = jiffies;
+- __u32 input[4], cycles = random_get_entropy();
++ cycles_t cycles = random_get_entropy();
++ __u32 input[4], c_high, j_high;
++ __u64 ip;
+
+- input[0] = cycles ^ jiffies;
+- input[1] = irq;
+- if (regs) {
+- __u64 ip = instruction_pointer(regs);
+- input[2] = ip;
+- input[3] = ip >> 32;
+- }
++ c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0;
++ j_high = (sizeof(now) > 4) ? now >> 32 : 0;
++ input[0] = cycles ^ j_high ^ irq;
++ input[1] = now ^ c_high;
++ ip = regs ? instruction_pointer(regs) : _RET_IP_;
++ input[2] = ip;
++ input[3] = ip >> 32;
+
+- fast_mix(fast_pool, input, sizeof(input));
++ fast_mix(fast_pool, input);
+
+- if ((fast_pool->count & 1023) &&
+- !time_after(now, fast_pool->last + HZ))
++ if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ))
+ return;
+
+ fast_pool->last = now;
+@@ -814,10 +897,8 @@ void add_disk_randomness(struct gendisk *disk)
+ if (!disk || !disk->random)
+ return;
+ /* first major is 1, so we get >= 0x200 here */
+- DEBUG_ENT("disk event %d:%d\n",
+- MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)));
+-
+ add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
++ trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool));
+ }
+ #endif
+
+@@ -835,97 +916,110 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ * from the primary pool to the secondary extraction pool. We make
+ * sure we pull enough for a 'catastrophic reseed'.
+ */
++static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes);
+ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
+ {
++ if (r->limit == 0 && random_min_urandom_seed) {
++ unsigned long now = jiffies;
++
++ if (time_before(now,
++ r->last_pulled + random_min_urandom_seed * HZ))
++ return;
++ r->last_pulled = now;
++ }
++ if (r->pull &&
++ r->entropy_count < (nbytes << (ENTROPY_SHIFT + 3)) &&
++ r->entropy_count < r->poolinfo->poolfracbits)
++ _xfer_secondary_pool(r, nbytes);
++}
++
++static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
++{
+ __u32 tmp[OUTPUT_POOL_WORDS];
+
+- if (r->pull && r->entropy_count < nbytes * 8 &&
+- r->entropy_count < r->poolinfo->POOLBITS) {
+- /* If we're limited, always leave two wakeup worth's BITS */
+- int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
+- int bytes = nbytes;
++ /* For /dev/random's pool, always leave two wakeups' worth */
++ int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4;
++ int bytes = nbytes;
+
+- /* pull at least as many as BYTES as wakeup BITS */
+- bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
+- /* but never more than the buffer size */
+- bytes = min_t(int, bytes, sizeof(tmp));
++ /* pull at least as much as a wakeup */
++ bytes = max_t(int, bytes, random_read_wakeup_bits / 8);
++ /* but never more than the buffer size */
++ bytes = min_t(int, bytes, sizeof(tmp));
+
+- DEBUG_ENT("going to reseed %s with %d bits "
+- "(%d of %d requested)\n",
+- r->name, bytes * 8, nbytes * 8, r->entropy_count);
+-
+- bytes = extract_entropy(r->pull, tmp, bytes,
+- random_read_wakeup_thresh / 8, rsvd);
+- mix_pool_bytes(r, tmp, bytes, NULL);
+- credit_entropy_bits(r, bytes*8);
+- }
++ trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8,
++ ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
++ bytes = extract_entropy(r->pull, tmp, bytes,
++ random_read_wakeup_bits / 8, rsvd_bytes);
++ mix_pool_bytes(r, tmp, bytes, NULL);
++ credit_entropy_bits(r, bytes*8);
+ }
+
+ /*
+- * These functions extracts randomness from the "entropy pool", and
+- * returns it in a buffer.
+- *
+- * The min parameter specifies the minimum amount we can pull before
+- * failing to avoid races that defeat catastrophic reseeding while the
+- * reserved parameter indicates how much entropy we must leave in the
+- * pool after each pull to avoid starving other readers.
+- *
+- * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
++ * Used as a workqueue function so that when the input pool is getting
++ * full, we can "spill over" some entropy to the output pools. That
++ * way the output pools can store some of the excess entropy instead
++ * of letting it go to waste.
+ */
++static void push_to_pool(struct work_struct *work)
++{
++ struct entropy_store *r = container_of(work, struct entropy_store,
++ push_work);
++ BUG_ON(!r);
++ _xfer_secondary_pool(r, random_read_wakeup_bits/8);
++ trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT,
++ r->pull->entropy_count >> ENTROPY_SHIFT);
++}
++/*
++ * This function decides how many bytes to actually take from the
++ * given pool, and also debits the entropy count accordingly.
++ */
+ static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ int reserved)
+ {
+- unsigned long flags;
++ int have_bytes;
++ int entropy_count, orig;
++ size_t ibytes;
+
+- /* Hold lock while accounting */
+- spin_lock_irqsave(&r->lock, flags);
+-
+- BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
+- DEBUG_ENT("trying to extract %d bits from %s\n",
+- nbytes * 8, r->name);
++ BUG_ON(r->entropy_count > r->poolinfo->poolfracbits);
+
+ /* Can we pull enough? */
+- if (r->entropy_count / 8 < min + reserved) {
+- nbytes = 0;
+- } else {
+- int entropy_count, orig;
+ retry:
+- entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+- /* If limited, never pull more than available */
+- if (r->limit && nbytes + reserved >= entropy_count / 8)
+- nbytes = entropy_count/8 - reserved;
++ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
++ have_bytes = entropy_count >> (ENTROPY_SHIFT + 3);
++ ibytes = nbytes;
++ /* If limited, never pull more than available */
++ if (r->limit)
++ ibytes = min_t(size_t, ibytes, have_bytes - reserved);
++ if (ibytes < min)
++ ibytes = 0;
++ entropy_count = max_t(int, 0,
++ entropy_count - (ibytes << (ENTROPY_SHIFT + 3)));
++ if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
++ goto retry;
+
+- if (entropy_count / 8 >= nbytes + reserved) {
+- entropy_count -= nbytes*8;
+- if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+- goto retry;
+- } else {
+- entropy_count = reserved;
+- if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig)
+- goto retry;
+- }
+-
- if (entropy_count < random_write_wakeup_thresh) {
- wake_up_interruptible(&random_write_wait);
- kill_fasync(&fasync, SIGIO, POLL_OUT);
- }
-+ if (entropy_count < random_write_wakeup_thresh)
-+ wakeup_write = 1;
++ trace_debit_entropy(r->name, 8 * ibytes);
++ if (ibytes &&
++ (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) {
++ wake_up_interruptible(&random_write_wait);
++ kill_fasync(&fasync, SIGIO, POLL_OUT);
}
- DEBUG_ENT("debiting %d entropy credits from %s%s\n",
-@@ -917,6 +929,11 @@ retry:
+- DEBUG_ENT("debiting %d entropy credits from %s%s\n",
+- nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
+-
+- spin_unlock_irqrestore(&r->lock, flags);
+-
+- return nbytes;
++ return ibytes;
+ }
- spin_unlock_irqrestore(&r->lock, flags);
++/*
++ * This function does the actual extraction for extract_entropy and
++ * extract_entropy_user.
++ *
++ * Note: we assume that .poolwords is a multiple of 16 words.
++ */
+ static void extract_buf(struct entropy_store *r, __u8 *out)
+ {
+ int i;
+ union {
+ __u32 w[5];
+- unsigned long l[LONGS(EXTRACT_SIZE)];
++ unsigned long l[LONGS(20)];
+ } hash;
+ __u32 workspace[SHA_WORKSPACE_WORDS];
+ __u8 extract[64];
+@@ -938,6 +1032,17 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
+ sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
-+ if (wakeup_write) {
-+ wake_up_interruptible(&random_write_wait);
-+ kill_fasync(&fasync, SIGIO, POLL_OUT);
+ /*
++ * If we have an architectural hardware random number
++ * generator, mix that in, too.
++ */
++ for (i = 0; i < LONGS(20); i++) {
++ unsigned long v;
++ if (!arch_get_random_long(&v))
++ break;
++ hash.l[i] ^= v;
+ }
+
- return nbytes;
++ /*
+ * We mix the hash back into the pool to prevent backtracking
+ * attacks (where the attacker knows the state of the pool
+ * plus the current outputs, and attempts to find previous
+@@ -966,27 +1071,43 @@ static void extract_buf(struct entropy_store *r, __u8 *out)
+ hash.w[1] ^= hash.w[4];
+ hash.w[2] ^= rol32(hash.w[2], 16);
+
+- /*
+- * If we have a architectural hardware random number
+- * generator, mix that in, too.
+- */
+- for (i = 0; i < LONGS(EXTRACT_SIZE); i++) {
+- unsigned long v;
+- if (!arch_get_random_long(&v))
+- break;
+- hash.l[i] ^= v;
+- }
+-
+ memcpy(out, &hash, EXTRACT_SIZE);
+ memset(&hash, 0, sizeof(hash));
}
-@@ -986,6 +1003,21 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
++/*
++ * This function extracts randomness from the "entropy pool", and
++ * returns it in a buffer.
++ *
++ * The min parameter specifies the minimum amount we can pull before
++ * failing to avoid races that defeat catastrophic reseeding while the
++ * reserved parameter indicates how much entropy we must leave in the
++ * pool after each pull to avoid starving other readers.
++ */
+ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ size_t nbytes, int min, int reserved)
{
ssize_t ret = 0, i;
__u8 tmp[EXTRACT_SIZE];
+ unsigned long flags;
-+
+
+ /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */
+ if (fips_enabled) {
+ spin_lock_irqsave(&r->lock, flags);
+ if (!r->last_data_init) {
-+ r->last_data_init = true;
++ r->last_data_init = 1;
+ spin_unlock_irqrestore(&r->lock, flags);
++ trace_extract_entropy(r->name, EXTRACT_SIZE,
++ ENTROPY_BITS(r), _RET_IP_);
+ xfer_secondary_pool(r, EXTRACT_SIZE);
+ extract_buf(r, tmp);
+ spin_lock_irqsave(&r->lock, flags);
@@ -33819,10 +34711,12 @@ index c244f0e..255f226 100644
+ }
+ spin_unlock_irqrestore(&r->lock, flags);
+ }
-
++
++ trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
xfer_secondary_pool(r, nbytes);
nbytes = account(r, nbytes, min, reserved);
-@@ -994,8 +1026,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+
+@@ -994,8 +1115,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
extract_buf(r, tmp);
if (fips_enabled) {
@@ -33831,7 +34725,25 @@ index c244f0e..255f226 100644
spin_lock_irqsave(&r->lock, flags);
if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
panic("Hardware RNG duplicated output!\n");
-@@ -1036,7 +1066,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+@@ -1015,12 +1134,17 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
+ return ret;
+ }
+
++/*
++ * This function extracts randomness from the "entropy pool", and
++ * returns it in a userspace buffer.
++ */
+ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+ size_t nbytes)
+ {
+ ssize_t ret = 0, i;
+ __u8 tmp[EXTRACT_SIZE];
+
++ trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_);
+ xfer_secondary_pool(r, nbytes);
+ nbytes = account(r, nbytes, 0, 0);
+
+@@ -1036,7 +1160,7 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
extract_buf(r, tmp);
i = min_t(int, nbytes, EXTRACT_SIZE);
@@ -33840,15 +34752,241 @@ index c244f0e..255f226 100644
ret = -EFAULT;
break;
}
-@@ -1113,6 +1143,7 @@ static void init_std_data(struct entropy_store *r)
-
- r->entropy_count = 0;
- r->entropy_total = 0;
-+ r->last_data_init = false;
+@@ -1055,11 +1179,18 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
+ /*
+ * This function is the exported kernel interface. It returns some
+ * number of good random numbers, suitable for key generation, seeding
+- * TCP sequence numbers, etc. It does not use the hw random number
+- * generator, if available; use get_random_bytes_arch() for that.
++ * TCP sequence numbers, etc. It does not rely on the hardware random
++ * number generator. For random bytes direct from the hardware RNG
++ * (when available), use get_random_bytes_arch().
+ */
+ void get_random_bytes(void *buf, int nbytes)
+ {
++ if (unlikely(nonblocking_pool.initialized == 0))
++ printk(KERN_NOTICE "random: %pF get_random_bytes called "
++ "with %d bits of entropy available\n",
++ (void *) _RET_IP_,
++ nonblocking_pool.entropy_total);
++ trace_get_random_bytes(nbytes, _RET_IP_);
+ extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
+ }
+ EXPORT_SYMBOL(get_random_bytes);
+@@ -1078,6 +1209,7 @@ void get_random_bytes_arch(void *buf, int nbytes)
+ {
+ char *p = buf;
+
++ trace_get_random_bytes_arch(nbytes, _RET_IP_);
+ while (nbytes) {
+ unsigned long v;
+ int chunk = min(nbytes, (int)sizeof(unsigned long));
+@@ -1111,12 +1243,11 @@ static void init_std_data(struct entropy_store *r)
+ ktime_t now = ktime_get_real();
+ unsigned long rv;
+
+- r->entropy_count = 0;
+- r->entropy_total = 0;
++ r->last_pulled = jiffies;
mix_pool_bytes(r, &now, sizeof(now), NULL);
- for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
+- for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) {
++ for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) {
if (!arch_get_random_long(&rv))
-@@ -1387,7 +1418,7 @@ EXPORT_SYMBOL(generate_random_uuid);
+- break;
++ rv = random_get_entropy();
+ mix_pool_bytes(r, &rv, sizeof(rv), NULL);
+ }
+ mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
+@@ -1139,25 +1270,7 @@ static int rand_initialize(void)
+ init_std_data(&nonblocking_pool);
+ return 0;
+ }
+-module_init(rand_initialize);
+-
+-void rand_initialize_irq(int irq)
+-{
+- struct timer_rand_state *state;
+-
+- state = get_timer_rand_state(irq);
+-
+- if (state)
+- return;
+-
+- /*
+- * If kzalloc returns null, we just won't use that entropy
+- * source.
+- */
+- state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
+- if (state)
+- set_timer_rand_state(irq, state);
+-}
++early_initcall(rand_initialize);
+
+ #ifdef CONFIG_BLOCK
+ void rand_initialize_disk(struct gendisk *disk)
+@@ -1169,71 +1282,59 @@ void rand_initialize_disk(struct gendisk *disk)
+ * source.
+ */
+ state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
+- if (state)
++ if (state) {
++ state->last_time = INITIAL_JIFFIES;
+ disk->random = state;
++ }
+ }
+ #endif
+
+ static ssize_t
+ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+ {
+- ssize_t n, retval = 0, count = 0;
++ ssize_t n;
+
+ if (nbytes == 0)
+ return 0;
+
+- while (nbytes > 0) {
+- n = nbytes;
+- if (n > SEC_XFER_SIZE)
+- n = SEC_XFER_SIZE;
+-
+- DEBUG_ENT("reading %d bits\n", n*8);
+-
+- n = extract_entropy_user(&blocking_pool, buf, n);
+-
+- DEBUG_ENT("read got %d bits (%d still needed)\n",
+- n*8, (nbytes-n)*8);
+-
+- if (n == 0) {
+- if (file->f_flags & O_NONBLOCK) {
+- retval = -EAGAIN;
+- break;
+- }
+-
+- DEBUG_ENT("sleeping?\n");
+-
+- wait_event_interruptible(random_read_wait,
+- input_pool.entropy_count >=
+- random_read_wakeup_thresh);
+-
+- DEBUG_ENT("awake\n");
+-
+- if (signal_pending(current)) {
+- retval = -ERESTARTSYS;
+- break;
+- }
+-
+- continue;
+- }
+-
+- if (n < 0) {
+- retval = n;
+- break;
+- }
+- count += n;
+- buf += n;
+- nbytes -= n;
+- break; /* This break makes the device work */
+- /* like a named pipe */
++ nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE);
++ while (1) {
++ n = extract_entropy_user(&blocking_pool, buf, nbytes);
++ if (n < 0)
++ return n;
++ trace_random_read(n*8, (nbytes-n)*8,
++ ENTROPY_BITS(&blocking_pool),
++ ENTROPY_BITS(&input_pool));
++ if (n > 0)
++ return n;
++ /* Pool is (near) empty. Maybe wait and retry. */
++
++ if (file->f_flags & O_NONBLOCK)
++ return -EAGAIN;
++
++ wait_event_interruptible(random_read_wait,
++ ENTROPY_BITS(&input_pool) >=
++ random_read_wakeup_bits);
++ if (signal_pending(current))
++ return -ERESTARTSYS;
+ }
+-
+- return (count ? count : retval);
+ }
+
+ static ssize_t
+ urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
+ {
+- return extract_entropy_user(&nonblocking_pool, buf, nbytes);
++ int ret;
++
++ if (unlikely(nonblocking_pool.initialized == 0))
++ printk_once(KERN_NOTICE "random: %s urandom read "
++ "with %d bits of entropy available\n",
++ current->comm, nonblocking_pool.entropy_total);
++
++ ret = extract_entropy_user(&nonblocking_pool, buf, nbytes);
++
++ trace_urandom_read(8 * nbytes, ENTROPY_BITS(&nonblocking_pool),
++ ENTROPY_BITS(&input_pool));
++ return ret;
+ }
+
+ static unsigned int
+@@ -1244,9 +1345,9 @@ random_poll(struct file *file, poll_table * wait)
+ poll_wait(file, &random_read_wait, wait);
+ poll_wait(file, &random_write_wait, wait);
+ mask = 0;
+- if (input_pool.entropy_count >= random_read_wakeup_thresh)
++ if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)
+ mask |= POLLIN | POLLRDNORM;
+- if (input_pool.entropy_count < random_write_wakeup_thresh)
++ if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits)
+ mask |= POLLOUT | POLLWRNORM;
+ return mask;
+ }
+@@ -1297,7 +1398,8 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ switch (cmd) {
+ case RNDGETENTCNT:
+ /* inherently racy, no point locking */
+- if (put_user(input_pool.entropy_count, p))
++ ent_count = ENTROPY_BITS(&input_pool);
++ if (put_user(ent_count, p))
+ return -EFAULT;
+ return 0;
+ case RNDADDTOENTCNT:
+@@ -1305,7 +1407,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ return -EPERM;
+ if (get_user(ent_count, p))
+ return -EFAULT;
+- credit_entropy_bits(&input_pool, ent_count);
++ credit_entropy_bits_safe(&input_pool, ent_count);
+ return 0;
+ case RNDADDENTROPY:
+ if (!capable(CAP_SYS_ADMIN))
+@@ -1320,14 +1422,19 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ size);
+ if (retval < 0)
+ return retval;
+- credit_entropy_bits(&input_pool, ent_count);
++ credit_entropy_bits_safe(&input_pool, ent_count);
+ return 0;
+ case RNDZAPENTCNT:
+ case RNDCLEARPOOL:
+- /* Clear the entropy pool counters. */
++ /*
++ * Clear the entropy pool counters. We no longer clear
++ * the entropy pool, as that's silly.
++ */
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+- rand_initialize();
++ input_pool.entropy_count = 0;
++ nonblocking_pool.entropy_count = 0;
++ blocking_pool.entropy_count = 0;
+ return 0;
+ default:
+ return -EINVAL;
+@@ -1387,23 +1494,23 @@ EXPORT_SYMBOL(generate_random_uuid);
#include <linux/sysctl.h>
static int min_read_thresh = 8, min_write_thresh;
@@ -33857,8 +34995,21 @@ index c244f0e..255f226 100644
static int max_write_thresh = INPUT_POOL_WORDS * 32;
static char sysctl_bootid[16];
-@@ -1403,7 +1434,7 @@ static char sysctl_bootid[16];
- static int proc_do_uuid(ctl_table *table, int write,
+ /*
+- * These functions is used to return both the bootid UUID, and random
++ * This function is used to return both the bootid UUID, and random
+ * UUID. The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+- * If the user accesses this via the proc interface, it will be returned
+- * as an ASCII string in the standard UUID format. If accesses via the
+- * sysctl system call, it is returned as 16 bytes of binary data.
++ * If the user accesses this via the proc interface, the UUID will be
++ * returned as an ASCII string in the standard UUID format; if via the
++ * sysctl system call, as 16 bytes of binary data.
+ */
+-static int proc_do_uuid(ctl_table *table, int write,
++static int proc_do_uuid(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
- ctl_table fake_table;
@@ -33866,6 +35017,89 @@ index c244f0e..255f226 100644
unsigned char buf[64], tmp_uuid[16], *uuid;
uuid = table->data;
+@@ -1427,8 +1534,26 @@ static int proc_do_uuid(ctl_table *table, int write,
+ return proc_dostring(&fake_table, write, buffer, lenp, ppos);
+ }
+
++/*
++ * Return entropy available scaled to integral bits
++ */
++static int proc_do_entropy(ctl_table *table, int write,
++ void __user *buffer, size_t *lenp, loff_t *ppos)
++{
++ ctl_table_no_const fake_table;
++ int entropy_count;
++
++ entropy_count = *(int *)table->data >> ENTROPY_SHIFT;
++
++ fake_table.data = &entropy_count;
++ fake_table.maxlen = sizeof(entropy_count);
++
++ return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
++}
++
+ static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
+-ctl_table random_table[] = {
++extern struct ctl_table random_table[];
++struct ctl_table random_table[] = {
+ {
+ .procname = "poolsize",
+ .data = &sysctl_poolsize,
+@@ -1440,12 +1565,12 @@ ctl_table random_table[] = {
+ .procname = "entropy_avail",
+ .maxlen = sizeof(int),
+ .mode = 0444,
+- .proc_handler = proc_dointvec,
++ .proc_handler = proc_do_entropy,
+ .data = &input_pool.entropy_count,
+ },
+ {
+ .procname = "read_wakeup_threshold",
+- .data = &random_read_wakeup_thresh,
++ .data = &random_read_wakeup_bits,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+@@ -1454,7 +1579,7 @@ ctl_table random_table[] = {
+ },
+ {
+ .procname = "write_wakeup_threshold",
+- .data = &random_write_wakeup_thresh,
++ .data = &random_write_wakeup_bits,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+@@ -1462,6 +1587,13 @@ ctl_table random_table[] = {
+ .extra2 = &max_write_thresh,
+ },
+ {
++ .procname = "urandom_min_reseed_secs",
++ .data = &random_min_urandom_seed,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec,
++ },
++ {
+ .procname = "boot_id",
+ .data = &sysctl_bootid,
+ .maxlen = 16,
+@@ -1492,7 +1624,7 @@ int random_int_secret_init(void)
+ * value is not cryptographically secure but for several uses the cost of
+ * depleting entropy is too high
+ */
+-DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
++static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
+ unsigned int get_random_int(void)
+ {
+ __u32 *hash;
+@@ -1510,6 +1642,7 @@ unsigned int get_random_int(void)
+
+ return ret;
+ }
++EXPORT_SYMBOL(get_random_int);
+
+ /*
+ * randomize_range() returns a start address such that
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 1ee8ce7..b778bef 100644
--- a/drivers/char/sonypi.c
@@ -40112,6 +41346,20 @@ index a8c08f3..155fe3d 100644
INIT_LIST_HEAD(&c->context_list);
#endif
+diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
+index 4eec7b7..f468a4e 100644
+--- a/drivers/mfd/ab3100-core.c
++++ b/drivers/mfd/ab3100-core.c
+@@ -937,9 +937,6 @@ static int __devinit ab3100_probe(struct i2c_client *client,
+
+ err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
+ IRQF_ONESHOT, "ab3100-core", ab3100);
+- /* This real unpredictable IRQ is of course sampled for entropy */
+- rand_initialize_irq(client->irq);
+-
+ if (err)
+ goto exit_no_irq;
+
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 5c2a06a..8fa077c 100644
--- a/drivers/mfd/janz-cmodio.c
@@ -43476,6 +44724,28 @@ index dee1a09..24adab6 100644
break;
default:
return -EINVAL;
+diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
+index e7522dc..f585e84 100644
+--- a/drivers/scsi/fcoe/fcoe_ctlr.c
++++ b/drivers/scsi/fcoe/fcoe_ctlr.c
+@@ -2030,7 +2030,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
+ */
+ port_id = fip->port_id;
+ if (fip->probe_tries)
+- port_id = prandom32(&fip->rnd_state) & 0xffff;
++ port_id = prandom_u32_state(&fip->rnd_state) & 0xffff;
+ else if (!port_id)
+ port_id = fip->lp->wwpn & 0xffff;
+ if (!port_id || port_id == 0xffff)
+@@ -2055,7 +2055,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip)
+ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
+ {
+ fip->probe_tries = 0;
+- prandom32_seed(&fip->rnd_state, fip->lp->wwpn);
++ prandom_seed_state(&fip->rnd_state, fip->lp->wwpn);
+ fcoe_ctlr_vn_restart(fip);
+ }
+
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index ee77a58..af9d518 100644
--- a/drivers/scsi/hosts.c
@@ -65484,10 +66754,10 @@ index 0000000..25f54ef
+};
diff --git a/grsecurity/gracl_policy.c b/grsecurity/gracl_policy.c
new file mode 100644
-index 0000000..b1f3247
+index 0000000..b4a4084
--- /dev/null
+++ b/grsecurity/gracl_policy.c
-@@ -0,0 +1,1776 @@
+@@ -0,0 +1,1781 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -65946,12 +67216,12 @@ index 0000000..b1f3247
+ printk(KERN_ALERT "Obtained real root device=%d, inode=%lu\n", __get_dev(gr_real_root.dentry), gr_real_root.dentry->d_inode->i_ino);
+#endif
+
-+ fakefs_obj_rw = acl_alloc(sizeof(struct acl_object_label));
++ fakefs_obj_rw = kzalloc(sizeof(struct acl_object_label), GFP_KERNEL);
+ if (fakefs_obj_rw == NULL)
+ return 1;
+ fakefs_obj_rw->mode = GR_FIND | GR_READ | GR_WRITE;
+
-+ fakefs_obj_rwx = acl_alloc(sizeof(struct acl_object_label));
++ fakefs_obj_rwx = kzalloc(sizeof(struct acl_object_label), GFP_KERNEL);
+ if (fakefs_obj_rwx == NULL)
+ return 1;
+ fakefs_obj_rwx->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
@@ -66029,6 +67299,11 @@ index 0000000..b1f3247
+ } while_each_thread(task2, task);
+ read_unlock(&tasklist_lock);
+
++ kfree(fakefs_obj_rw);
++ fakefs_obj_rw = NULL;
++ kfree(fakefs_obj_rwx);
++ fakefs_obj_rwx = NULL;
++
+ /* release the reference to the real root dentry and vfsmount */
+ path_put(&gr_real_root);
+ memset(&gr_real_root, 0, sizeof(gr_real_root));
@@ -74322,6 +75597,18 @@ index bff29c5..7437762 100644
/*
* irq_chip specific flags
+diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
+index f1e2527..9a323d1 100644
+--- a/include/linux/irqdesc.h
++++ b/include/linux/irqdesc.h
+@@ -39,7 +39,6 @@ struct module;
+ */
+ struct irq_desc {
+ struct irq_data irq_data;
+- struct timer_rand_state *timer_rand_state;
+ unsigned int __percpu *kstat_irqs;
+ irq_flow_handler_t handle_irq;
+ #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 265e2c3..cdd6f29 100644
--- a/include/linux/jiffies.h
@@ -75713,12 +77000,23 @@ index 800f113..13b3715 100644
}
diff --git a/include/linux/random.h b/include/linux/random.h
-index 7e77cee..207b34e 100644
+index 7e77cee..c8a8a43 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
-@@ -51,9 +51,19 @@ struct rnd_state {
- extern void rand_initialize_irq(int irq);
+@@ -41,19 +41,27 @@ struct rand_pool_info {
+ };
+
+ struct rnd_state {
+- __u32 s1, s2, s3;
++ __u32 s1, s2, s3, s4;
+ };
+
+ /* Exported functions */
+
+ #ifdef __KERNEL__
+-extern void rand_initialize_irq(int irq);
+-
extern void add_device_randomness(const void *, unsigned int);
+
+static inline void add_latent_entropy(void)
@@ -75738,25 +77036,71 @@ index 7e77cee..207b34e 100644
extern void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes_arch(void *buf, int nbytes);
-@@ -72,12 +82,17 @@ void srandom32(u32 seed);
-
- u32 prandom32(struct rnd_state *);
-
+@@ -67,10 +75,25 @@ extern const struct file_operations random_fops, urandom_fops;
+ unsigned int get_random_int(void);
+ unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len);
+
+-u32 random32(void);
+-void srandom32(u32 seed);
++u32 prandom_u32(void);
++void prandom_bytes(void *buf, int nbytes);
++void prandom_seed(u32 seed);
++void prandom_reseed_late(void);
+
+-u32 prandom32(struct rnd_state *);
++/*
++ * These macros are preserved for backward compatibility and should be
++ * removed as soon as a transition is finished.
++ */
++#define random32() prandom_u32()
++#define srandom32(seed) prandom_seed(seed)
++
++u32 prandom_u32_state(struct rnd_state *state);
++void prandom_bytes_state(struct rnd_state *state, void *buf, int nbytes);
++
+static inline unsigned long pax_get_random_long(void)
+{
+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
+}
-+
+
/*
* Handle minimum values for seeds
+@@ -81,17 +104,18 @@ static inline u32 __seed(u32 x, u32 m)
+ }
+
+ /**
+- * prandom32_seed - set seed for prandom32().
++ * prandom_seed_state - set seed for prandom_u32_state().
+ * @state: pointer to state structure to receive the seed.
+ * @seed: arbitrary 64-bit value to use as a seed.
*/
- static inline u32 __seed(u32 x, u32 m)
+-static inline void prandom32_seed(struct rnd_state *state, u64 seed)
++static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
{
-- return (x < m) ? x + m : x;
-+ return (x <= m) ? x + m + 1 : x;
+ u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
+
+- state->s1 = __seed(i, 1);
+- state->s2 = __seed(i, 7);
+- state->s3 = __seed(i, 15);
++ state->s1 = __seed(i, 2U);
++ state->s2 = __seed(i, 8U);
++ state->s3 = __seed(i, 16U);
++ state->s4 = __seed(i, 128U);
}
- /**
+ #ifdef CONFIG_ARCH_RANDOM
+@@ -107,6 +131,11 @@ static inline int arch_get_random_int(unsigned int *v)
+ }
+ #endif
+
++static inline u32 next_pseudo_random32(u32 seed)
++{
++ return seed * 1664525 + 1013904223;
++}
++
+ #endif /* __KERNEL___ */
+
+ #endif /* _LINUX_RANDOM_H */
diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 3863352..4ec4bfb 100644
--- a/include/linux/rculist.h
@@ -78403,6 +79747,327 @@ index 1c09820..7f5ec79 100644
TP_ARGS(irq, action, ret),
+diff --git a/include/trace/events/random.h b/include/trace/events/random.h
+new file mode 100644
+index 0000000..805af6d
+--- /dev/null
++++ b/include/trace/events/random.h
+@@ -0,0 +1,315 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM random
++
++#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_RANDOM_H
++
++#include <linux/writeback.h>
++#include <linux/tracepoint.h>
++
++TRACE_EVENT(add_device_randomness,
++ TP_PROTO(int bytes, unsigned long IP),
++
++ TP_ARGS(bytes, IP),
++
++ TP_STRUCT__entry(
++ __field( int, bytes )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->bytes = bytes;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("bytes %d caller %pF",
++ __entry->bytes, (void *)__entry->IP)
++);
++
++DECLARE_EVENT_CLASS(random__mix_pool_bytes,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, bytes )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->bytes = bytes;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: bytes %d caller %pF",
++ __entry->pool_name, __entry->bytes, (void *)__entry->IP)
++);
++
++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP)
++);
++
++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP)
++);
++
++TRACE_EVENT(credit_entropy_bits,
++ TP_PROTO(const char *pool_name, int bits, int entropy_count,
++ int entropy_total, unsigned long IP),
++
++ TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, bits )
++ __field( int, entropy_count )
++ __field( int, entropy_total )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->bits = bits;
++ __entry->entropy_count = entropy_count;
++ __entry->entropy_total = entropy_total;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
++ "caller %pF", __entry->pool_name, __entry->bits,
++ __entry->entropy_count, __entry->entropy_total,
++ (void *)__entry->IP)
++);
++
++TRACE_EVENT(push_to_pool,
++ TP_PROTO(const char *pool_name, int pool_bits, int input_bits),
++
++ TP_ARGS(pool_name, pool_bits, input_bits),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, pool_bits )
++ __field( int, input_bits )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->pool_bits = pool_bits;
++ __entry->input_bits = input_bits;
++ ),
++
++ TP_printk("%s: pool_bits %d input_pool_bits %d",
++ __entry->pool_name, __entry->pool_bits,
++ __entry->input_bits)
++);
++
++TRACE_EVENT(debit_entropy,
++ TP_PROTO(const char *pool_name, int debit_bits),
++
++ TP_ARGS(pool_name, debit_bits),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, debit_bits )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->debit_bits = debit_bits;
++ ),
++
++ TP_printk("%s: debit_bits %d", __entry->pool_name,
++ __entry->debit_bits)
++);
++
++TRACE_EVENT(add_input_randomness,
++ TP_PROTO(int input_bits),
++
++ TP_ARGS(input_bits),
++
++ TP_STRUCT__entry(
++ __field( int, input_bits )
++ ),
++
++ TP_fast_assign(
++ __entry->input_bits = input_bits;
++ ),
++
++ TP_printk("input_pool_bits %d", __entry->input_bits)
++);
++
++TRACE_EVENT(add_disk_randomness,
++ TP_PROTO(dev_t dev, int input_bits),
++
++ TP_ARGS(dev, input_bits),
++
++ TP_STRUCT__entry(
++ __field( dev_t, dev )
++ __field( int, input_bits )
++ ),
++
++ TP_fast_assign(
++ __entry->dev = dev;
++ __entry->input_bits = input_bits;
++ ),
++
++ TP_printk("dev %d,%d input_pool_bits %d", MAJOR(__entry->dev),
++ MINOR(__entry->dev), __entry->input_bits)
++);
++
++TRACE_EVENT(xfer_secondary_pool,
++ TP_PROTO(const char *pool_name, int xfer_bits, int request_bits,
++ int pool_entropy, int input_entropy),
++
++ TP_ARGS(pool_name, xfer_bits, request_bits, pool_entropy,
++ input_entropy),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, xfer_bits )
++ __field( int, request_bits )
++ __field( int, pool_entropy )
++ __field( int, input_entropy )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->xfer_bits = xfer_bits;
++ __entry->request_bits = request_bits;
++ __entry->pool_entropy = pool_entropy;
++ __entry->input_entropy = input_entropy;
++ ),
++
++ TP_printk("pool %s xfer_bits %d request_bits %d pool_entropy %d "
++ "input_entropy %d", __entry->pool_name, __entry->xfer_bits,
++ __entry->request_bits, __entry->pool_entropy,
++ __entry->input_entropy)
++);
++
++DECLARE_EVENT_CLASS(random__get_random_bytes,
++ TP_PROTO(int nbytes, unsigned long IP),
++
++ TP_ARGS(nbytes, IP),
++
++ TP_STRUCT__entry(
++ __field( int, nbytes )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->nbytes = nbytes;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP)
++);
++
++DEFINE_EVENT(random__get_random_bytes, get_random_bytes,
++ TP_PROTO(int nbytes, unsigned long IP),
++
++ TP_ARGS(nbytes, IP)
++);
++
++DEFINE_EVENT(random__get_random_bytes, get_random_bytes_arch,
++ TP_PROTO(int nbytes, unsigned long IP),
++
++ TP_ARGS(nbytes, IP)
++);
++
++DECLARE_EVENT_CLASS(random__extract_entropy,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, nbytes )
++ __field( int, entropy_count )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->nbytes = nbytes;
++ __entry->entropy_count = entropy_count;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: nbytes %d entropy_count %d caller %pF",
++ __entry->pool_name, __entry->nbytes, __entry->entropy_count,
++ (void *)__entry->IP)
++);
++
++
++DEFINE_EVENT(random__extract_entropy, extract_entropy,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP)
++);
++
++DEFINE_EVENT(random__extract_entropy, extract_entropy_user,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP)
++);
++
++TRACE_EVENT(random_read,
++ TP_PROTO(int got_bits, int need_bits, int pool_left, int input_left),
++
++ TP_ARGS(got_bits, need_bits, pool_left, input_left),
++
++ TP_STRUCT__entry(
++ __field( int, got_bits )
++ __field( int, need_bits )
++ __field( int, pool_left )
++ __field( int, input_left )
++ ),
++
++ TP_fast_assign(
++ __entry->got_bits = got_bits;
++ __entry->need_bits = need_bits;
++ __entry->pool_left = pool_left;
++ __entry->input_left = input_left;
++ ),
++
++ TP_printk("got_bits %d still_needed_bits %d "
++ "blocking_pool_entropy_left %d input_entropy_left %d",
++ __entry->got_bits, __entry->got_bits, __entry->pool_left,
++ __entry->input_left)
++);
++
++TRACE_EVENT(urandom_read,
++ TP_PROTO(int got_bits, int pool_left, int input_left),
++
++ TP_ARGS(got_bits, pool_left, input_left),
++
++ TP_STRUCT__entry(
++ __field( int, got_bits )
++ __field( int, pool_left )
++ __field( int, input_left )
++ ),
++
++ TP_fast_assign(
++ __entry->got_bits = got_bits;
++ __entry->pool_left = pool_left;
++ __entry->input_left = input_left;
++ ),
++
++ TP_printk("got_bits %d nonblocking_pool_entropy_left %d "
++ "input_entropy_left %d", __entry->got_bits,
++ __entry->pool_left, __entry->input_left)
++);
++
++#endif /* _TRACE_RANDOM_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index c41f308..6918de3 100644
--- a/include/video/udlfb.h
@@ -80547,7 +82212,7 @@ index ce0c182..c6ec99a 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index 1d0538e..04de80f 100644
+index 1d0538e..9a6f6fb 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -80570,6 +82235,15 @@ index 1d0538e..04de80f 100644
/*
* The futex address must be "naturally" aligned.
*/
+@@ -285,7 +291,7 @@ again:
+ put_page(page);
+ /* serialize against __split_huge_page_splitting() */
+ local_irq_disable();
+- if (likely(__get_user_pages_fast(address, 1, 1, &page) == 1)) {
++ if (likely(__get_user_pages_fast(address, 1, !ro, &page) == 1)) {
+ page_head = compound_head(page);
+ /*
+ * page_head is valid pointer but we must pin
@@ -438,7 +444,7 @@ static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr,
static int get_futex_value_locked(u32 *dest, u32 __user *from)
@@ -80659,6 +82333,41 @@ index 60f7e32..d703ad4 100644
.notifier_call = hrtimer_cpu_notify,
};
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 52bdd58..56002b5 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -900,22 +900,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+ return -ENOSYS;
+ if (!try_module_get(desc->owner))
+ return -ENODEV;
+- /*
+- * Some drivers like serial.c use request_irq() heavily,
+- * so we have to be careful not to interfere with a
+- * running system.
+- */
+- if (new->flags & IRQF_SAMPLE_RANDOM) {
+- /*
+- * This function might sleep, we want to call it first,
+- * outside of the atomic block.
+- * Yes, this might clear the entropy pool if the wrong
+- * driver is attempted to be loaded, without actually
+- * installing a new handler, but is this really a problem,
+- * only the sysadmin is able to do this.
+- */
+- rand_initialize_irq(irq);
+- }
+
+ /*
+ * Check whether the interrupt nests into another interrupt
+@@ -1361,7 +1345,6 @@ EXPORT_SYMBOL(free_irq);
+ * Flags:
+ *
+ * IRQF_SHARED Interrupt is shared
+- * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
+ * IRQF_TRIGGER_* Specify active edge(s) or level
+ *
+ */
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 66ff710..794bc5a 100644
--- a/kernel/jump_label.c
@@ -86308,6 +88017,495 @@ index d9df745..e73c2fe 100644
static inline void *ptr_to_indirect(void *ptr)
{
+diff --git a/lib/random32.c b/lib/random32.c
+index fc3545a..1e5b2df 100644
+--- a/lib/random32.c
++++ b/lib/random32.c
+@@ -2,19 +2,19 @@
+ This is a maximally equidistributed combined Tausworthe generator
+ based on code from GNU Scientific Library 1.5 (30 Jun 2004)
+
+- x_n = (s1_n ^ s2_n ^ s3_n)
++ lfsr113 version:
+
+- s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
+- s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
+- s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
++ x_n = (s1_n ^ s2_n ^ s3_n ^ s4_n)
+
+- The period of this generator is about 2^88.
++ s1_{n+1} = (((s1_n & 4294967294) << 18) ^ (((s1_n << 6) ^ s1_n) >> 13))
++ s2_{n+1} = (((s2_n & 4294967288) << 2) ^ (((s2_n << 2) ^ s2_n) >> 27))
++ s3_{n+1} = (((s3_n & 4294967280) << 7) ^ (((s3_n << 13) ^ s3_n) >> 21))
++ s4_{n+1} = (((s4_n & 4294967168) << 13) ^ (((s4_n << 3) ^ s4_n) >> 12))
++
++ The period of this generator is about 2^113 (see erratum paper).
+
+ From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
+- Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
+-
+- This is available on the net from L'Ecuyer's home page,
+-
++ Generators", Mathematics of Computation, 65, 213 (1996), 203--213:
+ http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
+ ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
+
+@@ -29,61 +29,148 @@
+ that paper.)
+
+ This affects the seeding procedure by imposing the requirement
+- s1 > 1, s2 > 7, s3 > 15.
++ s1 > 1, s2 > 7, s3 > 15, s4 > 127.
+
+ */
+
+ #include <linux/types.h>
+ #include <linux/percpu.h>
+-#include <linux/module.h>
++#include <linux/export.h>
+ #include <linux/jiffies.h>
+ #include <linux/random.h>
++#include <linux/sched.h>
++
++#ifdef CONFIG_RANDOM32_SELFTEST
++static void __init prandom_state_selftest(void);
++#endif
+
+ static DEFINE_PER_CPU(struct rnd_state, net_rand_state);
+
+ /**
+- * prandom32 - seeded pseudo-random number generator.
++ * prandom_u32_state - seeded pseudo-random number generator.
+ * @state: pointer to state structure holding seeded state.
+ *
+ * This is used for pseudo-randomness with no outside seeding.
+- * For more random results, use random32().
++ * For more random results, use prandom_u32().
+ */
+-u32 prandom32(struct rnd_state *state)
++u32 prandom_u32_state(struct rnd_state *state)
+ {
+ #define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
+
+- state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
+- state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
+- state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
++ state->s1 = TAUSWORTHE(state->s1, 6U, 13U, 4294967294U, 18U);
++ state->s2 = TAUSWORTHE(state->s2, 2U, 27U, 4294967288U, 2U);
++ state->s3 = TAUSWORTHE(state->s3, 13U, 21U, 4294967280U, 7U);
++ state->s4 = TAUSWORTHE(state->s4, 3U, 12U, 4294967168U, 13U);
+
+- return (state->s1 ^ state->s2 ^ state->s3);
++ return (state->s1 ^ state->s2 ^ state->s3 ^ state->s4);
+ }
+-EXPORT_SYMBOL(prandom32);
++EXPORT_SYMBOL(prandom_u32_state);
+
+ /**
+- * random32 - pseudo random number generator
++ * prandom_u32 - pseudo random number generator
+ *
+ * A 32 bit pseudo-random number is generated using a fast
+ * algorithm suitable for simulation. This algorithm is NOT
+ * considered safe for cryptographic use.
+ */
+-u32 random32(void)
++u32 prandom_u32(void)
+ {
+ unsigned long r;
+ struct rnd_state *state = &get_cpu_var(net_rand_state);
+- r = prandom32(state);
++ r = prandom_u32_state(state);
+ put_cpu_var(state);
+ return r;
+ }
+-EXPORT_SYMBOL(random32);
++EXPORT_SYMBOL(prandom_u32);
++
++/*
++ * prandom_bytes_state - get the requested number of pseudo-random bytes
++ *
++ * @state: pointer to state structure holding seeded state.
++ * @buf: where to copy the pseudo-random bytes to
++ * @bytes: the requested number of bytes
++ *
++ * This is used for pseudo-randomness with no outside seeding.
++ * For more random results, use prandom_bytes().
++ */
++void prandom_bytes_state(struct rnd_state *state, void *buf, int bytes)
++{
++ unsigned char *p = buf;
++ int i;
++
++ for (i = 0; i < round_down(bytes, sizeof(u32)); i += sizeof(u32)) {
++ u32 random = prandom_u32_state(state);
++ int j;
++
++ for (j = 0; j < sizeof(u32); j++) {
++ p[i + j] = random;
++ random >>= BITS_PER_BYTE;
++ }
++ }
++ if (i < bytes) {
++ u32 random = prandom_u32_state(state);
++
++ for (; i < bytes; i++) {
++ p[i] = random;
++ random >>= BITS_PER_BYTE;
++ }
++ }
++}
++EXPORT_SYMBOL(prandom_bytes_state);
++
++/**
++ * prandom_bytes - get the requested number of pseudo-random bytes
++ * @buf: where to copy the pseudo-random bytes to
++ * @bytes: the requested number of bytes
++ */
++void prandom_bytes(void *buf, int bytes)
++{
++ struct rnd_state *state = &get_cpu_var(net_rand_state);
++
++ prandom_bytes_state(state, buf, bytes);
++ put_cpu_var(state);
++}
++EXPORT_SYMBOL(prandom_bytes);
++
++static void prandom_warmup(struct rnd_state *state)
++{
++ /* Calling RNG ten times to satify recurrence condition */
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++ prandom_u32_state(state);
++}
++
++static void prandom_seed_very_weak(struct rnd_state *state, u32 seed)
++{
++ /* Note: This sort of seeding is ONLY used in test cases and
++ * during boot at the time from core_initcall until late_initcall
++ * as we don't have a stronger entropy source available yet.
++ * After late_initcall, we reseed entire state, we have to (!),
++ * otherwise an attacker just needs to search 32 bit space to
++ * probe for our internal 128 bit state if he knows a couple
++ * of prandom32 outputs!
++ */
++#define LCG(x) ((x) * 69069U) /* super-duper LCG */
++ state->s1 = __seed(LCG(seed), 2U);
++ state->s2 = __seed(LCG(state->s1), 8U);
++ state->s3 = __seed(LCG(state->s2), 16U);
++ state->s4 = __seed(LCG(state->s3), 128U);
++}
+
+ /**
+- * srandom32 - add entropy to pseudo random number generator
++ * prandom_seed - add entropy to pseudo random number generator
+ * @seed: seed value
+ *
+- * Add some additional seeding to the random32() pool.
++ * Add some additional seeding to the prandom pool.
+ */
+-void srandom32(u32 entropy)
++void prandom_seed(u32 entropy)
+ {
+ int i;
+ /*
+@@ -92,59 +179,264 @@ void srandom32(u32 entropy)
+ */
+ for_each_possible_cpu (i) {
+ struct rnd_state *state = &per_cpu(net_rand_state, i);
+- state->s1 = __seed(state->s1 ^ entropy, 1);
++
++ state->s1 = __seed(state->s1 ^ entropy, 2U);
++ prandom_warmup(state);
+ }
+ }
+-EXPORT_SYMBOL(srandom32);
++EXPORT_SYMBOL(prandom_seed);
+
+ /*
+ * Generate some initially weak seeding values to allow
+- * to start the random32() engine.
++ * to start the prandom_u32() engine.
+ */
+-static int __init random32_init(void)
++static int __init prandom_init(void)
+ {
+ int i;
+
++#ifdef CONFIG_RANDOM32_SELFTEST
++ prandom_state_selftest();
++#endif
++
+ for_each_possible_cpu(i) {
+ struct rnd_state *state = &per_cpu(net_rand_state,i);
+
+-#define LCG(x) ((x) * 69069) /* super-duper LCG */
+- state->s1 = __seed(LCG(i + jiffies), 1);
+- state->s2 = __seed(LCG(state->s1), 7);
+- state->s3 = __seed(LCG(state->s2), 15);
+-
+- /* "warm it up" */
+- prandom32(state);
+- prandom32(state);
+- prandom32(state);
+- prandom32(state);
+- prandom32(state);
+- prandom32(state);
++ prandom_seed_very_weak(state, (i + jiffies) ^ random_get_entropy());
++ prandom_warmup(state);
+ }
+ return 0;
+ }
+-core_initcall(random32_init);
++core_initcall(prandom_init);
++
++static void __prandom_timer(unsigned long dontcare);
++static DEFINE_TIMER(seed_timer, __prandom_timer, 0, 0);
++
++static void __prandom_timer(unsigned long dontcare)
++{
++ u32 entropy;
++ unsigned long expires;
++
++ get_random_bytes(&entropy, sizeof(entropy));
++ prandom_seed(entropy);
++
++ /* reseed every ~60 seconds, in [40 .. 80) interval with slack */
++ expires = 40 + (prandom_u32() % 40);
++ seed_timer.expires = jiffies + msecs_to_jiffies(expires * MSEC_PER_SEC);
++
++ add_timer(&seed_timer);
++}
++
++static void __init __prandom_start_seed_timer(void)
++{
++ set_timer_slack(&seed_timer, HZ);
++ seed_timer.expires = jiffies + msecs_to_jiffies(40 * MSEC_PER_SEC);
++ add_timer(&seed_timer);
++}
+
+ /*
+ * Generate better values after random number generator
+ * is fully initialized.
+ */
+-static int __init random32_reseed(void)
++static void __prandom_reseed(bool late)
+ {
+ int i;
++ unsigned long flags;
++ static bool latch = false;
++ static DEFINE_SPINLOCK(lock);
++
++ /* only allow initial seeding (late == false) once */
++ spin_lock_irqsave(&lock, flags);
++ if (latch && !late)
++ goto out;
++ latch = true;
+
+ for_each_possible_cpu(i) {
+ struct rnd_state *state = &per_cpu(net_rand_state,i);
+- u32 seeds[3];
++ u32 seeds[4];
+
+ get_random_bytes(&seeds, sizeof(seeds));
+- state->s1 = __seed(seeds[0], 1);
+- state->s2 = __seed(seeds[1], 7);
+- state->s3 = __seed(seeds[2], 15);
++ state->s1 = __seed(seeds[0], 2U);
++ state->s2 = __seed(seeds[1], 8U);
++ state->s3 = __seed(seeds[2], 16U);
++ state->s4 = __seed(seeds[3], 128U);
+
+- /* mix it in */
+- prandom32(state);
++ prandom_warmup(state);
+ }
++out:
++ spin_unlock_irqrestore(&lock, flags);
++}
++
++void prandom_reseed_late(void)
++{
++ __prandom_reseed(true);
++}
++
++static int __init prandom_reseed(void)
++{
++ __prandom_reseed(false);
++ __prandom_start_seed_timer();
+ return 0;
+ }
+-late_initcall(random32_reseed);
++late_initcall(prandom_reseed);
++
++#ifdef CONFIG_RANDOM32_SELFTEST
++static struct prandom_test1 {
++ u32 seed;
++ u32 result;
++} test1[] = {
++ { 1U, 3484351685U },
++ { 2U, 2623130059U },
++ { 3U, 3125133893U },
++ { 4U, 984847254U },
++};
++
++static struct prandom_test2 {
++ u32 seed;
++ u32 iteration;
++ u32 result;
++} test2[] = {
++ /* Test cases against taus113 from GSL library. */
++ { 931557656U, 959U, 2975593782U },
++ { 1339693295U, 876U, 3887776532U },
++ { 1545556285U, 961U, 1615538833U },
++ { 601730776U, 723U, 1776162651U },
++ { 1027516047U, 687U, 511983079U },
++ { 416526298U, 700U, 916156552U },
++ { 1395522032U, 652U, 2222063676U },
++ { 366221443U, 617U, 2992857763U },
++ { 1539836965U, 714U, 3783265725U },
++ { 556206671U, 994U, 799626459U },
++ { 684907218U, 799U, 367789491U },
++ { 2121230701U, 931U, 2115467001U },
++ { 1668516451U, 644U, 3620590685U },
++ { 768046066U, 883U, 2034077390U },
++ { 1989159136U, 833U, 1195767305U },
++ { 536585145U, 996U, 3577259204U },
++ { 1008129373U, 642U, 1478080776U },
++ { 1740775604U, 939U, 1264980372U },
++ { 1967883163U, 508U, 10734624U },
++ { 1923019697U, 730U, 3821419629U },
++ { 442079932U, 560U, 3440032343U },
++ { 1961302714U, 845U, 841962572U },
++ { 2030205964U, 962U, 1325144227U },
++ { 1160407529U, 507U, 240940858U },
++ { 635482502U, 779U, 4200489746U },
++ { 1252788931U, 699U, 867195434U },
++ { 1961817131U, 719U, 668237657U },
++ { 1071468216U, 983U, 917876630U },
++ { 1281848367U, 932U, 1003100039U },
++ { 582537119U, 780U, 1127273778U },
++ { 1973672777U, 853U, 1071368872U },
++ { 1896756996U, 762U, 1127851055U },
++ { 847917054U, 500U, 1717499075U },
++ { 1240520510U, 951U, 2849576657U },
++ { 1685071682U, 567U, 1961810396U },
++ { 1516232129U, 557U, 3173877U },
++ { 1208118903U, 612U, 1613145022U },
++ { 1817269927U, 693U, 4279122573U },
++ { 1510091701U, 717U, 638191229U },
++ { 365916850U, 807U, 600424314U },
++ { 399324359U, 702U, 1803598116U },
++ { 1318480274U, 779U, 2074237022U },
++ { 697758115U, 840U, 1483639402U },
++ { 1696507773U, 840U, 577415447U },
++ { 2081979121U, 981U, 3041486449U },
++ { 955646687U, 742U, 3846494357U },
++ { 1250683506U, 749U, 836419859U },
++ { 595003102U, 534U, 366794109U },
++ { 47485338U, 558U, 3521120834U },
++ { 619433479U, 610U, 3991783875U },
++ { 704096520U, 518U, 4139493852U },
++ { 1712224984U, 606U, 2393312003U },
++ { 1318233152U, 922U, 3880361134U },
++ { 855572992U, 761U, 1472974787U },
++ { 64721421U, 703U, 683860550U },
++ { 678931758U, 840U, 380616043U },
++ { 692711973U, 778U, 1382361947U },
++ { 677703619U, 530U, 2826914161U },
++ { 92393223U, 586U, 1522128471U },
++ { 1222592920U, 743U, 3466726667U },
++ { 358288986U, 695U, 1091956998U },
++ { 1935056945U, 958U, 514864477U },
++ { 735675993U, 990U, 1294239989U },
++ { 1560089402U, 897U, 2238551287U },
++ { 70616361U, 829U, 22483098U },
++ { 368234700U, 731U, 2913875084U },
++ { 20221190U, 879U, 1564152970U },
++ { 539444654U, 682U, 1835141259U },
++ { 1314987297U, 840U, 1801114136U },
++ { 2019295544U, 645U, 3286438930U },
++ { 469023838U, 716U, 1637918202U },
++ { 1843754496U, 653U, 2562092152U },
++ { 400672036U, 809U, 4264212785U },
++ { 404722249U, 965U, 2704116999U },
++ { 600702209U, 758U, 584979986U },
++ { 519953954U, 667U, 2574436237U },
++ { 1658071126U, 694U, 2214569490U },
++ { 420480037U, 749U, 3430010866U },
++ { 690103647U, 969U, 3700758083U },
++ { 1029424799U, 937U, 3787746841U },
++ { 2012608669U, 506U, 3362628973U },
++ { 1535432887U, 998U, 42610943U },
++ { 1330635533U, 857U, 3040806504U },
++ { 1223800550U, 539U, 3954229517U },
++ { 1322411537U, 680U, 3223250324U },
++ { 1877847898U, 945U, 2915147143U },
++ { 1646356099U, 874U, 965988280U },
++ { 805687536U, 744U, 4032277920U },
++ { 1948093210U, 633U, 1346597684U },
++ { 392609744U, 783U, 1636083295U },
++ { 690241304U, 770U, 1201031298U },
++ { 1360302965U, 696U, 1665394461U },
++ { 1220090946U, 780U, 1316922812U },
++ { 447092251U, 500U, 3438743375U },
++ { 1613868791U, 592U, 828546883U },
++ { 523430951U, 548U, 2552392304U },
++ { 726692899U, 810U, 1656872867U },
++ { 1364340021U, 836U, 3710513486U },
++ { 1986257729U, 931U, 935013962U },
++ { 407983964U, 921U, 728767059U },
++};
++
++static void __init prandom_state_selftest(void)
++{
++ int i, j, errors = 0, runs = 0;
++ bool error = false;
++
++ for (i = 0; i < ARRAY_SIZE(test1); i++) {
++ struct rnd_state state;
++
++ prandom_seed_very_weak(&state, test1[i].seed);
++ prandom_warmup(&state);
++
++ if (test1[i].result != prandom_u32_state(&state))
++ error = true;
++ }
++
++ if (error)
++ pr_warn("prandom: seed boundary self test failed\n");
++ else
++ pr_info("prandom: seed boundary self test passed\n");
++
++ for (i = 0; i < ARRAY_SIZE(test2); i++) {
++ struct rnd_state state;
++
++ prandom_seed_very_weak(&state, test2[i].seed);
++ prandom_warmup(&state);
++
++ for (j = 0; j < test2[i].iteration - 1; j++)
++ prandom_u32_state(&state);
++
++ if (test2[i].result != prandom_u32_state(&state))
++ errors++;
++
++ runs++;
++ cond_resched();
++ }
++
++ if (errors)
++ pr_warn("prandom: %d/%d self tests failed\n", errors, runs);
++ else
++ pr_info("prandom: %d self tests passed\n", runs);
++}
++#endif
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d74c317..1170419 100644
--- a/lib/vsprintf.c
@@ -104362,10 +106560,10 @@ index 0000000..679b9ef
+}
diff --git a/tools/gcc/size_overflow_hash.data b/tools/gcc/size_overflow_hash.data
new file mode 100644
-index 0000000..0634465
+index 0000000..a77968d
--- /dev/null
+++ b/tools/gcc/size_overflow_hash.data
-@@ -0,0 +1,5990 @@
+@@ -0,0 +1,5989 @@
+intel_fake_agp_alloc_by_type_1 intel_fake_agp_alloc_by_type 1 1 NULL
+ocfs2_get_refcount_tree_3 ocfs2_get_refcount_tree 0 3 NULL
+storvsc_connect_to_vsp_22 storvsc_connect_to_vsp 2 22 NULL
@@ -106025,7 +108223,6 @@ index 0000000..0634465
+smk_write_cipso_17989 smk_write_cipso 3 17989 NULL
+ext4_num_overhead_clusters_18001 ext4_num_overhead_clusters 2 18001 NULL
+pvr2_v4l2_read_18006 pvr2_v4l2_read 3 18006 NULL
-+prandom32_18007 prandom32 0 18007 NULL
+alloc_rx_desc_ring_18016 alloc_rx_desc_ring 2 18016 NULL
+fill_read_18019 fill_read 0 18019 NULL
+o2hb_highest_node_18034 o2hb_highest_node 2 18034 NULL
@@ -114848,7 +117045,7 @@ index 547628e..74de9f2 100644
+
#endif
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
-index 8bf05f0..61ba256 100644
+index 8bf05f0..e097f17 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -75,12 +75,17 @@ LIST_HEAD(vm_list);
@@ -114949,7 +117146,17 @@ index 8bf05f0..61ba256 100644
.release = kvm_vcpu_release,
.unlocked_ioctl = kvm_vcpu_ioctl,
#ifdef CONFIG_COMPAT
-@@ -2177,7 +2185,7 @@ static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma)
+@@ -1683,6 +1691,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
+ int r;
+ struct kvm_vcpu *vcpu, *v;
+
++ if (id >= KVM_MAX_VCPUS)
++ return -EINVAL;
++
+ vcpu = kvm_arch_vcpu_create(kvm, id);
+ if (IS_ERR(vcpu))
+ return PTR_ERR(vcpu);
+@@ -2177,7 +2188,7 @@ static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
@@ -114958,7 +117165,7 @@ index 8bf05f0..61ba256 100644
.release = kvm_vm_release,
.unlocked_ioctl = kvm_vm_ioctl,
#ifdef CONFIG_COMPAT
-@@ -2275,7 +2283,7 @@ out:
+@@ -2275,7 +2286,7 @@ out:
return r;
}
@@ -114967,7 +117174,7 @@ index 8bf05f0..61ba256 100644
.unlocked_ioctl = kvm_dev_ioctl,
.compat_ioctl = kvm_dev_ioctl,
.llseek = noop_llseek,
-@@ -2301,7 +2309,7 @@ static void hardware_enable_nolock(void *junk)
+@@ -2301,7 +2312,7 @@ static void hardware_enable_nolock(void *junk)
if (r) {
cpumask_clear_cpu(cpu, cpus_hardware_enabled);
@@ -114976,7 +117183,7 @@ index 8bf05f0..61ba256 100644
printk(KERN_INFO "kvm: enabling virtualization on "
"CPU%d failed\n", cpu);
}
-@@ -2355,10 +2363,10 @@ static int hardware_enable_all(void)
+@@ -2355,10 +2366,10 @@ static int hardware_enable_all(void)
kvm_usage_count++;
if (kvm_usage_count == 1) {
@@ -114989,7 +117196,7 @@ index 8bf05f0..61ba256 100644
hardware_disable_all_nolock();
r = -EBUSY;
}
-@@ -2709,7 +2717,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
+@@ -2709,7 +2720,7 @@ static void kvm_sched_out(struct preempt_notifier *pn,
kvm_arch_vcpu_put(vcpu);
}
@@ -114998,7 +117205,7 @@ index 8bf05f0..61ba256 100644
struct module *module)
{
int r;
-@@ -2772,7 +2780,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -2772,7 +2783,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
if (!vcpu_align)
vcpu_align = __alignof__(struct kvm_vcpu);
kvm_vcpu_cache = kmem_cache_create("kvm_vcpu", vcpu_size, vcpu_align,
@@ -115007,7 +117214,7 @@ index 8bf05f0..61ba256 100644
if (!kvm_vcpu_cache) {
r = -ENOMEM;
goto out_free_3;
-@@ -2782,9 +2790,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -2782,9 +2793,11 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
if (r)
goto out_free;
@@ -115019,7 +117226,7 @@ index 8bf05f0..61ba256 100644
r = misc_register(&kvm_dev);
if (r) {
-@@ -2794,9 +2804,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
+@@ -2794,9 +2807,6 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
register_syscore_ops(&kvm_syscore_ops);