diff options
-rw-r--r-- | 3.12.4/1003_linux-3.12.4.patch | 4725 | ||||
-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_README | 2 | ||||
-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 *) ð[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); |