public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/hardened-patchset:master commit in: 2.6.32/, 3.10.7/, 3.10.5/, 3.2.50/
@ 2013-08-18 14:10 Anthony G. Basile
  0 siblings, 0 replies; only message in thread
From: Anthony G. Basile @ 2013-08-18 14:10 UTC (permalink / raw
  To: gentoo-commits

commit:     c8f6f85ef12fe1c02fc3eadfa037bc47cc1cb122
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 18 14:09:47 2013 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Aug 18 14:09:47 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-patchset.git;a=commit;h=c8f6f85e

Grsec/PaX: 2.9.1-{2.6.32.61,3.2.50.3.10.7}-201308171249

---
 2.6.32/0000_README                                 |    2 +-
 ..._grsecurity-2.9.1-2.6.32.61-201308171247.patch} |  102 +-
 {3.10.5 => 3.10.7}/0000_README                     |    2 +-
 ...4420_grsecurity-2.9.1-3.10.7-201308171249.patch | 4304 +++++++++++++++++---
 {3.10.5 => 3.10.7}/4425_grsec_remove_EI_PAX.patch  |    0
 .../4427_force_XATTR_PAX_tmpfs.patch               |    0
 .../4430_grsec-remove-localversion-grsec.patch     |    0
 {3.10.5 => 3.10.7}/4435_grsec-mute-warnings.patch  |    0
 .../4440_grsec-remove-protected-paths.patch        |    0
 .../4450_grsec-kconfig-default-gids.patch          |    0
 .../4465_selinux-avc_audit-log-curr_ip.patch       |    0
 {3.10.5 => 3.10.7}/4470_disable-compat_vdso.patch  |    0
 {3.10.5 => 3.10.7}/4475_emutramp_default_on.patch  |    0
 3.2.50/0000_README                                 |    2 +-
 ...420_grsecurity-2.9.1-3.2.50-201308171247.patch} |  598 ++-
 15 files changed, 4223 insertions(+), 787 deletions(-)

diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index 53f88d5..e3fc2d2 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -38,7 +38,7 @@ Patch:	1060_linux-2.6.32.61.patch
 From:	http://www.kernel.org
 Desc:	Linux 2.6.32.61
 
-Patch:	4420_grsecurity-2.9.1-2.6.32.61-201308052140.patch
+Patch:	4420_grsecurity-2.9.1-2.6.32.61-201308171247.patch
 From:	http://www.grsecurity.net
 Desc:	hardened-sources base patch from upstream grsecurity
 

diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308052140.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308171247.patch
similarity index 99%
rename from 2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308052140.patch
rename to 2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308171247.patch
index 7620046..0348734 100644
--- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308052140.patch
+++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.61-201308171247.patch
@@ -8679,17 +8679,19 @@ index 43b0da9..f9f9985 100644
  	 * load/store/atomic was a write or not, it only says that there
  	 * was no match.  So in such a case we (carefully) read the
 diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
-index f27d103..7688136 100644
+index f27d103..9f5fc4f 100644
 --- a/arch/sparc/mm/hugetlbpage.c
 +++ b/arch/sparc/mm/hugetlbpage.c
-@@ -36,6 +36,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+@@ -30,7 +30,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+ 							unsigned long addr,
+ 							unsigned long len,
+ 							unsigned long pgoff,
+-							unsigned long flags)
++							unsigned long flags,
++							unsigned long offset)
+ {
+ 	struct mm_struct *mm = current->mm;
  	struct vm_area_struct * vma;
- 	unsigned long task_size = TASK_SIZE;
- 	unsigned long start_addr;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
- 
- 	if (test_thread_flag(TIF_32BIT))
- 		task_size = STACK_TOP32;
 @@ -69,7 +70,7 @@ full_search:
  			}
  			return -ENOMEM;
@@ -8699,14 +8701,16 @@ index f27d103..7688136 100644
  			/*
  			 * Remember the place where we stopped the search:
  			 */
-@@ -92,6 +93,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+@@ -87,7 +88,8 @@ static unsigned long
+ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 				  const unsigned long len,
+ 				  const unsigned long pgoff,
+-				  const unsigned long flags)
++				  const unsigned long flags,
++				  const unsigned long offset)
+ {
  	struct vm_area_struct *vma;
  	struct mm_struct *mm = current->mm;
- 	unsigned long addr = addr0;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
- 
- 	/* This should only ever run for 32-bit processes.  */
- 	BUG_ON(!test_thread_flag(TIF_32BIT));
 @@ -107,26 +109,28 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
  
  	/* make sure it can fit in the remaining address space */
@@ -8756,11 +8760,11 @@ index f27d103..7688136 100644
  	struct mm_struct *mm = current->mm;
  	struct vm_area_struct *vma;
  	unsigned long task_size = TASK_SIZE;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
++	unsigned long offset = gr_rand_threadstack_offset(mm, file, flags);
  
  	if (test_thread_flag(TIF_32BIT))
  		task_size = STACK_TOP32;
-@@ -183,8 +188,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+@@ -183,16 +188,15 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
  	if (addr) {
  		addr = ALIGN(addr, HPAGE_SIZE);
  		vma = find_vma(mm, addr);
@@ -8770,6 +8774,16 @@ index f27d103..7688136 100644
  			return addr;
  	}
  	if (mm->get_unmapped_area == arch_get_unmapped_area)
+ 		return hugetlb_get_unmapped_area_bottomup(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ 	else
+ 		return hugetlb_get_unmapped_area_topdown(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ }
+ 
+ pte_t *huge_pte_alloc(struct mm_struct *mm,
 diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
 index dc7c3b1..34c0070 100644
 --- a/arch/sparc/mm/init_32.c
@@ -77155,9 +77169,20 @@ index 20692fb..3b41113 100644
  	return 1;
  }
 diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
-index 42cec2a..2aba466 100644
+index 42cec2a..dfdf3d2 100644
 --- a/fs/cifs/cifs_debug.c
 +++ b/fs/cifs/cifs_debug.c
+@@ -242,8 +242,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
+ 
+ 	if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
+ #ifdef CONFIG_CIFS_STATS2
+-		atomic_set(&totBufAllocCount, 0);
+-		atomic_set(&totSmBufAllocCount, 0);
++		atomic_set_unchecked(&totBufAllocCount, 0);
++		atomic_set_unchecked(&totSmBufAllocCount, 0);
+ #endif /* CONFIG_CIFS_STATS2 */
+ 		read_lock(&cifs_tcp_ses_lock);
+ 		list_for_each(tmp1, &cifs_tcp_ses_list) {
 @@ -256,25 +256,25 @@ static ssize_t cifs_stats_proc_write(struct file *file,
  					tcon = list_entry(tmp3,
  							  struct cifsTconInfo,
@@ -77203,6 +77228,17 @@ index 42cec2a..2aba466 100644
  				}
  			}
  		}
+@@ -304,8 +304,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
+ 			smBufAllocCount.counter, cifs_min_small);
+ #ifdef CONFIG_CIFS_STATS2
+ 	seq_printf(m, "Total Large %d Small %d Allocations\n",
+-				atomic_read(&totBufAllocCount),
+-				atomic_read(&totSmBufAllocCount));
++				atomic_read_unchecked(&totBufAllocCount),
++				atomic_read_unchecked(&totSmBufAllocCount));
+ #endif /* CONFIG_CIFS_STATS2 */
+ 
+ 	seq_printf(m, "Operations (MIDs): %d\n", midCount.counter);
 @@ -334,41 +334,41 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
  				if (tcon->need_reconnect)
  					seq_puts(m, "\tDISCONNECTED ");
@@ -99712,7 +99748,7 @@ index 2333710..74767a7 100644
  		return false;
  
 diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
-index 7922742..27306a2 100644
+index 7922742..54e4350 100644
 --- a/include/linux/kallsyms.h
 +++ b/include/linux/kallsyms.h
 @@ -15,7 +15,8 @@
@@ -99725,18 +99761,22 @@ index 7922742..27306a2 100644
  /* Lookup the address for a symbol. Returns 0 if not found. */
  unsigned long kallsyms_lookup_name(const char *name);
  
-@@ -92,6 +93,15 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
+@@ -92,6 +93,19 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
  /* Stupid that this does nothing, but I didn't create this mess. */
  #define __print_symbol(fmt, addr)
  #endif /*CONFIG_KALLSYMS*/
-+#else /* when included by kallsyms.c, vsnprintf.c, or
++#else /* when included by kallsyms.c, vsnprintf.c, kprobes.c, or
 +	arch/x86/kernel/dumpstack.c, with HIDESYM enabled */
++extern unsigned long kallsyms_lookup_name(const char *name);
 +extern void __print_symbol(const char *fmt, unsigned long address);
 +extern int sprint_symbol(char *buffer, unsigned long address);
 +const char *kallsyms_lookup(unsigned long addr,
 +			    unsigned long *symbolsize,
 +			    unsigned long *offset,
 +			    char **modname, char *namebuf);
++extern int kallsyms_lookup_size_offset(unsigned long addr,
++				  unsigned long *symbolsize,
++				  unsigned long *offset);
 +#endif
  
  /* This macro allows us to keep printk typechecking */
@@ -105466,10 +105506,20 @@ index 8ecc509..98fcf05 100644
  		goto out;
  
 diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index 176d825..68c261a 100644
+index 176d825..af5d481 100644
 --- a/kernel/kprobes.c
 +++ b/kernel/kprobes.c
-@@ -183,7 +183,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(void)
+@@ -31,6 +31,9 @@
+  *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
+  *		<prasanna@in.ibm.com> added function-return probes.
+  */
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++#define __INCLUDED_BY_HIDESYM 1
++#endif
+ #include <linux/kprobes.h>
+ #include <linux/hash.h>
+ #include <linux/init.h>
+@@ -183,7 +186,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(void)
  	 * kernel image and loaded module images reside. This is required
  	 * so x86_64 can correctly handle the %rip-relative fixups.
  	 */
@@ -105478,7 +105528,7 @@ index 176d825..68c261a 100644
  	if (!kip->insns) {
  		kfree(kip);
  		return NULL;
-@@ -220,7 +220,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
+@@ -220,7 +223,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
  		 */
  		if (!list_is_singular(&kprobe_insn_pages)) {
  			list_del(&kip->list);
@@ -105487,7 +105537,7 @@ index 176d825..68c261a 100644
  			kfree(kip);
  		}
  		return 1;
-@@ -1189,7 +1189,7 @@ static int __init init_kprobes(void)
+@@ -1189,7 +1192,7 @@ static int __init init_kprobes(void)
  {
  	int i, err = 0;
  	unsigned long offset = 0, size = 0;
@@ -105496,7 +105546,7 @@ index 176d825..68c261a 100644
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
-@@ -1264,14 +1264,14 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
+@@ -1264,14 +1267,14 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
  	else
  		kprobe_type = "k";
  	if (sym)
@@ -105513,7 +105563,7 @@ index 176d825..68c261a 100644
  			p->addr, kprobe_type, p->addr,
  			(kprobe_gone(p) ? "[GONE]" : ""),
  			((kprobe_disabled(p) && !kprobe_gone(p)) ?
-@@ -1304,7 +1304,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
+@@ -1304,7 +1307,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
  	unsigned long offset = 0;

diff --git a/3.10.5/0000_README b/3.10.7/0000_README
similarity index 96%
rename from 3.10.5/0000_README
rename to 3.10.7/0000_README
index 231cc80..a11d231 100644
--- a/3.10.5/0000_README
+++ b/3.10.7/0000_README
@@ -2,7 +2,7 @@ README
 -----------------------------------------------------------------------------
 Individual Patch Descriptions:
 -----------------------------------------------------------------------------
-Patch:	4420_grsecurity-2.9.1-3.10.5-201308091415.patch
+Patch:	4420_grsecurity-2.9.1-3.10.7-201308171249.patch
 From:	http://www.grsecurity.net
 Desc:	hardened-sources base patch from upstream grsecurity
 

diff --git a/3.10.5/4420_grsecurity-2.9.1-3.10.5-201308091415.patch b/3.10.7/4420_grsecurity-2.9.1-3.10.7-201308171249.patch
similarity index 96%
rename from 3.10.5/4420_grsecurity-2.9.1-3.10.5-201308091415.patch
rename to 3.10.7/4420_grsecurity-2.9.1-3.10.7-201308171249.patch
index 1d4bcfe..9a72c3e 100644
--- a/3.10.5/4420_grsecurity-2.9.1-3.10.5-201308091415.patch
+++ b/3.10.7/4420_grsecurity-2.9.1-3.10.7-201308171249.patch
@@ -229,7 +229,7 @@ index b89a739..79768fb 100644
 +zconf.lex.c
  zoffset.h
 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 2fe6e76..df58221 100644
+index 2fe6e76..889ee23 100644
 --- a/Documentation/kernel-parameters.txt
 +++ b/Documentation/kernel-parameters.txt
 @@ -976,6 +976,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
@@ -243,7 +243,18 @@ index 2fe6e76..df58221 100644
  	hashdist=	[KNL,NUMA] Large hashes allocated during boot
  			are distributed across NUMA nodes.  Defaults on
  			for 64-bit NUMA, off otherwise.
-@@ -2195,6 +2199,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+@@ -1928,6 +1932,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ 			noexec=on: enable non-executable mappings (default)
+ 			noexec=off: disable non-executable mappings
+ 
++	nopcid		[X86-64]
++			Disable PCID (Process-Context IDentifier) even if it
++			is supported by the processor.
++
+ 	nosmap		[X86]
+ 			Disable SMAP (Supervisor Mode Access Prevention)
+ 			even if it is supported by processor.
+@@ -2195,6 +2203,25 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
  			the specified number of seconds.  This is to be used if
  			your oopses keep scrolling off the screen.
  
@@ -263,11 +274,14 @@ index 2fe6e76..df58221 100644
 +			from the first 4GB of memory as the bootmem allocator
 +			passes the memory pages to the buddy allocator.
 +
++	pax_weakuderef	[X86-64] enables the weaker but faster form of UDEREF
++			when the processor supports PCID.
++
  	pcbit=		[HW,ISDN]
  
  	pcd.		[PARIDE]
 diff --git a/Makefile b/Makefile
-index f8349d0..563a504 100644
+index 33e36ab..31f1dc8 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -815,7 +829,7 @@ index 0c4132d..88f0d53 100644
  		/* Allow reads even for write-only mappings */
  		if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
-index 136f263..f471277 100644
+index 18a9f5e..ca910b7 100644
 --- a/arch/arm/Kconfig
 +++ b/arch/arm/Kconfig
 @@ -1766,7 +1766,7 @@ config ALIGNMENT_TRAP
@@ -1628,7 +1642,7 @@ index 6ddbe44..b5e38b1 100644
  static inline void set_domain(unsigned val) { }
  static inline void modify_domain(unsigned dom, unsigned type)	{ }
 diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
-index 38050b1..9d90e8b 100644
+index 56211f2..17e8a25 100644
 --- a/arch/arm/include/asm/elf.h
 +++ b/arch/arm/include/asm/elf.h
 @@ -116,7 +116,14 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
@@ -1647,7 +1661,7 @@ index 38050b1..9d90e8b 100644
  
  /* When the program starts, a1 contains a pointer to a function to be 
     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
-@@ -126,8 +133,4 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+@@ -126,10 +133,6 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
  extern void elf_set_personality(const struct elf32_hdr *);
  #define SET_PERSONALITY(ex)	elf_set_personality(&(ex))
  
@@ -1655,7 +1669,9 @@ index 38050b1..9d90e8b 100644
 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 -#define arch_randomize_brk arch_randomize_brk
 -
- #endif
+ #ifdef CONFIG_MMU
+ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+ struct linux_binprm;
 diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
 index de53547..52b9a28 100644
 --- a/arch/arm/include/asm/fncpy.h
@@ -1788,7 +1804,7 @@ index 12f71a1..04e063c 100644
  #ifdef CONFIG_OUTER_CACHE
  
 diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
-index 812a494..71fc0b6 100644
+index cbdc7a2..32f44fe 100644
 --- a/arch/arm/include/asm/page.h
 +++ b/arch/arm/include/asm/page.h
 @@ -114,7 +114,7 @@ struct cpu_user_fns {
@@ -2059,22 +2075,6 @@ index f3628fb..a0672dd 100644
  
  #ifndef MULTI_CPU
  extern void cpu_proc_init(void);
-diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
-index 06e7d50..8a8e251 100644
---- a/arch/arm/include/asm/processor.h
-+++ b/arch/arm/include/asm/processor.h
-@@ -65,9 +65,8 @@ struct thread_struct {
- 	regs->ARM_cpsr |= PSR_ENDSTATE;					\
- 	regs->ARM_pc = pc & ~1;		/* pc */			\
- 	regs->ARM_sp = sp;		/* sp */			\
--	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
--	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
--	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
-+	/* r2 (envp), r1 (argv), r0 (argc) */				\
-+	(void)copy_from_user(&regs->ARM_r0, (const char __user *)stack, 3 * sizeof(unsigned long)); \
- 	nommu_start_thread(regs);					\
- })
- 
 diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
 index ce0dbe7..c085b6f 100644
 --- a/arch/arm/include/asm/psci.h
@@ -2102,7 +2102,7 @@ index d3a22be..3a69ad5 100644
  /*
   * set platform specific SMP operations
 diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
-index 1995d1a..76693a2 100644
+index f00b569..aa5bb41 100644
 --- a/arch/arm/include/asm/thread_info.h
 +++ b/arch/arm/include/asm/thread_info.h
 @@ -77,9 +77,9 @@ struct thread_info {
@@ -2131,7 +2131,7 @@ index 1995d1a..76693a2 100644
  #define TIF_USING_IWMMXT	17
  #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
  #define TIF_RESTORE_SIGMASK	20
-@@ -166,10 +170,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+@@ -165,10 +169,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
  #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
  #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
  #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
@@ -2144,8 +2144,35 @@ index 1995d1a..76693a2 100644
  
  /*
   * Change these and you break ASM code in entry-common.S
+diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
+index bdf2b84..aa9b4ac 100644
+--- a/arch/arm/include/asm/tlb.h
++++ b/arch/arm/include/asm/tlb.h
+@@ -43,6 +43,7 @@ struct mmu_gather {
+ 	struct mm_struct	*mm;
+ 	unsigned int		fullmm;
+ 	struct vm_area_struct	*vma;
++	unsigned long		start, end;
+ 	unsigned long		range_start;
+ 	unsigned long		range_end;
+ 	unsigned int		nr;
+@@ -107,10 +108,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+ }
+ 
+ static inline void
+-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
++tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+-	tlb->fullmm = fullmm;
++	tlb->fullmm = !(start | (end+1));
++	tlb->start = start;
++	tlb->end = end;
+ 	tlb->vma = NULL;
+ 	tlb->max = ARRAY_SIZE(tlb->local);
+ 	tlb->pages = tlb->local;
 diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
-index 7e1f760..d42d7f8 100644
+index 7e1f760..de33b13 100644
 --- a/arch/arm/include/asm/uaccess.h
 +++ b/arch/arm/include/asm/uaccess.h
 @@ -18,6 +18,7 @@
@@ -2156,7 +2183,7 @@ index 7e1f760..d42d7f8 100644
  
  #define VERIFY_READ 0
  #define VERIFY_WRITE 1
-@@ -63,11 +64,35 @@ extern int __put_user_bad(void);
+@@ -63,11 +64,38 @@ extern int __put_user_bad(void);
  static inline void set_fs(mm_segment_t fs)
  {
  	current_thread_info()->addr_limit = fs;
@@ -2166,6 +2193,9 @@ index 7e1f760..d42d7f8 100644
  
  #define segment_eq(a,b)	((a) == (b))
  
++#define __HAVE_ARCH_PAX_OPEN_USERLAND
++#define __HAVE_ARCH_PAX_CLOSE_USERLAND
++
 +static inline void pax_open_userland(void)
 +{
 +
@@ -2193,7 +2223,7 @@ index 7e1f760..d42d7f8 100644
  #define __addr_ok(addr) ({ \
  	unsigned long flag; \
  	__asm__("cmp %2, %0; movlo %0, #0" \
-@@ -143,8 +168,12 @@ extern int __get_user_4(void *);
+@@ -143,8 +171,12 @@ extern int __get_user_4(void *);
  
  #define get_user(x,p)							\
  	({								\
@@ -2207,7 +2237,7 @@ index 7e1f760..d42d7f8 100644
  	 })
  
  extern int __put_user_1(void *, unsigned int);
-@@ -188,8 +217,12 @@ extern int __put_user_8(void *, unsigned long long);
+@@ -188,8 +220,12 @@ extern int __put_user_8(void *, unsigned long long);
  
  #define put_user(x,p)							\
  	({								\
@@ -2221,7 +2251,7 @@ index 7e1f760..d42d7f8 100644
  	 })
  
  #else /* CONFIG_MMU */
-@@ -230,13 +263,17 @@ static inline void set_fs(mm_segment_t fs)
+@@ -230,13 +266,17 @@ static inline void set_fs(mm_segment_t fs)
  #define __get_user(x,ptr)						\
  ({									\
  	long __gu_err = 0;						\
@@ -2239,7 +2269,7 @@ index 7e1f760..d42d7f8 100644
  	(void) 0;							\
  })
  
-@@ -312,13 +349,17 @@ do {									\
+@@ -312,13 +352,17 @@ do {									\
  #define __put_user(x,ptr)						\
  ({									\
  	long __pu_err = 0;						\
@@ -2257,7 +2287,7 @@ index 7e1f760..d42d7f8 100644
  	(void) 0;							\
  })
  
-@@ -418,11 +459,44 @@ do {									\
+@@ -418,11 +462,44 @@ do {									\
  
  
  #ifdef CONFIG_MMU
@@ -2305,7 +2335,7 @@ index 7e1f760..d42d7f8 100644
  #else
  #define __copy_from_user(to,from,n)	(memcpy(to, (void __force *)from, n), 0)
  #define __copy_to_user(to,from,n)	(memcpy((void __force *)to, from, n), 0)
-@@ -431,6 +505,9 @@ extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned l
+@@ -431,6 +508,9 @@ extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned l
  
  static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
  {
@@ -2315,7 +2345,7 @@ index 7e1f760..d42d7f8 100644
  	if (access_ok(VERIFY_READ, from, n))
  		n = __copy_from_user(to, from, n);
  	else /* security hole - plug it */
-@@ -440,6 +517,9 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
+@@ -440,6 +520,9 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
  
  static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
  {
@@ -2365,7 +2395,7 @@ index 60d3b73..e5a0f22 100644
  EXPORT_SYMBOL(__get_user_1);
  EXPORT_SYMBOL(__get_user_2);
 diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
-index 582b405..a78366b 100644
+index d43c7e5..257c050 100644
 --- a/arch/arm/kernel/entry-armv.S
 +++ b/arch/arm/kernel/entry-armv.S
 @@ -47,6 +47,87 @@
@@ -2507,7 +2537,17 @@ index 582b405..a78366b 100644
  	sub	sp, sp, #S_FRAME_SIZE
   ARM(	stmib	sp, {r1 - r12}	)
   THUMB(	stmia	sp, {r0 - r12}	)
-@@ -414,7 +511,9 @@ __und_usr:
+@@ -357,7 +454,8 @@ ENDPROC(__pabt_svc)
+ 	.endm
+ 
+ 	.macro	kuser_cmpxchg_check
+-#if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
++#if !defined(CONFIG_CPU_32v6K) && defined(CONFIG_KUSER_HELPERS) && \
++    !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+ #ifndef CONFIG_MMU
+ #warning "NPTL on non MMU needs fixing"
+ #else
+@@ -414,7 +512,9 @@ __und_usr:
  	tst	r3, #PSR_T_BIT			@ Thumb mode?
  	bne	__und_usr_thumb
  	sub	r4, r2, #4			@ ARM instr at LR - 4
@@ -2517,7 +2557,7 @@ index 582b405..a78366b 100644
  #ifdef CONFIG_CPU_ENDIAN_BE8
  	rev	r0, r0				@ little endian instruction
  #endif
-@@ -449,10 +548,14 @@ __und_usr_thumb:
+@@ -449,10 +549,14 @@ __und_usr_thumb:
   */
  	.arch	armv6t2
  #endif
@@ -2532,7 +2572,7 @@ index 582b405..a78366b 100644
  	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
  	str	r2, [sp, #S_PC]			@ it's a 2x16bit instr, update
  	orr	r0, r0, r5, lsl #16
-@@ -481,7 +584,8 @@ ENDPROC(__und_usr)
+@@ -481,7 +585,8 @@ ENDPROC(__und_usr)
   */
  	.pushsection .fixup, "ax"
  	.align	2
@@ -2542,7 +2582,7 @@ index 582b405..a78366b 100644
  	.popsection
  	.pushsection __ex_table,"a"
  	.long	1b, 4b
-@@ -690,7 +794,7 @@ ENTRY(__switch_to)
+@@ -690,7 +795,7 @@ ENTRY(__switch_to)
   THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
   THUMB(	str	sp, [ip], #4		   )
   THUMB(	str	lr, [ip], #4		   )
@@ -2551,7 +2591,7 @@ index 582b405..a78366b 100644
  	ldr	r6, [r2, #TI_CPU_DOMAIN]
  #endif
  	set_tls	r3, r4, r5
-@@ -699,7 +803,7 @@ ENTRY(__switch_to)
+@@ -699,7 +804,7 @@ ENTRY(__switch_to)
  	ldr	r8, =__stack_chk_guard
  	ldr	r7, [r7, #TSK_STACK_CANARY]
  #endif
@@ -2721,19 +2761,32 @@ index 160f337..db67ee4 100644
  	ldrd	r0, r1, [sp, #S_LR]		@ calling lr and pc
  	clrex					@ clear the exclusive monitor
 diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
-index 2adda11..7fbe958 100644
+index 25442f4..d4948fc 100644
 --- a/arch/arm/kernel/fiq.c
 +++ b/arch/arm/kernel/fiq.c
-@@ -82,7 +82,9 @@ void set_fiq_handler(void *start, unsigned int length)
- #if defined(CONFIG_CPU_USE_DOMAINS)
- 	memcpy((void *)0xffff001c, start, length);
- #else
+@@ -84,17 +84,16 @@ int show_fiq_list(struct seq_file *p, int prec)
+ 
+ void set_fiq_handler(void *start, unsigned int length)
+ {
+-#if defined(CONFIG_CPU_USE_DOMAINS)
+-	void *base = (void *)0xffff0000;
+-#else
+ 	void *base = vectors_page;
+-#endif
+ 	unsigned offset = FIQ_OFFSET;
+ 
 +	pax_open_kernel();
- 	memcpy(vectors_page + 0x1c, start, length);
+ 	memcpy(base + offset, start, length);
 +	pax_close_kernel();
- #endif
- 	flush_icache_range(0xffff001c, 0xffff001c + length);
- 	if (!vectors_high())
++
++	if (!cache_is_vipt_nonaliasing())
++		flush_icache_range(base + offset, offset + length);
+ 	flush_icache_range(0xffff0000 + offset, 0xffff0000 + offset + length);
+-	if (!vectors_high())
+-		flush_icache_range(offset, offset + length);
+ }
+ 
+ int claim_fiq(struct fiq_handler *f)
 diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
 index 8bac553..caee108 100644
 --- a/arch/arm/kernel/head.S
@@ -2835,6 +2888,34 @@ index 07314af..c46655c 100644
  
  	flush_icache_range((uintptr_t)(addr),
  			   (uintptr_t)(addr) + size);
+diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
+index d9f5cd4..e186ee1 100644
+--- a/arch/arm/kernel/perf_event.c
++++ b/arch/arm/kernel/perf_event.c
+@@ -53,7 +53,12 @@ armpmu_map_cache_event(const unsigned (*cache_map)
+ static int
+ armpmu_map_hw_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
+ {
+-	int mapping = (*event_map)[config];
++	int mapping;
++
++	if (config >= PERF_COUNT_HW_MAX)
++		return -EINVAL;
++
++	mapping = (*event_map)[config];
+ 	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
+ }
+ 
+@@ -253,6 +258,9 @@ validate_event(struct pmu_hw_events *hw_events,
+ 	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+ 	struct pmu *leader_pmu = event->group_leader->pmu;
+ 
++	if (is_software_event(event))
++		return 1;
++
+ 	if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
+ 		return 1;
+ 
 diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
 index 1f2740e..b36e225 100644
 --- a/arch/arm/kernel/perf_event_cpu.c
@@ -2849,10 +2930,10 @@ index 1f2740e..b36e225 100644
  };
  
 diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
-index 6e8931c..82ec6a5 100644
+index 5bc2615..4f1a0c2 100644
 --- a/arch/arm/kernel/process.c
 +++ b/arch/arm/kernel/process.c
-@@ -28,7 +28,6 @@
+@@ -28,10 +28,10 @@
  #include <linux/tick.h>
  #include <linux/utsname.h>
  #include <linux/uaccess.h>
@@ -2860,7 +2941,11 @@ index 6e8931c..82ec6a5 100644
  #include <linux/hw_breakpoint.h>
  #include <linux/cpuidle.h>
  #include <linux/leds.h>
-@@ -223,6 +222,7 @@ void machine_power_off(void)
++#include <linux/random.h>
+ 
+ #include <asm/cacheflush.h>
+ #include <asm/idmap.h>
+@@ -223,6 +223,7 @@ void machine_power_off(void)
  
  	if (pm_power_off)
  		pm_power_off();
@@ -2868,7 +2953,7 @@ index 6e8931c..82ec6a5 100644
  }
  
  /*
-@@ -236,7 +236,7 @@ void machine_power_off(void)
+@@ -236,7 +237,7 @@ void machine_power_off(void)
   * executing pre-reset code, and using RAM that the primary CPU's code wishes
   * to use. Implementing such co-ordination would be essentially impossible.
   */
@@ -2877,18 +2962,18 @@ index 6e8931c..82ec6a5 100644
  {
  	smp_send_stop();
  
-@@ -258,8 +258,8 @@ void __show_regs(struct pt_regs *regs)
+@@ -258,8 +259,8 @@ void __show_regs(struct pt_regs *regs)
  
  	show_regs_print_info(KERN_DEFAULT);
  
 -	print_symbol("PC is at %s\n", instruction_pointer(regs));
 -	print_symbol("LR is at %s\n", regs->ARM_lr);
-+	printk("PC is at %pA\n", instruction_pointer(regs));
-+	printk("LR is at %pA\n", regs->ARM_lr);
++	printk("PC is at %pA\n", (void *)instruction_pointer(regs));
++	printk("LR is at %pA\n", (void *)regs->ARM_lr);
  	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
  	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
  		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
-@@ -426,12 +426,6 @@ unsigned long get_wchan(struct task_struct *p)
+@@ -426,12 +427,6 @@ unsigned long get_wchan(struct task_struct *p)
  	return 0;
  }
  
@@ -2899,23 +2984,70 @@ index 6e8931c..82ec6a5 100644
 -}
 -
  #ifdef CONFIG_MMU
+ #ifdef CONFIG_KUSER_HELPERS
  /*
-  * The vectors page is always readable from user space for the
-@@ -441,12 +435,12 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
- static struct vm_area_struct gate_vma = {
- 	.vm_start	= 0xffff0000,
- 	.vm_end		= 0xffff0000 + PAGE_SIZE,
--	.vm_flags	= VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC,
-+	.vm_flags	= VM_NONE,
- };
+@@ -447,7 +442,7 @@ static struct vm_area_struct gate_vma = {
  
  static int __init gate_vma_init(void)
  {
 -	gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
-+	gate_vma.vm_page_prot	= vm_get_page_prot(gate_vma.vm_flags);
++	gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
  	return 0;
  }
  arch_initcall(gate_vma_init);
+@@ -466,48 +461,23 @@ int in_gate_area_no_mm(unsigned long addr)
+ {
+ 	return in_gate_area(NULL, addr);
+ }
+-#define is_gate_vma(vma)	((vma) = &gate_vma)
++#define is_gate_vma(vma)	((vma) == &gate_vma)
+ #else
+ #define is_gate_vma(vma)	0
+ #endif
+ 
+ const char *arch_vma_name(struct vm_area_struct *vma)
+ {
+-	return is_gate_vma(vma) ? "[vectors]" :
+-		(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
+-		 "[sigpage]" : NULL;
++	return is_gate_vma(vma) ? "[vectors]" : NULL;
+ }
+ 
+-static struct page *signal_page;
+-extern struct page *get_signal_page(void);
+-
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+ 	struct mm_struct *mm = current->mm;
+-	unsigned long addr;
+-	int ret;
+-
+-	if (!signal_page)
+-		signal_page = get_signal_page();
+-	if (!signal_page)
+-		return -ENOMEM;
+ 
+ 	down_write(&mm->mmap_sem);
+-	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+-	if (IS_ERR_VALUE(addr)) {
+-		ret = addr;
+-		goto up_fail;
+-	}
+-
+-	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+-		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+-		&signal_page);
+-
+-	if (ret == 0)
+-		mm->context.sigpage = addr;
+-
+- up_fail:
++	mm->context.sigpage = (PAGE_OFFSET + (get_random_int() % 0x3FFEFFE0)) & 0xFFFFFFFC;
+ 	up_write(&mm->mmap_sem);
+-	return ret;
++	return 0;
+ }
+ #endif
 diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
 index 3653164..d83e55d 100644
 --- a/arch/arm/kernel/psci.c
@@ -3012,39 +3144,62 @@ index b4b1d39..efdc9be 100644
  #ifdef MULTI_TLB
  	cpu_tlb = *list->tlb;
 diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
-index 296786b..a8d4dd5 100644
+index 5a42c12..a2bb7c6 100644
 --- a/arch/arm/kernel/signal.c
 +++ b/arch/arm/kernel/signal.c
-@@ -396,22 +396,14 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
- 		    __put_user(sigreturn_codes[idx+1], rc+1))
- 			return 1;
- 
--		if (cpsr & MODE32_BIT) {
--			/*
--			 * 32-bit code can use the new high-page
--			 * signal return code support.
--			 */
--			retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
--		} else {
--			/*
--			 * Ensure that the instruction cache sees
--			 * the return code written onto the stack.
--			 */
--			flush_icache_range((unsigned long)rc,
--					   (unsigned long)(rc + 2));
-+		/*
-+		 * Ensure that the instruction cache sees
-+		 * the return code written onto the stack.
-+		 */
-+		flush_icache_range((unsigned long)rc,
-+				   (unsigned long)(rc + 2));
- 
--			retcode = ((unsigned long)rc) + thumb;
--		}
-+		retcode = ((unsigned long)rc) + thumb;
- 	}
+@@ -45,8 +45,6 @@ static const unsigned long sigreturn_codes[7] = {
+ 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
+ };
  
- 	regs->ARM_r0 = map_sig(ksig->sig);
+-static unsigned long signal_return_offset;
+-
+ #ifdef CONFIG_CRUNCH
+ static int preserve_crunch_context(struct crunch_sigframe __user *frame)
+ {
+@@ -406,8 +404,7 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
+ 			 * except when the MPU has protected the vectors
+ 			 * page from PL0
+ 			 */
+-			retcode = mm->context.sigpage + signal_return_offset +
+-				  (idx << 2) + thumb;
++			retcode = mm->context.sigpage + (idx << 2) + thumb;
+ 		} else
+ #endif
+ 		{
+@@ -611,33 +608,3 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+ 	} while (thread_flags & _TIF_WORK_MASK);
+ 	return 0;
+ }
+-
+-struct page *get_signal_page(void)
+-{
+-	unsigned long ptr;
+-	unsigned offset;
+-	struct page *page;
+-	void *addr;
+-
+-	page = alloc_pages(GFP_KERNEL, 0);
+-
+-	if (!page)
+-		return NULL;
+-
+-	addr = page_address(page);
+-
+-	/* Give the signal return code some randomness */
+-	offset = 0x200 + (get_random_int() & 0x7fc);
+-	signal_return_offset = offset;
+-
+-	/*
+-	 * Copy signal return handlers into the vector page, and
+-	 * set sigreturn to be a pointer to these.
+-	 */
+-	memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+-
+-	ptr = (unsigned long)addr + offset;
+-	flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+-
+-	return page;
+-}
 diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
 index 5919eb4..b5d6dfe 100644
 --- a/arch/arm/kernel/smp.c
@@ -3059,10 +3214,10 @@ index 5919eb4..b5d6dfe 100644
  void __init smp_set_ops(struct smp_operations *ops)
  {
 diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
-index 18b32e8..b0c8dca 100644
+index 6b9567e..b8af2d6 100644
 --- a/arch/arm/kernel/traps.c
 +++ b/arch/arm/kernel/traps.c
-@@ -57,7 +57,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
+@@ -55,7 +55,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
  void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
  {
  #ifdef CONFIG_KALLSYMS
@@ -3071,7 +3226,7 @@ index 18b32e8..b0c8dca 100644
  #else
  	printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
  #endif
-@@ -259,6 +259,8 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+@@ -257,6 +257,8 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
  static int die_owner = -1;
  static unsigned int die_nest_count;
  
@@ -3080,7 +3235,7 @@ index 18b32e8..b0c8dca 100644
  static unsigned long oops_begin(void)
  {
  	int cpu;
-@@ -301,6 +303,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+@@ -299,6 +301,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
  		panic("Fatal exception in interrupt");
  	if (panic_on_oops)
  		panic("Fatal exception");
@@ -3090,7 +3245,7 @@ index 18b32e8..b0c8dca 100644
  	if (signr)
  		do_exit(signr);
  }
-@@ -594,7 +599,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
+@@ -592,7 +597,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
  			 * The user helper at 0xffff0fe0 must be used instead.
  			 * (see entry-armv.S for details)
  			 */
@@ -3100,18 +3255,10 @@ index 18b32e8..b0c8dca 100644
  		}
  		return 0;
  
-@@ -834,13 +841,10 @@ void __init early_trap_init(void *vectors_base)
- 	 */
- 	kuser_get_tls_init(vectors);
+@@ -848,5 +855,9 @@ void __init early_trap_init(void *vectors_base)
+ 	kuser_init(vectors_base);
  
--	/*
--	 * Copy signal return handlers into the vector page, and
--	 * set sigreturn to be a pointer to these.
--	 */
--	memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
--	       sigreturn_codes, sizeof(sigreturn_codes));
--
- 	flush_icache_range(vectors, vectors + PAGE_SIZE);
+ 	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
 -	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 +
 +#ifndef CONFIG_PAX_MEMORY_UDEREF
@@ -3120,7 +3267,7 @@ index 18b32e8..b0c8dca 100644
 +
  }
 diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
-index a871b8e..123b00a 100644
+index 33f2ea3..0b91824 100644
 --- a/arch/arm/kernel/vmlinux.lds.S
 +++ b/arch/arm/kernel/vmlinux.lds.S
 @@ -8,7 +8,11 @@
@@ -3168,7 +3315,7 @@ index a871b8e..123b00a 100644
  
  #ifndef CONFIG_XIP_KERNEL
  	. = ALIGN(PAGE_SIZE);
-@@ -207,6 +220,11 @@ SECTIONS
+@@ -224,6 +237,11 @@ SECTIONS
  	. = PAGE_OFFSET + TEXT_OFFSET;
  #else
  	__init_end = .;
@@ -3541,10 +3688,10 @@ index cad3ca86..1d79e0f 100644
  extern void ux500_cpu_die(unsigned int cpu);
  
 diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
-index 35955b5..b475042 100644
+index 2950082..d0f0782 100644
 --- a/arch/arm/mm/Kconfig
 +++ b/arch/arm/mm/Kconfig
-@@ -432,7 +432,7 @@ config CPU_32v5
+@@ -436,7 +436,7 @@ config CPU_32v5
  
  config CPU_32v6
  	bool
@@ -3553,7 +3700,7 @@ index 35955b5..b475042 100644
  	select TLS_REG_EMUL if !CPU_32v6K && !MMU
  
  config CPU_32v6K
-@@ -581,6 +581,7 @@ config CPU_CP15_MPU
+@@ -585,6 +585,7 @@ config CPU_CP15_MPU
  
  config CPU_USE_DOMAINS
  	bool
@@ -3561,6 +3708,23 @@ index 35955b5..b475042 100644
  	help
  	  This option enables or disables the use of domain switching
  	  via the set_fs() function.
+@@ -780,6 +781,7 @@ config NEED_KUSER_HELPERS
+ config KUSER_HELPERS
+ 	bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+ 	default y
++	depends on !(CPU_V6 || CPU_V6K || CPU_V7)
+ 	help
+ 	  Warning: disabling this option may break user programs.
+ 
+@@ -790,7 +792,7 @@ config KUSER_HELPERS
+ 	  run on ARMv4 through to ARMv7 without modification.
+ 
+ 	  However, the fixed address nature of these helpers can be used
+-	  by ROP (return orientated programming) authors when creating
++	  by ROP (Return Oriented Programming) authors when creating
+ 	  exploits.
+ 
+ 	  If all of the binaries and libraries which run on your platform
 diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
 index 6f4585b..7b6f52b 100644
 --- a/arch/arm/mm/alignment.c
@@ -3627,7 +3791,7 @@ index 6f4585b..7b6f52b 100644
  			goto fault;				\
  	} while (0)
 diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
-index 5dbf13f..1a60561 100644
+index 5dbf13f..ee1ec24 100644
 --- a/arch/arm/mm/fault.c
 +++ b/arch/arm/mm/fault.c
 @@ -25,6 +25,7 @@
@@ -3730,11 +3894,29 @@ index 5dbf13f..1a60561 100644
  	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
  		inf->name, fsr, addr);
  
-@@ -575,9 +637,49 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+@@ -569,15 +631,67 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *
+ 	ifsr_info[nr].name = name;
+ }
+ 
++asmlinkage int sys_sigreturn(struct pt_regs *regs);
++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
++
+ asmlinkage void __exception
+ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+ {
  	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
  	struct siginfo info;
  
 +	if (user_mode(regs)) {
++		unsigned long sigpage = current->mm->context.sigpage;
++
++		if (sigpage <= addr && addr < sigpage + 7*4) {
++			if (addr < sigpage + 3*4)
++				sys_sigreturn(regs);
++			else
++				sys_rt_sigreturn(regs);
++			return;
++		}
 +		if (addr == 0xffff0fe0UL) {
 +			/*
 +			 * PaX: __kuser_get_tls emulation
@@ -3999,7 +4181,7 @@ index 10062ce..8695745 100644
  		mm->unmap_area = arch_unmap_area_topdown;
  	}
 diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
-index 4d409e6..f375351 100644
+index daf336f..4e6392c 100644
 --- a/arch/arm/mm/mmu.c
 +++ b/arch/arm/mm/mmu.c
 @@ -36,6 +36,22 @@
@@ -4066,7 +4248,7 @@ index 4d409e6..f375351 100644
  		.domain    = DOMAIN_KERNEL,
  	},
  #endif
-@@ -277,36 +301,65 @@ static struct mem_type mem_types[] = {
+@@ -277,36 +301,54 @@ static struct mem_type mem_types[] = {
  		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
  				L_PTE_RDONLY,
  		.prot_l1   = PMD_TYPE_TABLE,
@@ -4074,21 +4256,8 @@ index 4d409e6..f375351 100644
 +		.domain    = DOMAIN_VECTORS,
  	},
  	[MT_HIGH_VECTORS] = {
--		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
--				L_PTE_USER | L_PTE_RDONLY,
-+		/* we always want the vector page to be noaccess for userland on archs with
-+		   XN where we can enforce some reasonable measure of security
-+		   therefore, when kernexec is disabled, instead of L_PTE_USER | L_PTE_RDONLY
-+		   which turns into supervisor rwx, userland rx, we instead omit that entirely,
-+		   leaving it as supervisor rwx only
-+		*/
-+#ifdef CONFIG_PAX_KERNEXEC
-+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_RDONLY,
-+#elif __LINUX_ARM_ARCH__ >= 6
-+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
-+#else
-+		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_USER | L_PTE_RDONLY,
-+#endif
+ 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ 				L_PTE_USER | L_PTE_RDONLY,
  		.prot_l1   = PMD_TYPE_TABLE,
 -		.domain    = DOMAIN_USER,
 +		.domain    = DOMAIN_VECTORS,
@@ -4142,7 +4311,7 @@ index 4d409e6..f375351 100644
  		.domain    = DOMAIN_KERNEL,
  	},
  	[MT_MEMORY_ITCM] = {
-@@ -316,10 +369,10 @@ static struct mem_type mem_types[] = {
+@@ -316,10 +358,10 @@ static struct mem_type mem_types[] = {
  	},
  	[MT_MEMORY_SO] = {
  		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
@@ -4155,7 +4324,7 @@ index 4d409e6..f375351 100644
  		.domain    = DOMAIN_KERNEL,
  	},
  	[MT_MEMORY_DMA_READY] = {
-@@ -405,9 +458,35 @@ static void __init build_mem_type_table(void)
+@@ -405,9 +447,35 @@ static void __init build_mem_type_table(void)
  			 * to prevent speculative instruction fetches.
  			 */
  			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
@@ -4191,7 +4360,7 @@ index 4d409e6..f375351 100644
  		}
  		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
  			/*
-@@ -468,6 +547,9 @@ static void __init build_mem_type_table(void)
+@@ -468,6 +536,9 @@ static void __init build_mem_type_table(void)
  		 * from SVC mode and no access from userspace.
  		 */
  		mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
@@ -4201,7 +4370,7 @@ index 4d409e6..f375351 100644
  		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
  		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
  #endif
-@@ -485,11 +567,17 @@ static void __init build_mem_type_table(void)
+@@ -485,11 +556,17 @@ static void __init build_mem_type_table(void)
  			mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
  			mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
  			mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
@@ -4223,7 +4392,7 @@ index 4d409e6..f375351 100644
  		}
  	}
  
-@@ -500,15 +588,20 @@ static void __init build_mem_type_table(void)
+@@ -500,15 +577,20 @@ static void __init build_mem_type_table(void)
  	if (cpu_arch >= CPU_ARCH_ARMv6) {
  		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
  			/* Non-cacheable Normal is XCB = 001 */
@@ -4247,7 +4416,7 @@ index 4d409e6..f375351 100644
  	}
  
  #ifdef CONFIG_ARM_LPAE
-@@ -524,6 +617,8 @@ static void __init build_mem_type_table(void)
+@@ -524,6 +606,8 @@ static void __init build_mem_type_table(void)
  	vecs_pgprot |= PTE_EXT_AF;
  #endif
  
@@ -4256,7 +4425,7 @@ index 4d409e6..f375351 100644
  	for (i = 0; i < 16; i++) {
  		pteval_t v = pgprot_val(protection_map[i]);
  		protection_map[i] = __pgprot(v | user_pgprot);
-@@ -541,10 +636,15 @@ static void __init build_mem_type_table(void)
+@@ -541,10 +625,15 @@ static void __init build_mem_type_table(void)
  
  	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
  	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
@@ -4275,12 +4444,12 @@ index 4d409e6..f375351 100644
  	mem_types[MT_ROM].prot_sect |= cp->pmd;
  
  	switch (cp->pmd) {
-@@ -1166,18 +1266,15 @@ void __init arm_mm_memblock_reserve(void)
+@@ -1166,18 +1255,15 @@ void __init arm_mm_memblock_reserve(void)
   * called function.  This means you can't use any function or debugging
   * method which may touch any device, otherwise the kernel _will_ crash.
   */
 +
-+static char vectors[PAGE_SIZE] __read_only __aligned(PAGE_SIZE);
++static char vectors[PAGE_SIZE * 2] __read_only __aligned(PAGE_SIZE);
 +
  static void __init devicemaps_init(struct machine_desc *mdesc)
  {
@@ -4291,14 +4460,14 @@ index 4d409e6..f375351 100644
 -	/*
 -	 * Allocate the vector page early.
 -	 */
--	vectors = early_alloc(PAGE_SIZE);
+-	vectors = early_alloc(PAGE_SIZE * 2);
 -
 -	early_trap_init(vectors);
 +	early_trap_init(&vectors);
  
  	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
  		pmd_clear(pmd_off_k(addr));
-@@ -1217,7 +1314,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
+@@ -1217,7 +1303,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
  	 * location (0xffff0000).  If we aren't using high-vectors, also
  	 * create a mapping at the low-vectors virtual address.
  	 */
@@ -4306,8 +4475,8 @@ index 4d409e6..f375351 100644
 +	map.pfn = __phys_to_pfn(virt_to_phys(&vectors));
  	map.virtual = 0xffff0000;
  	map.length = PAGE_SIZE;
- 	map.type = MT_HIGH_VECTORS;
-@@ -1275,8 +1372,39 @@ static void __init map_lowmem(void)
+ #ifdef CONFIG_KUSER_HELPERS
+@@ -1287,8 +1373,39 @@ static void __init map_lowmem(void)
  		map.pfn = __phys_to_pfn(start);
  		map.virtual = __phys_to_virt(start);
  		map.length = end - start;
@@ -4374,6 +4543,33 @@ index ce6d763..cfea917 100644
  
  extern void *samsung_dmadev_get_ops(void);
  extern void *s3c_dma_get_ops(void);
+diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
+index 654f096..5546653 100644
+--- a/arch/arm64/include/asm/tlb.h
++++ b/arch/arm64/include/asm/tlb.h
+@@ -35,6 +35,7 @@ struct mmu_gather {
+ 	struct mm_struct	*mm;
+ 	unsigned int		fullmm;
+ 	struct vm_area_struct	*vma;
++	unsigned long		start, end;
+ 	unsigned long		range_start;
+ 	unsigned long		range_end;
+ 	unsigned int		nr;
+@@ -97,10 +98,12 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+ }
+ 
+ static inline void
+-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
++tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+-	tlb->fullmm = fullmm;
++	tlb->fullmm = !(start | (end+1));
++	tlb->start = start;
++	tlb->end = end;
+ 	tlb->vma = NULL;
+ 	tlb->max = ARRAY_SIZE(tlb->local);
+ 	tlb->pages = tlb->local;
 diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
 index f4726dc..39ed646 100644
 --- a/arch/arm64/kernel/debug-monitors.c
@@ -4783,6 +4979,45 @@ index 54ff557..70c88b7 100644
  }
  
  static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock)
+diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h
+index ef3a9de..bc5efc7 100644
+--- a/arch/ia64/include/asm/tlb.h
++++ b/arch/ia64/include/asm/tlb.h
+@@ -22,7 +22,7 @@
+  * unmapping a portion of the virtual address space, these hooks are called according to
+  * the following template:
+  *
+- *	tlb <- tlb_gather_mmu(mm, full_mm_flush);	// start unmap for address space MM
++ *	tlb <- tlb_gather_mmu(mm, start, end);		// start unmap for address space MM
+  *	{
+  *	  for each vma that needs a shootdown do {
+  *	    tlb_start_vma(tlb, vma);
+@@ -58,6 +58,7 @@ struct mmu_gather {
+ 	unsigned int		max;
+ 	unsigned char		fullmm;		/* non-zero means full mm flush */
+ 	unsigned char		need_flush;	/* really unmapped some PTEs? */
++	unsigned long		start, end;
+ 	unsigned long		start_addr;
+ 	unsigned long		end_addr;
+ 	struct page		**pages;
+@@ -155,13 +156,15 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb)
+ 
+ 
+ static inline void
+-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
++tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+ 	tlb->max = ARRAY_SIZE(tlb->local);
+ 	tlb->pages = tlb->local;
+ 	tlb->nr = 0;
+-	tlb->fullmm = full_mm_flush;
++	tlb->fullmm = !(start | (end+1));
++	tlb->start = start;
++	tlb->end = end;
+ 	tlb->start_addr = ~0UL;
+ }
+ 
 diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
 index 449c8c0..18965fb 100644
 --- a/arch/ia64/include/asm/uaccess.h
@@ -5317,6 +5552,97 @@ index c1f6afa..38cc6e9 100644
 +#define arch_align_stack(x) ((x) & ~0xfUL)
  
  #endif /* _ASM_EXEC_H */
+diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
+index d44622c..64990d2 100644
+--- a/arch/mips/include/asm/local.h
++++ b/arch/mips/include/asm/local.h
+@@ -12,15 +12,25 @@ typedef struct
+ 	atomic_long_t a;
+ } local_t;
+ 
++typedef struct {
++	atomic_long_unchecked_t a;
++} local_unchecked_t;
++
+ #define LOCAL_INIT(i)	{ ATOMIC_LONG_INIT(i) }
+ 
+ #define local_read(l)	atomic_long_read(&(l)->a)
++#define local_read_unchecked(l)	atomic_long_read_unchecked(&(l)->a)
+ #define local_set(l, i) atomic_long_set(&(l)->a, (i))
++#define local_set_unchecked(l, i)	atomic_long_set_unchecked(&(l)->a, (i))
+ 
+ #define local_add(i, l) atomic_long_add((i), (&(l)->a))
++#define local_add_unchecked(i, l) atomic_long_add_unchecked((i), (&(l)->a))
+ #define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
++#define local_sub_unchecked(i, l) atomic_long_sub_unchecked((i), (&(l)->a))
+ #define local_inc(l)	atomic_long_inc(&(l)->a)
++#define local_inc_unchecked(l)	atomic_long_inc_unchecked(&(l)->a)
+ #define local_dec(l)	atomic_long_dec(&(l)->a)
++#define local_dec_unchecked(l)	atomic_long_dec_unchecked(&(l)->a)
+ 
+ /*
+  * Same as above, but return the result value
+@@ -70,6 +80,51 @@ static __inline__ long local_add_return(long i, local_t * l)
+ 	return result;
+ }
+ 
++static __inline__ long local_add_return_unchecked(long i, local_unchecked_t * l)
++{
++	unsigned long result;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		unsigned long temp;
++
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:"	__LL	"%1, %2		# local_add_return	\n"
++		"	addu	%0, %1, %3				\n"
++			__SC	"%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++		"	addu	%0, %1, %3				\n"
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++		: "Ir" (i), "m" (l->a.counter)
++		: "memory");
++	} else if (kernel_uses_llsc) {
++		unsigned long temp;
++
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:"	__LL	"%1, %2		# local_add_return	\n"
++		"	addu	%0, %1, %3				\n"
++			__SC	"%0, %2					\n"
++		"	beqz	%0, 1b					\n"
++		"	addu	%0, %1, %3				\n"
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++		: "Ir" (i), "m" (l->a.counter)
++		: "memory");
++	} else {
++		unsigned long flags;
++
++		local_irq_save(flags);
++		result = l->a.counter;
++		result += i;
++		l->a.counter = result;
++		local_irq_restore(flags);
++	}
++
++	return result;
++}
++
+ static __inline__ long local_sub_return(long i, local_t * l)
+ {
+ 	unsigned long result;
+@@ -117,6 +172,8 @@ static __inline__ long local_sub_return(long i, local_t * l)
+ 
+ #define local_cmpxchg(l, o, n) \
+ 	((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
++#define local_cmpxchg_unchecked(l, o, n) \
++	((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+ #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+ 
+ /**
 diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
 index f59552f..3abe9b9 100644
 --- a/arch/mips/include/asm/page.h
@@ -6445,7 +6771,7 @@ index 4aad413..85d86bf 100644
  #define _PAGE_NO_CACHE	0x020	/* I: cache inhibit */
  #define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
 diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
-index 362142b..8b22c1b 100644
+index e1fb161..2290d1d 100644
 --- a/arch/powerpc/include/asm/reg.h
 +++ b/arch/powerpc/include/asm/reg.h
 @@ -234,6 +234,7 @@
@@ -6457,7 +6783,7 @@ index 362142b..8b22c1b 100644
  #define   DSISR_ISSTORE		0x02000000	/* access was a store */
  #define   DSISR_DABRMATCH	0x00400000	/* hit data breakpoint */
 diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
-index ffbaabe..eabe843 100644
+index 48cfc85..891382f 100644
 --- a/arch/powerpc/include/asm/smp.h
 +++ b/arch/powerpc/include/asm/smp.h
 @@ -50,7 +50,7 @@ struct smp_ops_t {
@@ -6698,10 +7024,10 @@ index 645170a..6cf0271 100644
  	ld	r4,_DAR(r1)
  	bl	.bad_page_fault
 diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
-index 4e00d22..b26abcc 100644
+index 902ca3c..e942155 100644
 --- a/arch/powerpc/kernel/exceptions-64s.S
 +++ b/arch/powerpc/kernel/exceptions-64s.S
-@@ -1356,10 +1356,10 @@ handle_page_fault:
+@@ -1357,10 +1357,10 @@ handle_page_fault:
  11:	ld	r4,_DAR(r1)
  	ld	r5,_DSISR(r1)
  	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -6747,10 +7073,10 @@ index 2e3200c..72095ce 100644
  	/* Find this entry, or if that fails, the next avail. entry */
  	while (entry->jump[0]) {
 diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
-index 076d124..6cb2cbf 100644
+index 7baa27b..f6b394a 100644
 --- a/arch/powerpc/kernel/process.c
 +++ b/arch/powerpc/kernel/process.c
-@@ -874,8 +874,8 @@ void show_regs(struct pt_regs * regs)
+@@ -884,8 +884,8 @@ void show_regs(struct pt_regs * regs)
  	 * Lookup NIP late so we have the best change of getting the
  	 * above info out without failing
  	 */
@@ -6761,7 +7087,7 @@ index 076d124..6cb2cbf 100644
  #endif
  #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
  	printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch);
-@@ -1335,10 +1335,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
+@@ -1345,10 +1345,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
  		newsp = stack[0];
  		ip = stack[STACK_FRAME_LR_SAVE];
  		if (!firstframe || ip != lr) {
@@ -6774,7 +7100,7 @@ index 076d124..6cb2cbf 100644
  				       (void *)current->ret_stack[curr_frame].ret);
  				curr_frame--;
  			}
-@@ -1358,7 +1358,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
+@@ -1368,7 +1368,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
  			struct pt_regs *regs = (struct pt_regs *)
  				(sp + STACK_FRAME_OVERHEAD);
  			lr = regs->link;
@@ -6783,7 +7109,7 @@ index 076d124..6cb2cbf 100644
  			       regs->trap, (void *)regs->nip, (void *)lr);
  			firstframe = 1;
  		}
-@@ -1394,58 +1394,3 @@ void notrace __ppc64_runlatch_off(void)
+@@ -1404,58 +1404,3 @@ void notrace __ppc64_runlatch_off(void)
  	mtspr(SPRN_CTRLT, ctrl);
  }
  #endif /* CONFIG_PPC64 */
@@ -6921,10 +7247,10 @@ index e68a845..8b140e6 100644
  };
  
 diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
-index e4f205a..8bfffb8 100644
+index 88929b1..bece8f8 100644
 --- a/arch/powerpc/kernel/traps.c
 +++ b/arch/powerpc/kernel/traps.c
-@@ -143,6 +143,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs)
+@@ -141,6 +141,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs)
  	return flags;
  }
  
@@ -6933,7 +7259,7 @@ index e4f205a..8bfffb8 100644
  static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
  			       int signr)
  {
-@@ -192,6 +194,9 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
+@@ -190,6 +192,9 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
  		panic("Fatal exception in interrupt");
  	if (panic_on_oops)
  		panic("Fatal exception");
@@ -7160,10 +7486,10 @@ index e779642..e5bb889 100644
  };
  
 diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
-index 2859a1f..74f9a6e 100644
+index cafad40..9cbc0fc 100644
 --- a/arch/powerpc/mm/numa.c
 +++ b/arch/powerpc/mm/numa.c
-@@ -919,7 +919,7 @@ static void __init *careful_zallocation(int nid, unsigned long size,
+@@ -920,7 +920,7 @@ static void __init *careful_zallocation(int nid, unsigned long size,
  	return ret;
  }
  
@@ -7319,6 +7645,34 @@ index c4a93d6..4d2a9b4 100644
 +#define arch_align_stack(x) ((x) & ~0xfUL)
  
  #endif /* __ASM_EXEC_H */
+diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
+index b75d7d6..6d6d92b 100644
+--- a/arch/s390/include/asm/tlb.h
++++ b/arch/s390/include/asm/tlb.h
+@@ -32,6 +32,7 @@ struct mmu_gather {
+ 	struct mm_struct *mm;
+ 	struct mmu_table_batch *batch;
+ 	unsigned int fullmm;
++	unsigned long start, end;
+ };
+ 
+ struct mmu_table_batch {
+@@ -48,10 +49,13 @@ extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+ 
+ static inline void tlb_gather_mmu(struct mmu_gather *tlb,
+ 				  struct mm_struct *mm,
+-				  unsigned int full_mm_flush)
++				  unsigned long start,
++				  unsigned long end)
+ {
+ 	tlb->mm = mm;
+-	tlb->fullmm = full_mm_flush;
++	tlb->start = start;
++	tlb->end = end;
++	tlb->fullmm = !(start | (end+1));
+ 	tlb->batch = NULL;
+ 	if (tlb->fullmm)
+ 		__tlb_flush_mm(mm);
 diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
 index 9c33ed4..e40cbef 100644
 --- a/arch/s390/include/asm/uaccess.h
@@ -7587,6 +7941,25 @@ index ef9e555..331bd29 100644
  
  #define __read_mostly __attribute__((__section__(".data..read_mostly")))
  
+diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
+index e61d43d..362192e 100644
+--- a/arch/sh/include/asm/tlb.h
++++ b/arch/sh/include/asm/tlb.h
+@@ -36,10 +36,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
+ }
+ 
+ static inline void
+-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
++tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+-	tlb->fullmm = full_mm_flush;
++	tlb->start = start;
++	tlb->end = end;
++	tlb->fullmm = !(start | (end+1));
+ 
+ 	init_tlb_gather(tlb);
+ }
 diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
 index 03f2b55..b0270327 100644
 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -9959,10 +10332,20 @@ index 5062ff3..e0b75f3 100644
  	 * load/store/atomic was a write or not, it only says that there
  	 * was no match.  So in such a case we (carefully) read the
 diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
-index d2b5944..bd813f2 100644
+index d2b5944..d878f3c 100644
 --- a/arch/sparc/mm/hugetlbpage.c
 +++ b/arch/sparc/mm/hugetlbpage.c
-@@ -38,7 +38,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+@@ -28,7 +28,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+ 							unsigned long addr,
+ 							unsigned long len,
+ 							unsigned long pgoff,
+-							unsigned long flags)
++							unsigned long flags,
++							unsigned long offset)
+ {
+ 	unsigned long task_size = TASK_SIZE;
+ 	struct vm_unmapped_area_info info;
+@@ -38,15 +39,22 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
  
  	info.flags = 0;
  	info.length = len;
@@ -9971,7 +10354,9 @@ index d2b5944..bd813f2 100644
  	info.high_limit = min(task_size, VA_EXCLUDE_START);
  	info.align_mask = PAGE_MASK & ~HPAGE_MASK;
  	info.align_offset = 0;
-@@ -47,6 +47,12 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
++	info.threadstack_offset = offset;
+ 	addr = vm_unmapped_area(&info);
+ 
  	if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
  		VM_BUG_ON(addr != -ENOMEM);
  		info.low_limit = VA_EXCLUDE_END;
@@ -9984,7 +10369,25 @@ index d2b5944..bd813f2 100644
  		info.high_limit = task_size;
  		addr = vm_unmapped_area(&info);
  	}
-@@ -85,6 +91,12 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+@@ -58,7 +66,8 @@ static unsigned long
+ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 				  const unsigned long len,
+ 				  const unsigned long pgoff,
+-				  const unsigned long flags)
++				  const unsigned long flags,
++				  const unsigned long offset)
+ {
+ 	struct mm_struct *mm = current->mm;
+ 	unsigned long addr = addr0;
+@@ -73,6 +82,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 	info.high_limit = mm->mmap_base;
+ 	info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ 	info.align_offset = 0;
++	info.threadstack_offset = offset;
+ 	addr = vm_unmapped_area(&info);
+ 
+ 	/*
+@@ -85,6 +95,12 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
  		VM_BUG_ON(addr != -ENOMEM);
  		info.flags = 0;
  		info.low_limit = TASK_UNMAPPED_BASE;
@@ -9997,7 +10400,7 @@ index d2b5944..bd813f2 100644
  		info.high_limit = STACK_TOP32;
  		addr = vm_unmapped_area(&info);
  	}
-@@ -99,6 +111,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+@@ -99,6 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
  	struct mm_struct *mm = current->mm;
  	struct vm_area_struct *vma;
  	unsigned long task_size = TASK_SIZE;
@@ -10005,7 +10408,7 @@ index d2b5944..bd813f2 100644
  
  	if (test_thread_flag(TIF_32BIT))
  		task_size = STACK_TOP32;
-@@ -114,11 +127,14 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+@@ -114,19 +131,22 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
  		return addr;
  	}
  
@@ -10022,6 +10425,16 @@ index d2b5944..bd813f2 100644
  			return addr;
  	}
  	if (mm->get_unmapped_area == arch_get_unmapped_area)
+ 		return hugetlb_get_unmapped_area_bottomup(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ 	else
+ 		return hugetlb_get_unmapped_area_topdown(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ }
+ 
+ pte_t *huge_pte_alloc(struct mm_struct *mm,
 diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
 index f4500c6..889656c 100644
 --- a/arch/tile/include/asm/atomic_64.h
@@ -10182,6 +10595,25 @@ index 0032f92..cd151e0 100644
  
  #ifdef CONFIG_64BIT
  #define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval))
+diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h
+index 4febacd..29b0301 100644
+--- a/arch/um/include/asm/tlb.h
++++ b/arch/um/include/asm/tlb.h
+@@ -45,10 +45,12 @@ static inline void init_tlb_gather(struct mmu_gather *tlb)
+ }
+ 
+ static inline void
+-tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
++tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+-	tlb->fullmm = full_mm_flush;
++	tlb->start = start;
++	tlb->end = end;
++	tlb->fullmm = !(start | (end+1));
+ 
+ 	init_tlb_gather(tlb);
+ }
 diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
 index bbcef52..6a2a483 100644
 --- a/arch/um/kernel/process.c
@@ -10961,6 +11393,57 @@ index 477e9d7..3ab339f 100644
  	ret
  ENDPROC(aesni_xts_crypt8)
  
+diff --git a/arch/x86/crypto/blowfish-avx2-asm_64.S b/arch/x86/crypto/blowfish-avx2-asm_64.S
+index 784452e..46982c7 100644
+--- a/arch/x86/crypto/blowfish-avx2-asm_64.S
++++ b/arch/x86/crypto/blowfish-avx2-asm_64.S
+@@ -221,6 +221,7 @@ __blowfish_enc_blk32:
+ 
+ 	write_block(RXl, RXr);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__blowfish_enc_blk32)
+ 
+@@ -250,6 +251,7 @@ __blowfish_dec_blk32:
+ 
+ 	write_block(RXl, RXr);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__blowfish_dec_blk32)
+ 
+@@ -284,6 +286,7 @@ ENTRY(blowfish_ecb_enc_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_ecb_enc_32way)
+ 
+@@ -318,6 +321,7 @@ ENTRY(blowfish_ecb_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_ecb_dec_32way)
+ 
+@@ -365,6 +369,7 @@ ENTRY(blowfish_cbc_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_cbc_dec_32way)
+ 
+@@ -445,5 +450,6 @@ ENTRY(blowfish_ctr_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_ctr_32way)
 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
 --- a/arch/x86/crypto/blowfish-x86_64-asm_64.S
@@ -11016,6 +11499,174 @@ index 246c670..4d1ed00 100644
 +	pax_force_retaddr 0, 1
  	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
+--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+@@ -16,6 +16,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+ 
+@@ -191,6 +192,7 @@ roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ 	roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ 		  %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15,
+ 		  %rcx, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ 
+@@ -199,6 +201,7 @@ roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ 	roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3,
+ 		  %xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11,
+ 		  %rax, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ 
+@@ -780,6 +783,7 @@ __camellia_enc_blk16:
+ 		    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ 		    %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -865,6 +869,7 @@ __camellia_dec_blk16:
+ 		    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ 		    %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -904,6 +909,7 @@ ENTRY(camellia_ecb_enc_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_enc_16way)
+ 
+@@ -932,6 +938,7 @@ ENTRY(camellia_ecb_dec_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_dec_16way)
+ 
+@@ -981,6 +988,7 @@ ENTRY(camellia_cbc_dec_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_cbc_dec_16way)
+ 
+@@ -1092,6 +1100,7 @@ ENTRY(camellia_ctr_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ctr_16way)
+ 
+@@ -1234,6 +1243,7 @@ camellia_xts_crypt_16way:
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	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 91a1878..bcf340a 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 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+ 
+@@ -212,6 +213,7 @@ roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ 	roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ 		  %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15,
+ 		  %rcx, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ 
+@@ -220,6 +222,7 @@ roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ 	roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3,
+ 		  %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11,
+ 		  %rax, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ 
+@@ -802,6 +805,7 @@ __camellia_enc_blk32:
+ 		    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ 		    %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -887,6 +891,7 @@ __camellia_dec_blk32:
+ 		    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ 		    %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -930,6 +935,7 @@ ENTRY(camellia_ecb_enc_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_enc_32way)
+ 
+@@ -962,6 +968,7 @@ ENTRY(camellia_ecb_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_dec_32way)
+ 
+@@ -1028,6 +1035,7 @@ ENTRY(camellia_cbc_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_cbc_dec_32way)
+ 
+@@ -1166,6 +1174,7 @@ ENTRY(camellia_ctr_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ctr_32way)
+ 
+@@ -1331,6 +1340,7 @@ camellia_xts_crypt_32way:
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	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
 --- a/arch/x86/crypto/camellia-x86_64-asm_64.S
@@ -11208,6 +11859,69 @@ index e3531f8..18ded3a 100644
 +	pax_force_retaddr
  	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
+--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
++++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+@@ -45,6 +45,7 @@
+ 
+ #include <asm/inst.h>
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
+ 
+@@ -312,6 +313,7 @@ do_return:
+ 	popq    %rsi
+ 	popq    %rdi
+ 	popq    %rbx
++	pax_force_retaddr 0, 1
+         ret
+ 
+         ################################################################
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+index 586f41a..d02851e 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
++++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+@@ -18,6 +18,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
++#include <asm/alternative-asm.h>
+ 
+ .data
+ 
+@@ -93,6 +94,7 @@ __clmul_gf128mul_ble:
+ 	psrlq $1, T2
+ 	pxor T2, T1
+ 	pxor T1, DATA
++	pax_force_retaddr
+ 	ret
+ ENDPROC(__clmul_gf128mul_ble)
+ 
+@@ -105,6 +107,7 @@ ENTRY(clmul_ghash_mul)
+ 	call __clmul_gf128mul_ble
+ 	PSHUFB_XMM BSWAP DATA
+ 	movups DATA, (%rdi)
++	pax_force_retaddr
+ 	ret
+ ENDPROC(clmul_ghash_mul)
+ 
+@@ -132,6 +135,7 @@ ENTRY(clmul_ghash_update)
+ 	PSHUFB_XMM BSWAP DATA
+ 	movups DATA, (%rdi)
+ .Lupdate_just_ret:
++	pax_force_retaddr
+ 	ret
+ ENDPROC(clmul_ghash_update)
+ 
+@@ -157,5 +161,6 @@ ENTRY(clmul_ghash_setkey)
+ 	pand .Lpoly, %xmm1
+ 	pxor %xmm1, %xmm0
+ 	movups %xmm0, (%rdi)
++	pax_force_retaddr
+ 	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
 --- a/arch/x86/crypto/salsa20-x86_64-asm_64.S
@@ -11316,6 +12030,81 @@ index 2f202f4..d9164d6 100644
 +	pax_force_retaddr
  	ret;
  ENDPROC(serpent_xts_dec_8way_avx)
+diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S
+index b222085..abd483c 100644
+--- a/arch/x86/crypto/serpent-avx2-asm_64.S
++++ b/arch/x86/crypto/serpent-avx2-asm_64.S
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx2.S"
+ 
+ .file "serpent-avx2-asm_64.S"
+@@ -610,6 +611,7 @@ __serpent_enc_blk16:
+ 	write_blocks(RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ 	write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(__serpent_enc_blk16)
+ 
+@@ -664,6 +666,7 @@ __serpent_dec_blk16:
+ 	write_blocks(RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ 	write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(__serpent_dec_blk16)
+ 
+@@ -684,6 +687,7 @@ ENTRY(serpent_ecb_enc_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_enc_16way)
+ 
+@@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_dec_16way)
+ 
+@@ -725,6 +730,7 @@ ENTRY(serpent_cbc_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_cbc_dec_16way)
+ 
+@@ -748,6 +754,7 @@ ENTRY(serpent_ctr_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ctr_16way)
+ 
+@@ -772,6 +779,7 @@ ENTRY(serpent_xts_enc_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_enc_16way)
+ 
+@@ -796,5 +804,6 @@ ENTRY(serpent_xts_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_dec_16way)
 diff --git a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
 index acc066c..1559cc4 100644
 --- a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
@@ -11370,6 +12159,126 @@ index a410950..3356d42 100644
  	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
+--- a/arch/x86/crypto/sha256-avx-asm.S
++++ b/arch/x86/crypto/sha256-avx-asm.S
+@@ -49,6 +49,7 @@
+ 
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define    VMOVDQ vmovdqu
+@@ -460,6 +461,7 @@ done_hash:
+ 	popq    %r13
+ 	popq    %rbp
+ 	popq    %rbx
++	pax_force_retaddr 0, 1
+ 	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
+--- a/arch/x86/crypto/sha256-avx2-asm.S
++++ b/arch/x86/crypto/sha256-avx2-asm.S
+@@ -50,6 +50,7 @@
+ 
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define	VMOVDQ vmovdqu
+@@ -720,6 +721,7 @@ done_hash:
+ 	popq	%r12
+ 	popq	%rbp
+ 	popq	%rbx
++	pax_force_retaddr 0, 1
+ 	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
+--- a/arch/x86/crypto/sha256-ssse3-asm.S
++++ b/arch/x86/crypto/sha256-ssse3-asm.S
+@@ -47,6 +47,7 @@
+ ########################################################################
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define    MOVDQ movdqu
+@@ -471,6 +472,7 @@ done_hash:
+ 	popq    %rbp
+ 	popq    %rbx
+ 
++	pax_force_retaddr 0, 1
+ 	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
+--- a/arch/x86/crypto/sha512-avx-asm.S
++++ b/arch/x86/crypto/sha512-avx-asm.S
+@@ -49,6 +49,7 @@
+ 
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -364,6 +365,7 @@ updateblock:
+ 	mov	frame_RSPSAVE(%rsp), %rsp
+ 
+ nowork:
++	pax_force_retaddr 0, 1
+ 	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
+--- a/arch/x86/crypto/sha512-avx2-asm.S
++++ b/arch/x86/crypto/sha512-avx2-asm.S
+@@ -51,6 +51,7 @@
+ 
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -678,6 +679,7 @@ done_hash:
+ 
+ 	# Restore Stack Pointer
+ 	mov	frame_RSPSAVE(%rsp), %rsp
++	pax_force_retaddr 0, 1
+ 	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
+--- a/arch/x86/crypto/sha512-ssse3-asm.S
++++ b/arch/x86/crypto/sha512-ssse3-asm.S
+@@ -48,6 +48,7 @@
+ ########################################################################
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -363,6 +364,7 @@ updateblock:
+ 	mov	frame_RSPSAVE(%rsp), %rsp
+ 
+ nowork:
++	pax_force_retaddr 0, 1
+ 	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
 --- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
@@ -11445,6 +12354,74 @@ index 0505813..63b1d00 100644
 +	pax_force_retaddr 0, 1
  	ret;
  ENDPROC(twofish_xts_dec_8way)
+diff --git a/arch/x86/crypto/twofish-avx2-asm_64.S b/arch/x86/crypto/twofish-avx2-asm_64.S
+index e1a83b9..33006b9 100644
+--- a/arch/x86/crypto/twofish-avx2-asm_64.S
++++ b/arch/x86/crypto/twofish-avx2-asm_64.S
+@@ -11,6 +11,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx2.S"
+ 
+ .file "twofish-avx2-asm_64.S"
+@@ -422,6 +423,7 @@ __twofish_enc_blk16:
+ 	outunpack_enc16(RA, RB, RC, RD);
+ 	write_blocks16(RA, RB, RC, RD);
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(__twofish_enc_blk16)
+ 
+@@ -454,6 +456,7 @@ __twofish_dec_blk16:
+ 	outunpack_dec16(RA, RB, RC, RD);
+ 	write_blocks16(RA, RB, RC, RD);
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(__twofish_dec_blk16)
+ 
+@@ -476,6 +479,7 @@ ENTRY(twofish_ecb_enc_16way)
+ 	popq %r12;
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ecb_enc_16way)
+ 
+@@ -498,6 +502,7 @@ ENTRY(twofish_ecb_dec_16way)
+ 	popq %r12;
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ecb_dec_16way)
+ 
+@@ -521,6 +526,7 @@ ENTRY(twofish_cbc_dec_16way)
+ 	popq %r12;
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_cbc_dec_16way)
+ 
+@@ -546,6 +552,7 @@ ENTRY(twofish_ctr_16way)
+ 	popq %r12;
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ctr_16way)
+ 
+@@ -574,6 +581,7 @@ twofish_xts_crypt_16way:
+ 	popq %r12;
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_xts_crypt_16way)
+ 
 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
 --- a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
@@ -11521,7 +12498,7 @@ index 52ff81c..98af645 100644
  	set_fs(KERNEL_DS);
  	has_dumped = 1;
 diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
-index cf1a471..3bc4cf8 100644
+index cf1a471..5ba2673 100644
 --- a/arch/x86/ia32/ia32_signal.c
 +++ b/arch/x86/ia32/ia32_signal.c
 @@ -340,7 +340,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
@@ -11551,7 +12528,12 @@ index cf1a471..3bc4cf8 100644
  	};
  
  	frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
-@@ -463,16 +463,18 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
+@@ -459,20 +459,22 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
+ 		else
+ 			put_user_ex(0, &frame->uc.uc_flags);
+ 		put_user_ex(0, &frame->uc.uc_link);
+-		err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
++		__compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
  
  		if (ksig->ka.sa.sa_flags & SA_RESTORER)
  			restorer = ksig->ka.sa.sa_restorer;
@@ -11574,7 +12556,7 @@ index cf1a471..3bc4cf8 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 474dc1b..24aaa3e 100644
+index 474dc1b..9297c58 100644
 --- a/arch/x86/ia32/ia32entry.S
 +++ b/arch/x86/ia32/ia32entry.S
 @@ -15,8 +15,10 @@
@@ -11634,7 +12616,7 @@ index 474dc1b..24aaa3e 100644
   	movl	%ebp,%ebp		/* zero extension */
  	pushq_cfi $__USER32_DS
  	/*CFI_REL_OFFSET ss,0*/
-@@ -135,24 +157,44 @@ ENTRY(ia32_sysenter_target)
+@@ -135,24 +157,49 @@ ENTRY(ia32_sysenter_target)
  	CFI_REL_OFFSET rsp,0
  	pushfq_cfi
  	/*CFI_REL_OFFSET rflags,0*/
@@ -11668,8 +12650,8 @@ index 474dc1b..24aaa3e 100644
   	   32bit zero extended */ 
 +
 +#ifdef CONFIG_PAX_MEMORY_UDEREF
-+	mov pax_user_shadow_base,%r11
-+	add %r11,%rbp
++	addq	pax_user_shadow_base,%rbp
++	ASM_PAX_OPEN_USERLAND
 +#endif
 +
  	ASM_STAC
@@ -11678,13 +12660,18 @@ index 474dc1b..24aaa3e 100644
  	ASM_CLAC
 -	orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
 -	testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
 +	GET_THREAD_INFO(%r11)
 +	orl    $TS_COMPAT,TI_status(%r11)
 +	testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
  	CFI_REMEMBER_STATE
  	jnz  sysenter_tracesys
  	cmpq	$(IA32_NR_syscalls-1),%rax
-@@ -162,12 +204,15 @@ sysenter_do_call:
+@@ -162,12 +209,15 @@ sysenter_do_call:
  sysenter_dispatch:
  	call	*ia32_sys_call_table(,%rax,8)
  	movq	%rax,RAX-ARGOFFSET(%rsp)
@@ -11702,7 +12689,7 @@ index 474dc1b..24aaa3e 100644
  	/* clear IF, that popfq doesn't enable interrupts early */
  	andl  $~0x200,EFLAGS-R11(%rsp) 
  	movl	RIP-R11(%rsp),%edx		/* User %eip */
-@@ -193,6 +238,9 @@ sysexit_from_sys_call:
+@@ -193,6 +243,9 @@ sysexit_from_sys_call:
  	movl %eax,%esi			/* 2nd arg: syscall number */
  	movl $AUDIT_ARCH_I386,%edi	/* 1st arg: audit arch */
  	call __audit_syscall_entry
@@ -11712,7 +12699,7 @@ index 474dc1b..24aaa3e 100644
  	movl RAX-ARGOFFSET(%rsp),%eax	/* reload syscall number */
  	cmpq $(IA32_NR_syscalls-1),%rax
  	ja ia32_badsys
-@@ -204,7 +252,7 @@ sysexit_from_sys_call:
+@@ -204,7 +257,7 @@ sysexit_from_sys_call:
  	.endm
  
  	.macro auditsys_exit exit
@@ -11721,7 +12708,7 @@ index 474dc1b..24aaa3e 100644
  	jnz ia32_ret_from_sys_call
  	TRACE_IRQS_ON
  	ENABLE_INTERRUPTS(CLBR_NONE)
-@@ -215,11 +263,12 @@ sysexit_from_sys_call:
+@@ -215,11 +268,12 @@ sysexit_from_sys_call:
  1:	setbe %al		/* 1 if error, 0 if not */
  	movzbl %al,%edi		/* zero-extend that into %edi */
  	call __audit_syscall_exit
@@ -11735,7 +12722,7 @@ index 474dc1b..24aaa3e 100644
  	jz \exit
  	CLEAR_RREGS -ARGOFFSET
  	jmp int_with_check
-@@ -237,7 +286,7 @@ sysexit_audit:
+@@ -237,7 +291,7 @@ sysexit_audit:
  
  sysenter_tracesys:
  #ifdef CONFIG_AUDITSYSCALL
@@ -11744,7 +12731,7 @@ index 474dc1b..24aaa3e 100644
  	jz	sysenter_auditsys
  #endif
  	SAVE_REST
-@@ -249,6 +298,9 @@ sysenter_tracesys:
+@@ -249,6 +303,9 @@ sysenter_tracesys:
  	RESTORE_REST
  	cmpq	$(IA32_NR_syscalls-1),%rax
  	ja	int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
@@ -11754,7 +12741,7 @@ index 474dc1b..24aaa3e 100644
  	jmp	sysenter_do_call
  	CFI_ENDPROC
  ENDPROC(ia32_sysenter_target)
-@@ -276,19 +328,25 @@ ENDPROC(ia32_sysenter_target)
+@@ -276,19 +333,25 @@ ENDPROC(ia32_sysenter_target)
  ENTRY(ia32_cstar_target)
  	CFI_STARTPROC32	simple
  	CFI_SIGNAL_FRAME
@@ -11782,14 +12769,15 @@ index 474dc1b..24aaa3e 100644
  	movl 	%eax,%eax	/* zero extension */
  	movq	%rax,ORIG_RAX-ARGOFFSET(%rsp)
  	movq	%rcx,RIP-ARGOFFSET(%rsp)
-@@ -304,12 +362,19 @@ ENTRY(ia32_cstar_target)
+@@ -304,12 +367,25 @@ ENTRY(ia32_cstar_target)
  	/* no need to do an access_ok check here because r8 has been
  	   32bit zero extended */ 
  	/* hardware stack frame is complete now */	
 +
 +#ifdef CONFIG_PAX_MEMORY_UDEREF
-+	mov pax_user_shadow_base,%r11
-+	add %r11,%r8
++	ASM_PAX_OPEN_USERLAND
++	movq	pax_user_shadow_base,%r8
++	addq	RSP-ARGOFFSET(%rsp),%r8
 +#endif
 +
  	ASM_STAC
@@ -11798,13 +12786,18 @@ index 474dc1b..24aaa3e 100644
  	ASM_CLAC
 -	orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
 -	testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
 +	GET_THREAD_INFO(%r11)
 +	orl   $TS_COMPAT,TI_status(%r11)
 +	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
  	CFI_REMEMBER_STATE
  	jnz   cstar_tracesys
  	cmpq $IA32_NR_syscalls-1,%rax
-@@ -319,12 +384,15 @@ cstar_do_call:
+@@ -319,12 +395,15 @@ cstar_do_call:
  cstar_dispatch:
  	call *ia32_sys_call_table(,%rax,8)
  	movq %rax,RAX-ARGOFFSET(%rsp)
@@ -11822,7 +12815,7 @@ index 474dc1b..24aaa3e 100644
  	RESTORE_ARGS 0,-ARG_SKIP,0,0,0
  	movl RIP-ARGOFFSET(%rsp),%ecx
  	CFI_REGISTER rip,rcx
-@@ -352,7 +420,7 @@ sysretl_audit:
+@@ -352,7 +431,7 @@ sysretl_audit:
  
  cstar_tracesys:
  #ifdef CONFIG_AUDITSYSCALL
@@ -11831,7 +12824,7 @@ index 474dc1b..24aaa3e 100644
  	jz cstar_auditsys
  #endif
  	xchgl %r9d,%ebp
-@@ -366,6 +434,9 @@ cstar_tracesys:
+@@ -366,11 +445,19 @@ cstar_tracesys:
  	xchgl %ebp,%r9d
  	cmpq $(IA32_NR_syscalls-1),%rax
  	ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
@@ -11841,7 +12834,17 @@ index 474dc1b..24aaa3e 100644
  	jmp cstar_do_call
  END(ia32_cstar_target)
  				
-@@ -407,19 +478,26 @@ ENTRY(ia32_syscall)
+ ia32_badarg:
+ 	ASM_CLAC
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
+ 	movq $-EFAULT,%rax
+ 	jmp ia32_sysret
+ 	CFI_ENDPROC
+@@ -407,19 +494,26 @@ ENTRY(ia32_syscall)
  	CFI_REL_OFFSET	rip,RIP-RIP
  	PARAVIRT_ADJUST_EXCEPTION_FRAME
  	SWAPGS
@@ -11875,7 +12878,7 @@ index 474dc1b..24aaa3e 100644
  	jnz ia32_tracesys
  	cmpq $(IA32_NR_syscalls-1),%rax
  	ja ia32_badsys
-@@ -442,6 +520,9 @@ ia32_tracesys:
+@@ -442,6 +536,9 @@ ia32_tracesys:
  	RESTORE_REST
  	cmpq $(IA32_NR_syscalls-1),%rax
  	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
@@ -13112,9 +14115,18 @@ index 59c6c40..5e0b22c 100644
  struct compat_timespec {
  	compat_time_t	tv_sec;
 diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
-index e99ac27..e89e28c 100644
+index e99ac27..10d834e 100644
 --- a/arch/x86/include/asm/cpufeature.h
 +++ b/arch/x86/include/asm/cpufeature.h
+@@ -203,7 +203,7 @@
+ #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
+ #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
+ #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
+-
++#define X86_FEATURE_STRONGUDEREF (8*32+31) /* PaX PCID based strong UDEREF */
+ 
+ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+ #define X86_FEATURE_FSGSBASE	(9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
 @@ -211,7 +211,7 @@
  #define X86_FEATURE_BMI1	(9*32+ 3) /* 1st group bit manipulation extensions */
  #define X86_FEATURE_HLE		(9*32+ 4) /* Hardware Lock Elision */
@@ -13124,7 +14136,15 @@ index e99ac27..e89e28c 100644
  #define X86_FEATURE_BMI2	(9*32+ 8) /* 2nd group bit manipulation extensions */
  #define X86_FEATURE_ERMS	(9*32+ 9) /* Enhanced REP MOVSB/STOSB */
  #define X86_FEATURE_INVPCID	(9*32+10) /* Invalidate Processor Context ID */
-@@ -394,7 +394,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
+@@ -353,6 +353,7 @@ extern const char * const x86_power_flags[32];
+ #undef  cpu_has_centaur_mcr
+ #define cpu_has_centaur_mcr	0
+ 
++#define cpu_has_pcid		boot_cpu_has(X86_FEATURE_PCID)
+ #endif /* CONFIG_X86_64 */
+ 
+ #if __GNUC__ >= 4
+@@ -394,7 +395,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
  			     ".section .discard,\"aw\",@progbits\n"
  			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
  			     ".previous\n"
@@ -13447,12 +14467,14 @@ index 75ce3f4..882e801 100644
  
  #endif /* _ASM_X86_EMERGENCY_RESTART_H */
 diff --git a/arch/x86/include/asm/fpu-internal.h b/arch/x86/include/asm/fpu-internal.h
-index e25cc33..425d099 100644
+index e25cc33..7d3ec01 100644
 --- a/arch/x86/include/asm/fpu-internal.h
 +++ b/arch/x86/include/asm/fpu-internal.h
-@@ -127,7 +127,9 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
+@@ -126,8 +126,11 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
+ #define user_insn(insn, output, input...)				\
  ({									\
  	int err;							\
++	pax_open_userland();						\
  	asm volatile(ASM_STAC "\n"					\
 -		     "1:" #insn "\n\t"					\
 +		     "1:"						\
@@ -13461,7 +14483,15 @@ index e25cc33..425d099 100644
  		     "2: " ASM_CLAC "\n"				\
  		     ".section .fixup,\"ax\"\n"				\
  		     "3:  movl $-1,%[err]\n"				\
-@@ -300,7 +302,7 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
+@@ -136,6 +139,7 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
+ 		     _ASM_EXTABLE(1b, 3b)				\
+ 		     : [err] "=r" (err), output				\
+ 		     : "0"(0), input);					\
++	pax_close_userland();						\
+ 	err;								\
+ })
+ 
+@@ -300,7 +304,7 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
  		"emms\n\t"		/* clear stack tags */
  		"fildl %P[addr]",	/* set F?P to defined value */
  		X86_FEATURE_FXSAVE_LEAK,
@@ -13471,7 +14501,7 @@ index e25cc33..425d099 100644
  	return fpu_restore_checking(&tsk->thread.fpu);
  }
 diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h
-index be27ba1..8f13ff9 100644
+index be27ba1..04a8801 100644
 --- a/arch/x86/include/asm/futex.h
 +++ b/arch/x86/include/asm/futex.h
 @@ -12,6 +12,7 @@
@@ -13510,8 +14540,11 @@ index be27ba1..8f13ff9 100644
  		     : "r" (oparg), "i" (-EFAULT), "1" (0))
  
  static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
-@@ -59,10 +61,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+@@ -57,12 +59,13 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+ 
+ 	pagefault_disable();
  
++	pax_open_userland();
  	switch (op) {
  	case FUTEX_OP_SET:
 -		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
@@ -13523,9 +14556,19 @@ index be27ba1..8f13ff9 100644
  				   uaddr, oparg);
  		break;
  	case FUTEX_OP_OR:
-@@ -116,14 +118,14 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+@@ -77,6 +80,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+ 	default:
+ 		ret = -ENOSYS;
+ 	}
++	pax_close_userland();
+ 
+ 	pagefault_enable();
+ 
+@@ -115,18 +119,20 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
  		return -EFAULT;
  
++	pax_open_userland();
  	asm volatile("\t" ASM_STAC "\n"
 -		     "1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n"
 +		     "1:\t" LOCK_PREFIX __copyuser_seg"cmpxchgl %4, %2\n"
@@ -13540,6 +14583,10 @@ index be27ba1..8f13ff9 100644
  		     : "i" (-EFAULT), "r" (newval), "1" (oldval)
  		     : "memory"
  	);
++	pax_close_userland();
+ 
+ 	*uval = oldval;
+ 	return ret;
 diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
 index 1da97ef..9c2ebff 100644
 --- a/arch/x86/include/asm/hw_irq.h
@@ -13926,29 +14973,31 @@ index 5f55e69..e20bfb1 100644
  
  #ifdef CONFIG_SMP
 diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
-index cdbf367..adb37ac 100644
+index cdbf367..4c73c9e 100644
 --- a/arch/x86/include/asm/mmu_context.h
 +++ b/arch/x86/include/asm/mmu_context.h
-@@ -24,6 +24,18 @@ void destroy_context(struct mm_struct *mm);
+@@ -24,6 +24,20 @@ void destroy_context(struct mm_struct *mm);
  
  static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  {
 +
 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
-+	unsigned int i;
-+	pgd_t *pgd;
++	if (!(static_cpu_has(X86_FEATURE_PCID))) {
++		unsigned int i;
++		pgd_t *pgd;
 +
-+	pax_open_kernel();
-+	pgd = get_cpu_pgd(smp_processor_id());
-+	for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
-+		set_pgd_batched(pgd+i, native_make_pgd(0));
-+	pax_close_kernel();
++		pax_open_kernel();
++		pgd = get_cpu_pgd(smp_processor_id(), kernel);
++		for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
++			set_pgd_batched(pgd+i, native_make_pgd(0));
++		pax_close_kernel();
++	}
 +#endif
 +
  #ifdef CONFIG_SMP
  	if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
  		this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
-@@ -34,16 +46,30 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+@@ -34,16 +48,55 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  			     struct task_struct *tsk)
  {
  	unsigned cpu = smp_processor_id();
@@ -13969,17 +15018,42 @@ index cdbf367..adb37ac 100644
  		/* Re-load page tables */
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +		pax_open_kernel();
-+		__clone_user_pgds(get_cpu_pgd(cpu), next->pgd);
-+		__shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd);
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID))
++			__clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd);
++		else
++#endif
++
++		__clone_user_pgds(get_cpu_pgd(cpu, kernel), next->pgd);
++		__shadow_user_pgds(get_cpu_pgd(cpu, kernel) + USER_PGD_PTRS, next->pgd);
 +		pax_close_kernel();
-+		load_cr3(get_cpu_pgd(cpu));
++		BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & __PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & __PHYSICAL_MASK));
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID)) {
++			if (static_cpu_has(X86_FEATURE_INVPCID)) {
++				unsigned long descriptor[2];
++				descriptor[0] = PCID_USER;
++				asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_CONTEXT) : "memory");
++			} else {
++				write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++				if (static_cpu_has(X86_FEATURE_STRONGUDEREF))
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++				else
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++			}
++		} else
++#endif
++
++			load_cr3(get_cpu_pgd(cpu, kernel));
 +#else
  		load_cr3(next->pgd);
 +#endif
  
  		/* stop flush ipis for the previous mm */
  		cpumask_clear_cpu(cpu, mm_cpumask(prev));
-@@ -53,9 +79,38 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+@@ -53,9 +106,63 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  		 */
  		if (unlikely(prev->context.ldt != next->context.ldt))
  			load_LDT_nolock(&next->context);
@@ -14009,17 +15083,42 @@ index cdbf367..adb37ac 100644
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +		pax_open_kernel();
-+		__clone_user_pgds(get_cpu_pgd(cpu), next->pgd);
-+		__shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd);
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID))
++			__clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd);
++		else
++#endif
++
++		__clone_user_pgds(get_cpu_pgd(cpu, kernel), next->pgd);
++		__shadow_user_pgds(get_cpu_pgd(cpu, kernel) + USER_PGD_PTRS, next->pgd);
 +		pax_close_kernel();
-+		load_cr3(get_cpu_pgd(cpu));
++		BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & __PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & __PHYSICAL_MASK));
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID)) {
++			if (static_cpu_has(X86_FEATURE_INVPCID)) {
++				unsigned long descriptor[2];
++				descriptor[0] = PCID_USER;
++				asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_CONTEXT) : "memory");
++			} else {
++				write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++				if (static_cpu_has(X86_FEATURE_STRONGUDEREF))
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++				else
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++			}
++		} else
++#endif
++
++			load_cr3(get_cpu_pgd(cpu, kernel));
 +#endif
 +
 +#ifdef CONFIG_SMP
  		this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
  		BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
  
-@@ -64,11 +119,28 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+@@ -64,11 +171,28 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  			 * tlb flush IPI delivery. We must reload CR3
  			 * to make sure to use no freed page tables.
  			 */
@@ -14384,7 +15483,7 @@ index 4cc9f2b..5fd9226 100644
  
  /*
 diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
-index 1e67223..dd6e7ea 100644
+index 1e67223..92a9585 100644
 --- a/arch/x86/include/asm/pgtable.h
 +++ b/arch/x86/include/asm/pgtable.h
 @@ -44,6 +44,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page);
@@ -14490,23 +15589,24 @@ index 1e67223..dd6e7ea 100644
  }
  
  static inline pte_t pte_mkdirty(pte_t pte)
-@@ -394,6 +459,15 @@ pte_t *populate_extra_pte(unsigned long vaddr);
+@@ -394,6 +459,16 @@ pte_t *populate_extra_pte(unsigned long vaddr);
  #endif
  
  #ifndef __ASSEMBLY__
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+extern pgd_t cpu_pgd[NR_CPUS][PTRS_PER_PGD];
-+static inline pgd_t *get_cpu_pgd(unsigned int cpu)
++extern pgd_t cpu_pgd[NR_CPUS][2][PTRS_PER_PGD];
++enum cpu_pgd_type {kernel = 0, user = 1};
++static inline pgd_t *get_cpu_pgd(unsigned int cpu, enum cpu_pgd_type type)
 +{
-+	return cpu_pgd[cpu];
++	return cpu_pgd[cpu][type];
 +}
 +#endif
 +
  #include <linux/mm_types.h>
  #include <linux/log2.h>
  
-@@ -529,7 +603,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
+@@ -529,7 +604,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
   * Currently stuck as a macro due to indirect forward reference to
   * linux/mmzone.h's __section_mem_map_addr() definition:
   */
@@ -14515,7 +15615,7 @@ index 1e67223..dd6e7ea 100644
  
  /* Find an entry in the second-level page table.. */
  static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
-@@ -569,7 +643,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+@@ -569,7 +644,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
   * Currently stuck as a macro due to indirect forward reference to
   * linux/mmzone.h's __section_mem_map_addr() definition:
   */
@@ -14524,7 +15624,7 @@ index 1e67223..dd6e7ea 100644
  
  /* to find an entry in a page-table-directory. */
  static inline unsigned long pud_index(unsigned long address)
-@@ -584,7 +658,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+@@ -584,7 +659,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
  
  static inline int pgd_bad(pgd_t pgd)
  {
@@ -14533,7 +15633,7 @@ index 1e67223..dd6e7ea 100644
  }
  
  static inline int pgd_none(pgd_t pgd)
-@@ -607,7 +681,12 @@ static inline int pgd_none(pgd_t pgd)
+@@ -607,7 +682,12 @@ static inline int pgd_none(pgd_t pgd)
   * pgd_offset() returns a (pgd_t *)
   * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
   */
@@ -14541,13 +15641,13 @@ index 1e67223..dd6e7ea 100644
 +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+#define pgd_offset_cpu(cpu, address) (get_cpu_pgd(cpu) + pgd_index(address))
++#define pgd_offset_cpu(cpu, type, address) (get_cpu_pgd(cpu, type) + pgd_index(address))
 +#endif
 +
  /*
   * a shortcut which implies the use of the kernel's pgd, instead
   * of a process's
-@@ -618,6 +697,22 @@ static inline int pgd_none(pgd_t pgd)
+@@ -618,6 +698,23 @@ static inline int pgd_none(pgd_t pgd)
  #define KERNEL_PGD_BOUNDARY	pgd_index(PAGE_OFFSET)
  #define KERNEL_PGD_PTRS		(PTRS_PER_PGD - KERNEL_PGD_BOUNDARY)
  
@@ -14562,6 +15662,7 @@ index 1e67223..dd6e7ea 100644
 +#define pax_user_shadow_base	pax_user_shadow_base(%rip)
 +#else
 +extern unsigned long pax_user_shadow_base;
++extern pgdval_t clone_pgd_mask;
 +#endif
 +#endif
 +
@@ -14570,7 +15671,7 @@ index 1e67223..dd6e7ea 100644
  #ifndef __ASSEMBLY__
  
  extern int direct_gbpages;
-@@ -784,11 +879,24 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
+@@ -784,11 +881,24 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
   * dst and src can be on the same page, but the range must not overlap,
   * and must not cross a page boundary.
   */
@@ -14862,10 +15963,33 @@ index e642300..0ef8f31 100644
  #define pgprot_writecombine	pgprot_writecombine
  extern pgprot_t pgprot_writecombine(pgprot_t prot);
 diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
-index 22224b3..30c80ca 100644
+index 22224b3..c5d8d7d 100644
 --- a/arch/x86/include/asm/processor.h
 +++ b/arch/x86/include/asm/processor.h
-@@ -282,7 +282,7 @@ struct tss_struct {
+@@ -198,9 +198,21 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
+ 	    : "memory");
+ }
+ 
++/* invpcid (%rdx),%rax */
++#define __ASM_INVPCID ".byte 0x66,0x0f,0x38,0x82,0x02"
++
++#define INVPCID_SINGLE_ADDRESS	0UL
++#define INVPCID_SINGLE_CONTEXT	1UL
++#define INVPCID_ALL_GLOBAL	2UL
++#define INVPCID_ALL_MONGLOBAL	3UL
++
++#define PCID_KERNEL		0UL
++#define PCID_USER		1UL
++#define PCID_NOFLUSH		(1UL << 63)
++
+ static inline void load_cr3(pgd_t *pgdir)
+ {
+-	write_cr3(__pa(pgdir));
++	write_cr3(__pa(pgdir) | PCID_KERNEL);
+ }
+ 
+ #ifdef CONFIG_X86_32
+@@ -282,7 +294,7 @@ struct tss_struct {
  
  } ____cacheline_aligned;
  
@@ -14874,7 +15998,15 @@ index 22224b3..30c80ca 100644
  
  /*
   * Save the original ist values for checking stack pointers during debugging
-@@ -823,11 +823,18 @@ static inline void spin_lock_prefetch(const void *x)
+@@ -452,6 +464,7 @@ struct thread_struct {
+ 	unsigned short		ds;
+ 	unsigned short		fsindex;
+ 	unsigned short		gsindex;
++	unsigned short		ss;
+ #endif
+ #ifdef CONFIG_X86_32
+ 	unsigned long		ip;
+@@ -823,11 +836,18 @@ static inline void spin_lock_prefetch(const void *x)
   */
  #define TASK_SIZE		PAGE_OFFSET
  #define TASK_SIZE_MAX		TASK_SIZE
@@ -14895,7 +16027,7 @@ index 22224b3..30c80ca 100644
  	.vm86_info		= NULL,					  \
  	.sysenter_cs		= __KERNEL_CS,				  \
  	.io_bitmap_ptr		= NULL,					  \
-@@ -841,7 +848,7 @@ static inline void spin_lock_prefetch(const void *x)
+@@ -841,7 +861,7 @@ static inline void spin_lock_prefetch(const void *x)
   */
  #define INIT_TSS  {							  \
  	.x86_tss = {							  \
@@ -14904,7 +16036,7 @@ index 22224b3..30c80ca 100644
  		.ss0		= __KERNEL_DS,				  \
  		.ss1		= __KERNEL_CS,				  \
  		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,		  \
-@@ -852,11 +859,7 @@ static inline void spin_lock_prefetch(const void *x)
+@@ -852,11 +872,7 @@ static inline void spin_lock_prefetch(const void *x)
  extern unsigned long thread_saved_pc(struct task_struct *tsk);
  
  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
@@ -14917,7 +16049,7 @@ index 22224b3..30c80ca 100644
  
  /*
   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
-@@ -871,7 +874,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+@@ -871,7 +887,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
  #define task_pt_regs(task)                                             \
  ({                                                                     \
         struct pt_regs *__regs__;                                       \
@@ -14926,7 +16058,7 @@ index 22224b3..30c80ca 100644
         __regs__ - 1;                                                   \
  })
  
-@@ -881,13 +884,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+@@ -881,13 +897,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
  /*
   * User space process size. 47bits minus one guard page.
   */
@@ -14942,7 +16074,7 @@ index 22224b3..30c80ca 100644
  
  #define TASK_SIZE		(test_thread_flag(TIF_ADDR32) ? \
  					IA32_PAGE_OFFSET : TASK_SIZE_MAX)
-@@ -898,11 +901,11 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+@@ -898,11 +914,11 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
  #define STACK_TOP_MAX		TASK_SIZE_MAX
  
  #define INIT_THREAD  { \
@@ -14956,7 +16088,7 @@ index 22224b3..30c80ca 100644
  }
  
  /*
-@@ -930,6 +933,10 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
+@@ -930,6 +946,10 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
   */
  #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
  
@@ -14967,7 +16099,7 @@ index 22224b3..30c80ca 100644
  #define KSTK_EIP(task)		(task_pt_regs(task)->ip)
  
  /* Get/set a process' ability to use the timestamp counter instruction */
-@@ -942,7 +949,8 @@ extern int set_tsc_mode(unsigned int val);
+@@ -942,7 +962,8 @@ extern int set_tsc_mode(unsigned int val);
  extern u16 amd_get_nb_id(int cpu);
  
  struct aperfmperf {
@@ -14977,7 +16109,7 @@ index 22224b3..30c80ca 100644
  };
  
  static inline void get_aperfmperf(struct aperfmperf *am)
-@@ -970,7 +978,7 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
+@@ -970,7 +991,7 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
  	return ratio;
  }
  
@@ -14986,7 +16118,7 @@ index 22224b3..30c80ca 100644
  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
  
  void default_idle(void);
-@@ -980,6 +988,6 @@ bool xen_set_default_idle(void);
+@@ -980,6 +1001,6 @@ bool xen_set_default_idle(void);
  #define xen_set_default_idle 0
  #endif
  
@@ -15234,7 +16366,7 @@ index cad82c9..2e5c5c1 100644
  
  #endif /* __KERNEL__ */
 diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
-index c48a950..c6d7468 100644
+index c48a950..bc40804 100644
 --- a/arch/x86/include/asm/segment.h
 +++ b/arch/x86/include/asm/segment.h
 @@ -64,10 +64,15 @@
@@ -15295,15 +16427,32 @@ index c48a950..c6d7468 100644
  #define GDT_ENTRY_TSS 8	/* needs two entries */
  #define GDT_ENTRY_LDT 10 /* needs two entries */
  #define GDT_ENTRY_TLS_MIN 12
-@@ -185,6 +200,7 @@
+@@ -173,6 +188,8 @@
+ #define GDT_ENTRY_PER_CPU 15	/* Abused to load per CPU data from limit */
+ #define __PER_CPU_SEG	(GDT_ENTRY_PER_CPU * 8 + 3)
+ 
++#define GDT_ENTRY_UDEREF_KERNEL_DS 16
++
+ /* TLS indexes for 64bit - hardcoded in arch_prctl */
+ #define FS_TLS 0
+ #define GS_TLS 1
+@@ -180,12 +197,14 @@
+ #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3)
+ #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)
+ 
+-#define GDT_ENTRIES 16
++#define GDT_ENTRIES 17
+ 
  #endif
  
  #define __KERNEL_CS	(GDT_ENTRY_KERNEL_CS*8)
 +#define __KERNEXEC_KERNEL_CS	(GDT_ENTRY_KERNEXEC_KERNEL_CS*8)
  #define __KERNEL_DS	(GDT_ENTRY_KERNEL_DS*8)
++#define __UDEREF_KERNEL_DS	(GDT_ENTRY_UDEREF_KERNEL_DS*8)
  #define __USER_DS	(GDT_ENTRY_DEFAULT_USER_DS*8+3)
  #define __USER_CS	(GDT_ENTRY_DEFAULT_USER_CS*8+3)
-@@ -265,7 +281,7 @@ static inline unsigned long get_limit(unsigned long segment)
+ #ifndef CONFIG_PARAVIRT
+@@ -265,7 +284,7 @@ static inline unsigned long get_limit(unsigned long segment)
  {
  	unsigned long __limit;
  	asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
@@ -15312,6 +16461,99 @@ index c48a950..c6d7468 100644
  }
  
  #endif /* !__ASSEMBLY__ */
+diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
+index 8d3120f..352b440 100644
+--- a/arch/x86/include/asm/smap.h
++++ b/arch/x86/include/asm/smap.h
+@@ -25,11 +25,40 @@
+ 
+ #include <asm/alternative-asm.h>
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define ASM_PAX_OPEN_USERLAND					\
++	661: jmp 663f;						\
++	.pushsection .altinstr_replacement, "a" ;		\
++	662: pushq %rax; nop;					\
++	.popsection ;						\
++	.pushsection .altinstructions, "a" ;			\
++	altinstruction_entry 661b, 662b, X86_FEATURE_STRONGUDEREF, 2, 2;\
++	.popsection ;						\
++	call __pax_open_userland;				\
++	popq %rax;						\
++	663:
++
++#define ASM_PAX_CLOSE_USERLAND					\
++	661: jmp 663f;						\
++	.pushsection .altinstr_replacement, "a" ;		\
++	662: pushq %rax; nop;					\
++	.popsection;						\
++	.pushsection .altinstructions, "a" ;			\
++	altinstruction_entry 661b, 662b, X86_FEATURE_STRONGUDEREF, 2, 2;\
++	.popsection;						\
++	call __pax_close_userland;				\
++	popq %rax;						\
++	663:
++#else
++#define ASM_PAX_OPEN_USERLAND
++#define ASM_PAX_CLOSE_USERLAND
++#endif
++
+ #ifdef CONFIG_X86_SMAP
+ 
+ #define ASM_CLAC							\
+ 	661: ASM_NOP3 ;							\
+-	.pushsection .altinstr_replacement, "ax" ;			\
++	.pushsection .altinstr_replacement, "a" ;			\
+ 	662: __ASM_CLAC ;						\
+ 	.popsection ;							\
+ 	.pushsection .altinstructions, "a" ;				\
+@@ -38,7 +67,7 @@
+ 
+ #define ASM_STAC							\
+ 	661: ASM_NOP3 ;							\
+-	.pushsection .altinstr_replacement, "ax" ;			\
++	.pushsection .altinstr_replacement, "a" ;			\
+ 	662: __ASM_STAC ;						\
+ 	.popsection ;							\
+ 	.pushsection .altinstructions, "a" ;				\
+@@ -56,6 +85,37 @@
+ 
+ #include <asm/alternative.h>
+ 
++#define __HAVE_ARCH_PAX_OPEN_USERLAND
++#define __HAVE_ARCH_PAX_CLOSE_USERLAND
++
++extern void __pax_open_userland(void);
++static __always_inline unsigned long pax_open_userland(void)
++{
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	asm volatile(ALTERNATIVE(ASM_NOP5, "call %P[open]", X86_FEATURE_STRONGUDEREF)
++		:
++		: [open] "i" (__pax_open_userland)
++		: "memory", "rax");
++#endif
++
++	return 0;
++}
++
++extern void __pax_close_userland(void);
++static __always_inline unsigned long pax_close_userland(void)
++{
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	asm volatile(ALTERNATIVE(ASM_NOP5, "call %P[close]", X86_FEATURE_STRONGUDEREF)
++		:
++		: [close] "i" (__pax_close_userland)
++		: "memory", "rax");
++#endif
++
++	return 0;
++}
++
+ #ifdef CONFIG_X86_SMAP
+ 
+ static __always_inline void clac(void)
 diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
 index b073aae..39f9bdd 100644
 --- a/arch/x86/include/asm/smp.h
@@ -15717,8 +16959,94 @@ index a1df6e8..e002940 100644
 +
  #endif
  #endif /* _ASM_X86_THREAD_INFO_H */
+diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
+index 50a7fc0..d00c622 100644
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -17,18 +17,39 @@
+ 
+ static inline void __native_flush_tlb(void)
+ {
+-	native_write_cr3(native_read_cr3());
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (static_cpu_has(X86_FEATURE_PCID)) {
++		unsigned int cpu = raw_get_cpu();
++
++		if (static_cpu_has(X86_FEATURE_INVPCID)) {
++			unsigned long descriptor[2];
++			asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : "memory");
++		} else {
++			native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++			native_write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++		}
++		raw_put_cpu_no_resched();
++	} else
++#endif
++
++		native_write_cr3(native_read_cr3());
+ }
+ 
+ static inline void __native_flush_tlb_global_irq_disabled(void)
+ {
+-	unsigned long cr4;
++	if (static_cpu_has(X86_FEATURE_INVPCID)) {
++		unsigned long descriptor[2];
++		asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : "memory");
++	} else {
++		unsigned long cr4;
+ 
+-	cr4 = native_read_cr4();
+-	/* clear PGE */
+-	native_write_cr4(cr4 & ~X86_CR4_PGE);
+-	/* write old PGE again and flush TLBs */
+-	native_write_cr4(cr4);
++		cr4 = native_read_cr4();
++		/* clear PGE */
++		native_write_cr4(cr4 & ~X86_CR4_PGE);
++		/* write old PGE again and flush TLBs */
++		native_write_cr4(cr4);
++	}
+ }
+ 
+ static inline void __native_flush_tlb_global(void)
+@@ -49,7 +70,33 @@ static inline void __native_flush_tlb_global(void)
+ 
+ static inline void __native_flush_tlb_single(unsigned long addr)
+ {
+-	asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (static_cpu_has(X86_FEATURE_PCID) && addr < TASK_SIZE_MAX) {
++		unsigned int cpu = raw_get_cpu();
++
++		if (static_cpu_has(X86_FEATURE_INVPCID)) {
++			unsigned long descriptor[2];
++			descriptor[0] = PCID_USER;
++			descriptor[1] = addr;
++			asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : "memory");
++			if (!static_cpu_has(X86_FEATURE_STRONGUDEREF)) {
++				descriptor[0] = PCID_KERNEL;
++				descriptor[1] = addr + pax_user_shadow_base;
++				asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : "memory");
++			}
++		} else {
++			native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER | PCID_NOFLUSH);
++			asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++			native_write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++			if (!static_cpu_has(X86_FEATURE_STRONGUDEREF))
++				asm volatile("invlpg (%0)" ::"r" (addr + pax_user_shadow_base) : "memory");
++		}
++		raw_put_cpu_no_resched();
++	} else
++#endif
++
++		asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+ }
+ 
+ static inline void __flush_tlb_all(void)
 diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
-index 5ee2687..70d5895 100644
+index 5ee2687..74590b9 100644
 --- a/arch/x86/include/asm/uaccess.h
 +++ b/arch/x86/include/asm/uaccess.h
 @@ -7,6 +7,7 @@
@@ -15778,7 +17106,20 @@ index 5ee2687..70d5895 100644
  
  /*
   * The exception table consists of pairs of addresses relative to the
-@@ -176,13 +207,21 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+@@ -165,10 +196,12 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+ 	register __inttype(*(ptr)) __val_gu asm("%edx");		\
+ 	__chk_user_ptr(ptr);						\
+ 	might_fault();							\
++	pax_open_userland();						\
+ 	asm volatile("call __get_user_%P3"				\
+ 		     : "=a" (__ret_gu), "=r" (__val_gu)			\
+ 		     : "0" (ptr), "i" (sizeof(*(ptr))));		\
+ 	(x) = (__typeof__(*(ptr))) __val_gu;				\
++	pax_close_userland();						\
+ 	__ret_gu;							\
+ })
+ 
+@@ -176,13 +209,21 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
  	asm volatile("call __put_user_" #size : "=a" (__ret_pu)	\
  		     : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
  
@@ -15803,7 +17144,7 @@ index 5ee2687..70d5895 100644
  		     "3: " ASM_CLAC "\n"				\
  		     ".section .fixup,\"ax\"\n"				\
  		     "4:	movl %3,%0\n"				\
-@@ -195,8 +234,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+@@ -195,8 +236,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
  
  #define __put_user_asm_ex_u64(x, addr)					\
  	asm volatile(ASM_STAC "\n"					\
@@ -15814,34 +17155,50 @@ index 5ee2687..70d5895 100644
  		     "3: " ASM_CLAC "\n"				\
  		     _ASM_EXTABLE_EX(1b, 2b)				\
  		     _ASM_EXTABLE_EX(2b, 3b)				\
-@@ -246,7 +285,7 @@ extern void __put_user_8(void);
+@@ -246,7 +287,8 @@ extern void __put_user_8(void);
  	__typeof__(*(ptr)) __pu_val;				\
  	__chk_user_ptr(ptr);					\
  	might_fault();						\
 -	__pu_val = x;						\
 +	__pu_val = (x);						\
++	pax_open_userland();					\
  	switch (sizeof(*(ptr))) {				\
  	case 1:							\
  		__put_user_x(1, __pu_val, ptr, __ret_pu);	\
-@@ -345,7 +384,7 @@ do {									\
+@@ -264,6 +306,7 @@ extern void __put_user_8(void);
+ 		__put_user_x(X, __pu_val, ptr, __ret_pu);	\
+ 		break;						\
+ 	}							\
++	pax_close_userland();					\
+ 	__ret_pu;						\
+ })
+ 
+@@ -344,8 +387,10 @@ do {									\
+ } while (0)
  
  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
++do {									\
++	pax_open_userland();						\
  	asm volatile(ASM_STAC "\n"					\
 -		     "1:	mov"itype" %2,%"rtype"1\n"		\
 +		     "1:	"__copyuser_seg"mov"itype" %2,%"rtype"1\n"\
  		     "2: " ASM_CLAC "\n"				\
  		     ".section .fixup,\"ax\"\n"				\
  		     "3:	mov %3,%0\n"				\
-@@ -353,7 +392,7 @@ do {									\
+@@ -353,8 +398,10 @@ do {									\
  		     "	jmp 2b\n"					\
  		     ".previous\n"					\
  		     _ASM_EXTABLE(1b, 3b)				\
 -		     : "=r" (err), ltype(x)				\
+-		     : "m" (__m(addr)), "i" (errret), "0" (err))
 +		     : "=r" (err), ltype (x)				\
- 		     : "m" (__m(addr)), "i" (errret), "0" (err))
++		     : "m" (__m(addr)), "i" (errret), "0" (err));	\
++	pax_close_userland();						\
++} while (0)
  
  #define __get_user_size_ex(x, ptr, size)				\
-@@ -378,7 +417,7 @@ do {									\
+ do {									\
+@@ -378,7 +425,7 @@ do {									\
  } while (0)
  
  #define __get_user_asm_ex(x, addr, itype, rtype, ltype)			\
@@ -15850,7 +17207,7 @@ index 5ee2687..70d5895 100644
  		     "2:\n"						\
  		     _ASM_EXTABLE_EX(1b, 2b)				\
  		     : ltype(x) : "m" (__m(addr)))
-@@ -395,13 +434,24 @@ do {									\
+@@ -395,13 +442,24 @@ do {									\
  	int __gu_err;							\
  	unsigned long __gu_val;						\
  	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
@@ -15877,21 +17234,26 @@ index 5ee2687..70d5895 100644
  
  /*
   * Tell gcc we read from memory instead of writing: this is because
-@@ -410,7 +460,7 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -409,8 +467,10 @@ struct __large_struct { unsigned long buf[100]; };
+  * aliasing issues.
   */
  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
++do {									\
++	pax_open_userland();						\
  	asm volatile(ASM_STAC "\n"					\
 -		     "1:	mov"itype" %"rtype"1,%2\n"		\
 +		     "1:	"__copyuser_seg"mov"itype" %"rtype"1,%2\n"\
  		     "2: " ASM_CLAC "\n"				\
  		     ".section .fixup,\"ax\"\n"				\
  		     "3:	mov %3,%0\n"				\
-@@ -418,10 +468,10 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -418,10 +478,12 @@ struct __large_struct { unsigned long buf[100]; };
  		     ".previous\n"					\
  		     _ASM_EXTABLE(1b, 3b)				\
  		     : "=r"(err)					\
 -		     : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
-+		     : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err))
++		     : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err));\
++	pax_close_userland();						\
++} while (0)
  
  #define __put_user_asm_ex(x, addr, itype, rtype, ltype)			\
 -	asm volatile("1:	mov"itype" %"rtype"0,%1\n"		\
@@ -15899,7 +17261,21 @@ index 5ee2687..70d5895 100644
  		     "2:\n"						\
  		     _ASM_EXTABLE_EX(1b, 2b)				\
  		     : : ltype(x), "m" (__m(addr)))
-@@ -460,8 +510,12 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -431,11 +493,13 @@ struct __large_struct { unsigned long buf[100]; };
+  */
+ #define uaccess_try	do {						\
+ 	current_thread_info()->uaccess_err = 0;				\
++	pax_open_userland();						\
+ 	stac();								\
+ 	barrier();
+ 
+ #define uaccess_catch(err)						\
+ 	clac();								\
++	pax_close_userland();						\
+ 	(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0);	\
+ } while (0)
+ 
+@@ -460,8 +524,12 @@ struct __large_struct { unsigned long buf[100]; };
   * On error, the variable @x is set to zero.
   */
  
@@ -15912,7 +17288,7 @@ index 5ee2687..70d5895 100644
  
  /**
   * __put_user: - Write a simple value into user space, with less checking.
-@@ -483,8 +537,12 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -483,8 +551,12 @@ struct __large_struct { unsigned long buf[100]; };
   * Returns zero on success, or -EFAULT on error.
   */
  
@@ -15925,7 +17301,7 @@ index 5ee2687..70d5895 100644
  
  #define __get_user_unaligned __get_user
  #define __put_user_unaligned __put_user
-@@ -502,7 +560,7 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -502,7 +574,7 @@ struct __large_struct { unsigned long buf[100]; };
  #define get_user_ex(x, ptr)	do {					\
  	unsigned long __gue_val;					\
  	__get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr))));	\
@@ -15934,7 +17310,7 @@ index 5ee2687..70d5895 100644
  } while (0)
  
  #define put_user_try		uaccess_try
-@@ -519,8 +577,8 @@ strncpy_from_user(char *dst, const char __user *src, long count);
+@@ -519,8 +591,8 @@ strncpy_from_user(char *dst, const char __user *src, long count);
  extern __must_check long strlen_user(const char __user *str);
  extern __must_check long strnlen_user(const char __user *str, long n);
  
@@ -16580,12 +17956,14 @@ index d8d9922..bf6cecb 100644
  extern struct x86_init_ops x86_init;
  extern struct x86_cpuinit_ops x86_cpuinit;
 diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
-index 0415cda..b43d877 100644
+index 0415cda..3b22adc 100644
 --- a/arch/x86/include/asm/xsave.h
 +++ b/arch/x86/include/asm/xsave.h
-@@ -71,7 +71,9 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+@@ -70,8 +70,11 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+ 	if (unlikely(err))
  		return -EFAULT;
  
++	pax_open_userland();
  	__asm__ __volatile__(ASM_STAC "\n"
 -			     "1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"
 +			     "1:"
@@ -16594,7 +17972,14 @@ index 0415cda..b43d877 100644
  			     "2: " ASM_CLAC "\n"
  			     ".section .fixup,\"ax\"\n"
  			     "3:  movl $-1,%[err]\n"
-@@ -87,12 +89,14 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+@@ -81,18 +84,22 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+ 			     : [err] "=r" (err)
+ 			     : "D" (buf), "a" (-1), "d" (-1), "0" (0)
+ 			     : "memory");
++	pax_close_userland();
+ 	return err;
+ }
+ 
  static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask)
  {
  	int err;
@@ -16603,6 +17988,7 @@ index 0415cda..b43d877 100644
  	u32 lmask = mask;
  	u32 hmask = mask >> 32;
  
++	pax_open_userland();
  	__asm__ __volatile__(ASM_STAC "\n"
 -			     "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
 +			     "1:"
@@ -16611,6 +17997,14 @@ index 0415cda..b43d877 100644
  			     "2: " ASM_CLAC "\n"
  			     ".section .fixup,\"ax\"\n"
  			     "3:  movl $-1,%[err]\n"
+@@ -102,6 +109,7 @@ static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask)
+ 			     : [err] "=r" (err)
+ 			     : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0)
+ 			     : "memory");	/* memory required? */
++	pax_close_userland();
+ 	return err;
+ }
+ 
 diff --git a/arch/x86/include/uapi/asm/e820.h b/arch/x86/include/uapi/asm/e820.h
 index bbae024..e1528f9 100644
 --- a/arch/x86/include/uapi/asm/e820.h
@@ -17210,7 +18604,7 @@ index 5013a48..0782c53 100644
  		if (c->x86_model == 3 && c->x86_mask == 0)
  			size = 64;
 diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
-index 22018f7..bc6f5e3 100644
+index 22018f7..a5883af 100644
 --- a/arch/x86/kernel/cpu/common.c
 +++ b/arch/x86/kernel/cpu/common.c
 @@ -88,60 +88,6 @@ static const struct cpu_dev __cpuinitconst default_cpu = {
@@ -17274,7 +18668,48 @@ index 22018f7..bc6f5e3 100644
  static int __init x86_xsave_setup(char *s)
  {
  	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
-@@ -386,7 +332,7 @@ void switch_to_new_gdt(int cpu)
+@@ -288,6 +234,40 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
+ 		set_in_cr4(X86_CR4_SMAP);
+ }
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++static __init int setup_disable_pcid(char *arg)
++{
++	setup_clear_cpu_cap(X86_FEATURE_PCID);
++	if (clone_pgd_mask != ~(pgdval_t)0UL)
++		pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT;
++	return 1;
++}
++__setup("nopcid", setup_disable_pcid);
++
++static void setup_pcid(struct cpuinfo_x86 *c)
++{
++	if (cpu_has(c, X86_FEATURE_PCID))
++		printk("PAX: PCID detected\n");
++
++	if (cpu_has(c, X86_FEATURE_INVPCID))
++		printk("PAX: INVPCID detected\n");
++
++	if (cpu_has(c, X86_FEATURE_PCID)) {
++		set_in_cr4(X86_CR4_PCIDE);
++		clone_pgd_mask = ~(pgdval_t)0UL;
++		if (pax_user_shadow_base)
++			printk("PAX: weak UDEREF enabled\n");
++		else {
++			set_cpu_cap(c, X86_FEATURE_STRONGUDEREF);
++			printk("PAX: strong UDEREF enabled\n");
++		}
++	} else if (pax_user_shadow_base)
++		printk("PAX: slow and weak UDEREF enabled\n");
++	else
++		printk("PAX: UDEREF disabled\n");
++}
++#endif
++
+ /*
+  * Some CPU features depend on higher CPUID levels, which may not always
+  * be available due to CPUID level capping or broken virtualization
+@@ -386,7 +366,7 @@ void switch_to_new_gdt(int cpu)
  {
  	struct desc_ptr gdt_descr;
  
@@ -17283,7 +18718,18 @@ index 22018f7..bc6f5e3 100644
  	gdt_descr.size = GDT_SIZE - 1;
  	load_gdt(&gdt_descr);
  	/* Reload the per-cpu base */
-@@ -882,6 +828,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+@@ -874,6 +854,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+ 	setup_smep(c);
+ 	setup_smap(c);
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	setup_pcid(c);
++#endif
++
+ 	/*
+ 	 * The vendor-specific functions might have changed features.
+ 	 * Now we do "generic changes."
+@@ -882,6 +866,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
  	/* Filter out anything that depends on CPUID levels we don't have */
  	filter_cpuid_features(c, true);
  
@@ -17294,7 +18740,7 @@ index 22018f7..bc6f5e3 100644
  	/* If the model name is still unset, do table lookup. */
  	if (!c->x86_model_id[0]) {
  		const char *p;
-@@ -1069,10 +1019,12 @@ static __init int setup_disablecpuid(char *arg)
+@@ -1069,10 +1057,12 @@ static __init int setup_disablecpuid(char *arg)
  }
  __setup("clearcpuid=", setup_disablecpuid);
  
@@ -17309,7 +18755,7 @@ index 22018f7..bc6f5e3 100644
  
  DEFINE_PER_CPU_FIRST(union irq_stack_union,
  		     irq_stack_union) __aligned(PAGE_SIZE);
-@@ -1086,7 +1038,7 @@ DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
+@@ -1086,7 +1076,7 @@ DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
  EXPORT_PER_CPU_SYMBOL(current_task);
  
  DEFINE_PER_CPU(unsigned long, kernel_stack) =
@@ -17318,7 +18764,7 @@ index 22018f7..bc6f5e3 100644
  EXPORT_PER_CPU_SYMBOL(kernel_stack);
  
  DEFINE_PER_CPU(char *, irq_stack_ptr) =
-@@ -1231,7 +1183,7 @@ void __cpuinit cpu_init(void)
+@@ -1231,7 +1221,7 @@ void __cpuinit cpu_init(void)
  	load_ucode_ap();
  
  	cpu = stack_smp_processor_id();
@@ -17327,7 +18773,7 @@ index 22018f7..bc6f5e3 100644
  	oist = &per_cpu(orig_ist, cpu);
  
  #ifdef CONFIG_NUMA
-@@ -1257,7 +1209,7 @@ void __cpuinit cpu_init(void)
+@@ -1257,7 +1247,7 @@ void __cpuinit cpu_init(void)
  	switch_to_new_gdt(cpu);
  	loadsegment(fs, 0);
  
@@ -17336,7 +18782,7 @@ index 22018f7..bc6f5e3 100644
  
  	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
  	syscall_init();
-@@ -1266,7 +1218,6 @@ void __cpuinit cpu_init(void)
+@@ -1266,7 +1256,6 @@ void __cpuinit cpu_init(void)
  	wrmsrl(MSR_KERNEL_GS_BASE, 0);
  	barrier();
  
@@ -17344,7 +18790,7 @@ index 22018f7..bc6f5e3 100644
  	enable_x2apic();
  
  	/*
-@@ -1318,7 +1269,7 @@ void __cpuinit cpu_init(void)
+@@ -1318,7 +1307,7 @@ void __cpuinit cpu_init(void)
  {
  	int cpu = smp_processor_id();
  	struct task_struct *curr = current;
@@ -18246,7 +19692,7 @@ index d15f575..d692043 100644
  #include <asm/processor.h>
  #include <asm/fcntl.h>
 diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
-index 8f3e2de..caecc4e 100644
+index 8f3e2de..6b71e39 100644
 --- a/arch/x86/kernel/entry_32.S
 +++ b/arch/x86/kernel/entry_32.S
 @@ -177,13 +177,153 @@
@@ -18756,6 +20202,15 @@ index 8f3e2de..caecc4e 100644
  
  ENTRY(simd_coprocessor_error)
  	RING0_INT_FRAME
+@@ -826,7 +1065,7 @@ ENTRY(simd_coprocessor_error)
+ .section .altinstructions,"a"
+ 	altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f
+ .previous
+-.section .altinstr_replacement,"ax"
++.section .altinstr_replacement,"a"
+ 663:	pushl $do_simd_coprocessor_error
+ 664:
+ .previous
 @@ -835,7 +1074,7 @@ ENTRY(simd_coprocessor_error)
  #endif
  	jmp error_code
@@ -19006,7 +20461,7 @@ index 8f3e2de..caecc4e 100644
  
  /*
 diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index 7272089..6204f9c5 100644
+index 7272089..833fdf8 100644
 --- a/arch/x86/kernel/entry_64.S
 +++ b/arch/x86/kernel/entry_64.S
 @@ -59,6 +59,8 @@
@@ -19093,7 +20548,7 @@ index 7272089..6204f9c5 100644
  #endif
  
  
-@@ -284,6 +293,309 @@ ENTRY(native_usergs_sysret64)
+@@ -284,6 +293,427 @@ ENTRY(native_usergs_sysret64)
  ENDPROC(native_usergs_sysret64)
  #endif /* CONFIG_PARAVIRT */
  
@@ -19113,18 +20568,19 @@ index 7272089..6204f9c5 100644
 +
 +	.macro pax_enter_kernel
 +	pax_set_fptr_mask
-+#ifdef CONFIG_PAX_KERNEXEC
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
 +	call pax_enter_kernel
 +#endif
 +	.endm
 +
 +	.macro pax_exit_kernel
-+#ifdef CONFIG_PAX_KERNEXEC
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
 +	call pax_exit_kernel
 +#endif
++
 +	.endm
 +
-+#ifdef CONFIG_PAX_KERNEXEC
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
 +ENTRY(pax_enter_kernel)
 +	pushq %rdi
 +
@@ -19132,6 +20588,7 @@ index 7272089..6204f9c5 100644
 +	PV_SAVE_REGS(CLBR_RDI)
 +#endif
 +
++#ifdef CONFIG_PAX_KERNEXEC
 +	GET_CR0_INTO_RDI
 +	bts $16,%rdi
 +	jnc 3f
@@ -19139,6 +20596,32 @@ index 7272089..6204f9c5 100644
 +	cmp $__KERNEL_CS,%edi
 +	jnz 2f
 +1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jnz 112f
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++	jmp 111f
++112:	cmp $1,%dil
++	jz 113f
++	ud2
++113:	sub $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__UDEREF_KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
 +
 +#ifdef CONFIG_PARAVIRT
 +	PV_RESTORE_REGS(CLBR_RDI)
@@ -19148,10 +20631,12 @@ index 7272089..6204f9c5 100644
 +	pax_force_retaddr
 +	retq
 +
++#ifdef CONFIG_PAX_KERNEXEC
 +2:	ljmpq __KERNEL_CS,1b
 +3:	ljmpq __KERNEXEC_KERNEL_CS,4f
 +4:	SET_RDI_INTO_CR0
 +	jmp 1b
++#endif
 +ENDPROC(pax_enter_kernel)
 +
 +ENTRY(pax_exit_kernel)
@@ -19161,6 +20646,7 @@ index 7272089..6204f9c5 100644
 +	PV_SAVE_REGS(CLBR_RDI)
 +#endif
 +
++#ifdef CONFIG_PAX_KERNEXEC
 +	mov %cs,%rdi
 +	cmp $__KERNEXEC_KERNEL_CS,%edi
 +	jz 2f
@@ -19168,6 +20654,30 @@ index 7272089..6204f9c5 100644
 +	bts $16,%rdi
 +	jnc 4f
 +1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	mov %ss,%edi
++	cmp $__UDEREF_KERNEL_DS,%edi
++	jnz 111f
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jz 112f
++	ud2
++112:	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
 +
 +#ifdef CONFIG_PARAVIRT
 +	PV_RESTORE_REGS(CLBR_RDI);
@@ -19177,6 +20687,7 @@ index 7272089..6204f9c5 100644
 +	pax_force_retaddr
 +	retq
 +
++#ifdef CONFIG_PAX_KERNEXEC
 +2:	GET_CR0_INTO_RDI
 +	btr $16,%rdi
 +	jnc 4f
@@ -19185,6 +20696,7 @@ index 7272089..6204f9c5 100644
 +	jmp 1b
 +4:	ud2
 +	jmp 4b
++#endif
 +ENDPROC(pax_exit_kernel)
 +#endif
 +
@@ -19217,6 +20729,21 @@ index 7272089..6204f9c5 100644
 +	PV_SAVE_REGS(CLBR_RDI)
 +#endif
 +
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $1,%dil
++	jnz 3f
++	sub $4097,%rdi
++	bts $63,%rdi
++	jmp 2f
++111:
++
 +	GET_CR3_INTO_RDI
 +	mov %rdi,%rbx
 +	add $__START_KERNEL_map,%rbx
@@ -19245,17 +20772,14 @@ index 7272089..6204f9c5 100644
 +	i = i + 1
 +	.endr
 +
-+#ifdef CONFIG_PARAVIRT
-+2:
-+#endif
-+	SET_RDI_INTO_CR3
-+
 +#ifdef CONFIG_PAX_KERNEXEC
 +	GET_CR0_INTO_RDI
 +	bts $16,%rdi
 +	SET_RDI_INTO_CR0
 +#endif
 +
++2:	SET_RDI_INTO_CR3
++
 +#ifdef CONFIG_PARAVIRT
 +	PV_RESTORE_REGS(CLBR_RDI)
 +#endif
@@ -19264,6 +20788,7 @@ index 7272089..6204f9c5 100644
 +	popq %rdi
 +	pax_force_retaddr
 +	retq
++3:	ud2
 +ENDPROC(pax_enter_kernel_user)
 +
 +ENTRY(pax_exit_kernel_user)
@@ -19274,14 +20799,21 @@ index 7272089..6204f9c5 100644
 +	PV_SAVE_REGS(CLBR_RDI)
 +#endif
 +
-+#ifdef CONFIG_PAX_KERNEXEC
-+	GET_CR0_INTO_RDI
-+	btr $16,%rdi
-+	jnc 3f
-+	SET_RDI_INTO_CR0
-+#endif
-+
 +	GET_CR3_INTO_RDI
++	661: jmp 1f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	cmp $0,%dil
++	jnz 3f
++	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	jmp 2f
++1:
 +	mov %rdi,%rbx
 +	add $__START_KERNEL_map,%rbx
 +	sub phys_base(%rip),%rbx
@@ -19289,6 +20821,7 @@ index 7272089..6204f9c5 100644
 +#ifdef CONFIG_PARAVIRT
 +	cmpl $0, pv_info+PARAVIRT_enabled
 +	jz 1f
++	pushq %rdi
 +	i = 0
 +	.rept USER_PGD_PTRS
 +	mov i*8(%rbx),%rsi
@@ -19297,18 +20830,27 @@ index 7272089..6204f9c5 100644
 +	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd_batched)
 +	i = i + 1
 +	.endr
++	popq %rdi
 +	jmp 2f
 +1:
 +#endif
 +
++#ifdef CONFIG_PAX_KERNEXEC
++	GET_CR0_INTO_RDI
++	btr $16,%rdi
++	jnc 3f
++	SET_RDI_INTO_CR0
++#endif
++
 +	i = 0
 +	.rept USER_PGD_PTRS
 +	movb $0x67,i*8(%rbx)
 +	i = i + 1
 +	.endr
++2:
 +
 +#ifdef CONFIG_PARAVIRT
-+2:	PV_RESTORE_REGS(CLBR_RDI)
++	PV_RESTORE_REGS(CLBR_RDI)
 +#endif
 +
 +	popq %rbx
@@ -19316,7 +20858,6 @@ index 7272089..6204f9c5 100644
 +	pax_force_retaddr
 +	retq
 +3:	ud2
-+	jmp 3b
 +ENDPROC(pax_exit_kernel_user)
 +#endif
 +
@@ -19331,6 +20872,26 @@ index 7272089..6204f9c5 100644
 +	or $2,%ebx
 +110:
 +#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jz 111f
++	sub $4097,%rdi
++	or $4,%ebx
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__UDEREF_KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
 +	.endm
 +
 +	.macro pax_exit_kernel_nmi
@@ -19342,6 +20903,18 @@ index 7272089..6204f9c5 100644
 +	SET_RDI_INTO_CR0
 +110:
 +#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	btr $2,%ebx
++	jnc 111f
++	GET_CR3_INTO_RDI
++	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
 +	.endm
 +
 +	.macro pax_erase_kstack
@@ -19403,7 +20976,7 @@ index 7272089..6204f9c5 100644
  
  .macro TRACE_IRQS_IRETQ offset=ARGOFFSET
  #ifdef CONFIG_TRACE_IRQFLAGS
-@@ -375,8 +687,8 @@ ENDPROC(native_usergs_sysret64)
+@@ -375,8 +805,8 @@ ENDPROC(native_usergs_sysret64)
  	.endm
  
  	.macro UNFAKE_STACK_FRAME
@@ -19414,7 +20987,7 @@ index 7272089..6204f9c5 100644
  	.endm
  
  /*
-@@ -463,7 +775,7 @@ ENDPROC(native_usergs_sysret64)
+@@ -463,7 +893,7 @@ ENDPROC(native_usergs_sysret64)
  	movq %rsp, %rsi
  
  	leaq -RBP(%rsp),%rdi	/* arg1 for handler */
@@ -19423,7 +20996,7 @@ index 7272089..6204f9c5 100644
  	je 1f
  	SWAPGS
  	/*
-@@ -498,9 +810,10 @@ ENTRY(save_rest)
+@@ -498,9 +928,10 @@ ENTRY(save_rest)
  	movq_cfi r15, R15+16
  	movq %r11, 8(%rsp)	/* return address */
  	FIXUP_TOP_OF_STACK %r11, 16
@@ -19435,7 +21008,7 @@ index 7272089..6204f9c5 100644
  
  /* save complete stack frame */
  	.pushsection .kprobes.text, "ax"
-@@ -529,9 +842,10 @@ ENTRY(save_paranoid)
+@@ -529,9 +960,10 @@ ENTRY(save_paranoid)
  	js 1f	/* negative -> in kernel */
  	SWAPGS
  	xorl %ebx,%ebx
@@ -19448,7 +21021,7 @@ index 7272089..6204f9c5 100644
  	.popsection
  
  /*
-@@ -553,7 +867,7 @@ ENTRY(ret_from_fork)
+@@ -553,7 +985,7 @@ ENTRY(ret_from_fork)
  
  	RESTORE_REST
  
@@ -19457,7 +21030,7 @@ index 7272089..6204f9c5 100644
  	jz   1f
  
  	testl $_TIF_IA32, TI_flags(%rcx)	# 32-bit compat task needs IRET
-@@ -571,7 +885,7 @@ ENTRY(ret_from_fork)
+@@ -571,7 +1003,7 @@ ENTRY(ret_from_fork)
  	RESTORE_REST
  	jmp int_ret_from_sys_call
  	CFI_ENDPROC
@@ -19466,7 +21039,7 @@ index 7272089..6204f9c5 100644
  
  /*
   * System call entry. Up to 6 arguments in registers are supported.
-@@ -608,7 +922,7 @@ END(ret_from_fork)
+@@ -608,7 +1040,7 @@ END(ret_from_fork)
  ENTRY(system_call)
  	CFI_STARTPROC	simple
  	CFI_SIGNAL_FRAME
@@ -19475,7 +21048,7 @@ index 7272089..6204f9c5 100644
  	CFI_REGISTER	rip,rcx
  	/*CFI_REGISTER	rflags,r11*/
  	SWAPGS_UNSAFE_STACK
-@@ -621,16 +935,23 @@ GLOBAL(system_call_after_swapgs)
+@@ -621,16 +1053,23 @@ GLOBAL(system_call_after_swapgs)
  
  	movq	%rsp,PER_CPU_VAR(old_rsp)
  	movq	PER_CPU_VAR(kernel_stack),%rsp
@@ -19501,7 +21074,7 @@ index 7272089..6204f9c5 100644
  	jnz tracesys
  system_call_fastpath:
  #if __SYSCALL_MASK == ~0
-@@ -640,7 +961,7 @@ system_call_fastpath:
+@@ -640,7 +1079,7 @@ system_call_fastpath:
  	cmpl $__NR_syscall_max,%eax
  #endif
  	ja badsys
@@ -19510,7 +21083,7 @@ index 7272089..6204f9c5 100644
  	call *sys_call_table(,%rax,8)  # XXX:	 rip relative
  	movq %rax,RAX-ARGOFFSET(%rsp)
  /*
-@@ -654,10 +975,13 @@ sysret_check:
+@@ -654,10 +1093,13 @@ sysret_check:
  	LOCKDEP_SYS_EXIT
  	DISABLE_INTERRUPTS(CLBR_NONE)
  	TRACE_IRQS_OFF
@@ -19525,7 +21098,7 @@ index 7272089..6204f9c5 100644
  	/*
  	 * sysretq will re-enable interrupts:
  	 */
-@@ -709,14 +1033,18 @@ badsys:
+@@ -709,14 +1151,18 @@ badsys:
  	 * jump back to the normal fast path.
  	 */
  auditsys:
@@ -19545,7 +21118,7 @@ index 7272089..6204f9c5 100644
  	jmp system_call_fastpath
  
  	/*
-@@ -737,7 +1065,7 @@ sysret_audit:
+@@ -737,7 +1183,7 @@ sysret_audit:
  	/* Do syscall tracing */
  tracesys:
  #ifdef CONFIG_AUDITSYSCALL
@@ -19554,7 +21127,7 @@ index 7272089..6204f9c5 100644
  	jz auditsys
  #endif
  	SAVE_REST
-@@ -745,12 +1073,16 @@ tracesys:
+@@ -745,12 +1191,16 @@ tracesys:
  	FIXUP_TOP_OF_STACK %rdi
  	movq %rsp,%rdi
  	call syscall_trace_enter
@@ -19571,7 +21144,7 @@ index 7272089..6204f9c5 100644
  	RESTORE_REST
  #if __SYSCALL_MASK == ~0
  	cmpq $__NR_syscall_max,%rax
-@@ -759,7 +1091,7 @@ tracesys:
+@@ -759,7 +1209,7 @@ tracesys:
  	cmpl $__NR_syscall_max,%eax
  #endif
  	ja   int_ret_from_sys_call	/* RAX(%rsp) set to -ENOSYS above */
@@ -19580,7 +21153,7 @@ index 7272089..6204f9c5 100644
  	call *sys_call_table(,%rax,8)
  	movq %rax,RAX-ARGOFFSET(%rsp)
  	/* Use IRET because user could have changed frame */
-@@ -780,7 +1112,9 @@ GLOBAL(int_with_check)
+@@ -780,7 +1230,9 @@ GLOBAL(int_with_check)
  	andl %edi,%edx
  	jnz   int_careful
  	andl    $~TS_COMPAT,TI_status(%rcx)
@@ -19591,7 +21164,7 @@ index 7272089..6204f9c5 100644
  
  	/* Either reschedule or signal or syscall exit tracking needed. */
  	/* First do a reschedule test. */
-@@ -826,7 +1160,7 @@ int_restore_rest:
+@@ -826,7 +1278,7 @@ int_restore_rest:
  	TRACE_IRQS_OFF
  	jmp int_with_check
  	CFI_ENDPROC
@@ -19600,7 +21173,7 @@ index 7272089..6204f9c5 100644
  
  	.macro FORK_LIKE func
  ENTRY(stub_\func)
-@@ -839,9 +1173,10 @@ ENTRY(stub_\func)
+@@ -839,9 +1291,10 @@ ENTRY(stub_\func)
  	DEFAULT_FRAME 0 8		/* offset 8: return address */
  	call sys_\func
  	RESTORE_TOP_OF_STACK %r11, 8
@@ -19612,7 +21185,7 @@ index 7272089..6204f9c5 100644
  	.endm
  
  	.macro FIXED_FRAME label,func
-@@ -851,9 +1186,10 @@ ENTRY(\label)
+@@ -851,9 +1304,10 @@ ENTRY(\label)
  	FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET
  	call \func
  	RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET
@@ -19624,7 +21197,7 @@ index 7272089..6204f9c5 100644
  	.endm
  
  	FORK_LIKE  clone
-@@ -870,9 +1206,10 @@ ENTRY(ptregscall_common)
+@@ -870,9 +1324,10 @@ ENTRY(ptregscall_common)
  	movq_cfi_restore R12+8, r12
  	movq_cfi_restore RBP+8, rbp
  	movq_cfi_restore RBX+8, rbx
@@ -19636,7 +21209,7 @@ index 7272089..6204f9c5 100644
  
  ENTRY(stub_execve)
  	CFI_STARTPROC
-@@ -885,7 +1222,7 @@ ENTRY(stub_execve)
+@@ -885,7 +1340,7 @@ ENTRY(stub_execve)
  	RESTORE_REST
  	jmp int_ret_from_sys_call
  	CFI_ENDPROC
@@ -19645,7 +21218,7 @@ index 7272089..6204f9c5 100644
  
  /*
   * sigreturn is special because it needs to restore all registers on return.
-@@ -902,7 +1239,7 @@ ENTRY(stub_rt_sigreturn)
+@@ -902,7 +1357,7 @@ ENTRY(stub_rt_sigreturn)
  	RESTORE_REST
  	jmp int_ret_from_sys_call
  	CFI_ENDPROC
@@ -19654,7 +21227,7 @@ index 7272089..6204f9c5 100644
  
  #ifdef CONFIG_X86_X32_ABI
  ENTRY(stub_x32_rt_sigreturn)
-@@ -916,7 +1253,7 @@ ENTRY(stub_x32_rt_sigreturn)
+@@ -916,7 +1371,7 @@ ENTRY(stub_x32_rt_sigreturn)
  	RESTORE_REST
  	jmp int_ret_from_sys_call
  	CFI_ENDPROC
@@ -19663,7 +21236,7 @@ index 7272089..6204f9c5 100644
  
  ENTRY(stub_x32_execve)
  	CFI_STARTPROC
-@@ -930,7 +1267,7 @@ ENTRY(stub_x32_execve)
+@@ -930,7 +1385,7 @@ ENTRY(stub_x32_execve)
  	RESTORE_REST
  	jmp int_ret_from_sys_call
  	CFI_ENDPROC
@@ -19672,7 +21245,7 @@ index 7272089..6204f9c5 100644
  
  #endif
  
-@@ -967,7 +1304,7 @@ vector=vector+1
+@@ -967,7 +1422,7 @@ vector=vector+1
  2:	jmp common_interrupt
  .endr
  	CFI_ENDPROC
@@ -19681,7 +21254,7 @@ index 7272089..6204f9c5 100644
  
  .previous
  END(interrupt)
-@@ -987,6 +1324,16 @@ END(interrupt)
+@@ -987,6 +1442,16 @@ END(interrupt)
  	subq $ORIG_RAX-RBP, %rsp
  	CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
  	SAVE_ARGS_IRQ
@@ -19698,7 +21271,7 @@ index 7272089..6204f9c5 100644
  	call \func
  	.endm
  
-@@ -1019,7 +1366,7 @@ ret_from_intr:
+@@ -1019,7 +1484,7 @@ ret_from_intr:
  
  exit_intr:
  	GET_THREAD_INFO(%rcx)
@@ -19707,7 +21280,7 @@ index 7272089..6204f9c5 100644
  	je retint_kernel
  
  	/* Interrupt came from user space */
-@@ -1041,12 +1388,16 @@ retint_swapgs:		/* return to user-space */
+@@ -1041,12 +1506,16 @@ retint_swapgs:		/* return to user-space */
  	 * The iretq could re-enable interrupts:
  	 */
  	DISABLE_INTERRUPTS(CLBR_ANY)
@@ -19724,7 +21297,7 @@ index 7272089..6204f9c5 100644
  	/*
  	 * The iretq could re-enable interrupts:
  	 */
-@@ -1129,7 +1480,7 @@ ENTRY(retint_kernel)
+@@ -1129,7 +1598,7 @@ ENTRY(retint_kernel)
  #endif
  
  	CFI_ENDPROC
@@ -19733,7 +21306,7 @@ index 7272089..6204f9c5 100644
  /*
   * End of kprobes section
   */
-@@ -1147,7 +1498,7 @@ ENTRY(\sym)
+@@ -1147,7 +1616,7 @@ ENTRY(\sym)
  	interrupt \do_sym
  	jmp ret_from_intr
  	CFI_ENDPROC
@@ -19742,7 +21315,7 @@ index 7272089..6204f9c5 100644
  .endm
  
  #ifdef CONFIG_SMP
-@@ -1208,12 +1559,22 @@ ENTRY(\sym)
+@@ -1208,12 +1677,22 @@ ENTRY(\sym)
  	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
  	call error_entry
  	DEFAULT_FRAME 0
@@ -19766,7 +21339,7 @@ index 7272089..6204f9c5 100644
  .endm
  
  .macro paranoidzeroentry sym do_sym
-@@ -1226,15 +1587,25 @@ ENTRY(\sym)
+@@ -1226,15 +1705,25 @@ ENTRY(\sym)
  	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
  	call save_paranoid
  	TRACE_IRQS_OFF
@@ -19794,7 +21367,7 @@ index 7272089..6204f9c5 100644
  .macro paranoidzeroentry_ist sym do_sym ist
  ENTRY(\sym)
  	INTR_FRAME
-@@ -1245,14 +1616,30 @@ ENTRY(\sym)
+@@ -1245,14 +1734,30 @@ ENTRY(\sym)
  	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
  	call save_paranoid
  	TRACE_IRQS_OFF_DEBUG
@@ -19826,7 +21399,7 @@ index 7272089..6204f9c5 100644
  .endm
  
  .macro errorentry sym do_sym
-@@ -1264,13 +1651,23 @@ ENTRY(\sym)
+@@ -1264,13 +1769,23 @@ ENTRY(\sym)
  	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
  	call error_entry
  	DEFAULT_FRAME 0
@@ -19851,7 +21424,7 @@ index 7272089..6204f9c5 100644
  .endm
  
  	/* error code is on the stack already */
-@@ -1284,13 +1681,23 @@ ENTRY(\sym)
+@@ -1284,13 +1799,23 @@ ENTRY(\sym)
  	call save_paranoid
  	DEFAULT_FRAME 0
  	TRACE_IRQS_OFF
@@ -19876,7 +21449,7 @@ index 7272089..6204f9c5 100644
  .endm
  
  zeroentry divide_error do_divide_error
-@@ -1320,9 +1727,10 @@ gs_change:
+@@ -1320,9 +1845,10 @@ gs_change:
  2:	mfence		/* workaround */
  	SWAPGS
  	popfq_cfi
@@ -19888,7 +21461,7 @@ index 7272089..6204f9c5 100644
  
  	_ASM_EXTABLE(gs_change,bad_gs)
  	.section .fixup,"ax"
-@@ -1350,9 +1758,10 @@ ENTRY(call_softirq)
+@@ -1350,9 +1876,10 @@ ENTRY(call_softirq)
  	CFI_DEF_CFA_REGISTER	rsp
  	CFI_ADJUST_CFA_OFFSET   -8
  	decl PER_CPU_VAR(irq_count)
@@ -19900,7 +21473,7 @@ index 7272089..6204f9c5 100644
  
  #ifdef CONFIG_XEN
  zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
-@@ -1390,7 +1799,7 @@ ENTRY(xen_do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
+@@ -1390,7 +1917,7 @@ ENTRY(xen_do_hypervisor_callback)   # do_hypervisor_callback(struct *pt_regs)
  	decl PER_CPU_VAR(irq_count)
  	jmp  error_exit
  	CFI_ENDPROC
@@ -19909,7 +21482,7 @@ index 7272089..6204f9c5 100644
  
  /*
   * Hypervisor uses this for application faults while it executes.
-@@ -1449,7 +1858,7 @@ ENTRY(xen_failsafe_callback)
+@@ -1449,7 +1976,7 @@ ENTRY(xen_failsafe_callback)
  	SAVE_ALL
  	jmp error_exit
  	CFI_ENDPROC
@@ -19918,7 +21491,7 @@ index 7272089..6204f9c5 100644
  
  apicinterrupt HYPERVISOR_CALLBACK_VECTOR \
  	xen_hvm_callback_vector xen_evtchn_do_upcall
-@@ -1501,18 +1910,33 @@ ENTRY(paranoid_exit)
+@@ -1501,18 +2028,33 @@ ENTRY(paranoid_exit)
  	DEFAULT_FRAME
  	DISABLE_INTERRUPTS(CLBR_NONE)
  	TRACE_IRQS_OFF_DEBUG
@@ -19954,7 +21527,7 @@ index 7272089..6204f9c5 100644
  	jmp irq_return
  paranoid_userspace:
  	GET_THREAD_INFO(%rcx)
-@@ -1541,7 +1965,7 @@ paranoid_schedule:
+@@ -1541,7 +2083,7 @@ paranoid_schedule:
  	TRACE_IRQS_OFF
  	jmp paranoid_userspace
  	CFI_ENDPROC
@@ -19963,7 +21536,7 @@ index 7272089..6204f9c5 100644
  
  /*
   * Exception entry point. This expects an error code/orig_rax on the stack.
-@@ -1568,12 +1992,13 @@ ENTRY(error_entry)
+@@ -1568,12 +2110,13 @@ ENTRY(error_entry)
  	movq_cfi r14, R14+8
  	movq_cfi r15, R15+8
  	xorl %ebx,%ebx
@@ -19978,7 +21551,7 @@ index 7272089..6204f9c5 100644
  	ret
  
  /*
-@@ -1600,7 +2025,7 @@ bstep_iret:
+@@ -1600,7 +2143,7 @@ bstep_iret:
  	movq %rcx,RIP+8(%rsp)
  	jmp error_swapgs
  	CFI_ENDPROC
@@ -19987,7 +21560,7 @@ index 7272089..6204f9c5 100644
  
  
  /* ebx:	no swapgs flag (1: don't need swapgs, 0: need it) */
-@@ -1611,7 +2036,7 @@ ENTRY(error_exit)
+@@ -1611,7 +2154,7 @@ ENTRY(error_exit)
  	DISABLE_INTERRUPTS(CLBR_NONE)
  	TRACE_IRQS_OFF
  	GET_THREAD_INFO(%rcx)
@@ -19996,7 +21569,7 @@ index 7272089..6204f9c5 100644
  	jne retint_kernel
  	LOCKDEP_SYS_EXIT_IRQ
  	movl TI_flags(%rcx),%edx
-@@ -1620,7 +2045,7 @@ ENTRY(error_exit)
+@@ -1620,7 +2163,7 @@ ENTRY(error_exit)
  	jnz retint_careful
  	jmp retint_swapgs
  	CFI_ENDPROC
@@ -20005,7 +21578,7 @@ index 7272089..6204f9c5 100644
  
  /*
   * Test if a given stack is an NMI stack or not.
-@@ -1678,9 +2103,11 @@ ENTRY(nmi)
+@@ -1678,9 +2221,11 @@ ENTRY(nmi)
  	 * If %cs was not the kernel segment, then the NMI triggered in user
  	 * space, which means it is definitely not nested.
  	 */
@@ -20018,7 +21591,7 @@ index 7272089..6204f9c5 100644
  	/*
  	 * Check the special variable on the stack to see if NMIs are
  	 * executing.
-@@ -1714,8 +2141,7 @@ nested_nmi:
+@@ -1714,8 +2259,7 @@ nested_nmi:
  
  1:
  	/* Set up the interrupted NMIs stack to jump to repeat_nmi */
@@ -20028,7 +21601,7 @@ index 7272089..6204f9c5 100644
  	CFI_ADJUST_CFA_OFFSET 1*8
  	leaq -10*8(%rsp), %rdx
  	pushq_cfi $__KERNEL_DS
-@@ -1733,6 +2159,7 @@ nested_nmi_out:
+@@ -1733,6 +2277,7 @@ nested_nmi_out:
  	CFI_RESTORE rdx
  
  	/* No need to check faults here */
@@ -20036,7 +21609,7 @@ index 7272089..6204f9c5 100644
  	INTERRUPT_RETURN
  
  	CFI_RESTORE_STATE
-@@ -1849,6 +2276,8 @@ end_repeat_nmi:
+@@ -1849,6 +2394,8 @@ end_repeat_nmi:
  	 */
  	movq %cr2, %r12
  
@@ -20045,7 +21618,7 @@ index 7272089..6204f9c5 100644
  	/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
  	movq %rsp,%rdi
  	movq $-1,%rsi
-@@ -1861,26 +2290,31 @@ end_repeat_nmi:
+@@ -1861,26 +2408,31 @@ end_repeat_nmi:
  	movq %r12, %cr2
  1:
  	
@@ -20201,7 +21774,7 @@ index 55b6761..a6456fc 100644
  	init_level4_pgt[511] = early_level4_pgt[511];
  
 diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
-index 73afd11..d1670f5 100644
+index 73afd11..0ef46f2 100644
 --- a/arch/x86/kernel/head_32.S
 +++ b/arch/x86/kernel/head_32.S
 @@ -26,6 +26,12 @@
@@ -20522,7 +22095,7 @@ index 73afd11..d1670f5 100644
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +ENTRY(cpu_pgd)
-+	.rept NR_CPUS
++	.rept 2*NR_CPUS
 +	.fill	4,8,0
 +	.endr
 +#endif
@@ -20633,7 +22206,7 @@ index 73afd11..d1670f5 100644
 +	.fill PAGE_SIZE_asm - GDT_SIZE,1,0
 +	.endr
 diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
-index a836860..bdeb7a5 100644
+index a836860..1b5c665 100644
 --- a/arch/x86/kernel/head_64.S
 +++ b/arch/x86/kernel/head_64.S
 @@ -20,6 +20,8 @@
@@ -20768,7 +22341,7 @@ index a836860..bdeb7a5 100644
  
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +NEXT_PAGE(cpu_pgd)
-+	.rept NR_CPUS
++	.rept 2*NR_CPUS
 +	.fill	512,8,0
 +	.endr
 +#endif
@@ -20813,7 +22386,7 @@ index a836860..bdeb7a5 100644
  NEXT_PAGE(level2_kernel_pgt)
  	/*
  	 * 512 MB kernel mapping. We spend a full page on this pagetable
-@@ -488,39 +544,64 @@ NEXT_PAGE(level2_kernel_pgt)
+@@ -488,39 +544,70 @@ NEXT_PAGE(level2_kernel_pgt)
  		KERNEL_IMAGE_SIZE/PMD_SIZE)
  
  NEXT_PAGE(level2_fixmap_pgt)
@@ -20856,6 +22429,12 @@ index a836860..bdeb7a5 100644
 +	.quad	0x0000f40000000000	/* node/CPU stored in limit */
 +	/* asm/segment.h:GDT_ENTRIES must match this */
 +
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	.quad	0x00cf93000000ffff	/* __UDEREF_KERNEL_DS */
++#else
++	.quad	0x0			/* unused */
++#endif
++
 +	/* zero the remaining page */
 +	.fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
 +	.endr
@@ -20919,7 +22498,7 @@ index 0fa6912..37fce70 100644
 +EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
 +#endif
 diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
-index cb33909..1163b40 100644
+index f7ea30d..6318acc 100644
 --- a/arch/x86/kernel/i387.c
 +++ b/arch/x86/kernel/i387.c
 @@ -51,7 +51,7 @@ static inline bool interrupted_kernel_fpu_idle(void)
@@ -22291,7 +23870,7 @@ index 7305f7d..22f73d6 100644
  }
 -
 diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
-index 355ae06..4530766 100644
+index 355ae06..560fbbe 100644
 --- a/arch/x86/kernel/process_64.c
 +++ b/arch/x86/kernel/process_64.c
 @@ -151,10 +151,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
@@ -22307,7 +23886,16 @@ index 355ae06..4530766 100644
  	set_tsk_thread_flag(p, TIF_FORK);
  	p->fpu_counter = 0;
  	p->thread.io_bitmap_ptr = NULL;
-@@ -273,7 +274,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+@@ -165,6 +166,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
+ 	p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
+ 	savesegment(es, p->thread.es);
+ 	savesegment(ds, p->thread.ds);
++	savesegment(ss, p->thread.ss);
++	BUG_ON(p->thread.ss == __UDEREF_KERNEL_DS);
+ 	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+ 
+ 	if (unlikely(p->flags & PF_KTHREAD)) {
+@@ -273,7 +276,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
  	struct thread_struct *prev = &prev_p->thread;
  	struct thread_struct *next = &next_p->thread;
  	int cpu = smp_processor_id();
@@ -22316,7 +23904,17 @@ index 355ae06..4530766 100644
  	unsigned fsindex, gsindex;
  	fpu_switch_t fpu;
  
-@@ -355,10 +356,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+@@ -296,6 +299,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+ 	if (unlikely(next->ds | prev->ds))
+ 		loadsegment(ds, next->ds);
+ 
++	savesegment(ss, prev->ss);
++	if (unlikely(next->ss != prev->ss))
++		loadsegment(ss, next->ss);
+ 
+ 	/* We must save %fs and %gs before load_TLS() because
+ 	 * %fs and %gs may be cleared by load_TLS().
+@@ -355,10 +361,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
  	prev->usersp = this_cpu_read(old_rsp);
  	this_cpu_write(old_rsp, next->usersp);
  	this_cpu_write(current_task, next_p);
@@ -22329,7 +23927,7 @@ index 355ae06..4530766 100644
  
  	/*
  	 * Now maybe reload the debug registers and handle I/O bitmaps
-@@ -427,12 +427,11 @@ unsigned long get_wchan(struct task_struct *p)
+@@ -427,12 +432,11 @@ unsigned long get_wchan(struct task_struct *p)
  	if (!p || p == current || p->state == TASK_RUNNING)
  		return 0;
  	stack = (unsigned long)task_stack_page(p);
@@ -22650,7 +24248,7 @@ index f2bb9c9..bed145d7 100644
  
  1:
 diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
-index 56f7fcf..fa229f4 100644
+index 56f7fcf..3b88ad1 100644
 --- a/arch/x86/kernel/setup.c
 +++ b/arch/x86/kernel/setup.c
 @@ -110,6 +110,7 @@
@@ -22661,7 +24259,23 @@ index 56f7fcf..fa229f4 100644
  
  /*
   * max_low_pfn_mapped: highest direct mapped pfn under 4GB
-@@ -444,7 +445,7 @@ static void __init parse_setup_data(void)
+@@ -205,10 +206,12 @@ EXPORT_SYMBOL(boot_cpu_data);
+ #endif
+ 
+ 
+-#if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
+-unsigned long mmu_cr4_features;
++#ifdef CONFIG_X86_64
++unsigned long mmu_cr4_features __read_only = X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE;
++#elif defined(CONFIG_X86_PAE)
++unsigned long mmu_cr4_features __read_only = X86_CR4_PAE;
+ #else
+-unsigned long mmu_cr4_features = X86_CR4_PAE;
++unsigned long mmu_cr4_features __read_only;
+ #endif
+ 
+ /* Boot loader ID and version as integers, for the benefit of proc_dointvec */
+@@ -444,7 +447,7 @@ static void __init parse_setup_data(void)
  
  		switch (data->type) {
  		case SETUP_E820_EXT:
@@ -22670,7 +24284,7 @@ index 56f7fcf..fa229f4 100644
  			break;
  		case SETUP_DTB:
  			add_dtb(pa_data);
-@@ -771,7 +772,7 @@ static void __init trim_bios_range(void)
+@@ -771,7 +774,7 @@ static void __init trim_bios_range(void)
  	 * area (640->1Mb) as ram even though it is not.
  	 * take them out.
  	 */
@@ -22679,7 +24293,7 @@ index 56f7fcf..fa229f4 100644
  
  	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
  }
-@@ -779,7 +780,7 @@ static void __init trim_bios_range(void)
+@@ -779,7 +782,7 @@ static void __init trim_bios_range(void)
  /* called before trim_bios_range() to spare extra sanitize */
  static void __init e820_add_kernel_range(void)
  {
@@ -22688,7 +24302,7 @@ index 56f7fcf..fa229f4 100644
  	u64 size = __pa_symbol(_end) - start;
  
  	/*
-@@ -841,8 +842,12 @@ static void __init trim_low_memory_range(void)
+@@ -841,8 +844,12 @@ static void __init trim_low_memory_range(void)
  
  void __init setup_arch(char **cmdline_p)
  {
@@ -22701,7 +24315,7 @@ index 56f7fcf..fa229f4 100644
  
  	early_reserve_initrd();
  
-@@ -934,14 +939,14 @@ void __init setup_arch(char **cmdline_p)
+@@ -934,14 +941,14 @@ void __init setup_arch(char **cmdline_p)
  
  	if (!boot_params.hdr.root_flags)
  		root_mountflags &= ~MS_RDONLY;
@@ -22798,7 +24412,7 @@ index 5cdff03..80fa283 100644
  		 * Up to this point, the boot CPU has been using .init.data
  		 * area.  Reload any changed state for the boot CPU.
 diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
-index 6956299..f20beae 100644
+index 6956299..18126ec4 100644
 --- a/arch/x86/kernel/signal.c
 +++ b/arch/x86/kernel/signal.c
 @@ -196,7 +196,7 @@ static unsigned long align_sigframe(unsigned long sp)
@@ -22831,8 +24445,12 @@ index 6956299..f20beae 100644
  
  	if (err)
  		return -EFAULT;
-@@ -367,7 +367,10 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
- 		err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
+@@ -364,10 +364,13 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
+ 		else
+ 			put_user_ex(0, &frame->uc.uc_flags);
+ 		put_user_ex(0, &frame->uc.uc_link);
+-		err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
++		__save_altstack_ex(&frame->uc.uc_stack, regs->sp);
  
  		/* Set up to return from userspace.  */
 -		restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -22852,6 +24470,15 @@ index 6956299..f20beae 100644
  	} put_user_catch(err);
  	
  	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+@@ -429,7 +432,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
+ 		else
+ 			put_user_ex(0, &frame->uc.uc_flags);
+ 		put_user_ex(0, &frame->uc.uc_link);
+-		err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
++		__save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+ 
+ 		/* Set up to return from userspace.  If provided, use a stub
+ 		   already in userspace.  */
 @@ -615,7 +618,12 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
  {
  	int usig = signr_convert(ksig->sig);
@@ -22889,10 +24516,35 @@ index 48d2b7d..90d328a 100644
  	.smp_prepare_cpus	= native_smp_prepare_cpus,
  	.smp_cpus_done		= native_smp_cpus_done,
 diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
-index bfd348e..4816ad8 100644
+index bfd348e..f0c1bf2 100644
 --- a/arch/x86/kernel/smpboot.c
 +++ b/arch/x86/kernel/smpboot.c
-@@ -748,6 +748,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+@@ -251,14 +251,18 @@ notrace static void __cpuinit start_secondary(void *unused)
+ 
+ 	enable_start_cpu0 = 0;
+ 
+-#ifdef CONFIG_X86_32
+-	/* switch away from the initial page table */
+-	load_cr3(swapper_pg_dir);
+-	__flush_tlb_all();
+-#endif
+-
+ 	/* otherwise gcc will move up smp_processor_id before the cpu_init */
+ 	barrier();
++
++	/* switch away from the initial page table */
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	load_cr3(get_cpu_pgd(smp_processor_id(), kernel));
++	__flush_tlb_all();
++#elif defined(CONFIG_X86_32)
++	load_cr3(swapper_pg_dir);
++	__flush_tlb_all();
++#endif
++
+ 	/*
+ 	 * Check TSC synchronization with the BP:
+ 	 */
+@@ -748,6 +752,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
  	idle->thread.sp = (unsigned long) (((struct pt_regs *)
  			  (THREAD_SIZE +  task_stack_page(idle))) - 1);
  	per_cpu(current_task, cpu) = idle;
@@ -22900,7 +24552,7 @@ index bfd348e..4816ad8 100644
  
  #ifdef CONFIG_X86_32
  	/* Stack for startup_32 can be just as for start_secondary onwards */
-@@ -755,11 +756,13 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+@@ -755,11 +760,13 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
  #else
  	clear_tsk_thread_flag(idle, TIF_FORK);
  	initial_gs = per_cpu_offset(cpu);
@@ -22917,12 +24569,15 @@ index bfd348e..4816ad8 100644
  	initial_code = (unsigned long)start_secondary;
  	stack_start  = idle->thread.sp;
  
-@@ -908,6 +911,15 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
+@@ -908,6 +915,18 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
  	/* the FPU context is blank, nobody can own it */
  	__cpu_disable_lazy_restore(cpu);
  
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	clone_pgd_range(get_cpu_pgd(cpu) + KERNEL_PGD_BOUNDARY,
++	clone_pgd_range(get_cpu_pgd(cpu, kernel) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++	clone_pgd_range(get_cpu_pgd(cpu, user) + KERNEL_PGD_BOUNDARY,
 +			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
 +			KERNEL_PGD_PTRS);
 +#endif
@@ -25226,27 +26881,43 @@ 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..d25fab6 100644
+index a30ca15..6b3f4e1 100644
 --- a/arch/x86/lib/copy_user_64.S
 +++ b/arch/x86/lib/copy_user_64.S
-@@ -18,6 +18,7 @@
+@@ -18,31 +18,7 @@
  #include <asm/alternative-asm.h>
  #include <asm/asm.h>
  #include <asm/smap.h>
+-
+-/*
+- * By placing feature2 after feature1 in altinstructions section, we logically
+- * implement:
+- * If CPU has feature2, jmp to alt2 is used
+- * else if CPU has feature1, jmp to alt1 is used
+- * else jmp to orig is used.
+- */
+-	.macro ALTERNATIVE_JUMP feature1,feature2,orig,alt1,alt2
+-0:
+-	.byte 0xe9	/* 32bit jump */
+-	.long \orig-1f	/* by default jump to orig */
+-1:
+-	.section .altinstr_replacement,"ax"
+-2:	.byte 0xe9			/* near jump with 32bit immediate */
+-	.long \alt1-1b /* offset */   /* or alternatively to alt1 */
+-3:	.byte 0xe9			/* near jump with 32bit immediate */
+-	.long \alt2-1b /* offset */   /* or alternatively to alt2 */
+-	.previous
+-
+-	.section .altinstructions,"a"
+-	altinstruction_entry 0b,2b,\feature1,5,5
+-	altinstruction_entry 0b,3b,\feature2,5,5
+-	.previous
+-	.endm
 +#include <asm/pgtable.h>
  
- /*
-  * By placing feature2 after feature1 in altinstructions section, we logically
-@@ -31,7 +32,7 @@
- 	.byte 0xe9	/* 32bit jump */
- 	.long \orig-1f	/* by default jump to orig */
- 1:
--	.section .altinstr_replacement,"ax"
-+	.section .altinstr_replacement,"a"
- 2:	.byte 0xe9			/* near jump with 32bit immediate */
- 	.long \alt1-1b /* offset */   /* or alternatively to alt1 */
- 3:	.byte 0xe9			/* near jump with 32bit immediate */
-@@ -70,47 +71,20 @@
+ 	.macro ALIGN_DESTINATION
+ #ifdef FIX_ALIGNMENT
+@@ -70,52 +46,6 @@
  #endif
  	.endm
  
@@ -25280,24 +26951,34 @@ index a30ca15..d25fab6 100644
 -	CFI_ENDPROC
 -ENDPROC(_copy_from_user)
 -
- 	.section .fixup,"ax"
- 	/* must zero dest */
- ENTRY(bad_from_user)
- bad_from_user:
+-	.section .fixup,"ax"
+-	/* must zero dest */
+-ENTRY(bad_from_user)
+-bad_from_user:
+-	CFI_STARTPROC
+-	movl %edx,%ecx
+-	xorl %eax,%eax
+-	rep
+-	stosb
+-bad_to_user:
+-	movl %edx,%eax
+-	ret
+-	CFI_ENDPROC
+-ENDPROC(bad_from_user)
+-	.previous
+-
+ /*
+  * copy_user_generic_unrolled - memory copy with exception handling.
+  * This version is for CPUs like P4 that don't have efficient micro
+@@ -131,6 +61,7 @@ ENDPROC(bad_from_user)
+  */
+ ENTRY(copy_user_generic_unrolled)
  	CFI_STARTPROC
-+	testl %edx,%edx
-+	js bad_to_user
- 	movl %edx,%ecx
- 	xorl %eax,%eax
- 	rep
- 	stosb
- bad_to_user:
- 	movl %edx,%eax
-+	pax_force_retaddr
- 	ret
- 	CFI_ENDPROC
- ENDPROC(bad_from_user)
-@@ -141,19 +115,19 @@ ENTRY(copy_user_generic_unrolled)
++	ASM_PAX_OPEN_USERLAND
+ 	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
@@ -25321,32 +27002,51 @@ index a30ca15..d25fab6 100644
  16:	movq %r11,7*8(%rdi)
  	leaq 64(%rsi),%rsi
  	leaq 64(%rdi),%rdi
-@@ -180,6 +154,7 @@ ENTRY(copy_user_generic_unrolled)
+@@ -180,6 +111,8 @@ ENTRY(copy_user_generic_unrolled)
  	jnz 21b
  23:	xor %eax,%eax
  	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
 +	pax_force_retaddr
  	ret
  
  	.section .fixup,"ax"
-@@ -251,6 +226,7 @@ ENTRY(copy_user_generic_string)
+@@ -235,6 +168,7 @@ ENDPROC(copy_user_generic_unrolled)
+  */
+ ENTRY(copy_user_generic_string)
+ 	CFI_STARTPROC
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	andl %edx,%edx
+ 	jz 4f
+@@ -251,6 +185,8 @@ ENTRY(copy_user_generic_string)
  	movsb
  4:	xorl %eax,%eax
  	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
 +	pax_force_retaddr
  	ret
  
  	.section .fixup,"ax"
-@@ -286,6 +262,7 @@ ENTRY(copy_user_enhanced_fast_string)
+@@ -278,6 +214,7 @@ ENDPROC(copy_user_generic_string)
+  */
+ ENTRY(copy_user_enhanced_fast_string)
+ 	CFI_STARTPROC
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	andl %edx,%edx
+ 	jz 2f
+@@ -286,6 +223,8 @@ ENTRY(copy_user_enhanced_fast_string)
  	movsb
  2:	xorl %eax,%eax
  	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
 +	pax_force_retaddr
  	ret
  
  	.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..f08b4a2 100644
+index 6a4f43c..55d26f2 100644
 --- a/arch/x86/lib/copy_user_nocache_64.S
 +++ b/arch/x86/lib/copy_user_nocache_64.S
 @@ -8,6 +8,7 @@
@@ -25365,7 +27065,7 @@ index 6a4f43c..f08b4a2 100644
  
  	.macro ALIGN_DESTINATION
  #ifdef FIX_ALIGNMENT
-@@ -49,6 +51,15 @@
+@@ -49,6 +51,16 @@
   */
  ENTRY(__copy_user_nocache)
  	CFI_STARTPROC
@@ -25378,10 +27078,11 @@ index 6a4f43c..f08b4a2 100644
 +1:
 +#endif
 +
++	ASM_PAX_OPEN_USERLAND
  	ASM_STAC
  	cmpl $8,%edx
  	jb 20f		/* less then 8 bytes, go to byte copy loop */
-@@ -59,19 +70,19 @@ ENTRY(__copy_user_nocache)
+@@ -59,19 +71,19 @@ ENTRY(__copy_user_nocache)
  	jz 17f
  1:	movq (%rsi),%r8
  2:	movq 1*8(%rsi),%r9
@@ -25405,9 +27106,11 @@ index 6a4f43c..f08b4a2 100644
  16:	movnti %r11,7*8(%rdi)
  	leaq 64(%rsi),%rsi
  	leaq 64(%rdi),%rdi
-@@ -99,6 +110,7 @@ ENTRY(__copy_user_nocache)
+@@ -98,7 +110,9 @@ ENTRY(__copy_user_nocache)
+ 	jnz 21b
  23:	xorl %eax,%eax
  	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
  	sfence
 +	pax_force_retaddr
  	ret
@@ -25434,27 +27137,38 @@ index 2419d5f..953ee51 100644
  	CFI_RESTORE_STATE
  
 diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
-index 25b7ae8..169fafc 100644
+index 25b7ae8..c40113e 100644
 --- a/arch/x86/lib/csum-wrappers_64.c
 +++ b/arch/x86/lib/csum-wrappers_64.c
-@@ -52,7 +52,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
+@@ -52,8 +52,12 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
  			len -= 2;
  		}
  	}
 -	isum = csum_partial_copy_generic((__force const void *)src,
++	pax_open_userland();
++	stac();
 +	isum = csum_partial_copy_generic((const void __force_kernel *)____m(src),
  				dst, len, isum, errp, NULL);
++	clac();
++	pax_close_userland();
  	if (unlikely(*errp))
  		goto out_err;
-@@ -105,7 +105,7 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
+ 
+@@ -105,8 +109,13 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
  	}
  
  	*errp = 0;
 -	return csum_partial_copy_generic(src, (void __force *)dst,
-+	return csum_partial_copy_generic(src, (void __force_kernel *)____m(dst),
++	pax_open_userland();
++	stac();
++	isum = csum_partial_copy_generic(src, (void __force_kernel *)____m(dst),
  					 len, isum, NULL, errp);
++	clac();
++	pax_close_userland();
++	return isum;
  }
  EXPORT_SYMBOL(csum_partial_copy_to_user);
+ 
 diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S
 index a451235..1daa956 100644
 --- a/arch/x86/lib/getuser.S
@@ -25659,9 +27373,18 @@ 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..aa84a79 100644
+index 56313a3..9b59269 100644
 --- a/arch/x86/lib/memcpy_64.S
 +++ b/arch/x86/lib/memcpy_64.S
+@@ -24,7 +24,7 @@
+  * This gets patched over the unrolled variant (below) via the
+  * alternative instructions framework:
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemcpy_c:
+ 	movq %rdi, %rax
+ 	movq %rdx, %rcx
 @@ -33,6 +33,7 @@
  	rep movsq
  	movl %edx, %ecx
@@ -25670,7 +27393,13 @@ index 56313a3..aa84a79 100644
  	ret
  .Lmemcpy_e:
  	.previous
-@@ -49,6 +50,7 @@
+@@ -44,11 +45,12 @@
+  * This gets patched over the unrolled variant (below) via the
+  * alternative instructions framework:
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemcpy_c_e:
  	movq %rdi, %rax
  	movq %rdx, %rcx
  	rep movsb
@@ -25750,7 +27479,7 @@ index 56313a3..aa84a79 100644
  	CFI_ENDPROC
  ENDPROC(memcpy)
 diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
-index 65268a6..c9518d1 100644
+index 65268a6..5aa7815 100644
 --- a/arch/x86/lib/memmove_64.S
 +++ b/arch/x86/lib/memmove_64.S
 @@ -61,13 +61,13 @@ ENTRY(memmove)
@@ -25865,7 +27594,7 @@ index 65268a6..c9518d1 100644
  	jmp 13f
  12:
  	cmp $1, %rdx
-@@ -202,6 +202,7 @@ ENTRY(memmove)
+@@ -202,14 +202,16 @@ ENTRY(memmove)
  	movb (%rsi), %r11b
  	movb %r11b, (%rdi)
  13:
@@ -25873,7 +27602,9 @@ index 65268a6..c9518d1 100644
  	retq
  	CFI_ENDPROC
  
-@@ -210,6 +211,7 @@ ENTRY(memmove)
+-	.section .altinstr_replacement,"ax"
++	.section .altinstr_replacement,"a"
+ .Lmemmove_begin_forward_efs:
  	/* Forward moving data. */
  	movq %rdx, %rcx
  	rep movsb
@@ -25882,9 +27613,18 @@ index 65268a6..c9518d1 100644
  .Lmemmove_end_forward_efs:
  	.previous
 diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
-index 2dcb380..963660a 100644
+index 2dcb380..50a78bc 100644
 --- a/arch/x86/lib/memset_64.S
 +++ b/arch/x86/lib/memset_64.S
+@@ -16,7 +16,7 @@
+  * 
+  * rax   original destination
+  */	
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemset_c:
+ 	movq %rdi,%r9
+ 	movq %rdx,%rcx
 @@ -30,6 +30,7 @@
  	movl %edx,%ecx
  	rep stosb
@@ -25893,7 +27633,15 @@ index 2dcb380..963660a 100644
  	ret
  .Lmemset_e:
  	.previous
-@@ -52,6 +53,7 @@
+@@ -45,13 +46,14 @@
+  *
+  * rax   original destination
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemset_c_e:
+ 	movq %rdi,%r9
+ 	movb %sil,%al
  	movq %rdx,%rcx
  	rep stosb
  	movq %r9,%rax
@@ -27170,10 +28918,18 @@ index 3eb18ac..6890bc3 100644
 +EXPORT_SYMBOL(set_fs);
 +#endif
 diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c
-index 906fea3..5646695 100644
+index 906fea3..0194a18 100644
 --- a/arch/x86/lib/usercopy_64.c
 +++ b/arch/x86/lib/usercopy_64.c
-@@ -39,7 +39,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
+@@ -18,6 +18,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
+ 	might_fault();
+ 	/* no memory constraint because it doesn't change any memory gcc knows
+ 	   about */
++	pax_open_userland();
+ 	stac();
+ 	asm volatile(
+ 		"	testq  %[size8],%[size8]\n"
+@@ -39,9 +40,10 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
  		_ASM_EXTABLE(0b,3b)
  		_ASM_EXTABLE(1b,2b)
  		: [size8] "=&c"(size), [dst] "=&D" (__d0)
@@ -27181,8 +28937,11 @@ index 906fea3..5646695 100644
 +		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(____m(addr)),
  		  [zero] "r" (0UL), [eight] "r" (8UL));
  	clac();
++	pax_close_userland();
  	return size;
-@@ -54,12 +54,11 @@ unsigned long clear_user(void __user *to, unsigned long n)
+ }
+ EXPORT_SYMBOL(__clear_user);
+@@ -54,12 +56,11 @@ unsigned long clear_user(void __user *to, unsigned long n)
  }
  EXPORT_SYMBOL(clear_user);
  
@@ -27199,7 +28958,7 @@ index 906fea3..5646695 100644
  }
  EXPORT_SYMBOL(copy_in_user);
  
-@@ -69,7 +68,7 @@ EXPORT_SYMBOL(copy_in_user);
+@@ -69,11 +70,13 @@ EXPORT_SYMBOL(copy_in_user);
   * it is not necessary to optimize tail handling.
   */
  unsigned long
@@ -27208,6 +28967,31 @@ index 906fea3..5646695 100644
  {
  	char c;
  	unsigned zero_len;
+ 
++	clac();
++	pax_close_userland();
+ 	for (; len; --len, to++) {
+ 		if (__get_user_nocheck(c, from++, sizeof(char)))
+ 			break;
+@@ -84,6 +87,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)
+ 	for (c = 0, zero_len = len; zerorest && zero_len; --zero_len)
+ 		if (__put_user_nocheck(c, to++, sizeof(char)))
+ 			break;
+-	clac();
+ 	return len;
+ }
+diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
+index 23d8e5f..9ccc13a 100644
+--- a/arch/x86/mm/Makefile
++++ b/arch/x86/mm/Makefile
+@@ -28,3 +28,7 @@ obj-$(CONFIG_ACPI_NUMA)		+= srat.o
+ obj-$(CONFIG_NUMA_EMU)		+= numa_emulation.o
+ 
+ obj-$(CONFIG_MEMTEST)		+= memtest.o
++
++quote:="
++obj-$(CONFIG_X86_64)		+= uderef_64.o
++CFLAGS_uderef_64.o		:= $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
 diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
 index 903ec1e..c4166b2 100644
 --- a/arch/x86/mm/extable.c
@@ -27263,7 +29047,7 @@ index 903ec1e..c4166b2 100644
  }
  
 diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
-index 654be4a..d36985f 100644
+index 654be4a..a4a3da1 100644
 --- a/arch/x86/mm/fault.c
 +++ b/arch/x86/mm/fault.c
 @@ -14,11 +14,18 @@
@@ -27353,7 +29137,7 @@ index 654be4a..d36985f 100644
  DEFINE_SPINLOCK(pgd_lock);
  LIST_HEAD(pgd_list);
  
-@@ -232,10 +273,22 @@ void vmalloc_sync_all(void)
+@@ -232,10 +273,27 @@ void vmalloc_sync_all(void)
  	for (address = VMALLOC_START & PMD_MASK;
  	     address >= TASK_SIZE && address < FIXADDR_TOP;
  	     address += PMD_SIZE) {
@@ -27368,15 +29152,20 @@ index 654be4a..d36985f 100644
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
-+			pgd_t *pgd = get_cpu_pgd(cpu);
++			pgd_t *pgd = get_cpu_pgd(cpu, user);
 +			pmd_t *ret;
++
++			ret = vmalloc_sync_one(pgd, address);
++			if (!ret)
++				break;
++			pgd = get_cpu_pgd(cpu, kernel);
 +#else
  		list_for_each_entry(page, &pgd_list, lru) {
 +			pgd_t *pgd;
  			spinlock_t *pgt_lock;
  			pmd_t *ret;
  
-@@ -243,8 +296,14 @@ void vmalloc_sync_all(void)
+@@ -243,8 +301,14 @@ void vmalloc_sync_all(void)
  			pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
  
  			spin_lock(pgt_lock);
@@ -27392,34 +29181,47 @@ index 654be4a..d36985f 100644
  
  			if (!ret)
  				break;
-@@ -278,6 +337,11 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
+@@ -278,6 +342,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
  	 * an interrupt in the middle of a task switch..
  	 */
  	pgd_paddr = read_cr3();
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (pgd_paddr & PHYSICAL_PAGE_MASK));
++	BUG_ON(__pa(get_cpu_pgd(smp_processor_id(), kernel)) != (pgd_paddr & __PHYSICAL_MASK));
++	vmalloc_sync_one(__va(pgd_paddr + PAGE_SIZE), address);
 +#endif
 +
  	pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
  	if (!pmd_k)
  		return -1;
-@@ -373,7 +437,14 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
+@@ -373,11 +443,25 @@ static noinline __kprobes int vmalloc_fault(unsigned long address)
  	 * happen within a race in page table update. In the later
  	 * case just flush:
  	 */
+-	pgd = pgd_offset(current->active_mm, address);
 +
+ 	pgd_ref = pgd_offset_k(address);
+ 	if (pgd_none(*pgd_ref))
+ 		return -1;
+ 
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (read_cr3() & PHYSICAL_PAGE_MASK));
-+	pgd = pgd_offset_cpu(smp_processor_id(), address);
++	BUG_ON(__pa(get_cpu_pgd(smp_processor_id(), kernel)) != (read_cr3() & __PHYSICAL_MASK));
++	pgd = pgd_offset_cpu(smp_processor_id(), user, address);
++	if (pgd_none(*pgd)) {
++		set_pgd(pgd, *pgd_ref);
++		arch_flush_lazy_mmu_mode();
++	} else {
++		BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
++	}
++	pgd = pgd_offset_cpu(smp_processor_id(), kernel, address);
 +#else
- 	pgd = pgd_offset(current->active_mm, address);
++	pgd = pgd_offset(current->active_mm, address);
 +#endif
 +
- 	pgd_ref = pgd_offset_k(address);
- 	if (pgd_none(*pgd_ref))
- 		return -1;
-@@ -543,7 +614,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
+ 	if (pgd_none(*pgd)) {
+ 		set_pgd(pgd, *pgd_ref);
+ 		arch_flush_lazy_mmu_mode();
+@@ -543,7 +627,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
  static int is_errata100(struct pt_regs *regs, unsigned long address)
  {
  #ifdef CONFIG_X86_64
@@ -27428,7 +29230,7 @@ index 654be4a..d36985f 100644
  		return 1;
  #endif
  	return 0;
-@@ -570,7 +641,7 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
+@@ -570,7 +654,7 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address)
  }
  
  static const char nx_warning[] = KERN_CRIT
@@ -27437,7 +29239,7 @@ index 654be4a..d36985f 100644
  
  static void
  show_fault_oops(struct pt_regs *regs, unsigned long error_code,
-@@ -579,15 +650,27 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
+@@ -579,15 +663,27 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
  	if (!oops_may_print())
  		return;
  
@@ -27467,7 +29269,7 @@ index 654be4a..d36985f 100644
  	printk(KERN_ALERT "BUG: unable to handle kernel ");
  	if (address < PAGE_SIZE)
  		printk(KERN_CONT "NULL pointer dereference");
-@@ -750,6 +833,22 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
+@@ -750,6 +846,22 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
  				return;
  		}
  #endif
@@ -27490,7 +29292,7 @@ index 654be4a..d36985f 100644
  		/* Kernel addresses are always protection faults: */
  		if (address >= TASK_SIZE)
  			error_code |= PF_PROT;
-@@ -835,7 +934,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
+@@ -835,7 +947,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
  	if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
  		printk(KERN_ERR
  	"MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",
@@ -27499,7 +29301,7 @@ index 654be4a..d36985f 100644
  		code = BUS_MCEERR_AR;
  	}
  #endif
-@@ -898,6 +997,99 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte)
+@@ -898,6 +1010,99 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte)
  	return 1;
  }
  
@@ -27599,7 +29401,7 @@ index 654be4a..d36985f 100644
  /*
   * Handle a spurious fault caused by a stale TLB entry.
   *
-@@ -964,6 +1156,9 @@ int show_unhandled_signals = 1;
+@@ -964,6 +1169,9 @@ int show_unhandled_signals = 1;
  static inline int
  access_error(unsigned long error_code, struct vm_area_struct *vma)
  {
@@ -27609,7 +29411,7 @@ index 654be4a..d36985f 100644
  	if (error_code & PF_WRITE) {
  		/* write, present and write, not present: */
  		if (unlikely(!(vma->vm_flags & VM_WRITE)))
-@@ -992,7 +1187,7 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
+@@ -992,7 +1200,7 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs)
  	if (error_code & PF_USER)
  		return false;
  
@@ -27618,7 +29420,7 @@ index 654be4a..d36985f 100644
  		return false;
  
  	return true;
-@@ -1008,18 +1203,33 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
+@@ -1008,18 +1216,33 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
  {
  	struct vm_area_struct *vma;
  	struct task_struct *tsk;
@@ -27657,7 +29459,7 @@ index 654be4a..d36985f 100644
  
  	/*
  	 * Detect and handle instructions that would cause a page fault for
-@@ -1080,7 +1290,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
+@@ -1080,7 +1303,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
  	 * User-mode registers count as a user access even for any
  	 * potential system fault or CPU buglet:
  	 */
@@ -27666,7 +29468,7 @@ index 654be4a..d36985f 100644
  		local_irq_enable();
  		error_code |= PF_USER;
  	} else {
-@@ -1142,6 +1352,11 @@ retry:
+@@ -1142,6 +1365,11 @@ retry:
  		might_sleep();
  	}
  
@@ -27678,7 +29480,7 @@ index 654be4a..d36985f 100644
  	vma = find_vma(mm, address);
  	if (unlikely(!vma)) {
  		bad_area(regs, error_code, address);
-@@ -1153,18 +1368,24 @@ retry:
+@@ -1153,18 +1381,24 @@ retry:
  		bad_area(regs, error_code, address);
  		return;
  	}
@@ -27714,7 +29516,7 @@ index 654be4a..d36985f 100644
  	if (unlikely(expand_stack(vma, address))) {
  		bad_area(regs, error_code, address);
  		return;
-@@ -1230,3 +1451,292 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
+@@ -1230,3 +1464,292 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
  	__do_page_fault(regs, error_code);
  	exception_exit(prev_state);
  }
@@ -28145,7 +29947,7 @@ index ae1aa71..d9bea75 100644
  
  #endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
 diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
-index 1f34e92..d252637 100644
+index 1f34e92..c97b98f 100644
 --- a/arch/x86/mm/init.c
 +++ b/arch/x86/mm/init.c
 @@ -4,6 +4,7 @@
@@ -28165,15 +29967,18 @@ index 1f34e92..d252637 100644
  
  #include "mm_internal.h"
  
-@@ -465,7 +468,15 @@ void __init init_mem_mapping(void)
+@@ -465,7 +468,18 @@ void __init init_mem_mapping(void)
  	early_ioremap_page_table_range_init();
  #endif
  
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
++	clone_pgd_range(get_cpu_pgd(0, kernel) + KERNEL_PGD_BOUNDARY,
 +			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
 +			KERNEL_PGD_PTRS);
-+	load_cr3(get_cpu_pgd(0));
++	clone_pgd_range(get_cpu_pgd(0, user) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++	load_cr3(get_cpu_pgd(0, kernel));
 +#else
  	load_cr3(swapper_pg_dir);
 +#endif
@@ -28181,7 +29986,7 @@ index 1f34e92..d252637 100644
  	__flush_tlb_all();
  
  	early_memtest(0, max_pfn_mapped << PAGE_SHIFT);
-@@ -481,10 +492,40 @@ void __init init_mem_mapping(void)
+@@ -481,10 +495,40 @@ void __init init_mem_mapping(void)
   * Access has to be given to non-kernel-ram areas as well, these contain the PCI
   * mmio resources as well as potential bios/acpi data regions.
   */
@@ -28223,7 +30028,7 @@ index 1f34e92..d252637 100644
  	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
  		return 0;
  	if (!page_is_ram(pagenr))
-@@ -538,8 +579,117 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
+@@ -538,8 +582,117 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
  #endif
  }
  
@@ -28604,7 +30409,7 @@ index 3ac7e31..89611b7 100644
  	printk(KERN_INFO "Write protecting the kernel text: %luk\n",
  		size >> 10);
 diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
-index bb00c46..f31d2f0 100644
+index bb00c46..bf91a67 100644
 --- a/arch/x86/mm/init_64.c
 +++ b/arch/x86/mm/init_64.c
 @@ -151,7 +151,7 @@ early_param("gbpages", parse_direct_gbpages_on);
@@ -28616,7 +30421,7 @@ index bb00c46..f31d2f0 100644
  EXPORT_SYMBOL_GPL(__supported_pte_mask);
  
  int force_personality32;
-@@ -184,12 +184,22 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+@@ -184,12 +184,29 @@ void sync_global_pgds(unsigned long start, unsigned long end)
  
  	for (address = start; address <= end; address += PGDIR_SIZE) {
  		const pgd_t *pgd_ref = pgd_offset_k(address);
@@ -28634,12 +30439,19 @@ index bb00c46..f31d2f0 100644
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
-+			pgd_t *pgd = pgd_offset_cpu(cpu, address);
++			pgd_t *pgd = pgd_offset_cpu(cpu, user, address);
++
++			if (pgd_none(*pgd))
++				set_pgd(pgd, *pgd_ref);
++			else
++				BUG_ON(pgd_page_vaddr(*pgd)
++				       != pgd_page_vaddr(*pgd_ref));
++			pgd = pgd_offset_cpu(cpu, kernel, address);
 +#else
  		list_for_each_entry(page, &pgd_list, lru) {
  			pgd_t *pgd;
  			spinlock_t *pgt_lock;
-@@ -198,6 +208,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+@@ -198,6 +215,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
  			/* the pgt_lock only for Xen */
  			pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
  			spin_lock(pgt_lock);
@@ -28647,7 +30459,7 @@ index bb00c46..f31d2f0 100644
  
  			if (pgd_none(*pgd))
  				set_pgd(pgd, *pgd_ref);
-@@ -205,7 +216,10 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+@@ -205,7 +223,10 @@ void sync_global_pgds(unsigned long start, unsigned long end)
  				BUG_ON(pgd_page_vaddr(*pgd)
  				       != pgd_page_vaddr(*pgd_ref));
  
@@ -28658,7 +30470,7 @@ index bb00c46..f31d2f0 100644
  		}
  		spin_unlock(&pgd_lock);
  	}
-@@ -238,7 +252,7 @@ static pud_t *fill_pud(pgd_t *pgd, unsigned long vaddr)
+@@ -238,7 +259,7 @@ static pud_t *fill_pud(pgd_t *pgd, unsigned long vaddr)
  {
  	if (pgd_none(*pgd)) {
  		pud_t *pud = (pud_t *)spp_getpage();
@@ -28667,7 +30479,7 @@ index bb00c46..f31d2f0 100644
  		if (pud != pud_offset(pgd, 0))
  			printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n",
  			       pud, pud_offset(pgd, 0));
-@@ -250,7 +264,7 @@ static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr)
+@@ -250,7 +271,7 @@ static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr)
  {
  	if (pud_none(*pud)) {
  		pmd_t *pmd = (pmd_t *) spp_getpage();
@@ -28676,7 +30488,7 @@ index bb00c46..f31d2f0 100644
  		if (pmd != pmd_offset(pud, 0))
  			printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
  			       pmd, pmd_offset(pud, 0));
-@@ -279,7 +293,9 @@ void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte)
+@@ -279,7 +300,9 @@ void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte)
  	pmd = fill_pmd(pud, vaddr);
  	pte = fill_pte(pmd, vaddr);
  
@@ -28686,7 +30498,7 @@ index bb00c46..f31d2f0 100644
  
  	/*
  	 * It's enough to flush this one mapping.
-@@ -338,14 +354,12 @@ static void __init __init_extra_mapping(unsigned long phys, unsigned long size,
+@@ -338,14 +361,12 @@ static void __init __init_extra_mapping(unsigned long phys, unsigned long size,
  		pgd = pgd_offset_k((unsigned long)__va(phys));
  		if (pgd_none(*pgd)) {
  			pud = (pud_t *) spp_getpage();
@@ -28703,7 +30515,7 @@ index bb00c46..f31d2f0 100644
  		}
  		pmd = pmd_offset(pud, phys);
  		BUG_ON(!pmd_none(*pmd));
-@@ -586,7 +600,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
+@@ -586,7 +607,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
  					      prot);
  
  		spin_lock(&init_mm.page_table_lock);
@@ -28712,7 +30524,7 @@ index bb00c46..f31d2f0 100644
  		spin_unlock(&init_mm.page_table_lock);
  	}
  	__flush_tlb_all();
-@@ -627,7 +641,7 @@ kernel_physical_mapping_init(unsigned long start,
+@@ -627,7 +648,7 @@ kernel_physical_mapping_init(unsigned long start,
  						 page_size_mask);
  
  		spin_lock(&init_mm.page_table_lock);
@@ -28721,7 +30533,7 @@ index bb00c46..f31d2f0 100644
  		spin_unlock(&init_mm.page_table_lock);
  		pgd_changed = true;
  	}
-@@ -1221,8 +1235,8 @@ int kern_addr_valid(unsigned long addr)
+@@ -1221,8 +1242,8 @@ int kern_addr_valid(unsigned long addr)
  static struct vm_area_struct gate_vma = {
  	.vm_start	= VSYSCALL_START,
  	.vm_end		= VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
@@ -28732,7 +30544,7 @@ index bb00c46..f31d2f0 100644
  };
  
  struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
-@@ -1256,7 +1270,7 @@ int in_gate_area_no_mm(unsigned long addr)
+@@ -1256,7 +1277,7 @@ int in_gate_area_no_mm(unsigned long addr)
  
  const char *arch_vma_name(struct vm_area_struct *vma)
  {
@@ -28995,7 +30807,7 @@ index d0b1773..4c3327c 100644
  
  struct split_state {
 diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
-index bb32480..aef8278 100644
+index bb32480..75f2f5e 100644
 --- a/arch/x86/mm/pageattr.c
 +++ b/arch/x86/mm/pageattr.c
 @@ -261,7 +261,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
@@ -29060,7 +30872,7 @@ index bb32480..aef8278 100644
  
 +#ifdef CONFIG_PAX_PER_CPU_PGD
 +		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
-+			pgd_t *pgd = get_cpu_pgd(cpu);
++			pgd_t *pgd = get_cpu_pgd(cpu, kernel);
 +#else
  		list_for_each_entry(page, &pgd_list, lru) {
 -			pgd_t *pgd;
@@ -29196,10 +31008,10 @@ index 9f0614d..92ae64a 100644
  	p += get_opcode(p, &opcode);
  	for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
 diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
-index 17fda6a..489c74a 100644
+index 17fda6a..f7d54a0 100644
 --- a/arch/x86/mm/pgtable.c
 +++ b/arch/x86/mm/pgtable.c
-@@ -91,10 +91,64 @@ static inline void pgd_list_del(pgd_t *pgd)
+@@ -91,10 +91,67 @@ static inline void pgd_list_del(pgd_t *pgd)
  	list_del(&page->lru);
  }
  
@@ -29212,6 +31024,9 @@ index 17fda6a..489c74a 100644
 +{
 +	unsigned int count = USER_PGD_PTRS;
  
++	if (!pax_user_shadow_base)
++		return;
++
 +	while (count--)
 +		*dst++ = __pgd((pgd_val(*src++) | (_PAGE_NX & __supported_pte_mask)) & ~_PAGE_USER);
 +}
@@ -29266,7 +31081,7 @@ index 17fda6a..489c74a 100644
  static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm)
  {
  	BUILD_BUG_ON(sizeof(virt_to_page(pgd)->index) < sizeof(mm));
-@@ -135,6 +189,7 @@ static void pgd_dtor(pgd_t *pgd)
+@@ -135,6 +192,7 @@ static void pgd_dtor(pgd_t *pgd)
  	pgd_list_del(pgd);
  	spin_unlock(&pgd_lock);
  }
@@ -29274,7 +31089,7 @@ index 17fda6a..489c74a 100644
  
  /*
   * List of all pgd's needed for non-PAE so it can invalidate entries
-@@ -147,7 +202,7 @@ static void pgd_dtor(pgd_t *pgd)
+@@ -147,7 +205,7 @@ static void pgd_dtor(pgd_t *pgd)
   * -- nyc
   */
  
@@ -29283,7 +31098,7 @@ index 17fda6a..489c74a 100644
  /*
   * In PAE mode, we need to do a cr3 reload (=tlb flush) when
   * updating the top-level pagetable entries to guarantee the
-@@ -159,7 +214,7 @@ static void pgd_dtor(pgd_t *pgd)
+@@ -159,7 +217,7 @@ static void pgd_dtor(pgd_t *pgd)
   * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
   * and initialize the kernel pmds here.
   */
@@ -29292,7 +31107,7 @@ index 17fda6a..489c74a 100644
  
  void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
  {
-@@ -177,36 +232,38 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
+@@ -177,36 +235,38 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
  	 */
  	flush_tlb_mm(mm);
  }
@@ -29342,7 +31157,7 @@ index 17fda6a..489c74a 100644
  		return -ENOMEM;
  	}
  
-@@ -219,51 +276,55 @@ static int preallocate_pmds(pmd_t *pmds[])
+@@ -219,51 +279,55 @@ static int preallocate_pmds(pmd_t *pmds[])
   * preallocate which never got a corresponding vma will need to be
   * freed manually.
   */
@@ -29415,7 +31230,7 @@ index 17fda6a..489c74a 100644
  
  	pgd = (pgd_t *)__get_free_page(PGALLOC_GFP);
  
-@@ -272,11 +333,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+@@ -272,11 +336,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
  
  	mm->pgd = pgd;
  
@@ -29429,7 +31244,7 @@ index 17fda6a..489c74a 100644
  
  	/*
  	 * Make sure that pre-populating the pmds is atomic with
-@@ -286,14 +347,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+@@ -286,14 +350,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
  	spin_lock(&pgd_lock);
  
  	pgd_ctor(mm, pgd);
@@ -29447,7 +31262,7 @@ index 17fda6a..489c74a 100644
  out_free_pgd:
  	free_page((unsigned long)pgd);
  out:
-@@ -302,7 +363,7 @@ out:
+@@ -302,7 +366,7 @@ out:
  
  void pgd_free(struct mm_struct *mm, pgd_t *pgd)
  {
@@ -29545,6 +31360,49 @@ index 282375f..e03a98f 100644
  	}
  }
  EXPORT_SYMBOL_GPL(leave_mm);
+diff --git a/arch/x86/mm/uderef_64.c b/arch/x86/mm/uderef_64.c
+new file mode 100644
+index 0000000..dace51c
+--- /dev/null
++++ b/arch/x86/mm/uderef_64.c
+@@ -0,0 +1,37 @@
++#include <linux/mm.h>
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++/* PaX: due to the special call convention these functions must
++ * - remain leaf functions under all configurations,
++ * - never be called directly, only dereferenced from the wrappers.
++ */
++void __pax_open_userland(void)
++{
++	unsigned int cpu;
++
++	if (unlikely(!segment_eq(get_fs(), USER_DS)))
++		return;
++
++	cpu = raw_get_cpu();
++	BUG_ON((read_cr3() & ~PAGE_MASK) != PCID_KERNEL);
++	write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER | PCID_NOFLUSH);
++	raw_put_cpu_no_resched();
++}
++EXPORT_SYMBOL(__pax_open_userland);
++
++void __pax_close_userland(void)
++{
++	unsigned int cpu;
++
++	if (unlikely(!segment_eq(get_fs(), USER_DS)))
++		return;
++
++	cpu = raw_get_cpu();
++	BUG_ON((read_cr3() & ~PAGE_MASK) != PCID_USER);
++	write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++	raw_put_cpu_no_resched();
++}
++EXPORT_SYMBOL(__pax_close_userland);
++#endif
 diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
 index 877b9a1..a8ecf42 100644
 --- a/arch/x86/net/bpf_jit.S
@@ -30457,7 +32315,7 @@ index c77b24a..c979855 100644
  }
  EXPORT_SYMBOL(pcibios_set_irq_routing);
 diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
-index 40e4469..0592924 100644
+index 40e4469..d915bf9 100644
 --- a/arch/x86/platform/efi/efi_32.c
 +++ b/arch/x86/platform/efi/efi_32.c
 @@ -44,11 +44,22 @@ void efi_call_phys_prelog(void)
@@ -30500,7 +32358,7 @@ index 40e4469..0592924 100644
  	load_gdt(&gdt_descr);
  
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	load_cr3(get_cpu_pgd(smp_processor_id()));
++	load_cr3(get_cpu_pgd(smp_processor_id(), kernel));
 +#else
  	load_cr3(swapper_pg_dir);
 +#endif
@@ -30509,7 +32367,7 @@ index 40e4469..0592924 100644
  
  	local_irq_restore(efi_rt_eflags);
 diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
-index 39a0e7f1..ecc2f1e 100644
+index 39a0e7f1..872396e 100644
 --- a/arch/x86/platform/efi/efi_64.c
 +++ b/arch/x86/platform/efi/efi_64.c
 @@ -76,6 +76,11 @@ void __init efi_call_phys_prelog(void)
@@ -30530,7 +32388,7 @@ index 39a0e7f1..ecc2f1e 100644
  	kfree(save_pgd);
 +
 +#ifdef CONFIG_PAX_PER_CPU_PGD
-+	load_cr3(get_cpu_pgd(smp_processor_id()));
++	load_cr3(get_cpu_pgd(smp_processor_id(), kernel));
 +#endif
 +
  	__flush_tlb_all();
@@ -30897,10 +32755,18 @@ index c1b2791..f9e31c7 100644
  END(trampoline_header)
  	
 diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
-index bb360dc..3e5945f 100644
+index bb360dc..d0fd8f8 100644
 --- a/arch/x86/realmode/rm/trampoline_64.S
 +++ b/arch/x86/realmode/rm/trampoline_64.S
-@@ -107,7 +107,7 @@ ENTRY(startup_32)
+@@ -94,6 +94,7 @@ ENTRY(startup_32)
+ 	movl	%edx, %gs
+ 
+ 	movl	pa_tr_cr4, %eax
++	andl	$~X86_CR4_PCIDE, %eax
+ 	movl	%eax, %cr4		# Enable PAE mode
+ 
+ 	# Setup trampoline 4 level pagetables
+@@ -107,7 +108,7 @@ ENTRY(startup_32)
  	wrmsr
  
  	# Enable paging and in turn activate Long Mode
@@ -34449,10 +36315,10 @@ index 84ddc55..1d32f1e 100644
  	return 0;
  }
 diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
-index 1b456fe..2510242 100644
+index fc45567..fa2a590 100644
 --- a/drivers/char/virtio_console.c
 +++ b/drivers/char/virtio_console.c
-@@ -679,7 +679,7 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
+@@ -682,7 +682,7 @@ static ssize_t fill_readbuf(struct port *port, char *out_buf, size_t out_count,
  	if (to_user) {
  		ssize_t ret;
  
@@ -34461,7 +36327,7 @@ index 1b456fe..2510242 100644
  		if (ret)
  			return -EFAULT;
  	} else {
-@@ -778,7 +778,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
+@@ -785,7 +785,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf,
  	if (!port_has_data(port) && !port->host_connected)
  		return 0;
  
@@ -34521,6 +36387,19 @@ index a2b2541..bc1e7ff 100644
  	.notifier_call = arch_timer_cpu_notify,
  };
  
+diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c
+index 350f493..489479e 100644
+--- a/drivers/clocksource/bcm_kona_timer.c
++++ b/drivers/clocksource/bcm_kona_timer.c
+@@ -199,7 +199,7 @@ static struct irqaction kona_timer_irq = {
+ 	.handler = kona_timer_interrupt,
+ };
+ 
+-static void __init kona_timer_init(void)
++static void __init kona_timer_init(struct device_node *np)
+ {
+ 	kona_timers_init();
+ 	kona_timer_clockevents_init();
 diff --git a/drivers/clocksource/metag_generic.c b/drivers/clocksource/metag_generic.c
 index ade7513..069445f 100644
 --- a/drivers/clocksource/metag_generic.c
@@ -34587,10 +36466,10 @@ index edc089e..bc7c0bc 100644
  	pr_debug("CPU%u - ACPI performance management activated.\n", cpu);
  	for (i = 0; i < perf->state_count; i++)
 diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
-index 178fe7a..5ee8501 100644
+index 6485547..477033e 100644
 --- a/drivers/cpufreq/cpufreq.c
 +++ b/drivers/cpufreq/cpufreq.c
-@@ -1853,7 +1853,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
+@@ -1854,7 +1854,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
  	return NOTIFY_OK;
  }
  
@@ -34599,7 +36478,7 @@ index 178fe7a..5ee8501 100644
      .notifier_call = cpufreq_cpu_callback,
  };
  
-@@ -1885,8 +1885,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
+@@ -1886,8 +1886,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
  
  	pr_debug("trying to register driver %s\n", driver_data->name);
  
@@ -34614,7 +36493,7 @@ index 178fe7a..5ee8501 100644
  	write_lock_irqsave(&cpufreq_driver_lock, flags);
  	if (cpufreq_driver) {
 diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c
-index 5af40ad..ddf907b 100644
+index a86ff72..aad2b03 100644
 --- a/drivers/cpufreq/cpufreq_governor.c
 +++ b/drivers/cpufreq/cpufreq_governor.c
 @@ -235,7 +235,7 @@ int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -34645,7 +36524,7 @@ index 5af40ad..ddf907b 100644
  				cpufreq_unregister_notifier(cs_ops->notifier_block,
  						CPUFREQ_TRANSITION_NOTIFIER);
 diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h
-index e16a961..0e68927 100644
+index 0d9e6be..461fd3b 100644
 --- a/drivers/cpufreq/cpufreq_governor.h
 +++ b/drivers/cpufreq/cpufreq_governor.h
 @@ -204,7 +204,7 @@ struct common_dbs_data {
@@ -34658,7 +36537,7 @@ index e16a961..0e68927 100644
  
  /* Governer Per policy data */
 diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
-index 93eb5cb..f8ab572 100644
+index c087347..dad6268 100644
 --- a/drivers/cpufreq/cpufreq_ondemand.c
 +++ b/drivers/cpufreq/cpufreq_ondemand.c
 @@ -615,14 +615,18 @@ void od_register_powersave_bias_handler(unsigned int (*f)
@@ -35647,7 +37526,7 @@ index e913d32..4d9b351 100644
  		if (IS_GEN6(dev) || IS_GEN7(dev)) {
  			seq_printf(m,
 diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
-index f968590..19115e35 100644
+index 17d9b0b..860e6d9 100644
 --- a/drivers/gpu/drm/i915/i915_dma.c
 +++ b/drivers/gpu/drm/i915/i915_dma.c
 @@ -1259,7 +1259,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
@@ -35836,10 +37715,10 @@ index e5e32869..1678f36 100644
  	iir = I915_READ(IIR);
  
 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
-index e1f4e6e..c94a4b3 100644
+index eea5982..eeef407 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
-@@ -8933,13 +8933,13 @@ struct intel_quirk {
+@@ -8935,13 +8935,13 @@ struct intel_quirk {
  	int subsystem_vendor;
  	int subsystem_device;
  	void (*hook)(struct drm_device *dev);
@@ -35855,7 +37734,7 @@ index e1f4e6e..c94a4b3 100644
  
  static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
  {
-@@ -8947,18 +8947,20 @@ static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
+@@ -8949,18 +8949,20 @@ static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
  	return 1;
  }
  
@@ -40072,6 +41951,19 @@ index f975696..4597e21 100644
  
  #ifdef CONFIG_NET_POLL_CONTROLLER
  	/*
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
+index 25723d8..925ab8e 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
+@@ -649,7 +649,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
+ 		if ((mc->ptr + rec_len) > mc->end)
+ 			goto decode_failed;
+ 
+-		memcpy(cf->data, mc->ptr, rec_len);
++		memcpy(cf->data, mc->ptr, cf->can_dlc);
+ 		mc->ptr += rec_len;
+ 	}
+ 
 diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
 index e1d2643..7f4133b 100644
 --- a/drivers/net/ethernet/8390/ax88796.c
@@ -40390,6 +42282,18 @@ index d3f8797..82a03d3 100644
  
  	vlan_req = (struct qlcnic_vlan_req *)&req->words[1];
  	vlan_req->vlan_id = cpu_to_le16(vlan_id);
+diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
+index 887aebe..9095ff9 100644
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -524,6 +524,7 @@ rx_status_loop:
+ 					 PCI_DMA_FROMDEVICE);
+ 		if (dma_mapping_error(&cp->pdev->dev, new_mapping)) {
+ 			dev->stats.rx_dropped++;
++			kfree_skb(new_skb);
+ 			goto rx_next;
+ 		}
+ 
 diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
 index 393f961..d343034 100644
 --- a/drivers/net/ethernet/realtek/r8169.c
@@ -40607,10 +42511,32 @@ index b305105..8ead6df 100644
  };
  
 diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index 2491eb2..694b2ec 100644
+index 2491eb2..1a453eb 100644
 --- a/drivers/net/tun.c
 +++ b/drivers/net/tun.c
-@@ -1869,7 +1869,7 @@ unlock:
+@@ -1076,8 +1076,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
+ 	u32 rxhash;
+ 
+ 	if (!(tun->flags & TUN_NO_PI)) {
+-		if ((len -= sizeof(pi)) > total_len)
++		if (len < sizeof(pi))
+ 			return -EINVAL;
++		len -= sizeof(pi);
+ 
+ 		if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
+ 			return -EFAULT;
+@@ -1085,8 +1086,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
+ 	}
+ 
+ 	if (tun->flags & TUN_VNET_HDR) {
+-		if ((len -= tun->vnet_hdr_sz) > total_len)
++		if (len < tun->vnet_hdr_sz)
+ 			return -EINVAL;
++		len -= tun->vnet_hdr_sz;
+ 
+ 		if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
+ 			return -EFAULT;
+@@ -1869,7 +1871,7 @@ unlock:
  }
  
  static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
@@ -40619,7 +42545,7 @@ index 2491eb2..694b2ec 100644
  {
  	struct tun_file *tfile = file->private_data;
  	struct tun_struct *tun;
-@@ -1881,6 +1881,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+@@ -1881,6 +1883,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
  	int vnet_hdr_sz;
  	int ret;
  
@@ -41216,7 +43142,7 @@ index 7510723..5ba37f5 100644
  
  static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
 diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
-index 2c12311..7b77f24 100644
+index d955741..8730748 100644
 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
 +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
 @@ -252,9 +252,9 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
@@ -42938,7 +44864,7 @@ index 4d231c1..2892c37 100644
  	ddb_entry->default_relogin_timeout =
  		(def_timeout > LOGIN_TOV) && (def_timeout < LOGIN_TOV * 10) ?
 diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
-index 3b1ea34..1583a72 100644
+index eaa808e..95f8841 100644
 --- a/drivers/scsi/scsi.c
 +++ b/drivers/scsi/scsi.c
 @@ -661,7 +661,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
@@ -50086,10 +52012,10 @@ index 3752b9f..8db5569 100644
  
  	atomic_set(&midCount, 0);
 diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
-index 4f07f6f..55de8ce 100644
+index ea3a0b3..0194e39 100644
 --- a/fs/cifs/cifsglob.h
 +++ b/fs/cifs/cifsglob.h
-@@ -751,35 +751,35 @@ struct cifs_tcon {
+@@ -752,35 +752,35 @@ struct cifs_tcon {
  	__u16 Flags;		/* optional support bits */
  	enum statusEnum tidStatus;
  #ifdef CONFIG_CIFS_STATS
@@ -50149,7 +52075,7 @@ index 4f07f6f..55de8ce 100644
  		} smb2_stats;
  #endif /* CONFIG_CIFS_SMB2 */
  	} stats;
-@@ -1080,7 +1080,7 @@ convert_delimiter(char *path, char delim)
+@@ -1081,7 +1081,7 @@ convert_delimiter(char *path, char delim)
  }
  
  #ifdef CONFIG_CIFS_STATS
@@ -50158,7 +52084,7 @@ index 4f07f6f..55de8ce 100644
  
  static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
  					    unsigned int bytes)
-@@ -1445,8 +1445,8 @@ GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
+@@ -1446,8 +1446,8 @@ GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
  /* Various Debug counters */
  GLOBAL_EXTERN atomic_t bufAllocCount;    /* current number allocated  */
  #ifdef CONFIG_CIFS_STATS2
@@ -50846,7 +52772,7 @@ index f09b908..04b9690 100644
  	dcache_init();
  	inode_init();
 diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
-index 4888cb3..e0f7cf8 100644
+index c7c83ff..bda9461 100644
 --- a/fs/debugfs/inode.c
 +++ b/fs/debugfs/inode.c
 @@ -415,7 +415,11 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
@@ -50897,7 +52823,7 @@ index e4141f2..d8263e8 100644
  		i += packet_length_size;
  		if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
 diff --git a/fs/exec.c b/fs/exec.c
-index ffd7a81..d95acf6 100644
+index ffd7a81..3c84660 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -55,8 +55,20 @@
@@ -51104,6 +53030,24 @@ index ffd7a81..d95acf6 100644
  	/*
  	 * cover the whole range: [new_start, old_end)
  	 */
+@@ -607,7 +653,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+ 		return -ENOMEM;
+ 
+ 	lru_add_drain();
+-	tlb_gather_mmu(&tlb, mm, 0);
++	tlb_gather_mmu(&tlb, mm, old_start, old_end);
+ 	if (new_end > old_start) {
+ 		/*
+ 		 * when the old and new regions overlap clear from new_end.
+@@ -624,7 +670,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift)
+ 		free_pgd_range(&tlb, old_start, old_end, new_end,
+ 			vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING);
+ 	}
+-	tlb_finish_mmu(&tlb, new_end, old_end);
++	tlb_finish_mmu(&tlb, old_start, old_end);
+ 
+ 	/*
+ 	 * Shrink the vma to just the new range.  Always succeeds.
 @@ -672,10 +718,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
  	stack_top = arch_align_stack(stack_top);
  	stack_top = PAGE_ALIGN(stack_top);
@@ -51379,7 +53323,7 @@ index ffd7a81..d95acf6 100644
  out:
  	if (bprm->mm) {
  		acct_arg_size(bprm, 0);
-@@ -1701,3 +1875,285 @@ asmlinkage long compat_sys_execve(const char __user * filename,
+@@ -1701,3 +1875,287 @@ asmlinkage long compat_sys_execve(const char __user * filename,
  	return error;
  }
  #endif
@@ -51488,7 +53432,7 @@ index ffd7a81..d95acf6 100644
 +			offset = vma_fault->vm_pgoff << PAGE_SHIFT;
 +			if (vma_fault->vm_file)
 +				path_fault = pax_get_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
-+			else if (pc >= mm->start_brk && pc < mm->brk)
++			else if ((unsigned long)pc >= mm->start_brk && (unsigned long)pc < mm->brk)
 +				path_fault = "<heap>";
 +			else if (vma_fault->vm_flags & (VM_GROWSDOWN | VM_GROWSUP))
 +				path_fault = "<stack>";
@@ -51526,7 +53470,9 @@ index ffd7a81..d95acf6 100644
 +		printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n", current->comm, task_pid_nr(current),
 +				from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()));
 +	print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
++	preempt_disable();
 +	show_regs(regs);
++	preempt_enable();
 +	force_sig_info(SIGKILL, SEND_SIG_FORCED, current);
 +}
 +#endif
@@ -51918,7 +53864,7 @@ index 49d3c01..9579efd 100644
  	else if (input->reserved_blocks > input->blocks_count / 5)
  		ext4_warning(sb, "Reserved blocks too high (%u)",
 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index 6681c03..d88cd33 100644
+index 3f7c39e..227f24f 100644
 --- a/fs/ext4/super.c
 +++ b/fs/ext4/super.c
 @@ -1236,7 +1236,7 @@ static ext4_fsblk_t get_sb_block(void **data)
@@ -53684,7 +55630,7 @@ index 916da8c..1588998 100644
  					    next->d_inode->i_ino, 
  					    dt_type(next->d_inode)) < 0)
 diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
-index 9760ecb..9b838ef 100644
+index acd3947..1f896e2 100644
 --- a/fs/lockd/clntproc.c
 +++ b/fs/lockd/clntproc.c
 @@ -36,11 +36,11 @@ static const struct rpc_call_ops nlmclnt_cancel_ops;
@@ -54672,18 +56618,10 @@ index e7bc1d7..06bd4bb 100644
  	}
  
 diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
-index 6c80083..a1e6299 100644
+index 77cc85d..a1e6299 100644
 --- a/fs/notify/fanotify/fanotify_user.c
 +++ b/fs/notify/fanotify/fanotify_user.c
-@@ -122,6 +122,7 @@ static int fill_event_metadata(struct fsnotify_group *group,
- 	metadata->event_len = FAN_EVENT_METADATA_LEN;
- 	metadata->metadata_len = FAN_EVENT_METADATA_LEN;
- 	metadata->vers = FANOTIFY_METADATA_VERSION;
-+	metadata->reserved = 0;
- 	metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS;
- 	metadata->pid = pid_vnr(event->tgid);
- 	if (unlikely(event->mask & FAN_Q_OVERFLOW))
-@@ -252,8 +253,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
+@@ -253,8 +253,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
  
  	fd = fanotify_event_metadata.fd;
  	ret = -EFAULT;
@@ -54742,6 +56680,50 @@ index c5670b8..01a3656 100644
  
 -const struct inode_operations ntfs_empty_inode_ops = {};
 +const struct inode_operations ntfs_empty_inode_ops __read_only;
+diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
+index 20dfec7..e238cb7 100644
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -1756,7 +1756,7 @@ try_again:
+ 		goto out;
+ 	} else if (ret == 1) {
+ 		clusters_need = wc->w_clen;
+-		ret = ocfs2_refcount_cow(inode, filp, di_bh,
++		ret = ocfs2_refcount_cow(inode, di_bh,
+ 					 wc->w_cpos, wc->w_clen, UINT_MAX);
+ 		if (ret) {
+ 			mlog_errno(ret);
+diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
+index ff54014..ff125fd 100644
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -370,7 +370,7 @@ static int ocfs2_cow_file_pos(struct inode *inode,
+ 	if (!(ext_flags & OCFS2_EXT_REFCOUNTED))
+ 		goto out;
+ 
+-	return ocfs2_refcount_cow(inode, NULL, fe_bh, cpos, 1, cpos+1);
++	return ocfs2_refcount_cow(inode, fe_bh, cpos, 1, cpos+1);
+ 
+ out:
+ 	return status;
+@@ -899,7 +899,7 @@ static int ocfs2_zero_extend_get_range(struct inode *inode,
+ 		zero_clusters = last_cpos - zero_cpos;
+ 
+ 	if (needs_cow) {
+-		rc = ocfs2_refcount_cow(inode, NULL, di_bh, zero_cpos,
++		rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos,
+ 					zero_clusters, UINT_MAX);
+ 		if (rc) {
+ 			mlog_errno(rc);
+@@ -2078,7 +2078,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
+ 
+ 	*meta_level = 1;
+ 
+-	ret = ocfs2_refcount_cow(inode, file, di_bh, cpos, clusters, UINT_MAX);
++	ret = ocfs2_refcount_cow(inode, di_bh, cpos, clusters, UINT_MAX);
+ 	if (ret)
+ 		mlog_errno(ret);
+ out:
 diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
 index aebeacd..0dcdd26 100644
 --- a/fs/ocfs2/localalloc.c
@@ -54755,6 +56737,19 @@ index aebeacd..0dcdd26 100644
  
  bail:
  	if (handle)
+diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
+index f1fc172..452068b 100644
+--- a/fs/ocfs2/move_extents.c
++++ b/fs/ocfs2/move_extents.c
+@@ -69,7 +69,7 @@ static int __ocfs2_move_extent(handle_t *handle,
+ 	u64 ino = ocfs2_metadata_cache_owner(context->et.et_ci);
+ 	u64 old_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cpos);
+ 
+-	ret = ocfs2_duplicate_clusters_by_page(handle, context->file, cpos,
++	ret = ocfs2_duplicate_clusters_by_page(handle, inode, cpos,
+ 					       p_cpos, new_p_cpos, len);
+ 	if (ret) {
+ 		mlog_errno(ret);
 diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
 index d355e6e..578d905 100644
 --- a/fs/ocfs2/ocfs2.h
@@ -54776,6 +56771,188 @@ index d355e6e..578d905 100644
  };
  
  enum ocfs2_local_alloc_state
+diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
+index 998b17e..aefe414 100644
+--- a/fs/ocfs2/refcounttree.c
++++ b/fs/ocfs2/refcounttree.c
+@@ -49,7 +49,6 @@
+ 
+ struct ocfs2_cow_context {
+ 	struct inode *inode;
+-	struct file *file;
+ 	u32 cow_start;
+ 	u32 cow_len;
+ 	struct ocfs2_extent_tree data_et;
+@@ -66,7 +65,7 @@ struct ocfs2_cow_context {
+ 			    u32 *num_clusters,
+ 			    unsigned int *extent_flags);
+ 	int (*cow_duplicate_clusters)(handle_t *handle,
+-				      struct file *file,
++				      struct inode *inode,
+ 				      u32 cpos, u32 old_cluster,
+ 				      u32 new_cluster, u32 new_len);
+ };
+@@ -2922,14 +2921,12 @@ static int ocfs2_clear_cow_buffer(handle_t *handle, struct buffer_head *bh)
+ }
+ 
+ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+-				     struct file *file,
++				     struct inode *inode,
+ 				     u32 cpos, u32 old_cluster,
+ 				     u32 new_cluster, u32 new_len)
+ {
+ 	int ret = 0, partial;
+-	struct inode *inode = file_inode(file);
+-	struct ocfs2_caching_info *ci = INODE_CACHE(inode);
+-	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
++	struct super_block *sb = inode->i_sb;
+ 	u64 new_block = ocfs2_clusters_to_blocks(sb, new_cluster);
+ 	struct page *page;
+ 	pgoff_t page_index;
+@@ -2973,13 +2970,6 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+ 		if (PAGE_CACHE_SIZE <= OCFS2_SB(sb)->s_clustersize)
+ 			BUG_ON(PageDirty(page));
+ 
+-		if (PageReadahead(page)) {
+-			page_cache_async_readahead(mapping,
+-						   &file->f_ra, file,
+-						   page, page_index,
+-						   readahead_pages);
+-		}
+-
+ 		if (!PageUptodate(page)) {
+ 			ret = block_read_full_page(page, ocfs2_get_block);
+ 			if (ret) {
+@@ -2999,7 +2989,8 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+ 			}
+ 		}
+ 
+-		ocfs2_map_and_dirty_page(inode, handle, from, to,
++		ocfs2_map_and_dirty_page(inode,
++					 handle, from, to,
+ 					 page, 0, &new_block);
+ 		mark_page_accessed(page);
+ unlock:
+@@ -3015,12 +3006,11 @@ unlock:
+ }
+ 
+ int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
+-				    struct file *file,
++				    struct inode *inode,
+ 				    u32 cpos, u32 old_cluster,
+ 				    u32 new_cluster, u32 new_len)
+ {
+ 	int ret = 0;
+-	struct inode *inode = file_inode(file);
+ 	struct super_block *sb = inode->i_sb;
+ 	struct ocfs2_caching_info *ci = INODE_CACHE(inode);
+ 	int i, blocks = ocfs2_clusters_to_blocks(sb, new_len);
+@@ -3145,7 +3135,7 @@ static int ocfs2_replace_clusters(handle_t *handle,
+ 
+ 	/*If the old clusters is unwritten, no need to duplicate. */
+ 	if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) {
+-		ret = context->cow_duplicate_clusters(handle, context->file,
++		ret = context->cow_duplicate_clusters(handle, context->inode,
+ 						      cpos, old, new, len);
+ 		if (ret) {
+ 			mlog_errno(ret);
+@@ -3423,35 +3413,12 @@ static int ocfs2_replace_cow(struct ocfs2_cow_context *context)
+ 	return ret;
+ }
+ 
+-static void ocfs2_readahead_for_cow(struct inode *inode,
+-				    struct file *file,
+-				    u32 start, u32 len)
+-{
+-	struct address_space *mapping;
+-	pgoff_t index;
+-	unsigned long num_pages;
+-	int cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+-
+-	if (!file)
+-		return;
+-
+-	mapping = file->f_mapping;
+-	num_pages = (len << cs_bits) >> PAGE_CACHE_SHIFT;
+-	if (!num_pages)
+-		num_pages = 1;
+-
+-	index = ((loff_t)start << cs_bits) >> PAGE_CACHE_SHIFT;
+-	page_cache_sync_readahead(mapping, &file->f_ra, file,
+-				  index, num_pages);
+-}
+-
+ /*
+  * Starting at cpos, try to CoW write_len clusters.  Don't CoW
+  * past max_cpos.  This will stop when it runs into a hole or an
+  * unrefcounted extent.
+  */
+ static int ocfs2_refcount_cow_hunk(struct inode *inode,
+-				   struct file *file,
+ 				   struct buffer_head *di_bh,
+ 				   u32 cpos, u32 write_len, u32 max_cpos)
+ {
+@@ -3480,8 +3447,6 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
+ 
+ 	BUG_ON(cow_len == 0);
+ 
+-	ocfs2_readahead_for_cow(inode, file, cow_start, cow_len);
+-
+ 	context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS);
+ 	if (!context) {
+ 		ret = -ENOMEM;
+@@ -3503,7 +3468,6 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
+ 	context->ref_root_bh = ref_root_bh;
+ 	context->cow_duplicate_clusters = ocfs2_duplicate_clusters_by_page;
+ 	context->get_clusters = ocfs2_di_get_clusters;
+-	context->file = file;
+ 
+ 	ocfs2_init_dinode_extent_tree(&context->data_et,
+ 				      INODE_CACHE(inode), di_bh);
+@@ -3532,7 +3496,6 @@ out:
+  * clusters between cpos and cpos+write_len are safe to modify.
+  */
+ int ocfs2_refcount_cow(struct inode *inode,
+-		       struct file *file,
+ 		       struct buffer_head *di_bh,
+ 		       u32 cpos, u32 write_len, u32 max_cpos)
+ {
+@@ -3552,7 +3515,7 @@ int ocfs2_refcount_cow(struct inode *inode,
+ 			num_clusters = write_len;
+ 
+ 		if (ext_flags & OCFS2_EXT_REFCOUNTED) {
+-			ret = ocfs2_refcount_cow_hunk(inode, file, di_bh, cpos,
++			ret = ocfs2_refcount_cow_hunk(inode, di_bh, cpos,
+ 						      num_clusters, max_cpos);
+ 			if (ret) {
+ 				mlog_errno(ret);
+diff --git a/fs/ocfs2/refcounttree.h b/fs/ocfs2/refcounttree.h
+index 7754608..6422bbcdb 100644
+--- a/fs/ocfs2/refcounttree.h
++++ b/fs/ocfs2/refcounttree.h
+@@ -53,7 +53,7 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
+ 					  int *credits,
+ 					  int *ref_blocks);
+ int ocfs2_refcount_cow(struct inode *inode,
+-		       struct file *filep, struct buffer_head *di_bh,
++		       struct buffer_head *di_bh,
+ 		       u32 cpos, u32 write_len, u32 max_cpos);
+ 
+ typedef int (ocfs2_post_refcount_func)(struct inode *inode,
+@@ -85,11 +85,11 @@ int ocfs2_refcount_cow_xattr(struct inode *inode,
+ 			     u32 cpos, u32 write_len,
+ 			     struct ocfs2_post_refcount *post);
+ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
+-				     struct file *file,
++				     struct inode *inode,
+ 				     u32 cpos, u32 old_cluster,
+ 				     u32 new_cluster, u32 new_len);
+ int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
+-				    struct file *file,
++				    struct inode *inode,
+ 				    u32 cpos, u32 old_cluster,
+ 				    u32 new_cluster, u32 new_len);
+ int ocfs2_cow_sync_writeback(struct super_block *sb,
 diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
 index b7e74b5..19c6536 100644
 --- a/fs/ocfs2/suballoc.c
@@ -56276,7 +58453,7 @@ index 6b6a993..807cccc 100644
  		kfree(s);
  }
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 3e636d8..83e3b71 100644
+index 3e636d8..350cc48 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
 @@ -11,12 +11,19 @@
@@ -56443,6 +58620,34 @@ index 3e636d8..83e3b71 100644
  		   mss.resident >> 10,
  		   (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
  		   mss.shared_clean  >> 10,
+@@ -792,14 +843,14 @@ typedef struct {
+ } pagemap_entry_t;
+ 
+ struct pagemapread {
+-	int pos, len;
++	int pos, len;		/* units: PM_ENTRY_BYTES, not bytes */
+ 	pagemap_entry_t *buffer;
+ };
+ 
+ #define PAGEMAP_WALK_SIZE	(PMD_SIZE)
+ #define PAGEMAP_WALK_MASK	(PMD_MASK)
+ 
+-#define PM_ENTRY_BYTES      sizeof(u64)
++#define PM_ENTRY_BYTES      sizeof(pagemap_entry_t)
+ #define PM_STATUS_BITS      3
+ #define PM_STATUS_OFFSET    (64 - PM_STATUS_BITS)
+ #define PM_STATUS_MASK      (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
+@@ -1038,8 +1089,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+ 	if (!count)
+ 		goto out_task;
+ 
+-	pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
+-	pm.buffer = kmalloc(pm.len, GFP_TEMPORARY);
++	pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
++	pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY);
+ 	ret = -ENOMEM;
+ 	if (!pm.buffer)
+ 		goto out_task;
 @@ -1264,6 +1315,13 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
  	int n;
  	char buffer[50];
@@ -56699,10 +58904,10 @@ index 2b7882b..1c5ef48 100644
  
  	/* balance leaf returns 0 except if combining L R and S into
 diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
-index 33532f7..4846ade 100644
+index 1d48974..2f8f4e0 100644
 --- a/fs/reiserfs/procfs.c
 +++ b/fs/reiserfs/procfs.c
-@@ -112,7 +112,7 @@ static int show_super(struct seq_file *m, struct super_block *sb)
+@@ -114,7 +114,7 @@ static int show_super(struct seq_file *m, void *unused)
  		   "SMALL_TAILS " : "NO_TAILS ",
  		   replay_only(sb) ? "REPLAY_ONLY " : "",
  		   convert_reiserfs(sb) ? "CONV " : "",
@@ -68355,6 +70560,36 @@ index a59ff51..2594a70 100644
  #endif /* CONFIG_MMU */
  
  #endif /* !__ASSEMBLY__ */
+diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
+index 13821c3..5672d7e 100644
+--- a/include/asm-generic/tlb.h
++++ b/include/asm-generic/tlb.h
+@@ -112,7 +112,7 @@ struct mmu_gather {
+ 
+ #define HAVE_GENERIC_MMU_GATHER
+ 
+-void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm);
++void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end);
+ void tlb_flush_mmu(struct mmu_gather *tlb);
+ void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
+ 							unsigned long end);
+diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
+index c184aa8..d049942 100644
+--- a/include/asm-generic/uaccess.h
++++ b/include/asm-generic/uaccess.h
+@@ -343,4 +343,12 @@ clear_user(void __user *to, unsigned long n)
+ 	return __clear_user(to, n);
+ }
+ 
++#ifndef __HAVE_ARCH_PAX_OPEN_USERLAND
++//static inline unsigned long pax_open_userland(void) { return 0; }
++#endif
++
++#ifndef __HAVE_ARCH_PAX_CLOSE_USERLAND
++//static inline unsigned long pax_close_userland(void) { return 0; }
++#endif
++
+ #endif /* __ASM_GENERIC_UACCESS_H */
 diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
 index eb58d2d..df131bf 100644
 --- a/include/asm-generic/vmlinux.lds.h
@@ -68644,7 +70879,7 @@ index 1186098..f87e53d 100644
  /**
   * struct clk_init_data - holds init data that's common to all clocks and is
 diff --git a/include/linux/compat.h b/include/linux/compat.h
-index 7f0c1dd..b5729c6 100644
+index 7f0c1dd..206ac34 100644
 --- a/include/linux/compat.h
 +++ b/include/linux/compat.h
 @@ -312,7 +312,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
@@ -68665,6 +70900,14 @@ index 7f0c1dd..b5729c6 100644
  
  asmlinkage long compat_sys_lookup_dcookie(u32, u32, char __user *, size_t);
  /*
+@@ -669,6 +669,7 @@ asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
+ 
+ int compat_restore_altstack(const compat_stack_t __user *uss);
+ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
++void __compat_save_altstack_ex(compat_stack_t __user *, unsigned long);
+ 
+ asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
+ 						 struct compat_timespec __user *interval);
 diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
 index 842de22..7f3a41f 100644
 --- a/include/linux/compiler-gcc4.h
@@ -70942,7 +73185,7 @@ index 3e203eb..3fe68d0 100644
  void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
  		    u32 offset, struct device_node *);
 diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
-index 6883e19..06992b1 100644
+index 6883e19..e854fcb 100644
 --- a/include/linux/kallsyms.h
 +++ b/include/linux/kallsyms.h
 @@ -15,7 +15,8 @@
@@ -70955,12 +73198,13 @@ index 6883e19..06992b1 100644
  /* Lookup the address for a symbol. Returns 0 if not found. */
  unsigned long kallsyms_lookup_name(const char *name);
  
-@@ -106,6 +107,17 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
+@@ -106,6 +107,21 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
  /* Stupid that this does nothing, but I didn't create this mess. */
  #define __print_symbol(fmt, addr)
  #endif /*CONFIG_KALLSYMS*/
-+#else /* when included by kallsyms.c, vsnprintf.c, or
++#else /* when included by kallsyms.c, vsnprintf.c, kprobes.c, or
 +	arch/x86/kernel/dumpstack.c, with HIDESYM enabled */
++extern unsigned long kallsyms_lookup_name(const char *name);
 +extern void __print_symbol(const char *fmt, unsigned long address);
 +extern int sprint_backtrace(char *buffer, unsigned long address);
 +extern int sprint_symbol(char *buffer, unsigned long address);
@@ -70969,6 +73213,9 @@ index 6883e19..06992b1 100644
 +			    unsigned long *symbolsize,
 +			    unsigned long *offset,
 +			    char **modname, char *namebuf);
++extern int kallsyms_lookup_size_offset(unsigned long addr,
++				  unsigned long *symbolsize,
++				  unsigned long *offset);
 +#endif
  
  /* This macro allows us to keep printk typechecking */
@@ -72119,6 +74366,61 @@ index 4ea1d37..80f4b33 100644
  
  /*
   * The return value from decompress routine is the length of the
+diff --git a/include/linux/preempt.h b/include/linux/preempt.h
+index f5d4723..a6ea2fa 100644
+--- a/include/linux/preempt.h
++++ b/include/linux/preempt.h
+@@ -18,8 +18,13 @@
+ # define sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
+ #endif
+ 
++#define raw_add_preempt_count(val)	do { preempt_count() += (val); } while (0)
++#define raw_sub_preempt_count(val)	do { preempt_count() -= (val); } while (0)
++
+ #define inc_preempt_count() add_preempt_count(1)
++#define raw_inc_preempt_count() raw_add_preempt_count(1)
+ #define dec_preempt_count() sub_preempt_count(1)
++#define raw_dec_preempt_count() raw_sub_preempt_count(1)
+ 
+ #define preempt_count()	(current_thread_info()->preempt_count)
+ 
+@@ -64,6 +69,12 @@ do { \
+ 	barrier(); \
+ } while (0)
+ 
++#define raw_preempt_disable() \
++do { \
++	raw_inc_preempt_count(); \
++	barrier(); \
++} while (0)
++
+ #define sched_preempt_enable_no_resched() \
+ do { \
+ 	barrier(); \
+@@ -72,6 +83,12 @@ do { \
+ 
+ #define preempt_enable_no_resched()	sched_preempt_enable_no_resched()
+ 
++#define raw_preempt_enable_no_resched() \
++do { \
++	barrier(); \
++	raw_dec_preempt_count(); \
++} while (0)
++
+ #define preempt_enable() \
+ do { \
+ 	preempt_enable_no_resched(); \
+@@ -116,8 +133,10 @@ do { \
+  * region.
+  */
+ #define preempt_disable()		barrier()
++#define raw_preempt_disable()		barrier()
+ #define sched_preempt_enable_no_resched()	barrier()
+ #define preempt_enable_no_resched()	barrier()
++#define raw_preempt_enable_no_resched()	barrier()
+ #define preempt_enable()		barrier()
+ 
+ #define preempt_disable_notrace()		barrier()
 diff --git a/include/linux/printk.h b/include/linux/printk.h
 index 22c7052..ad3fa0a 100644
 --- a/include/linux/printk.h
@@ -72651,6 +74953,18 @@ index 429c199..4d42e38 100644
  };
  
  /* shm_mode upper byte flags */
+diff --git a/include/linux/signal.h b/include/linux/signal.h
+index d897484..323ba98 100644
+--- a/include/linux/signal.h
++++ b/include/linux/signal.h
+@@ -433,6 +433,7 @@ void signals_init(void);
+ 
+ int restore_altstack(const stack_t __user *);
+ int __save_altstack(stack_t __user *, unsigned long);
++void __save_altstack_ex(stack_t __user *, unsigned long);
+ 
+ #ifdef CONFIG_PROC_FS
+ struct seq_file;
 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
 index dec1748..112c1f9 100644
 --- a/include/linux/skbuff.h
@@ -72975,6 +75289,20 @@ index 027276f..092bfe8 100644
  void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
  
  #ifdef CONFIG_TRACING
+diff --git a/include/linux/smp.h b/include/linux/smp.h
+index c848876..11e8a84 100644
+--- a/include/linux/smp.h
++++ b/include/linux/smp.h
+@@ -221,7 +221,9 @@ static inline void kick_all_cpus_sync(void) {  }
+ #endif
+ 
+ #define get_cpu()		({ preempt_disable(); smp_processor_id(); })
++#define raw_get_cpu()		({ raw_preempt_disable(); raw_smp_processor_id(); })
+ #define put_cpu()		preempt_enable()
++#define raw_put_cpu_no_resched()	raw_preempt_enable_no_resched()
+ 
+ /*
+  * Callback to arch code if there's nosmp or maxcpus=0 on the
 diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
 index 54f91d3..be2c379 100644
 --- a/include/linux/sock_diag.h
@@ -75148,7 +77476,7 @@ index a67ef9d..2d17ed9 100644
  #ifdef CONFIG_BLK_DEV_RAM
  		int fd;
 diff --git a/init/main.c b/init/main.c
-index 9484f4b..4c01430 100644
+index 9484f4b..0eac7c3 100644
 --- a/init/main.c
 +++ b/init/main.c
 @@ -100,6 +100,8 @@ static inline void mark_rodata_ro(void) { }
@@ -75160,7 +77488,7 @@ index 9484f4b..4c01430 100644
  /*
   * Debug helper: via this flag we know that we are in 'early bootup code'
   * where only the boot processor is running with IRQ disabled.  This means
-@@ -153,6 +155,64 @@ static int __init set_reset_devices(char *str)
+@@ -153,6 +155,74 @@ static int __init set_reset_devices(char *str)
  
  __setup("reset_devices", set_reset_devices);
  
@@ -75175,11 +77503,10 @@ index 9484f4b..4c01430 100644
 +#endif
 +
 +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
-+unsigned long pax_user_shadow_base __read_only = 1UL << TASK_SIZE_MAX_SHIFT;
++unsigned long pax_user_shadow_base __read_only;
 +EXPORT_SYMBOL(pax_user_shadow_base);
 +extern char pax_enter_kernel_user[];
 +extern char pax_exit_kernel_user[];
-+extern pgdval_t clone_pgd_mask;
 +#endif
 +
 +#if defined(CONFIG_X86) && defined(CONFIG_PAX_MEMORY_UDEREF)
@@ -75204,11 +77531,22 @@ index 9484f4b..4c01430 100644
 +	memcpy(pax_exit_kernel_user, (unsigned char []){0xc3}, 1);
 +	clone_pgd_mask = ~(pgdval_t)0UL;
 +	pax_user_shadow_base = 0UL;
++	setup_clear_cpu_cap(X86_FEATURE_PCID);
 +#endif
 +
 +	return 0;
 +}
 +early_param("pax_nouderef", setup_pax_nouderef);
++
++#ifdef CONFIG_X86_64
++static int __init setup_pax_weakuderef(char *str)
++{
++	if (clone_pgd_mask != ~(pgdval_t)0UL)
++		pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT;
++	return 1;
++}
++__setup("pax_weakuderef", setup_pax_weakuderef);
++#endif
 +#endif
 +
 +#ifdef CONFIG_PAX_SOFTMODE
@@ -75225,7 +77563,7 @@ index 9484f4b..4c01430 100644
  static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
  const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
  static const char *panic_later, *panic_param;
-@@ -655,8 +715,6 @@ static void __init do_ctors(void)
+@@ -655,8 +725,6 @@ static void __init do_ctors(void)
  bool initcall_debug;
  core_param(initcall_debug, initcall_debug, bool, 0644);
  
@@ -75234,7 +77572,7 @@ index 9484f4b..4c01430 100644
  static int __init_or_module do_one_initcall_debug(initcall_t fn)
  {
  	ktime_t calltime, delta, rettime;
-@@ -679,23 +737,22 @@ int __init_or_module do_one_initcall(initcall_t fn)
+@@ -679,23 +747,22 @@ int __init_or_module do_one_initcall(initcall_t fn)
  {
  	int count = preempt_count();
  	int ret;
@@ -75262,7 +77600,7 @@ index 9484f4b..4c01430 100644
  
  	return ret;
  }
-@@ -748,8 +805,14 @@ static void __init do_initcall_level(int level)
+@@ -748,8 +815,14 @@ static void __init do_initcall_level(int level)
  		   level, level,
  		   &repair_env_string);
  
@@ -75278,7 +77616,7 @@ index 9484f4b..4c01430 100644
  }
  
  static void __init do_initcalls(void)
-@@ -783,8 +846,14 @@ static void __init do_pre_smp_initcalls(void)
+@@ -783,8 +856,14 @@ static void __init do_pre_smp_initcalls(void)
  {
  	initcall_t *fn;
  
@@ -75294,7 +77632,7 @@ index 9484f4b..4c01430 100644
  }
  
  /*
-@@ -802,8 +871,8 @@ static int run_init_process(const char *init_filename)
+@@ -802,8 +881,8 @@ static int run_init_process(const char *init_filename)
  {
  	argv_init[0] = init_filename;
  	return do_execve(init_filename,
@@ -75305,7 +77643,7 @@ index 9484f4b..4c01430 100644
  }
  
  static noinline void __init kernel_init_freeable(void);
-@@ -880,7 +949,7 @@ static noinline void __init kernel_init_freeable(void)
+@@ -880,7 +959,7 @@ static noinline void __init kernel_init_freeable(void)
  	do_basic_setup();
  
  	/* Open the /dev/console on the rootfs, this should never fail */
@@ -75314,7 +77652,7 @@ index 9484f4b..4c01430 100644
  		pr_err("Warning: unable to open an initial console.\n");
  
  	(void) sys_dup(0);
-@@ -893,11 +962,13 @@ static noinline void __init kernel_init_freeable(void)
+@@ -893,11 +972,13 @@ static noinline void __init kernel_init_freeable(void)
  	if (!ramdisk_execute_command)
  		ramdisk_execute_command = "/init";
  
@@ -75743,10 +78081,10 @@ index f6c2ce5..982c0f9 100644
 +	return ns_capable_nolog(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
 +}
 diff --git a/kernel/cgroup.c b/kernel/cgroup.c
-index c6e77ef..af531a0 100644
+index 2e9b387..61817b1 100644
 --- a/kernel/cgroup.c
 +++ b/kernel/cgroup.c
-@@ -5391,7 +5391,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
+@@ -5398,7 +5398,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
  		struct css_set *cg = link->cg;
  		struct task_struct *task;
  		int count = 0;
@@ -77166,10 +79504,20 @@ index 8241906..d625f2c 100644
  	kernel_cap_t new_cap;
  	int err, i;
 diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index bddf3b2..07b90dd 100644
+index bddf3b2..233bf40 100644
 --- a/kernel/kprobes.c
 +++ b/kernel/kprobes.c
-@@ -185,7 +185,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
+@@ -31,6 +31,9 @@
+  *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
+  *		<prasanna@in.ibm.com> added function-return probes.
+  */
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++#define __INCLUDED_BY_HIDESYM 1
++#endif
+ #include <linux/kprobes.h>
+ #include <linux/hash.h>
+ #include <linux/init.h>
+@@ -185,7 +188,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
  	 * kernel image and loaded module images reside. This is required
  	 * so x86_64 can correctly handle the %rip-relative fixups.
  	 */
@@ -77178,7 +79526,7 @@ index bddf3b2..07b90dd 100644
  	if (!kip->insns) {
  		kfree(kip);
  		return NULL;
-@@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
+@@ -225,7 +228,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
  		 */
  		if (!list_is_singular(&kip->list)) {
  			list_del(&kip->list);
@@ -77187,7 +79535,7 @@ index bddf3b2..07b90dd 100644
  			kfree(kip);
  		}
  		return 1;
-@@ -2083,7 +2083,7 @@ static int __init init_kprobes(void)
+@@ -2083,7 +2086,7 @@ static int __init init_kprobes(void)
  {
  	int i, err = 0;
  	unsigned long offset = 0, size = 0;
@@ -77196,7 +79544,7 @@ index bddf3b2..07b90dd 100644
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
-@@ -2168,11 +2168,11 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
+@@ -2168,11 +2171,11 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
  		kprobe_type = "k";
  
  	if (sym)
@@ -77210,7 +79558,7 @@ index bddf3b2..07b90dd 100644
  			p->addr, kprobe_type, p->addr);
  
  	if (!pp)
-@@ -2209,7 +2209,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
+@@ -2209,7 +2212,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
  	unsigned long offset = 0;
@@ -79731,7 +82079,7 @@ index ce39224d..0e09343 100644
  #define sched_class_highest (&stop_sched_class)
  #define for_each_class(class) \
 diff --git a/kernel/signal.c b/kernel/signal.c
-index 113411b..17190e2 100644
+index 113411b..20d0a99 100644
 --- a/kernel/signal.c
 +++ b/kernel/signal.c
 @@ -51,12 +51,12 @@ static struct kmem_cache *sigqueue_cachep;
@@ -79857,7 +82205,24 @@ index 113411b..17190e2 100644
  	if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
  		error = check_kill_permission(sig, info, p);
  		/*
-@@ -3240,8 +3271,8 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack,
+@@ -3219,6 +3250,16 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
+ 		__put_user(t->sas_ss_size, &uss->ss_size);
+ }
+ 
++#ifdef CONFIG_X86
++void __save_altstack_ex(stack_t __user *uss, unsigned long sp)
++{
++	struct task_struct *t = current;
++	put_user_ex((void __user *)t->sas_ss_sp, &uss->ss_sp);
++	put_user_ex(sas_ss_flags(sp), &uss->ss_flags);
++	put_user_ex(t->sas_ss_size, &uss->ss_size);
++}
++#endif
++
+ #ifdef CONFIG_COMPAT
+ COMPAT_SYSCALL_DEFINE2(sigaltstack,
+ 			const compat_stack_t __user *, uss_ptr,
+@@ -3240,8 +3281,8 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack,
  	}
  	seg = get_fs();
  	set_fs(KERNEL_DS);
@@ -79868,6 +82233,23 @@ index 113411b..17190e2 100644
  			     compat_user_stack_pointer());
  	set_fs(seg);
  	if (ret >= 0 && uoss_ptr)  {
+@@ -3268,6 +3309,16 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
+ 		__put_user(sas_ss_flags(sp), &uss->ss_flags) |
+ 		__put_user(t->sas_ss_size, &uss->ss_size);
+ }
++
++#ifdef CONFIG_X86
++void __compat_save_altstack_ex(compat_stack_t __user *uss, unsigned long sp)
++{
++	struct task_struct *t = current;
++	put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &uss->ss_sp);
++	put_user_ex(sas_ss_flags(sp), &uss->ss_flags);
++	put_user_ex(t->sas_ss_size, &uss->ss_size);
++}
++#endif
+ #endif
+ 
+ #ifdef __ARCH_WANT_SYS_SIGPENDING
 diff --git a/kernel/smp.c b/kernel/smp.c
 index 4dba0f7..fe9f773 100644
 --- a/kernel/smp.c
@@ -81021,10 +83403,10 @@ index e444ff8..438b8f4 100644
  		*data_page = bpage;
  
 diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
-index f7bc3ce..b8ef9b5 100644
+index 06a5bce..53ad6e7 100644
 --- a/kernel/trace/trace.c
 +++ b/kernel/trace/trace.c
-@@ -3303,7 +3303,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
+@@ -3347,7 +3347,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
  	return 0;
  }
  
@@ -81184,10 +83566,10 @@ index b20428c..4845a10 100644
  
  	local_irq_save(flags);
 diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
-index d8c30db..f2f6af5 100644
+index 9064b91..1f5d2f8 100644
 --- a/kernel/user_namespace.c
 +++ b/kernel/user_namespace.c
-@@ -79,6 +79,21 @@ int create_user_ns(struct cred *new)
+@@ -82,6 +82,21 @@ int create_user_ns(struct cred *new)
  	    !kgid_has_mapping(parent_ns, group))
  		return -EPERM;
  
@@ -81209,30 +83591,7 @@ index d8c30db..f2f6af5 100644
  	ns = kmem_cache_zalloc(user_ns_cachep, GFP_KERNEL);
  	if (!ns)
  		return -ENOMEM;
-@@ -105,6 +120,7 @@ int create_user_ns(struct cred *new)
- int unshare_userns(unsigned long unshare_flags, struct cred **new_cred)
- {
- 	struct cred *cred;
-+	int err;
- 
- 	if (!(unshare_flags & CLONE_NEWUSER))
- 		return 0;
-@@ -113,8 +129,12 @@ int unshare_userns(unsigned long unshare_flags, struct cred **new_cred)
- 	if (!cred)
- 		return -ENOMEM;
- 
--	*new_cred = cred;
--	return create_user_ns(cred);
-+	err = create_user_ns(cred);
-+	if (err)
-+		put_cred(cred);
-+	else
-+		*new_cred = cred;
-+	return err;
- }
- 
- void free_user_ns(struct user_namespace *ns)
-@@ -853,7 +873,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
+@@ -862,7 +877,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
  	if (atomic_read(&current->mm->mm_users) > 1)
  		return -EINVAL;
  
@@ -81268,10 +83627,10 @@ index 05039e3..17490c7 100644
  	.thread_should_run	= watchdog_should_run,
  	.thread_fn		= watchdog,
 diff --git a/kernel/workqueue.c b/kernel/workqueue.c
-index ee8e29a..410568e 100644
+index 6f01921..139869b 100644
 --- a/kernel/workqueue.c
 +++ b/kernel/workqueue.c
-@@ -4584,7 +4584,7 @@ static void rebind_workers(struct worker_pool *pool)
+@@ -4596,7 +4596,7 @@ static void rebind_workers(struct worker_pool *pool)
  		WARN_ON_ONCE(!(worker_flags & WORKER_UNBOUND));
  		worker_flags |= WORKER_REBOUND;
  		worker_flags &= ~WORKER_UNBOUND;
@@ -82046,7 +84405,7 @@ index b32b70c..e512eb0 100644
  	set_page_address(page, (void *)vaddr);
  
 diff --git a/mm/hugetlb.c b/mm/hugetlb.c
-index 5cf99bf..28634c8 100644
+index 5cf99bf..5c01c2f 100644
 --- a/mm/hugetlb.c
 +++ b/mm/hugetlb.c
 @@ -2022,15 +2022,17 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
@@ -82091,6 +84450,15 @@ index 5cf99bf..28634c8 100644
  	if (ret)
  		goto out;
  
+@@ -2490,7 +2494,7 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+ 
+ 	mm = vma->vm_mm;
+ 
+-	tlb_gather_mmu(&tlb, mm, 0);
++	tlb_gather_mmu(&tlb, mm, start, end);
+ 	__unmap_hugepage_range(&tlb, vma, start, end, ref_page);
+ 	tlb_finish_mmu(&tlb, start, end);
+ }
 @@ -2545,6 +2549,27 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
  	return 1;
  }
@@ -82181,7 +84549,7 @@ index 5cf99bf..28634c8 100644
  	if (!ptep)
  		return VM_FAULT_OOM;
 diff --git a/mm/internal.h b/mm/internal.h
-index 8562de0..7fdfe92 100644
+index 8562de0..92b2073 100644
 --- a/mm/internal.h
 +++ b/mm/internal.h
 @@ -100,6 +100,7 @@ extern pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address);
@@ -82192,6 +84560,15 @@ index 8562de0..7fdfe92 100644
  extern void prep_compound_page(struct page *page, unsigned long order);
  #ifdef CONFIG_MEMORY_FAILURE
  extern bool is_free_buddy_page(struct page *page);
+@@ -355,7 +356,7 @@ extern u32 hwpoison_filter_enable;
+ 
+ extern unsigned long vm_mmap_pgoff(struct file *, unsigned long,
+         unsigned long, unsigned long,
+-        unsigned long, unsigned long);
++        unsigned long, unsigned long) __intentional_overflow(-1);
+ 
+ extern void set_pageblock_order(void);
+ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
 diff --git a/mm/kmemleak.c b/mm/kmemleak.c
 index c8d7f31..2dbeffd 100644
 --- a/mm/kmemleak.c
@@ -82434,10 +84811,39 @@ index ceb0c7f..b2b8e94 100644
  	} else {
  		pr_info("soft offline: %#lx: isolation failed: %d, page count %d, type %lx\n",
 diff --git a/mm/memory.c b/mm/memory.c
-index 5e50800..c47ba9a 100644
+index 5e50800..7c0340f 100644
 --- a/mm/memory.c
 +++ b/mm/memory.c
-@@ -429,6 +429,7 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+@@ -211,14 +211,15 @@ static int tlb_next_batch(struct mmu_gather *tlb)
+  *	tear-down from @mm. The @fullmm argument is used when @mm is without
+  *	users and we're going to destroy the full address space (exit/execve).
+  */
+-void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
++void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end)
+ {
+ 	tlb->mm = mm;
+ 
+-	tlb->fullmm     = fullmm;
++	/* Is it from 0 to ~0? */
++	tlb->fullmm     = !(start | (end+1));
+ 	tlb->need_flush_all = 0;
+-	tlb->start	= -1UL;
+-	tlb->end	= 0;
++	tlb->start	= start;
++	tlb->end	= end;
+ 	tlb->need_flush = 0;
+ 	tlb->local.next = NULL;
+ 	tlb->local.nr   = 0;
+@@ -258,8 +259,6 @@ void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long e
+ {
+ 	struct mmu_gather_batch *batch, *next;
+ 
+-	tlb->start = start;
+-	tlb->end   = end;
+ 	tlb_flush_mmu(tlb);
+ 
+ 	/* keep the page table cache within bounds */
+@@ -429,6 +428,7 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
  		free_pte_range(tlb, pmd, addr);
  	} while (pmd++, addr = next, addr != end);
  
@@ -82445,7 +84851,7 @@ index 5e50800..c47ba9a 100644
  	start &= PUD_MASK;
  	if (start < floor)
  		return;
-@@ -443,6 +444,8 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+@@ -443,6 +443,8 @@ static inline void free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
  	pmd = pmd_offset(pud, start);
  	pud_clear(pud);
  	pmd_free_tlb(tlb, pmd, start);
@@ -82454,7 +84860,7 @@ index 5e50800..c47ba9a 100644
  }
  
  static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
-@@ -462,6 +465,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+@@ -462,6 +464,7 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
  		free_pmd_range(tlb, pud, addr, next, floor, ceiling);
  	} while (pud++, addr = next, addr != end);
  
@@ -82462,7 +84868,7 @@ index 5e50800..c47ba9a 100644
  	start &= PGDIR_MASK;
  	if (start < floor)
  		return;
-@@ -476,6 +480,8 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+@@ -476,6 +479,8 @@ static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
  	pud = pud_offset(pgd, start);
  	pgd_clear(pgd);
  	pud_free_tlb(tlb, pud, start);
@@ -82471,7 +84877,65 @@ index 5e50800..c47ba9a 100644
  }
  
  /*
-@@ -1638,12 +1644,6 @@ no_page_table:
+@@ -1101,7 +1106,6 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
+ 	spinlock_t *ptl;
+ 	pte_t *start_pte;
+ 	pte_t *pte;
+-	unsigned long range_start = addr;
+ 
+ again:
+ 	init_rss_vec(rss);
+@@ -1204,17 +1208,25 @@ again:
+ 	 * and page-free while holding it.
+ 	 */
+ 	if (force_flush) {
++		unsigned long old_end;
++
+ 		force_flush = 0;
+ 
+-#ifdef HAVE_GENERIC_MMU_GATHER
+-		tlb->start = range_start;
++		/*
++		 * Flush the TLB just for the previous segment,
++		 * then update the range to be the remaining
++		 * TLB range.
++		 */
++		old_end = tlb->end;
+ 		tlb->end = addr;
+-#endif
++
+ 		tlb_flush_mmu(tlb);
+-		if (addr != end) {
+-			range_start = addr;
++
++		tlb->start = addr;
++		tlb->end = old_end;
++
++		if (addr != end)
+ 			goto again;
+-		}
+ 	}
+ 
+ 	return addr;
+@@ -1399,7 +1411,7 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start,
+ 	unsigned long end = start + size;
+ 
+ 	lru_add_drain();
+-	tlb_gather_mmu(&tlb, mm, 0);
++	tlb_gather_mmu(&tlb, mm, start, end);
+ 	update_hiwater_rss(mm);
+ 	mmu_notifier_invalidate_range_start(mm, start, end);
+ 	for ( ; vma && vma->vm_start < end; vma = vma->vm_next)
+@@ -1425,7 +1437,7 @@ static void zap_page_range_single(struct vm_area_struct *vma, unsigned long addr
+ 	unsigned long end = address + size;
+ 
+ 	lru_add_drain();
+-	tlb_gather_mmu(&tlb, mm, 0);
++	tlb_gather_mmu(&tlb, mm, address, end);
+ 	update_hiwater_rss(mm);
+ 	mmu_notifier_invalidate_range_start(mm, address, end);
+ 	unmap_single_vma(&tlb, vma, address, end, details);
+@@ -1638,12 +1650,6 @@ no_page_table:
  	return page;
  }
  
@@ -82484,7 +84948,7 @@ index 5e50800..c47ba9a 100644
  /**
   * __get_user_pages() - pin user pages in memory
   * @tsk:	task_struct of target task
-@@ -1730,10 +1730,10 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+@@ -1730,10 +1736,10 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
  
  	i = 0;
  
@@ -82497,7 +84961,7 @@ index 5e50800..c47ba9a 100644
  		if (!vma && in_gate_area(mm, start)) {
  			unsigned long pg = start & PAGE_MASK;
  			pgd_t *pgd;
-@@ -1782,7 +1782,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+@@ -1782,7 +1788,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
  			goto next_page;
  		}
  
@@ -82506,7 +84970,7 @@ index 5e50800..c47ba9a 100644
  		    (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
  		    !(vm_flags & vma->vm_flags))
  			return i ? : -EFAULT;
-@@ -1811,11 +1811,6 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+@@ -1811,11 +1817,6 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
  				int ret;
  				unsigned int fault_flags = 0;
  
@@ -82518,7 +84982,7 @@ index 5e50800..c47ba9a 100644
  				if (foll_flags & FOLL_WRITE)
  					fault_flags |= FAULT_FLAG_WRITE;
  				if (nonblocking)
-@@ -1895,7 +1890,7 @@ next_page:
+@@ -1895,7 +1896,7 @@ next_page:
  			start += page_increm * PAGE_SIZE;
  			nr_pages -= page_increm;
  		} while (nr_pages && start < vma->vm_end);
@@ -82527,7 +84991,7 @@ index 5e50800..c47ba9a 100644
  	return i;
  }
  EXPORT_SYMBOL(__get_user_pages);
-@@ -2102,6 +2097,10 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
+@@ -2102,6 +2103,10 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
  	page_add_file_rmap(page);
  	set_pte_at(mm, addr, pte, mk_pte(page, prot));
  
@@ -82538,7 +85002,7 @@ index 5e50800..c47ba9a 100644
  	retval = 0;
  	pte_unmap_unlock(pte, ptl);
  	return retval;
-@@ -2146,9 +2145,21 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
+@@ -2146,9 +2151,21 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
  	if (!page_count(page))
  		return -EINVAL;
  	if (!(vma->vm_flags & VM_MIXEDMAP)) {
@@ -82560,7 +85024,7 @@ index 5e50800..c47ba9a 100644
  	}
  	return insert_page(vma, addr, page, vma->vm_page_prot);
  }
-@@ -2231,6 +2242,7 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
+@@ -2231,6 +2248,7 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
  			unsigned long pfn)
  {
  	BUG_ON(!(vma->vm_flags & VM_MIXEDMAP));
@@ -82568,7 +85032,7 @@ index 5e50800..c47ba9a 100644
  
  	if (addr < vma->vm_start || addr >= vma->vm_end)
  		return -EFAULT;
-@@ -2478,7 +2490,9 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
+@@ -2478,7 +2496,9 @@ static int apply_to_pmd_range(struct mm_struct *mm, pud_t *pud,
  
  	BUG_ON(pud_huge(*pud));
  
@@ -82579,7 +85043,7 @@ index 5e50800..c47ba9a 100644
  	if (!pmd)
  		return -ENOMEM;
  	do {
-@@ -2498,7 +2512,9 @@ static int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
+@@ -2498,7 +2518,9 @@ static int apply_to_pud_range(struct mm_struct *mm, pgd_t *pgd,
  	unsigned long next;
  	int err;
  
@@ -82590,7 +85054,7 @@ index 5e50800..c47ba9a 100644
  	if (!pud)
  		return -ENOMEM;
  	do {
-@@ -2586,6 +2602,186 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
+@@ -2586,6 +2608,186 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
  		copy_user_highpage(dst, src, va, vma);
  }
  
@@ -82777,7 +85241,7 @@ index 5e50800..c47ba9a 100644
  /*
   * This routine handles present pages, when users try to write
   * to a shared page. It is done by copying the page to a new address
-@@ -2802,6 +2998,12 @@ gotten:
+@@ -2802,6 +3004,12 @@ gotten:
  	 */
  	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
  	if (likely(pte_same(*page_table, orig_pte))) {
@@ -82790,7 +85254,7 @@ index 5e50800..c47ba9a 100644
  		if (old_page) {
  			if (!PageAnon(old_page)) {
  				dec_mm_counter_fast(mm, MM_FILEPAGES);
-@@ -2853,6 +3055,10 @@ gotten:
+@@ -2853,6 +3061,10 @@ gotten:
  			page_remove_rmap(old_page);
  		}
  
@@ -82801,7 +85265,7 @@ index 5e50800..c47ba9a 100644
  		/* Free the old page.. */
  		new_page = old_page;
  		ret |= VM_FAULT_WRITE;
-@@ -3128,6 +3334,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3128,6 +3340,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
  	swap_free(entry);
  	if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
  		try_to_free_swap(page);
@@ -82813,7 +85277,7 @@ index 5e50800..c47ba9a 100644
  	unlock_page(page);
  	if (page != swapcache) {
  		/*
-@@ -3151,6 +3362,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3151,6 +3368,11 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
  
  	/* No need to invalidate - it was non-present before */
  	update_mmu_cache(vma, address, page_table);
@@ -82825,7 +85289,7 @@ index 5e50800..c47ba9a 100644
  unlock:
  	pte_unmap_unlock(page_table, ptl);
  out:
-@@ -3170,40 +3386,6 @@ out_release:
+@@ -3170,40 +3392,6 @@ out_release:
  }
  
  /*
@@ -82866,7 +85330,7 @@ index 5e50800..c47ba9a 100644
   * We enter with non-exclusive mmap_sem (to exclude vma changes,
   * but allow concurrent faults), and pte mapped but not yet locked.
   * We return with mmap_sem still held, but pte unmapped and unlocked.
-@@ -3212,27 +3394,23 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3212,27 +3400,23 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
  		unsigned long address, pte_t *page_table, pmd_t *pmd,
  		unsigned int flags)
  {
@@ -82899,7 +85363,7 @@ index 5e50800..c47ba9a 100644
  	if (unlikely(anon_vma_prepare(vma)))
  		goto oom;
  	page = alloc_zeroed_user_highpage_movable(vma, address);
-@@ -3256,6 +3434,11 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3256,6 +3440,11 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
  	if (!pte_none(*page_table))
  		goto release;
  
@@ -82911,7 +85375,7 @@ index 5e50800..c47ba9a 100644
  	inc_mm_counter_fast(mm, MM_ANONPAGES);
  	page_add_new_anon_rmap(page, vma, address);
  setpte:
-@@ -3263,6 +3446,12 @@ setpte:
+@@ -3263,6 +3452,12 @@ setpte:
  
  	/* No need to invalidate - it was non-present before */
  	update_mmu_cache(vma, address, page_table);
@@ -82924,7 +85388,7 @@ index 5e50800..c47ba9a 100644
  unlock:
  	pte_unmap_unlock(page_table, ptl);
  	return 0;
-@@ -3406,6 +3595,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3406,6 +3601,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
  	 */
  	/* Only go through if we didn't race with anybody else... */
  	if (likely(pte_same(*page_table, orig_pte))) {
@@ -82937,7 +85401,7 @@ index 5e50800..c47ba9a 100644
  		flush_icache_page(vma, page);
  		entry = mk_pte(page, vma->vm_page_prot);
  		if (flags & FAULT_FLAG_WRITE)
-@@ -3425,6 +3620,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3425,6 +3626,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
  
  		/* no need to invalidate: a not-present page won't be cached */
  		update_mmu_cache(vma, address, page_table);
@@ -82952,7 +85416,7 @@ index 5e50800..c47ba9a 100644
  	} else {
  		if (cow_page)
  			mem_cgroup_uncharge_page(cow_page);
-@@ -3746,6 +3949,12 @@ int handle_pte_fault(struct mm_struct *mm,
+@@ -3746,6 +3955,12 @@ int handle_pte_fault(struct mm_struct *mm,
  		if (flags & FAULT_FLAG_WRITE)
  			flush_tlb_fix_spurious_fault(vma, address);
  	}
@@ -82965,7 +85429,7 @@ index 5e50800..c47ba9a 100644
  unlock:
  	pte_unmap_unlock(pte, ptl);
  	return 0;
-@@ -3762,6 +3971,10 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3762,6 +3977,10 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
  	pmd_t *pmd;
  	pte_t *pte;
  
@@ -82976,7 +85440,7 @@ index 5e50800..c47ba9a 100644
  	__set_current_state(TASK_RUNNING);
  
  	count_vm_event(PGFAULT);
-@@ -3773,6 +3986,34 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -3773,6 +3992,34 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
  	if (unlikely(is_vm_hugetlb_page(vma)))
  		return hugetlb_fault(mm, vma, address, flags);
  
@@ -83011,7 +85475,7 @@ index 5e50800..c47ba9a 100644
  retry:
  	pgd = pgd_offset(mm, address);
  	pud = pud_alloc(mm, pgd, address);
-@@ -3871,6 +4112,23 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+@@ -3871,6 +4118,23 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
  	spin_unlock(&mm->page_table_lock);
  	return 0;
  }
@@ -83035,7 +85499,7 @@ index 5e50800..c47ba9a 100644
  #endif /* __PAGETABLE_PUD_FOLDED */
  
  #ifndef __PAGETABLE_PMD_FOLDED
-@@ -3901,6 +4159,30 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+@@ -3901,6 +4165,30 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
  	spin_unlock(&mm->page_table_lock);
  	return 0;
  }
@@ -83066,7 +85530,7 @@ index 5e50800..c47ba9a 100644
  #endif /* __PAGETABLE_PMD_FOLDED */
  
  #if !defined(__HAVE_ARCH_GATE_AREA)
-@@ -3914,7 +4196,7 @@ static int __init gate_vma_init(void)
+@@ -3914,7 +4202,7 @@ static int __init gate_vma_init(void)
  	gate_vma.vm_start = FIXADDR_USER_START;
  	gate_vma.vm_end = FIXADDR_USER_END;
  	gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
@@ -83075,7 +85539,7 @@ index 5e50800..c47ba9a 100644
  
  	return 0;
  }
-@@ -4048,8 +4330,8 @@ out:
+@@ -4048,8 +4336,8 @@ out:
  	return ret;
  }
  
@@ -83086,7 +85550,7 @@ index 5e50800..c47ba9a 100644
  {
  	resource_size_t phys_addr;
  	unsigned long prot = 0;
-@@ -4074,8 +4356,8 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
+@@ -4074,8 +4362,8 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
   * Access another process' address space as given in mm.  If non-NULL, use the
   * given task for page fault accounting.
   */
@@ -83097,7 +85561,7 @@ index 5e50800..c47ba9a 100644
  {
  	struct vm_area_struct *vma;
  	void *old_buf = buf;
-@@ -4083,7 +4365,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+@@ -4083,7 +4371,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
  	down_read(&mm->mmap_sem);
  	/* ignore errors, just check how much was successfully transferred */
  	while (len) {
@@ -83106,7 +85570,7 @@ index 5e50800..c47ba9a 100644
  		void *maddr;
  		struct page *page = NULL;
  
-@@ -4142,8 +4424,8 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+@@ -4142,8 +4430,8 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
   *
   * The caller must hold a reference on @mm.
   */
@@ -83117,7 +85581,7 @@ index 5e50800..c47ba9a 100644
  {
  	return __access_remote_vm(NULL, mm, addr, buf, len, write);
  }
-@@ -4153,11 +4435,11 @@ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+@@ -4153,11 +4441,11 @@ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
   * Source/target buffer must be kernel space,
   * Do not walk the page table directly, use get_user_pages
   */
@@ -83294,7 +85758,7 @@ index 79b7cf7..9944291 100644
  	    capable(CAP_IPC_LOCK))
  		ret = do_mlockall(flags);
 diff --git a/mm/mmap.c b/mm/mmap.c
-index 7dbe397..e84c411 100644
+index 7dbe397..bfb7626 100644
 --- a/mm/mmap.c
 +++ b/mm/mmap.c
 @@ -36,6 +36,7 @@
@@ -84163,6 +86627,15 @@ index 7dbe397..e84c411 100644
  		if (vma->vm_flags & VM_ACCOUNT)
  			nr_accounted += nrpages;
  		vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
+@@ -2356,7 +2728,7 @@ static void unmap_region(struct mm_struct *mm,
+ 	struct mmu_gather tlb;
+ 
+ 	lru_add_drain();
+-	tlb_gather_mmu(&tlb, mm, 0);
++	tlb_gather_mmu(&tlb, mm, start, end);
+ 	update_hiwater_rss(mm);
+ 	unmap_vmas(&tlb, vma, start, end);
+ 	free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS,
 @@ -2379,6 +2751,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
  	insertion_point = (prev ? &prev->vm_next : &mm->mmap);
  	vma->vm_prev = NULL;
@@ -84468,6 +86941,15 @@ index 7dbe397..e84c411 100644
  	return addr;
  }
  
+@@ -2735,7 +3232,7 @@ void exit_mmap(struct mm_struct *mm)
+ 
+ 	lru_add_drain();
+ 	flush_cache_mm(mm);
+-	tlb_gather_mmu(&tlb, mm, 1);
++	tlb_gather_mmu(&tlb, mm, 0, -1);
+ 	/* update_hiwater_rss(mm) here? but nobody should be looking */
+ 	/* Use -1 here to ensure all VMAs in the mm are unmapped */
+ 	unmap_vmas(&tlb, vma, 0, -1);
 @@ -2750,6 +3247,7 @@ void exit_mmap(struct mm_struct *mm)
  	while (vma) {
  		if (vma->vm_flags & VM_ACCOUNT)
@@ -86952,6 +89434,89 @@ index f680ee1..97e3542 100644
  
  	if (batadv_ogm_packet->flags & BATADV_DIRECTLINK)
  		has_directlink_flag = 1;
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index de27b31..7058bfe 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -1522,6 +1522,8 @@ out:
+  * in these cases, the skb is further handled by this function and
+  * returns 1, otherwise it returns 0 and the caller shall further
+  * process the skb.
++ *
++ * This call might reallocate skb data.
+  */
+ int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid)
+ {
+diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
+index f105219..7614af3 100644
+--- a/net/batman-adv/gateway_client.c
++++ b/net/batman-adv/gateway_client.c
+@@ -508,6 +508,7 @@ out:
+ 	return 0;
+ }
+ 
++/* this call might reallocate skb data */
+ static bool batadv_is_type_dhcprequest(struct sk_buff *skb, int header_len)
+ {
+ 	int ret = false;
+@@ -568,6 +569,7 @@ out:
+ 	return ret;
+ }
+ 
++/* this call might reallocate skb data */
+ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
+ {
+ 	struct ethhdr *ethhdr;
+@@ -619,6 +621,12 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
+ 
+ 	if (!pskb_may_pull(skb, *header_len + sizeof(*udphdr)))
+ 		return false;
++
++	/* skb->data might have been reallocated by pskb_may_pull() */
++	ethhdr = (struct ethhdr *)skb->data;
++	if (ntohs(ethhdr->h_proto) == ETH_P_8021Q)
++		ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
++
+ 	udphdr = (struct udphdr *)(skb->data + *header_len);
+ 	*header_len += sizeof(*udphdr);
+ 
+@@ -634,12 +642,14 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
+ 	return true;
+ }
+ 
++/* this call might reallocate skb data */
+ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
+-			    struct sk_buff *skb, struct ethhdr *ethhdr)
++			    struct sk_buff *skb)
+ {
+ 	struct batadv_neigh_node *neigh_curr = NULL, *neigh_old = NULL;
+ 	struct batadv_orig_node *orig_dst_node = NULL;
+ 	struct batadv_gw_node *curr_gw = NULL;
++	struct ethhdr *ethhdr;
+ 	bool ret, out_of_range = false;
+ 	unsigned int header_len = 0;
+ 	uint8_t curr_tq_avg;
+@@ -648,6 +658,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
+ 	if (!ret)
+ 		goto out;
+ 
++	ethhdr = (struct ethhdr *)skb->data;
+ 	orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
+ 						 ethhdr->h_dest);
+ 	if (!orig_dst_node)
+diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h
+index 039902d..1037d75 100644
+--- a/net/batman-adv/gateway_client.h
++++ b/net/batman-adv/gateway_client.h
+@@ -34,7 +34,6 @@ void batadv_gw_node_delete(struct batadv_priv *bat_priv,
+ void batadv_gw_node_purge(struct batadv_priv *bat_priv);
+ int batadv_gw_client_seq_print_text(struct seq_file *seq, void *offset);
+ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len);
+-bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
+-			    struct sk_buff *skb, struct ethhdr *ethhdr);
++bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, struct sk_buff *skb);
+ 
+ #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
 diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
 index 522243a..b48c0ef 100644
 --- a/net/batman-adv/hard-interface.c
@@ -86975,10 +89540,31 @@ index 522243a..b48c0ef 100644
  
  	return hard_iface;
 diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
-index 819dfb0..9a672d1 100644
+index 819dfb0..226bacd 100644
 --- a/net/batman-adv/soft-interface.c
 +++ b/net/batman-adv/soft-interface.c
-@@ -253,7 +253,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
+@@ -180,6 +180,9 @@ static int batadv_interface_tx(struct sk_buff *skb,
+ 	if (batadv_bla_tx(bat_priv, skb, vid))
+ 		goto dropped;
+ 
++	/* skb->data might have been reallocated by batadv_bla_tx() */
++	ethhdr = (struct ethhdr *)skb->data;
++
+ 	/* Register the client MAC in the transtable */
+ 	if (!is_multicast_ether_addr(ethhdr->h_source))
+ 		batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
+@@ -220,6 +223,10 @@ static int batadv_interface_tx(struct sk_buff *skb,
+ 		default:
+ 			break;
+ 		}
++
++		/* reminder: ethhdr might have become unusable from here on
++		 * (batadv_gw_is_dhcp_target() might have reallocated skb data)
++		 */
+ 	}
+ 
+ 	/* ethernet packet should be broadcasted */
+@@ -253,7 +260,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
  		       primary_if->net_dev->dev_addr, ETH_ALEN);
  
  		/* set broadcast sequence number */
@@ -86987,7 +89573,16 @@ index 819dfb0..9a672d1 100644
  		bcast_packet->seqno = htonl(seqno);
  
  		batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay);
-@@ -472,7 +472,7 @@ static int batadv_softif_init_late(struct net_device *dev)
+@@ -266,7 +273,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
+ 	/* unicast packet */
+ 	} else {
+ 		if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_OFF) {
+-			ret = batadv_gw_out_of_range(bat_priv, skb, ethhdr);
++			ret = batadv_gw_out_of_range(bat_priv, skb);
+ 			if (ret)
+ 				goto dropped;
+ 		}
+@@ -472,7 +479,7 @@ static int batadv_softif_init_late(struct net_device *dev)
  	atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
  
  	atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
@@ -87028,7 +89623,7 @@ index aba8364..50fcbb8 100644
  	atomic_t batman_queue_left;
  	char num_ifaces;
 diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
-index 0bb3b59..ffcbf2f 100644
+index 0bb3b59..0e3052e 100644
 --- a/net/batman-adv/unicast.c
 +++ b/net/batman-adv/unicast.c
 @@ -270,7 +270,7 @@ int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
@@ -87040,6 +89635,58 @@ index 0bb3b59..ffcbf2f 100644
  	frag1->seqno = htons(seqno - 1);
  	frag2->seqno = htons(seqno);
  
+@@ -326,7 +326,9 @@ static bool batadv_unicast_push_and_fill_skb(struct sk_buff *skb, int hdr_size,
+  * @skb: the skb containing the payload to encapsulate
+  * @orig_node: the destination node
+  *
+- * Returns false if the payload could not be encapsulated or true otherwise
++ * Returns false if the payload could not be encapsulated or true otherwise.
++ *
++ * This call might reallocate skb data.
+  */
+ static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
+ 				       struct batadv_orig_node *orig_node)
+@@ -343,7 +345,9 @@ static bool batadv_unicast_prepare_skb(struct sk_buff *skb,
+  * @orig_node: the destination node
+  * @packet_subtype: the batman 4addr packet subtype to use
+  *
+- * Returns false if the payload could not be encapsulated or true otherwise
++ * Returns false if the payload could not be encapsulated or true otherwise.
++ *
++ * This call might reallocate skb data.
+  */
+ bool batadv_unicast_4addr_prepare_skb(struct batadv_priv *bat_priv,
+ 				      struct sk_buff *skb,
+@@ -401,7 +405,7 @@ int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
+ 	struct batadv_neigh_node *neigh_node;
+ 	int data_len = skb->len;
+ 	int ret = NET_RX_DROP;
+-	unsigned int dev_mtu;
++	unsigned int dev_mtu, header_len;
+ 
+ 	/* get routing information */
+ 	if (is_multicast_ether_addr(ethhdr->h_dest)) {
+@@ -429,10 +433,12 @@ find_router:
+ 	switch (packet_type) {
+ 	case BATADV_UNICAST:
+ 		batadv_unicast_prepare_skb(skb, orig_node);
++		header_len = sizeof(struct batadv_unicast_packet);
+ 		break;
+ 	case BATADV_UNICAST_4ADDR:
+ 		batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
+ 						 packet_subtype);
++		header_len = sizeof(struct batadv_unicast_4addr_packet);
+ 		break;
+ 	default:
+ 		/* this function supports UNICAST and UNICAST_4ADDR only. It
+@@ -441,6 +447,7 @@ find_router:
+ 		goto out;
+ 	}
+ 
++	ethhdr = (struct ethhdr *)(skb->data + header_len);
+ 	unicast_packet = (struct batadv_unicast_packet *)skb->data;
+ 
+ 	/* inform the destination node that we are still missing a correct route
 diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
 index ace5e55..a65a1c0 100644
 --- a/net/bluetooth/hci_core.c
@@ -87761,7 +90408,7 @@ index f9765203..9feaef8 100644
  	return error;
  }
 diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
-index a08bd2b..4e8f43c 100644
+index a08bd2b..c59bd7c 100644
 --- a/net/core/rtnetlink.c
 +++ b/net/core/rtnetlink.c
 @@ -58,7 +58,7 @@ struct rtnl_link {
@@ -87799,6 +90446,15 @@ index a08bd2b..4e8f43c 100644
  }
  EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
  
+@@ -2374,7 +2377,7 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
+ 	struct nlattr *extfilt;
+ 	u32 filter_mask = 0;
+ 
+-	extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct rtgenmsg),
++	extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
+ 				  IFLA_EXT_MASK);
+ 	if (extfilt)
+ 		filter_mask = nla_get_u32(extfilt);
 diff --git a/net/core/scm.c b/net/core/scm.c
 index 03795d0..eaf7368 100644
 --- a/net/core/scm.c
@@ -88245,9 +90901,18 @@ index dfc39d4..0d4fa52 100644
  #endif
  	if (dflt != &ipv4_devconf_dflt)
 diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
-index 4cfe34d..a6ba66e 100644
+index 4cfe34d..d2fac8a 100644
 --- a/net/ipv4/esp4.c
 +++ b/net/ipv4/esp4.c
+@@ -477,7 +477,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
+ 	}
+ 
+ 	return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
+-		 net_adj) & ~(align - 1)) + (net_adj - 2);
++		 net_adj) & ~(align - 1)) + net_adj - 2;
+ }
+ 
+ static void esp4_err(struct sk_buff *skb, u32 info)
 @@ -503,7 +503,7 @@ static void esp4_err(struct sk_buff *skb, u32 info)
  		return;
  
@@ -88298,6 +90963,30 @@ index 8f6cb7a..34507f9 100644
  
  	return nh->nh_saddr;
  }
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 49616fe..6e8a13d 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -71,7 +71,6 @@
+ #include <linux/init.h>
+ #include <linux/list.h>
+ #include <linux/slab.h>
+-#include <linux/prefetch.h>
+ #include <linux/export.h>
+ #include <net/net_namespace.h>
+ #include <net/ip.h>
+@@ -1761,10 +1760,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
+ 			if (!c)
+ 				continue;
+ 
+-			if (IS_LEAF(c)) {
+-				prefetch(rcu_dereference_rtnl(p->child[idx]));
++			if (IS_LEAF(c))
+ 				return (struct leaf *) c;
+-			}
+ 
+ 			/* Rescan start scanning in new node */
+ 			p = (struct tnode *) c;
 diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
 index 6acb541..9ea617d 100644
 --- a/net/ipv4/inet_connection_sock.c
@@ -88407,7 +91096,7 @@ index b66910a..cfe416e 100644
  	return -ENOMEM;
  }
 diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
-index 855004f..68e7458 100644
+index 855004f..9644112 100644
 --- a/net/ipv4/ip_gre.c
 +++ b/net/ipv4/ip_gre.c
 @@ -115,7 +115,7 @@ static bool log_ecn_error = true;
@@ -88419,6 +91108,15 @@ index 855004f..68e7458 100644
  static int ipgre_tunnel_init(struct net_device *dev);
  
  static int ipgre_net_id __read_mostly;
+@@ -572,7 +572,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
+ 	if (daddr)
+ 		memcpy(&iph->daddr, daddr, 4);
+ 	if (iph->daddr)
+-		return t->hlen;
++		return t->hlen + sizeof(*iph);
+ 
+ 	return -(t->hlen + sizeof(*iph));
+ }
 @@ -919,7 +919,7 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
  	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
  };
@@ -88771,10 +91469,10 @@ index d35bbf0..faa3ab8 100644
  			 sizeof(net->ipv4.dev_addr_genid));
  	return 0;
 diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
-index fa2f63f..6554815 100644
+index 3f25e75..3ae0f4d 100644
 --- a/net/ipv4/sysctl_net_ipv4.c
 +++ b/net/ipv4/sysctl_net_ipv4.c
-@@ -55,7 +55,7 @@ static int ipv4_local_port_range(ctl_table *table, int write,
+@@ -57,7 +57,7 @@ static int ipv4_local_port_range(ctl_table *table, int write,
  {
  	int ret;
  	int range[2];
@@ -88783,7 +91481,7 @@ index fa2f63f..6554815 100644
  		.data = &range,
  		.maxlen = sizeof(range),
  		.mode = table->mode,
-@@ -108,7 +108,7 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
+@@ -110,7 +110,7 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
  	int ret;
  	gid_t urange[2];
  	kgid_t low, high;
@@ -88792,7 +91490,7 @@ index fa2f63f..6554815 100644
  		.data = &urange,
  		.maxlen = sizeof(urange),
  		.mode = table->mode,
-@@ -139,7 +139,7 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write,
+@@ -141,7 +141,7 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write,
  				       void __user *buffer, size_t *lenp, loff_t *ppos)
  {
  	char val[TCP_CA_NAME_MAX];
@@ -88801,7 +91499,7 @@ index fa2f63f..6554815 100644
  		.data = val,
  		.maxlen = TCP_CA_NAME_MAX,
  	};
-@@ -158,7 +158,7 @@ static int proc_tcp_available_congestion_control(ctl_table *ctl,
+@@ -160,7 +160,7 @@ static int proc_tcp_available_congestion_control(ctl_table *ctl,
  						 void __user *buffer, size_t *lenp,
  						 loff_t *ppos)
  {
@@ -88810,7 +91508,7 @@ index fa2f63f..6554815 100644
  	int ret;
  
  	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
-@@ -175,7 +175,7 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
+@@ -177,7 +177,7 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
  					   void __user *buffer, size_t *lenp,
  					   loff_t *ppos)
  {
@@ -88819,7 +91517,7 @@ index fa2f63f..6554815 100644
  	int ret;
  
  	tbl.data = kmalloc(tbl.maxlen, GFP_USER);
-@@ -201,15 +201,17 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
+@@ -203,15 +203,17 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
  	struct mem_cgroup *memcg;
  #endif
  
@@ -88840,7 +91538,7 @@ index fa2f63f..6554815 100644
  	}
  
  	ret = proc_doulongvec_minmax(&tmp, write, buffer, lenp, ppos);
-@@ -236,7 +238,7 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
+@@ -238,7 +240,7 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write,
  static int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer,
  				 size_t *lenp, loff_t *ppos)
  {
@@ -88849,7 +91547,7 @@ index fa2f63f..6554815 100644
  	struct tcp_fastopen_context *ctxt;
  	int ret;
  	u32  user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */
-@@ -477,7 +479,7 @@ static struct ctl_table ipv4_table[] = {
+@@ -481,7 +483,7 @@ static struct ctl_table ipv4_table[] = {
  	},
  	{
  		.procname	= "ip_local_reserved_ports",
@@ -88858,7 +91556,7 @@ index fa2f63f..6554815 100644
  		.maxlen		= 65536,
  		.mode		= 0644,
  		.proc_handler	= proc_do_large_bitmap,
-@@ -842,11 +844,10 @@ static struct ctl_table ipv4_net_table[] = {
+@@ -846,11 +848,10 @@ static struct ctl_table ipv4_net_table[] = {
  
  static __net_init int ipv4_sysctl_init_net(struct net *net)
  {
@@ -88872,7 +91570,7 @@ index fa2f63f..6554815 100644
  		if (table == NULL)
  			goto err_alloc;
  
-@@ -881,15 +882,17 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
+@@ -885,15 +886,17 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
  
  	tcp_init_mem(net);
  
@@ -88893,7 +91591,7 @@ index fa2f63f..6554815 100644
  err_alloc:
  	return -ENOMEM;
  }
-@@ -911,16 +914,6 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
+@@ -915,16 +918,6 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
  static __init int sysctl_ipv4_init(void)
  {
  	struct ctl_table_header *hdr;
@@ -89291,6 +91989,19 @@ index fb8c94c..fb18024 100644
  	int ret;
  
  	/*
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 40ffd72..aeac0dc 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -425,7 +425,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
+ 		net_adj = 0;
+ 
+ 	return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
+-		 net_adj) & ~(align - 1)) + (net_adj - 2);
++		 net_adj) & ~(align - 1)) + net_adj - 2;
+ }
+ 
+ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
 index b4ff0a4..db9b764 100644
 --- a/net/ipv6/icmp.c
@@ -89909,10 +92620,10 @@ index 4fe76ff..426a904 100644
  };
  
 diff --git a/net/key/af_key.c b/net/key/af_key.c
-index 9da8620..97070ad 100644
+index ab8bd2c..cd2d641 100644
 --- a/net/key/af_key.c
 +++ b/net/key/af_key.c
-@@ -3047,10 +3047,10 @@ static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, const struc
+@@ -3048,10 +3048,10 @@ static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, const struc
  static u32 get_acqseq(void)
  {
  	u32 res;
@@ -89926,10 +92637,10 @@ index 9da8620..97070ad 100644
  	return res;
  }
 diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-index 4fdb306e..920086a 100644
+index ae36f8e..09d42ac 100644
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -804,7 +804,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
+@@ -806,7 +806,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
  			ret = ieee80211_vif_use_channel(sdata, chandef,
  					IEEE80211_CHANCTX_EXCLUSIVE);
  		}
@@ -89938,7 +92649,7 @@ index 4fdb306e..920086a 100644
  		local->_oper_chandef = *chandef;
  		ieee80211_hw_config(local, 0);
  	}
-@@ -2920,7 +2920,7 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
+@@ -2922,7 +2922,7 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
  		else
  			local->probe_req_reg--;
  
@@ -89947,7 +92658,7 @@ index 4fdb306e..920086a 100644
  			break;
  
  		ieee80211_queue_work(&local->hw, &local->reconfig_filter);
-@@ -3383,8 +3383,8 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
+@@ -3385,8 +3385,8 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
  	if (chanctx_conf) {
  		*chandef = chanctx_conf->def;
  		ret = 0;
@@ -90069,7 +92780,7 @@ index 8a7bfc4..4407cd0 100644
  		/*
  		 * Goal:
 diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
-index 7fc5d0d..07ea536 100644
+index 3401262..d5cd68d 100644
 --- a/net/mac80211/pm.c
 +++ b/net/mac80211/pm.c
 @@ -12,7 +12,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
@@ -90090,7 +92801,7 @@ index 7fc5d0d..07ea536 100644
  	if (local->wowlan) {
  		int err = drv_suspend(local, wowlan);
  		if (err < 0) {
-@@ -113,7 +113,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+@@ -116,7 +116,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
  	WARN_ON(!list_empty(&local->chanctx_list));
  
  	/* stop hardware - this must stop RX */
@@ -90493,6 +93204,49 @@ index a99b6c3..3841268 100644
  	return -NF_ACCEPT;
  }
  
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
+index 4d4d8f1..e0f9a32 100644
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -526,7 +526,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
+ 	__u32 seq, ack, sack, end, win, swin;
+ 	s16 receiver_offset;
+-	bool res;
++	bool res, in_recv_win;
+ 
+ 	/*
+ 	 * Get the required data from the packet.
+@@ -649,14 +649,18 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ 		 receiver->td_scale);
+ 
++	/* Is the ending sequence in the receive window (if available)? */
++	in_recv_win = !receiver->td_maxwin ||
++		      after(end, sender->td_end - receiver->td_maxwin - 1);
++
+ 	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
+ 		 before(seq, sender->td_maxend + 1),
+-		 after(end, sender->td_end - receiver->td_maxwin - 1),
++		 (in_recv_win ? 1 : 0),
+ 		 before(sack, receiver->td_end + 1),
+ 		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
+ 
+ 	if (before(seq, sender->td_maxend + 1) &&
+-	    after(end, sender->td_end - receiver->td_maxwin - 1) &&
++	    in_recv_win &&
+ 	    before(sack, receiver->td_end + 1) &&
+ 	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
+ 		/*
+@@ -725,7 +729,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 			nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
+ 			"nf_ct_tcp: %s ",
+ 			before(seq, sender->td_maxend + 1) ?
+-			after(end, sender->td_end - receiver->td_maxwin - 1) ?
++			in_recv_win ?
+ 			before(sack, receiver->td_end + 1) ?
+ 			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
+ 			: "ACK is under the lower bound (possible overly delayed ACK)"
 diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
 index bd700b4..4a3dc61 100644
 --- a/net/netfilter/nf_conntrack_standalone.c
@@ -90575,7 +93329,7 @@ index f042ae5..30ea486 100644
  }
  EXPORT_SYMBOL(nf_unregister_sockopt);
 diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
-index 962e979..d4ae2e9 100644
+index 962e979..e46f350 100644
 --- a/net/netfilter/nfnetlink_log.c
 +++ b/net/netfilter/nfnetlink_log.c
 @@ -82,7 +82,7 @@ static int nfnl_log_net_id __read_mostly;
@@ -90587,7 +93341,27 @@ index 962e979..d4ae2e9 100644
  };
  
  static struct nfnl_log_net *nfnl_log_pernet(struct net *net)
-@@ -559,7 +559,7 @@ __build_packet_message(struct nfnl_log_net *log,
+@@ -419,6 +419,7 @@ __build_packet_message(struct nfnl_log_net *log,
+ 	nfmsg->version = NFNETLINK_V0;
+ 	nfmsg->res_id = htons(inst->group_num);
+ 
++	memset(&pmsg, 0, sizeof(pmsg));
+ 	pmsg.hw_protocol	= skb->protocol;
+ 	pmsg.hook		= hooknum;
+ 
+@@ -498,7 +499,10 @@ __build_packet_message(struct nfnl_log_net *log,
+ 	if (indev && skb->dev &&
+ 	    skb->mac_header != skb->network_header) {
+ 		struct nfulnl_msg_packet_hw phw;
+-		int len = dev_parse_header(skb, phw.hw_addr);
++		int len;
++
++		memset(&phw, 0, sizeof(phw));
++		len = dev_parse_header(skb, phw.hw_addr);
+ 		if (len > 0) {
+ 			phw.hw_addrlen = htons(len);
+ 			if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw))
+@@ -559,7 +563,7 @@ __build_packet_message(struct nfnl_log_net *log,
  	/* global sequence number */
  	if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) &&
  	    nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL,
@@ -90596,6 +93370,130 @@ index 962e979..d4ae2e9 100644
  		goto nla_put_failure;
  
  	if (data_len) {
+diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
+index 5352b2d..e0083ce 100644
+--- a/net/netfilter/nfnetlink_queue_core.c
++++ b/net/netfilter/nfnetlink_queue_core.c
+@@ -444,7 +444,10 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
+ 	if (indev && entskb->dev &&
+ 	    entskb->mac_header != entskb->network_header) {
+ 		struct nfqnl_msg_packet_hw phw;
+-		int len = dev_parse_header(entskb, phw.hw_addr);
++		int len;
++
++		memset(&phw, 0, sizeof(phw));
++		len = dev_parse_header(entskb, phw.hw_addr);
+ 		if (len) {
+ 			phw.hw_addrlen = htons(len);
+ 			if (nla_put(skb, NFQA_HWADDR, sizeof(phw), &phw))
+diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
+index 7011c71..6113cc7 100644
+--- a/net/netfilter/xt_TCPMSS.c
++++ b/net/netfilter/xt_TCPMSS.c
+@@ -52,7 +52,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ {
+ 	const struct xt_tcpmss_info *info = par->targinfo;
+ 	struct tcphdr *tcph;
+-	unsigned int tcplen, i;
++	int len, tcp_hdrlen;
++	unsigned int i;
+ 	__be16 oldval;
+ 	u16 newmss;
+ 	u8 *opt;
+@@ -64,11 +65,14 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 	if (!skb_make_writable(skb, skb->len))
+ 		return -1;
+ 
+-	tcplen = skb->len - tcphoff;
++	len = skb->len - tcphoff;
++	if (len < (int)sizeof(struct tcphdr))
++		return -1;
++
+ 	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
++	tcp_hdrlen = tcph->doff * 4;
+ 
+-	/* Header cannot be larger than the packet */
+-	if (tcplen < tcph->doff*4)
++	if (len < tcp_hdrlen)
+ 		return -1;
+ 
+ 	if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
+@@ -87,9 +91,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 		newmss = info->mss;
+ 
+ 	opt = (u_int8_t *)tcph;
+-	for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) {
+-		if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS &&
+-		    opt[i+1] == TCPOLEN_MSS) {
++	for (i = sizeof(struct tcphdr); i <= tcp_hdrlen - TCPOLEN_MSS; i += optlen(opt, i)) {
++		if (opt[i] == TCPOPT_MSS && opt[i+1] == TCPOLEN_MSS) {
+ 			u_int16_t oldmss;
+ 
+ 			oldmss = (opt[i+2] << 8) | opt[i+3];
+@@ -112,9 +115,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 	}
+ 
+ 	/* There is data after the header so the option can't be added
+-	   without moving it, and doing so may make the SYN packet
+-	   itself too large. Accept the packet unmodified instead. */
+-	if (tcplen > tcph->doff*4)
++	 * without moving it, and doing so may make the SYN packet
++	 * itself too large. Accept the packet unmodified instead.
++	 */
++	if (len > tcp_hdrlen)
+ 		return 0;
+ 
+ 	/*
+@@ -143,10 +147,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 		newmss = min(newmss, (u16)1220);
+ 
+ 	opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
+-	memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
++	memmove(opt + TCPOLEN_MSS, opt, len - sizeof(struct tcphdr));
+ 
+ 	inet_proto_csum_replace2(&tcph->check, skb,
+-				 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
++				 htons(len), htons(len + TCPOLEN_MSS), 1);
+ 	opt[0] = TCPOPT_MSS;
+ 	opt[1] = TCPOLEN_MSS;
+ 	opt[2] = (newmss & 0xff00) >> 8;
+diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
+index b68fa19..625fa1d 100644
+--- a/net/netfilter/xt_TCPOPTSTRIP.c
++++ b/net/netfilter/xt_TCPOPTSTRIP.c
+@@ -38,7 +38,7 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
+ 	struct tcphdr *tcph;
+ 	u_int16_t n, o;
+ 	u_int8_t *opt;
+-	int len;
++	int len, tcp_hdrlen;
+ 
+ 	/* This is a fragment, no TCP header is available */
+ 	if (par->fragoff != 0)
+@@ -52,7 +52,9 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
+ 		return NF_DROP;
+ 
+ 	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
+-	if (tcph->doff * 4 > len)
++	tcp_hdrlen = tcph->doff * 4;
++
++	if (len < tcp_hdrlen)
+ 		return NF_DROP;
+ 
+ 	opt  = (u_int8_t *)tcph;
+@@ -61,10 +63,10 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
+ 	 * Walk through all TCP options - if we find some option to remove,
+ 	 * set all octets to %TCPOPT_NOP and adjust checksum.
+ 	 */
+-	for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) {
++	for (i = sizeof(struct tcphdr); i < tcp_hdrlen - 1; i += optl) {
+ 		optl = optlen(opt, i);
+ 
+-		if (i + optl > tcp_hdrlen(skb))
++		if (i + optl > tcp_hdrlen)
+ 			break;
+ 
+ 		if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i]))
 diff --git a/net/netfilter/xt_gradm.c b/net/netfilter/xt_gradm.c
 new file mode 100644
 index 0000000..c566332
@@ -90710,7 +93608,7 @@ index 57ee84d..8b99cf5 100644
  			);
  
 diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
-index 2fd6dbe..1032269 100644
+index 1076fe1..8285fd7 100644
 --- a/net/netlink/genetlink.c
 +++ b/net/netlink/genetlink.c
 @@ -310,18 +310,20 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
@@ -90751,6 +93649,27 @@ index 2fd6dbe..1032269 100644
  			return 0;
  		}
  	}
+@@ -789,6 +791,10 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
+ 	struct net *net = sock_net(skb->sk);
+ 	int chains_to_skip = cb->args[0];
+ 	int fams_to_skip = cb->args[1];
++	bool need_locking = chains_to_skip || fams_to_skip;
++
++	if (need_locking)
++		genl_lock();
+ 
+ 	for (i = chains_to_skip; i < GENL_FAM_TAB_SIZE; i++) {
+ 		n = 0;
+@@ -810,6 +816,9 @@ errout:
+ 	cb->args[0] = i;
+ 	cb->args[1] = n;
+ 
++	if (need_locking)
++		genl_unlock();
++
+ 	return skb->len;
+ }
+ 
 diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
 index ec0c80f..41e1830 100644
 --- a/net/netrom/af_netrom.c
@@ -91318,18 +94237,6 @@ index f226709..0e735a8 100644
  	_proto("Tx RESPONSE %%%u", ntohl(hdr->serial));
  
  	ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len);
-diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
-index ca8e0a5..1f9c314 100644
---- a/net/sched/sch_atm.c
-+++ b/net/sched/sch_atm.c
-@@ -605,6 +605,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
- 		struct sockaddr_atmpvc pvc;
- 		int state;
- 
-+		memset(&pvc, 0, sizeof(pvc));
- 		pvc.sap_family = AF_ATMPVC;
- 		pvc.sap_addr.itf = flow->vcc->dev ? flow->vcc->dev->number : -1;
- 		pvc.sap_addr.vpi = flow->vcc->vpi;
 diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
 index 391a245..296b3d7 100644
 --- a/net/sctp/ipv6.c
@@ -91535,6 +94442,25 @@ index bf3c6e8..376d8d0 100644
  	int i;
  
  	table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
+diff --git a/net/sctp/transport.c b/net/sctp/transport.c
+index 098f1d5f..60da2f7 100644
+--- a/net/sctp/transport.c
++++ b/net/sctp/transport.c
+@@ -178,12 +178,12 @@ static void sctp_transport_destroy(struct sctp_transport *transport)
+ {
+ 	SCTP_ASSERT(transport->dead, "Transport is not dead", return);
+ 
+-	call_rcu(&transport->rcu, sctp_transport_destroy_rcu);
+-
+ 	sctp_packet_free(&transport->packet);
+ 
+ 	if (transport->asoc)
+ 		sctp_association_put(transport->asoc);
++
++	call_rcu(&transport->rcu, sctp_transport_destroy_rcu);
+ }
+ 
+ /* Start T3_rtx timer if it is not already running and update the heartbeat
 diff --git a/net/socket.c b/net/socket.c
 index 4ca1526..df83e47 100644
 --- a/net/socket.c
@@ -91782,7 +94708,7 @@ index 4ca1526..df83e47 100644
  	set_fs(KERNEL_DS);
  	if (level == SOL_SOCKET)
 diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
-index 5a750b9..ca5d7af 100644
+index 426f8fc..1ef9c32 100644
 --- a/net/sunrpc/clnt.c
 +++ b/net/sunrpc/clnt.c
 @@ -1288,7 +1288,9 @@ call_start(struct rpc_task *task)
@@ -92201,6 +95127,19 @@ index 8800604..0526440 100644
  
  	table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL);
  	if (table == NULL)
+diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
+index 3f77f42..662d89b 100644
+--- a/net/vmw_vsock/af_vsock.c
++++ b/net/vmw_vsock/af_vsock.c
+@@ -335,7 +335,7 @@ void vsock_for_each_connected_socket(void (*fn)(struct sock *sk))
+ 	for (i = 0; i < ARRAY_SIZE(vsock_connected_table); i++) {
+ 		struct vsock_sock *vsk;
+ 		list_for_each_entry(vsk, &vsock_connected_table[i],
+-				    connected_table);
++				    connected_table)
+ 			fn(sk_vsock(vsk));
+ 	}
+ 
 diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
 index c8717c1..08539f5 100644
 --- a/net/wireless/wext-core.c
@@ -92883,10 +95822,10 @@ index f5eb43d..1814de8 100644
  	shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
  	shstrtab_sec = shdr + r2(&ehdr->e_shstrndx);
 diff --git a/security/Kconfig b/security/Kconfig
-index e9c6ac7..80e2642 100644
+index e9c6ac7..3e3f362 100644
 --- a/security/Kconfig
 +++ b/security/Kconfig
-@@ -4,6 +4,954 @@
+@@ -4,6 +4,959 @@
  
  menu "Security options"
  
@@ -93254,7 +96193,7 @@ index e9c6ac7..80e2642 100644
 +config PAX_NOEXEC
 +	bool "Enforce non-executable pages"
 +	default y if GRKERNSEC_CONFIG_AUTO
-+	depends on ALPHA || (ARM && (CPU_V6 || CPU_V7)) || IA64 || MIPS || PARISC || PPC || S390 || SPARC || X86
++	depends on ALPHA || (ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || IA64 || MIPS || PARISC || PPC || S390 || SPARC || X86
 +	help
 +	  By design some architectures do not allow for protecting memory
 +	  pages against execution or even if they do, Linux does not make
@@ -93465,7 +96404,7 @@ index e9c6ac7..80e2642 100644
 +config PAX_KERNEXEC
 +	bool "Enforce non-executable kernel pages"
 +	default y if GRKERNSEC_CONFIG_AUTO && (GRKERNSEC_CONFIG_VIRT_NONE || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_GUEST) || (GRKERNSEC_CONFIG_VIRT_EPT && GRKERNSEC_CONFIG_VIRT_KVM))
-+	depends on (X86 || (ARM && (CPU_V6 || CPU_V7) && !(ARM_LPAE && MODULES))) && !XEN
++	depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !(ARM_LPAE && MODULES))) && !XEN
 +	select PAX_PER_CPU_PGD if X86_64 || (X86_32 && X86_PAE)
 +	select PAX_KERNEXEC_PLUGIN if X86_64
 +	help
@@ -93697,7 +96636,7 @@ index e9c6ac7..80e2642 100644
 +config PAX_MEMORY_UDEREF
 +	bool "Prevent invalid userland pointer dereference"
 +	default y if GRKERNSEC_CONFIG_AUTO && !(X86_64 && GRKERNSEC_CONFIG_PRIORITY_PERF) && (GRKERNSEC_CONFIG_VIRT_NONE || GRKERNSEC_CONFIG_VIRT_EPT)
-+	depends on (X86 || (ARM && (CPU_V6 || CPU_V7) && !ARM_LPAE)) && !UML_X86 && !XEN
++	depends on (X86 || (ARM && (CPU_V6 || CPU_V6K || CPU_V7) && !ARM_LPAE)) && !UML_X86 && !XEN
 +	select PAX_PER_CPU_PGD if X86_64
 +	help
 +	  By saying Y here the kernel will be prevented from dereferencing
@@ -93714,10 +96653,15 @@ index e9c6ac7..80e2642 100644
 +	  VMs running on CPUs without hardware virtualization support (i.e.,
 +	  the majority of IA-32 CPUs) will likely experience the slowdown.
 +
++	  On X86_64 the kernel will make use of PCID support when available
++	  (Intel's Westmere, Sandy Bridge, etc) for better security (default)
++	  or performance impact.  Pass pax_weakuderef on the kernel command
++	  line to choose the latter.
++
 +config PAX_REFCOUNT
 +	bool "Prevent various kernel object reference counter overflows"
 +	default y if GRKERNSEC_CONFIG_AUTO
-+	depends on GRKERNSEC && ((ARM && (CPU_32v6 || CPU_32v6K || CPU_32v7)) || SPARC64 || X86)
++	depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || SPARC64 || X86)
 +	help
 +	  By saying Y here the kernel will detect and prevent overflowing
 +	  various (but not all) kinds of object reference counters.  Such
@@ -93841,7 +96785,7 @@ index e9c6ac7..80e2642 100644
  source security/keys/Kconfig
  
  config SECURITY_DMESG_RESTRICT
-@@ -103,7 +1051,7 @@ config INTEL_TXT
+@@ -103,7 +1056,7 @@ config INTEL_TXT
  config LSM_MMAP_MIN_ADDR
  	int "Low address space for LSM to protect from user allocation"
  	depends on SECURITY && SECURITY_SELINUX
@@ -106248,6 +109192,32 @@ index 0000000..4fae911
 +
 +	return 0;
 +}
+diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
+index 926cbf3..b8403e0 100644
+--- a/tools/lib/lk/Makefile
++++ b/tools/lib/lk/Makefile
+@@ -10,7 +10,7 @@ LIB_OBJS += $(OUTPUT)debugfs.o
+ 
+ LIBFILE = liblk.a
+ 
+-CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
++CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
+ EXTLIBS = -lpthread -lrt -lelf -lm
+ ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+ ALL_LDFLAGS = $(LDFLAGS)
+diff --git a/tools/perf/Makefile b/tools/perf/Makefile
+index b0f164b..63c9f7d 100644
+--- a/tools/perf/Makefile
++++ b/tools/perf/Makefile
+@@ -188,7 +188,7 @@ endif
+ 
+ ifndef PERF_DEBUG
+ 	ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
+-		CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
++		CFLAGS := $(CFLAGS) -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
+ 	endif
+ endif
+ 
 diff --git a/tools/perf/util/include/asm/alternative-asm.h b/tools/perf/util/include/asm/alternative-asm.h
 index 6789d78..4afd019e 100644
 --- a/tools/perf/util/include/asm/alternative-asm.h

diff --git a/3.10.5/4425_grsec_remove_EI_PAX.patch b/3.10.7/4425_grsec_remove_EI_PAX.patch
similarity index 100%
rename from 3.10.5/4425_grsec_remove_EI_PAX.patch
rename to 3.10.7/4425_grsec_remove_EI_PAX.patch

diff --git a/3.10.5/4427_force_XATTR_PAX_tmpfs.patch b/3.10.7/4427_force_XATTR_PAX_tmpfs.patch
similarity index 100%
rename from 3.10.5/4427_force_XATTR_PAX_tmpfs.patch
rename to 3.10.7/4427_force_XATTR_PAX_tmpfs.patch

diff --git a/3.10.5/4430_grsec-remove-localversion-grsec.patch b/3.10.7/4430_grsec-remove-localversion-grsec.patch
similarity index 100%
rename from 3.10.5/4430_grsec-remove-localversion-grsec.patch
rename to 3.10.7/4430_grsec-remove-localversion-grsec.patch

diff --git a/3.10.5/4435_grsec-mute-warnings.patch b/3.10.7/4435_grsec-mute-warnings.patch
similarity index 100%
rename from 3.10.5/4435_grsec-mute-warnings.patch
rename to 3.10.7/4435_grsec-mute-warnings.patch

diff --git a/3.10.5/4440_grsec-remove-protected-paths.patch b/3.10.7/4440_grsec-remove-protected-paths.patch
similarity index 100%
rename from 3.10.5/4440_grsec-remove-protected-paths.patch
rename to 3.10.7/4440_grsec-remove-protected-paths.patch

diff --git a/3.10.5/4450_grsec-kconfig-default-gids.patch b/3.10.7/4450_grsec-kconfig-default-gids.patch
similarity index 100%
rename from 3.10.5/4450_grsec-kconfig-default-gids.patch
rename to 3.10.7/4450_grsec-kconfig-default-gids.patch

diff --git a/3.10.5/4465_selinux-avc_audit-log-curr_ip.patch b/3.10.7/4465_selinux-avc_audit-log-curr_ip.patch
similarity index 100%
rename from 3.10.5/4465_selinux-avc_audit-log-curr_ip.patch
rename to 3.10.7/4465_selinux-avc_audit-log-curr_ip.patch

diff --git a/3.10.5/4470_disable-compat_vdso.patch b/3.10.7/4470_disable-compat_vdso.patch
similarity index 100%
rename from 3.10.5/4470_disable-compat_vdso.patch
rename to 3.10.7/4470_disable-compat_vdso.patch

diff --git a/3.10.5/4475_emutramp_default_on.patch b/3.10.7/4475_emutramp_default_on.patch
similarity index 100%
rename from 3.10.5/4475_emutramp_default_on.patch
rename to 3.10.7/4475_emutramp_default_on.patch

diff --git a/3.2.50/0000_README b/3.2.50/0000_README
index 7f6cb30..574e6bc 100644
--- a/3.2.50/0000_README
+++ b/3.2.50/0000_README
@@ -118,7 +118,7 @@ Patch:	1049_linux-3.2.50.patch
 From:	http://www.kernel.org
 Desc:	Linux 3.2.50
 
-Patch:	4420_grsecurity-2.9.1-3.2.50-201308052151.patch
+Patch:	4420_grsecurity-2.9.1-3.2.50-201308171247.patch
 From:	http://www.grsecurity.net
 Desc:	hardened-sources base patch from upstream grsecurity
 

diff --git a/3.2.50/4420_grsecurity-2.9.1-3.2.50-201308052151.patch b/3.2.50/4420_grsecurity-2.9.1-3.2.50-201308171247.patch
similarity index 99%
rename from 3.2.50/4420_grsecurity-2.9.1-3.2.50-201308052151.patch
rename to 3.2.50/4420_grsecurity-2.9.1-3.2.50-201308171247.patch
index bf119a8..a0281fe 100644
--- a/3.2.50/4420_grsecurity-2.9.1-3.2.50-201308052151.patch
+++ b/3.2.50/4420_grsecurity-2.9.1-3.2.50-201308171247.patch
@@ -1748,8 +1748,26 @@ index 1e9be5d..4e0f470 100644
  	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
  				GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
  				__builtin_return_address(0));
+diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
+index 778d248..692233d 100644
+--- a/arch/arm/kernel/perf_event.c
++++ b/arch/arm/kernel/perf_event.c
+@@ -116,7 +116,12 @@ armpmu_map_cache_event(const unsigned (*cache_map)
+ static int
+ armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
+ {
+-	int mapping = (*event_map)[config];
++	int mapping;
++
++	if (config >= PERF_COUNT_HW_MAX)
++		return -ENOENT;
++
++	mapping = (*event_map)[config];
+ 	return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
+ }
+ 
 diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
-index e68d251..c950684 100644
+index e68d251..c5bac2c 100644
 --- a/arch/arm/kernel/process.c
 +++ b/arch/arm/kernel/process.c
 @@ -28,7 +28,6 @@
@@ -1792,8 +1810,8 @@ index e68d251..c950684 100644
  		init_utsname()->version);
 -	print_symbol("PC is at %s\n", instruction_pointer(regs));
 -	print_symbol("LR is at %s\n", regs->ARM_lr);
-+	printk("PC is at %pA\n", instruction_pointer(regs));
-+	printk("LR is at %pA\n", regs->ARM_lr);
++	printk("PC is at %pA\n", (void *)instruction_pointer(regs));
++	printk("LR is at %pA\n", (void *)regs->ARM_lr);
  	printk("pc : [<%08lx>]    lr : [<%08lx>]    psr: %08lx\n"
  	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
  		regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
@@ -8413,17 +8431,19 @@ index 504c062..a383267 100644
  	 * load/store/atomic was a write or not, it only says that there
  	 * was no match.  So in such a case we (carefully) read the
 diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
-index 07e1453..2ec39cd 100644
+index 07e1453..ae6e02e 100644
 --- a/arch/sparc/mm/hugetlbpage.c
 +++ b/arch/sparc/mm/hugetlbpage.c
-@@ -34,6 +34,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+@@ -28,7 +28,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+ 							unsigned long addr,
+ 							unsigned long len,
+ 							unsigned long pgoff,
+-							unsigned long flags)
++							unsigned long flags,
++							unsigned long offset)
+ {
+ 	struct mm_struct *mm = current->mm;
  	struct vm_area_struct * vma;
- 	unsigned long task_size = TASK_SIZE;
- 	unsigned long start_addr;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
- 
- 	if (test_thread_flag(TIF_32BIT))
- 		task_size = STACK_TOP32;
 @@ -67,7 +68,7 @@ full_search:
  			}
  			return -ENOMEM;
@@ -8433,14 +8453,16 @@ index 07e1453..2ec39cd 100644
  			/*
  			 * Remember the place where we stopped the search:
  			 */
-@@ -90,6 +91,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+@@ -85,7 +86,8 @@ static unsigned long
+ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 				  const unsigned long len,
+ 				  const unsigned long pgoff,
+-				  const unsigned long flags)
++				  const unsigned long flags,
++				  const unsigned long offset)
+ {
  	struct vm_area_struct *vma;
  	struct mm_struct *mm = current->mm;
- 	unsigned long addr = addr0;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
- 
- 	/* This should only ever run for 32-bit processes.  */
- 	BUG_ON(!test_thread_flag(TIF_32BIT));
 @@ -105,26 +107,28 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
  
  	/* make sure it can fit in the remaining address space */
@@ -8490,11 +8512,11 @@ index 07e1453..2ec39cd 100644
  	struct mm_struct *mm = current->mm;
  	struct vm_area_struct *vma;
  	unsigned long task_size = TASK_SIZE;
-+	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
++	unsigned long offset = gr_rand_threadstack_offset(mm, file, flags);
  
  	if (test_thread_flag(TIF_32BIT))
  		task_size = STACK_TOP32;
-@@ -181,8 +186,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+@@ -181,16 +186,15 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
  	if (addr) {
  		addr = ALIGN(addr, HPAGE_SIZE);
  		vma = find_vma(mm, addr);
@@ -8504,6 +8526,16 @@ index 07e1453..2ec39cd 100644
  			return addr;
  	}
  	if (mm->get_unmapped_area == arch_get_unmapped_area)
+ 		return hugetlb_get_unmapped_area_bottomup(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ 	else
+ 		return hugetlb_get_unmapped_area_topdown(file, addr, len,
+-				pgoff, flags);
++				pgoff, flags, offset);
+ }
+ 
+ pte_t *huge_pte_alloc(struct mm_struct *mm,
 diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
 index 7b00de6..78239f4 100644
 --- a/arch/sparc/mm/init_32.c
@@ -13105,7 +13137,7 @@ index 2dddb31..100c638 100644
  /*
   * x86-64 Task Priority Register, CR8
 diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
-index f7c89e2..07d412d 100644
+index f7c89e2..cd4bff6 100644
 --- a/arch/x86/include/asm/processor.h
 +++ b/arch/x86/include/asm/processor.h
 @@ -266,7 +266,7 @@ struct tss_struct {
@@ -13210,6 +13242,16 @@ index f7c89e2..07d412d 100644
  #define KSTK_EIP(task)		(task_pt_regs(task)->ip)
  
  /* Get/set a process' ability to use the timestamp counter instruction */
+@@ -972,7 +979,8 @@ extern int set_tsc_mode(unsigned int val);
+ extern int amd_get_nb_id(int cpu);
+ 
+ struct aperfmperf {
+-	u64 aperf, mperf;
++	u64 aperf __intentional_overflow(0);
++	u64 mperf __intentional_overflow(0);
+ };
+ 
+ static inline void get_aperfmperf(struct aperfmperf *am)
 diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
 index 3b96fd4..8790004 100644
 --- a/arch/x86/include/asm/ptrace.h
@@ -16023,7 +16065,7 @@ index 37250fe..bf2ec74 100644
  
  		.__cr3		= __pa_nodebug(swapper_pg_dir),
 diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
-index 1aae78f..aab3a3d 100644
+index 1aae78f..138ca1b 100644
 --- a/arch/x86/kernel/dumpstack.c
 +++ b/arch/x86/kernel/dumpstack.c
 @@ -2,6 +2,9 @@
@@ -16121,6 +16163,15 @@ index 1aae78f..aab3a3d 100644
  	}
  
  	return (unsigned long)frame;
+@@ -147,7 +147,7 @@ static int print_trace_stack(void *data, char *name)
+ static void print_trace_address(void *data, unsigned long addr, int reliable)
+ {
+ 	touch_nmi_watchdog();
+-	printk(data);
++	printk("%s", (char *)data);
+ 	printk_address(addr, reliable);
+ }
+ 
 @@ -186,7 +186,7 @@ void dump_stack(void)
  
  	bp = stack_frame(current, NULL);
@@ -20822,6 +20873,19 @@ index 47f4e5f..849a8a6 100644
  	.power_off = native_machine_power_off,
  	.shutdown = native_machine_shutdown,
  	.emergency_restart = native_machine_emergency_restart,
+diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
+index c8e41e9..64049ef 100644
+--- a/arch/x86/kernel/reboot_fixups_32.c
++++ b/arch/x86/kernel/reboot_fixups_32.c
+@@ -57,7 +57,7 @@ struct device_fixup {
+ 	unsigned int vendor;
+ 	unsigned int device;
+ 	void (*reboot_fixup)(struct pci_dev *);
+-};
++} __do_const;
+ 
+ /*
+  * PCI ids solely used for fixups_table go here
 diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S
 index f2bb9c9..bed145d7 100644
 --- a/arch/x86/kernel/relocate_kernel_64.S
@@ -40187,7 +40251,7 @@ index 46db5c5..37c1536 100644
  	err = platform_driver_register(&sk_isa_driver);
  	if (err)
 diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index f4c5de6..68c9070 100644
+index f4c5de6..31aa71c 100644
 --- a/drivers/net/tun.c
 +++ b/drivers/net/tun.c
 @@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev)
@@ -40199,7 +40263,29 @@ index f4c5de6..68c9070 100644
  }
  
  /* Net device open. */
-@@ -981,10 +981,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
+@@ -614,8 +614,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
+ 	int offset = 0;
+ 
+ 	if (!(tun->flags & TUN_NO_PI)) {
+-		if ((len -= sizeof(pi)) > count)
++		if (len < sizeof(pi))
+ 			return -EINVAL;
++		len -= sizeof(pi);
+ 
+ 		if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
+ 			return -EFAULT;
+@@ -623,8 +624,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
+ 	}
+ 
+ 	if (tun->flags & TUN_VNET_HDR) {
+-		if ((len -= tun->vnet_hdr_sz) > count)
++		if (len < tun->vnet_hdr_sz)
+ 			return -EINVAL;
++		len -= tun->vnet_hdr_sz;
+ 
+ 		if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
+ 			return -EFAULT;
+@@ -981,10 +983,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
  	return ret;
  }
  
@@ -40218,7 +40304,7 @@ index f4c5de6..68c9070 100644
  };
  
  static struct proto tun_proto = {
-@@ -1111,10 +1119,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
+@@ -1111,10 +1121,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
  		tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
  
  		err = -ENOMEM;
@@ -40231,7 +40317,7 @@ index f4c5de6..68c9070 100644
  		tun->socket.wq = &tun->wq;
  		init_waitqueue_head(&tun->wq.wait);
  		tun->socket.ops = &tun_socket_ops;
-@@ -1175,7 +1184,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
+@@ -1175,7 +1186,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
  	return 0;
  
   err_free_sk:
@@ -40240,7 +40326,7 @@ index f4c5de6..68c9070 100644
   err_free_dev:
  	free_netdev(dev);
   failed:
-@@ -1234,7 +1243,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
+@@ -1234,7 +1245,7 @@ static int set_offload(struct tun_struct *tun, unsigned long arg)
  }
  
  static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
@@ -40249,7 +40335,7 @@ index f4c5de6..68c9070 100644
  {
  	struct tun_file *tfile = file->private_data;
  	struct tun_struct *tun;
-@@ -1245,6 +1254,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
+@@ -1245,6 +1256,9 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
  	int vnet_hdr_sz;
  	int ret;
  
@@ -40744,7 +40830,7 @@ index 69a77e24..552b42c 100644
  #endif				/* CONFIG_IWLWIFI_DEBUG */
  
 diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
-index 93e6179..534bbd8 100644
+index 93e6179..b221e4f 100644
 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
 +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
 @@ -163,7 +163,7 @@ static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
@@ -40801,6 +40887,21 @@ index 93e6179..534bbd8 100644
  	int traffic_log;
  
  	memset(buf, 0, sizeof(buf));
+@@ -912,10 +912,10 @@ static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
+ 	return count;
+ }
+ 
+-static const char *fmt_value = "  %-30s %10u\n";
+-static const char *fmt_hex   = "  %-30s       0x%02X\n";
+-static const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
+-static const char *fmt_header =
++static const char fmt_value[] = "  %-30s %10u\n";
++static const char fmt_hex[]   = "  %-30s       0x%02X\n";
++static const char fmt_table[] = "  %-30s %10u  %10u  %10u  %10u\n";
++static const char fmt_header[] =
+ 	"%-32s    current  cumulative       delta         max\n";
+ 
+ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
 @@ -2078,7 +2078,7 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
  {
  	struct iwl_priv *priv = file->private_data;
@@ -44363,6 +44464,19 @@ index 46f72ed..107788d 100644
  
  	return 0;
  }
+diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
+index 7363c1b..b69ad66 100644
+--- a/drivers/video/backlight/backlight.c
++++ b/drivers/video/backlight/backlight.c
+@@ -303,7 +303,7 @@ struct backlight_device *backlight_device_register(const char *name,
+ 	new_bd->dev.class = backlight_class;
+ 	new_bd->dev.parent = parent;
+ 	new_bd->dev.release = bl_device_release;
+-	dev_set_name(&new_bd->dev, name);
++	dev_set_name(&new_bd->dev, "%s", name);
+ 	dev_set_drvdata(&new_bd->dev, devdata);
+ 
+ 	/* Set default properties */
 diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c
 index 72dd555..5f9bfbe 100644
 --- a/drivers/video/backlight/kb3886_bl.c
@@ -44376,6 +44490,19 @@ index 72dd555..5f9bfbe 100644
  	{
  		.ident = "Sahara Touch-iT",
  		.matches = {
+diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
+index 71a11ca..86afe4b 100644
+--- a/drivers/video/backlight/lcd.c
++++ b/drivers/video/backlight/lcd.c
+@@ -209,7 +209,7 @@ struct lcd_device *lcd_device_register(const char *name, struct device *parent,
+ 	new_ld->dev.class = lcd_class;
+ 	new_ld->dev.parent = parent;
+ 	new_ld->dev.release = lcd_device_release;
+-	dev_set_name(&new_ld->dev, name);
++	dev_set_name(&new_ld->dev, "%s", name);
+ 	dev_set_drvdata(&new_ld->dev, devdata);
+ 
+ 	rc = device_register(&new_ld->dev);
 diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c
 index e132157..516db70 100644
 --- a/drivers/video/backlight/s6e63m0.c
@@ -48141,7 +48268,7 @@ index a6395bd..f1e376a 100644
  		(unsigned long) create_aout_tables((char __user *) bprm->p, bprm);
  #ifdef __alpha__
 diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 8dd615c..f3bbb60 100644
+index 8dd615c..0d06360 100644
 --- a/fs/binfmt_elf.c
 +++ b/fs/binfmt_elf.c
 @@ -32,6 +32,7 @@
@@ -48924,7 +49051,7 @@ index 8dd615c..f3bbb60 100644
  		if (size > cprm->limit
  		    || !dump_write(cprm->file, shdr4extnum,
  				   sizeof(*shdr4extnum)))
-@@ -2064,6 +2523,126 @@ out:
+@@ -2064,6 +2523,167 @@ out:
  
  #endif		/* CONFIG_ELF_CORE */
  
@@ -48992,9 +49119,9 @@ index 8dd615c..f3bbb60 100644
 +				elf_dyn dyn;
 +
 +				if (sizeof(dyn) != kernel_read(vma->vm_file, elf_p.p_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
-+					return;
++					break;
 +				if (dyn.d_tag == DT_NULL)
-+					return;
++					break;
 +				if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
 +					gr_log_textrel(vma);
 +					if (is_textrel_rw)
@@ -49002,18 +49129,59 @@ index 8dd615c..f3bbb60 100644
 +					else
 +						/* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
 +						vma->vm_flags &= ~VM_MAYWRITE;
-+					return;
++					break;
 +				}
 +				i++;
 +			}
-+			return;
++			is_textrel_rw = false;
++			is_textrel_rx = false;
++			continue;
 +
 +		case PT_GNU_RELRO:
 +			if (!is_relro)
 +				continue;
 +			if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start)
 +				vma->vm_flags &= ~VM_MAYWRITE;
-+			return;
++			is_relro = false;
++			continue;
++
++#ifdef CONFIG_PAX_PT_PAX_FLAGS
++		case PT_PAX_FLAGS: {
++			const char *msg_mprotect = "", *msg_emutramp = "";
++			char *buffer_lib, *buffer_exe;
++
++			if (elf_p.p_flags & PF_NOMPROTECT)
++				msg_mprotect = "MPROTECT disabled";
++
++#ifdef CONFIG_PAX_EMUTRAMP
++			if (!(vma->vm_mm->pax_flags & MF_PAX_EMUTRAMP) && !(elf_p.p_flags & PF_NOEMUTRAMP))
++				msg_emutramp = "EMUTRAMP enabled";
++#endif
++
++			if (!msg_mprotect[0] && !msg_emutramp[0])
++				continue;
++
++			if (!printk_ratelimit())
++				continue;
++
++			buffer_lib = (char *)__get_free_page(GFP_KERNEL);
++			buffer_exe = (char *)__get_free_page(GFP_KERNEL);
++			if (buffer_lib && buffer_exe) {
++				char *path_lib, *path_exe;
++
++				path_lib = pax_get_path(&vma->vm_file->f_path, buffer_lib, PAGE_SIZE);
++				path_exe = pax_get_path(&vma->vm_mm->exe_file->f_path, buffer_exe, PAGE_SIZE);
++
++				pr_info("PAX: %s wants %s%s%s on %s\n", path_lib, msg_mprotect,
++					(msg_mprotect[0] && msg_emutramp[0] ? " and " : ""), msg_emutramp, path_exe);
++
++			}
++			free_page((unsigned long)buffer_exe);
++			free_page((unsigned long)buffer_lib);
++			continue;
++		}
++#endif
++
 +		}
 +	}
 +}
@@ -50224,7 +50392,7 @@ index 451b9b8..12e5a03 100644
  
  out_free_fd:
 diff --git a/fs/exec.c b/fs/exec.c
-index a2d0e51..744f7c6 100644
+index a2d0e51..d46efb6 100644
 --- a/fs/exec.c
 +++ b/fs/exec.c
 @@ -55,12 +55,35 @@
@@ -50862,6 +51030,25 @@ index a2d0e51..744f7c6 100644
 +EXPORT_SYMBOL(pax_check_flags);
 +
 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++char *pax_get_path(const struct path *path, char *buf, int buflen)
++{
++	char *pathname = d_path(path, buf, buflen);
++
++	if (IS_ERR(pathname))
++		goto toolong;
++
++	pathname = mangle_path(buf, pathname, "\t\n\\");
++	if (!pathname)
++		goto toolong;
++
++	*pathname = 0;
++	return buf;
++
++toolong:
++	return "<path too long>";
++}
++EXPORT_SYMBOL(pax_get_path);
++
 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
 +{
 +	struct task_struct *tsk = current;
@@ -50884,36 +51071,15 @@ index a2d0e51..744f7c6 100644
 +				vma_fault = vma;
 +			vma = vma->vm_next;
 +		}
-+		if (vma_exec) {
-+			path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
-+			if (IS_ERR(path_exec))
-+				path_exec = "<path too long>";
-+			else {
-+				path_exec = mangle_path(buffer_exec, path_exec, "\t\n\\");
-+				if (path_exec) {
-+					*path_exec = 0;
-+					path_exec = buffer_exec;
-+				} else
-+					path_exec = "<path too long>";
-+			}
-+		}
++		if (vma_exec)
++			path_exec = pax_get_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
 +		if (vma_fault) {
 +			start = vma_fault->vm_start;
 +			end = vma_fault->vm_end;
 +			offset = vma_fault->vm_pgoff << PAGE_SHIFT;
-+			if (vma_fault->vm_file) {
-+				path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
-+				if (IS_ERR(path_fault))
-+					path_fault = "<path too long>";
-+				else {
-+					path_fault = mangle_path(buffer_fault, path_fault, "\t\n\\");
-+					if (path_fault) {
-+						*path_fault = 0;
-+						path_fault = buffer_fault;
-+					} else
-+						path_fault = "<path too long>";
-+				}
-+			} else if (pc >= mm->start_brk && pc < mm->brk)
++			if (vma_fault->vm_file)
++				path_fault = pax_get_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
++			else if ((unsigned long)pc >= mm->start_brk && (unsigned long)pc < mm->brk)
 +				path_fault = "<heap>";
 +			else if (vma_fault->vm_flags & (VM_GROWSDOWN | VM_GROWSUP))
 +				path_fault = "<stack>";
@@ -50946,7 +51112,9 @@ index a2d0e51..744f7c6 100644
 +		printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
 +				 current->comm, task_pid_nr(current), current_uid(), current_euid());
 +	print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
++	preempt_disable();
 +	show_regs(regs);
++	preempt_enable();
 +	force_sig_info(SIGKILL, SEND_SIG_FORCED, current);
 +}
 +#endif
@@ -56342,7 +56510,7 @@ index 03102d9..4ae347e 100644
  }
  
 diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index 3efa725..27582ca 100644
+index 3efa725..18a278b 100644
 --- a/fs/proc/task_mmu.c
 +++ b/fs/proc/task_mmu.c
 @@ -11,12 +11,19 @@
@@ -56518,7 +56686,15 @@ index 3efa725..27582ca 100644
  		   mss.resident >> 10,
  		   (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
  		   mss.shared_clean  >> 10,
-@@ -798,7 +849,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+@@ -792,13 +843,13 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
+ 	if (!count)
+ 		goto out_task;
+ 
+-	pm.len = PM_ENTRY_BYTES * (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
+-	pm.buffer = kmalloc(pm.len, GFP_TEMPORARY);
++	pm.len = (PAGEMAP_WALK_SIZE >> PAGE_SHIFT);
++	pm.buffer = kmalloc(pm.len * PM_ENTRY_BYTES, GFP_TEMPORARY);
+ 	ret = -ENOMEM;
  	if (!pm.buffer)
  		goto out_task;
  
@@ -71443,7 +71619,7 @@ index bff29c5..7437762 100644
  /*
   * irq_chip specific flags
 diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
-index 3875719..4cd454c 100644
+index 3875719..4663bc3 100644
 --- a/include/linux/kallsyms.h
 +++ b/include/linux/kallsyms.h
 @@ -15,7 +15,8 @@
@@ -71456,12 +71632,13 @@ index 3875719..4cd454c 100644
  /* Lookup the address for a symbol. Returns 0 if not found. */
  unsigned long kallsyms_lookup_name(const char *name);
  
-@@ -99,6 +100,16 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
+@@ -99,6 +100,20 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
  /* Stupid that this does nothing, but I didn't create this mess. */
  #define __print_symbol(fmt, addr)
  #endif /*CONFIG_KALLSYMS*/
-+#else /* when included by kallsyms.c, vsnprintf.c, or
++#else /* when included by kallsyms.c, vsnprintf.c, kprobes.c, or
 +	arch/x86/kernel/dumpstack.c, with HIDESYM enabled */
++extern unsigned long kallsyms_lookup_name(const char *name);
 +extern void __print_symbol(const char *fmt, unsigned long address);
 +extern int sprint_backtrace(char *buffer, unsigned long address);
 +extern int sprint_symbol(char *buffer, unsigned long address);
@@ -71469,6 +71646,9 @@ index 3875719..4cd454c 100644
 +			    unsigned long *symbolsize,
 +			    unsigned long *offset,
 +			    char **modname, char *namebuf);
++extern int kallsyms_lookup_size_offset(unsigned long addr,
++				  unsigned long *symbolsize,
++				  unsigned long *offset);
 +#endif
  
  /* This macro allows us to keep printk typechecking */
@@ -71703,7 +71883,7 @@ index 88e78de..c63979a 100644
  		} apparmor_audit_data;
  #endif
 diff --git a/include/linux/math64.h b/include/linux/math64.h
-index b8ba855..0148090 100644
+index b8ba855..4382e1f 100644
 --- a/include/linux/math64.h
 +++ b/include/linux/math64.h
 @@ -14,7 +14,7 @@
@@ -71715,6 +71895,15 @@ index b8ba855..0148090 100644
  {
  	*remainder = dividend % divisor;
  	return dividend / divisor;
+@@ -32,7 +32,7 @@ static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
+ /**
+  * div64_u64 - unsigned 64bit divide with 64bit divisor
+  */
+-static inline u64 div64_u64(u64 dividend, u64 divisor)
++static inline u64 __intentional_overflow(0) div64_u64(u64 dividend, u64 divisor)
+ {
+ 	return dividend / divisor;
+ }
 @@ -50,7 +50,7 @@ static inline s64 div64_s64(s64 dividend, s64 divisor)
  #define div64_long(x,y) div_s64((x),(y))
  
@@ -72912,7 +73101,7 @@ index 2148b12..519b820 100644
  
  static inline void anon_vma_merge(struct vm_area_struct *vma,
 diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 8204898..b268075 100644
+index 8204898..76f518d 100644
 --- a/include/linux/sched.h
 +++ b/include/linux/sched.h
 @@ -101,6 +101,7 @@ struct bio_list;
@@ -73093,7 +73282,7 @@ index 8204898..b268075 100644
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  	/* Index of current stored address in ret_stack */
  	int curr_ret_stack;
-@@ -1578,6 +1644,50 @@ struct task_struct {
+@@ -1578,6 +1644,52 @@ struct task_struct {
  #endif
  };
  
@@ -73137,6 +73326,8 @@ index 8204898..b268075 100644
 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
 +#endif
 +
++struct path;
++extern char *pax_get_path(const struct path *path, char *buf, int buflen);
 +extern void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_insns(struct pt_regs *regs, void *pc, void *sp);
 +extern void pax_report_refcount_overflow(struct pt_regs *regs);
@@ -73144,7 +73335,7 @@ index 8204898..b268075 100644
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
  #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
  
-@@ -2093,7 +2203,9 @@ void yield(void);
+@@ -2093,7 +2205,9 @@ void yield(void);
  extern struct exec_domain	default_exec_domain;
  
  union thread_union {
@@ -73154,7 +73345,7 @@ index 8204898..b268075 100644
  	unsigned long stack[THREAD_SIZE/sizeof(long)];
  };
  
-@@ -2126,6 +2238,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -2126,6 +2240,7 @@ extern struct pid_namespace init_pid_ns;
   */
  
  extern struct task_struct *find_task_by_vpid(pid_t nr);
@@ -73162,7 +73353,7 @@ index 8204898..b268075 100644
  extern struct task_struct *find_task_by_pid_ns(pid_t nr,
  		struct pid_namespace *ns);
  
-@@ -2247,6 +2360,12 @@ static inline void mmdrop(struct mm_struct * mm)
+@@ -2247,6 +2362,12 @@ static inline void mmdrop(struct mm_struct * mm)
  extern void mmput(struct mm_struct *);
  /* Grab a reference to a task's mm, if it is not already going away */
  extern struct mm_struct *get_task_mm(struct task_struct *task);
@@ -73175,7 +73366,7 @@ index 8204898..b268075 100644
  /* Remove the current tasks stale references to the old mm_struct */
  extern void mm_release(struct task_struct *, struct mm_struct *);
  /* Allocate a new mm structure and copy contents from tsk->mm */
-@@ -2263,7 +2382,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2263,7 +2384,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
  extern void exit_itimers(struct signal_struct *);
  extern void flush_itimer_signals(void);
  
@@ -73184,7 +73375,7 @@ index 8204898..b268075 100644
  
  extern void daemonize(const char *, ...);
  extern int allow_signal(int);
-@@ -2428,9 +2547,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2428,9 +2549,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
  
  #endif
  
@@ -77540,10 +77731,20 @@ index a16dac1..a1ac7cb 100644
  	kernel_cap_t new_cap;
  	int err, i;
 diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index bc90b87..6fc810d 100644
+index bc90b87..32da385 100644
 --- a/kernel/kprobes.c
 +++ b/kernel/kprobes.c
-@@ -185,7 +185,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
+@@ -31,6 +31,9 @@
+  *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
+  *		<prasanna@in.ibm.com> added function-return probes.
+  */
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++#define __INCLUDED_BY_HIDESYM 1
++#endif
+ #include <linux/kprobes.h>
+ #include <linux/hash.h>
+ #include <linux/init.h>
+@@ -185,7 +188,7 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
  	 * kernel image and loaded module images reside. This is required
  	 * so x86_64 can correctly handle the %rip-relative fixups.
  	 */
@@ -77552,7 +77753,7 @@ index bc90b87..6fc810d 100644
  	if (!kip->insns) {
  		kfree(kip);
  		return NULL;
-@@ -225,7 +225,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
+@@ -225,7 +228,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
  		 */
  		if (!list_is_singular(&kip->list)) {
  			list_del(&kip->list);
@@ -77561,7 +77762,7 @@ index bc90b87..6fc810d 100644
  			kfree(kip);
  		}
  		return 1;
-@@ -1955,7 +1955,7 @@ static int __init init_kprobes(void)
+@@ -1955,7 +1958,7 @@ static int __init init_kprobes(void)
  {
  	int i, err = 0;
  	unsigned long offset = 0, size = 0;
@@ -77570,7 +77771,7 @@ index bc90b87..6fc810d 100644
  	const char *symbol_name;
  	void *addr;
  	struct kprobe_blackpoint *kb;
-@@ -2040,11 +2040,11 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
+@@ -2040,11 +2043,11 @@ static void __kprobes report_probe(struct seq_file *pi, struct kprobe *p,
  		kprobe_type = "k";
  
  	if (sym)
@@ -77584,7 +77785,7 @@ index bc90b87..6fc810d 100644
  			p->addr, kprobe_type, p->addr);
  
  	if (!pp)
-@@ -2081,7 +2081,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
+@@ -2081,7 +2084,7 @@ static int __kprobes show_kprobe_addr(struct seq_file *pi, void *v)
  	const char *sym = NULL;
  	unsigned int i = *(loff_t *) v;
  	unsigned long offset = 0;
@@ -77593,7 +77794,7 @@ index bc90b87..6fc810d 100644
  
  	head = &kprobe_table[i];
  	preempt_disable();
-@@ -2204,7 +2204,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
+@@ -2204,7 +2207,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
  	       const char __user *user_buf, size_t count, loff_t *ppos)
  {
  	char buf[32];
@@ -89161,6 +89362,19 @@ index e41c40f..fbed7a7 100644
  	.init = devinet_init_net,
  	.exit = devinet_exit_net,
  };
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 238fc3b..4455673 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -472,7 +472,7 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
+ 	}
+ 
+ 	return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
+-		 net_adj) & ~(align - 1)) + (net_adj - 2);
++		 net_adj) & ~(align - 1)) + net_adj - 2;
+ }
+ 
+ static void esp4_err(struct sk_buff *skb, u32 info)
 diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
 index 92fc5f6..b790d91 100644
 --- a/net/ipv4/fib_frontend.c
@@ -89202,6 +89416,30 @@ index d01f9c6..284c56c 100644
  
  	return nh->nh_saddr;
  }
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index cd2d639..c7c6724 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -72,7 +72,6 @@
+ #include <linux/init.h>
+ #include <linux/list.h>
+ #include <linux/slab.h>
+-#include <linux/prefetch.h>
+ #include <linux/export.h>
+ #include <net/net_namespace.h>
+ #include <net/ip.h>
+@@ -1773,10 +1772,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
+ 			if (!c)
+ 				continue;
+ 
+-			if (IS_LEAF(c)) {
+-				prefetch(rcu_dereference_rtnl(p->child[idx]));
++			if (IS_LEAF(c))
+ 				return (struct leaf *) c;
+-			}
+ 
+ 			/* Rescan start scanning in new node */
+ 			p = (struct tnode *) c;
 diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
 index ab188ae..662585c 100644
 --- a/net/ipv4/icmp.c
@@ -90299,7 +90537,7 @@ index 314bda2..9503a4f 100644
  		if (ops->ndo_do_ioctl) {
  			mm_segment_t oldfs = get_fs();
 diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
-index 65dd543..df67080 100644
+index 65dd543..e6c6e6d 100644
 --- a/net/ipv6/esp6.c
 +++ b/net/ipv6/esp6.c
 @@ -164,8 +164,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
@@ -90323,6 +90561,15 @@ index 65dd543..df67080 100644
  
  	seqhi = esp_tmp_seqhi(tmp);
  	iv = esp_tmp_iv(aead, tmp, seqhilen);
+@@ -419,7 +419,7 @@ static u32 esp6_get_mtu(struct xfrm_state *x, int mtu)
+ 		net_adj = 0;
+ 
+ 	return ((mtu - x->props.header_len - crypto_aead_authsize(esp->aead) -
+-		 net_adj) & ~(align - 1)) + (net_adj - 2);
++		 net_adj) & ~(align - 1)) + net_adj - 2;
+ }
+ 
+ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
 index 90868fb..7aeff1e 100644
 --- a/net/ipv6/icmp.c
@@ -91503,6 +91750,49 @@ index 2e664a6..4264602 100644
  	return -NF_ACCEPT;
  }
  
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
+index 57ad466..e53ab60 100644
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -519,7 +519,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 	const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
+ 	__u32 seq, ack, sack, end, win, swin;
+ 	s16 receiver_offset;
+-	bool res;
++	bool res, in_recv_win;
+ 
+ 	/*
+ 	 * Get the required data from the packet.
+@@ -642,14 +642,18 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 		 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
+ 		 receiver->td_scale);
+ 
++	/* Is the ending sequence in the receive window (if available)? */
++	in_recv_win = !receiver->td_maxwin ||
++		      after(end, sender->td_end - receiver->td_maxwin - 1);
++
+ 	pr_debug("tcp_in_window: I=%i II=%i III=%i IV=%i\n",
+ 		 before(seq, sender->td_maxend + 1),
+-		 after(end, sender->td_end - receiver->td_maxwin - 1),
++		 (in_recv_win ? 1 : 0),
+ 		 before(sack, receiver->td_end + 1),
+ 		 after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
+ 
+ 	if (before(seq, sender->td_maxend + 1) &&
+-	    after(end, sender->td_end - receiver->td_maxwin - 1) &&
++	    in_recv_win &&
+ 	    before(sack, receiver->td_end + 1) &&
+ 	    after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
+ 		/*
+@@ -718,7 +722,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
+ 			nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+ 			"nf_ct_tcp: %s ",
+ 			before(seq, sender->td_maxend + 1) ?
+-			after(end, sender->td_end - receiver->td_maxwin - 1) ?
++			in_recv_win ?
+ 			before(sack, receiver->td_end + 1) ?
+ 			after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1) ? "BUG"
+ 			: "ACK is under the lower bound (possible overly delayed ACK)"
 diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
 index 05e9feb..3b519f3 100644
 --- a/net/netfilter/nf_conntrack_standalone.c
@@ -91585,7 +91875,7 @@ index f042ae5..30ea486 100644
  }
  EXPORT_SYMBOL(nf_unregister_sockopt);
 diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
-index 66b2c54..c7884e3 100644
+index 66b2c54..4ea49be 100644
 --- a/net/netfilter/nfnetlink_log.c
 +++ b/net/netfilter/nfnetlink_log.c
 @@ -70,7 +70,7 @@ struct nfulnl_instance {
@@ -91597,7 +91887,27 @@ index 66b2c54..c7884e3 100644
  
  #define INSTANCE_BUCKETS	16
  static struct hlist_head instance_table[INSTANCE_BUCKETS];
-@@ -502,7 +502,7 @@ __build_packet_message(struct nfulnl_instance *inst,
+@@ -388,6 +388,7 @@ __build_packet_message(struct nfulnl_instance *inst,
+ 	nfmsg->version = NFNETLINK_V0;
+ 	nfmsg->res_id = htons(inst->group_num);
+ 
++	memset(&pmsg, 0, sizeof(pmsg));
+ 	pmsg.hw_protocol	= skb->protocol;
+ 	pmsg.hook		= hooknum;
+ 
+@@ -456,7 +457,10 @@ __build_packet_message(struct nfulnl_instance *inst,
+ 	if (indev && skb->dev &&
+ 	    skb->mac_header != skb->network_header) {
+ 		struct nfulnl_msg_packet_hw phw;
+-		int len = dev_parse_header(skb, phw.hw_addr);
++		int len;
++
++		memset(&phw, 0, sizeof(phw));
++		len = dev_parse_header(skb, phw.hw_addr);
+ 		if (len > 0) {
+ 			phw.hw_addrlen = htons(len);
+ 			NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
+@@ -502,7 +506,7 @@ __build_packet_message(struct nfulnl_instance *inst,
  	/* global sequence number */
  	if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
  		NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL,
@@ -91606,6 +91916,93 @@ index 66b2c54..c7884e3 100644
  
  	if (data_len) {
  		struct nlattr *nla;
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index a80b0cb..f7e08e7 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -344,7 +344,10 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
+ 	if (indev && entskb->dev &&
+ 	    entskb->mac_header != entskb->network_header) {
+ 		struct nfqnl_msg_packet_hw phw;
+-		int len = dev_parse_header(entskb, phw.hw_addr);
++		int len;
++
++		memset(&phw, 0, sizeof(phw));
++		len = dev_parse_header(entskb, phw.hw_addr);
+ 		if (len) {
+ 			phw.hw_addrlen = htons(len);
+ 			NLA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
+diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
+index 9e63b43..a61bc90 100644
+--- a/net/netfilter/xt_TCPMSS.c
++++ b/net/netfilter/xt_TCPMSS.c
+@@ -50,7 +50,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 		     unsigned int minlen)
+ {
+ 	struct tcphdr *tcph;
+-	unsigned int tcplen, i;
++	int len, tcp_hdrlen;
++	unsigned int i;
+ 	__be16 oldval;
+ 	u16 newmss;
+ 	u8 *opt;
+@@ -58,11 +59,14 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 	if (!skb_make_writable(skb, skb->len))
+ 		return -1;
+ 
+-	tcplen = skb->len - tcphoff;
++	len = skb->len - tcphoff;
++	if (len < (int)sizeof(struct tcphdr))
++		return -1;
++
+ 	tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
++	tcp_hdrlen = tcph->doff * 4;
+ 
+-	/* Header cannot be larger than the packet */
+-	if (tcplen < tcph->doff*4)
++	if (len < tcp_hdrlen)
+ 		return -1;
+ 
+ 	if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
+@@ -83,9 +87,8 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 		newmss = info->mss;
+ 
+ 	opt = (u_int8_t *)tcph;
+-	for (i = sizeof(struct tcphdr); i < tcph->doff*4; i += optlen(opt, i)) {
+-		if (opt[i] == TCPOPT_MSS && tcph->doff*4 - i >= TCPOLEN_MSS &&
+-		    opt[i+1] == TCPOLEN_MSS) {
++	for (i = sizeof(struct tcphdr); i <= tcp_hdrlen - TCPOLEN_MSS; i += optlen(opt, i)) {
++		if (opt[i] == TCPOPT_MSS && opt[i+1] == TCPOLEN_MSS) {
+ 			u_int16_t oldmss;
+ 
+ 			oldmss = (opt[i+2] << 8) | opt[i+3];
+@@ -108,9 +111,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 	}
+ 
+ 	/* There is data after the header so the option can't be added
+-	   without moving it, and doing so may make the SYN packet
+-	   itself too large. Accept the packet unmodified instead. */
+-	if (tcplen > tcph->doff*4)
++	 * without moving it, and doing so may make the SYN packet
++	 * itself too large. Accept the packet unmodified instead.
++	 */
++	if (len > tcp_hdrlen)
+ 		return 0;
+ 
+ 	/*
+@@ -127,10 +131,10 @@ tcpmss_mangle_packet(struct sk_buff *skb,
+ 	skb_put(skb, TCPOLEN_MSS);
+ 
+ 	opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
+-	memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
++	memmove(opt + TCPOLEN_MSS, opt, len - sizeof(struct tcphdr));
+ 
+ 	inet_proto_csum_replace2(&tcph->check, skb,
+-				 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
++				 htons(len), htons(len + TCPOLEN_MSS), 1);
+ 	opt[0] = TCPOPT_MSS;
+ 	opt[1] = TCPOLEN_MSS;
+ 	opt[2] = (newmss & 0xff00) >> 8;
 diff --git a/net/netfilter/xt_gradm.c b/net/netfilter/xt_gradm.c
 new file mode 100644
 index 0000000..c566332
@@ -91729,7 +92126,7 @@ index 3d1d55d..1ee2a18 100644
  	.exit = netlink_net_exit,
  };
 diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
-index 874f8ff..339bb58 100644
+index 874f8ff..d8b8f87 100644
 --- a/net/netlink/genetlink.c
 +++ b/net/netlink/genetlink.c
 @@ -288,18 +288,20 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
@@ -91770,6 +92167,27 @@ index 874f8ff..339bb58 100644
  			return 0;
  		}
  	}
+@@ -700,6 +702,10 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
+ 	struct net *net = sock_net(skb->sk);
+ 	int chains_to_skip = cb->args[0];
+ 	int fams_to_skip = cb->args[1];
++	bool need_locking = chains_to_skip || fams_to_skip;
++
++	if (need_locking)
++		genl_lock();
+ 
+ 	for (i = chains_to_skip; i < GENL_FAM_TAB_SIZE; i++) {
+ 		n = 0;
+@@ -721,6 +727,9 @@ errout:
+ 	cb->args[0] = i;
+ 	cb->args[1] = n;
+ 
++	if (need_locking)
++		genl_unlock();
++
+ 	return skb->len;
+ }
+ 
 diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
 index 3df7c5a..8f324b0 100644
 --- a/net/netrom/af_netrom.c
@@ -94563,10 +94981,10 @@ index 38f6617..e70b72b 100755
  
  exuberant()
 diff --git a/security/Kconfig b/security/Kconfig
-index 51bd5a0..7ac4fad 100644
+index 51bd5a0..433ef3c 100644
 --- a/security/Kconfig
 +++ b/security/Kconfig
-@@ -4,6 +4,956 @@
+@@ -4,6 +4,954 @@
  
  menu "Security options"
  
@@ -94963,8 +95381,6 @@ index 51bd5a0..7ac4fad 100644
 +	bool "Paging based non-executable pages"
 +	default y if GRKERNSEC_CONFIG_AUTO
 +	depends on PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MATOM || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
-+	select S390_SWITCH_AMODE if S390
-+	select S390_EXEC_PROTECT if S390
 +	select ARCH_TRACK_EXEC_LIMIT if X86_32
 +	help
 +	  This implementation is based on the paging feature of the CPU.
@@ -95523,7 +95939,7 @@ index 51bd5a0..7ac4fad 100644
  config KEYS
  	bool "Enable access key retention support"
  	help
-@@ -169,7 +1119,7 @@ config INTEL_TXT
+@@ -169,7 +1117,7 @@ config INTEL_TXT
  config LSM_MMAP_MIN_ADDR
  	int "Low address space for LSM to protect from user allocation"
  	depends on SECURITY && SECURITY_SELINUX


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2013-08-18 14:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-18 14:10 [gentoo-commits] proj/hardened-patchset:master commit in: 2.6.32/, 3.10.7/, 3.10.5/, 3.2.50/ Anthony G. Basile

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox