]> git.ipfire.org Git - thirdparty/grsecurity-scrape.git/commitdiff
Auto commit, 1 new patch{es}.
authorPiotr Karbowski <piotr.karbowski@gmail.com>
Tue, 10 Nov 2015 03:08:04 +0000 (04:08 +0100)
committerPiotr Karbowski <piotr.karbowski@gmail.com>
Tue, 10 Nov 2015 03:08:04 +0000 (04:08 +0100)
test/changelog-test.txt
test/grsecurity-3.1-4.2.6-201511092040.patch [new file with mode: 0644]
test/grsecurity-3.1-4.2.6-201511092040.patch.sig [new file with mode: 0644]

index 3cf16c613fac683ea582dd502ca838a338f9ce26..134248ee76d96c25e3c3e270e3063c1da7e97f8c 100644 (file)
@@ -1,3 +1,51 @@
+commit 9c49029fe4cb9a52cb174aebfd5946a9d26b9956
+Merge: 5482e7e 7033393
+Author: Brad Spengler <spender@grsecurity.net>
+Date:   Mon Nov 9 19:51:58 2015 -0500
+
+    Merge branch 'pax-test' into grsec-test
+
+commit 70333935932c9f3eb333a354dd760b4233efcc37
+Author: Brad Spengler <spender@grsecurity.net>
+Date:   Mon Nov 9 19:51:19 2015 -0500
+
+    Update to pax-linux-4.2.6-test18.patch:
+    - cleaned up the last of the FPU changes, by spender
+    - fixed a few KERNEXEC regressions (backported from 4.3)
+    - Emese fixed a few size overflow false positives in kvm, reported by Christian Roessner (https://bugs.gentoo.org/show_bug.cgi?id=558138#c23)
+    - David Sterba fixed a few integer overflows in btrfs caught by the size overflow plugin (https://patchwork.kernel.org/patch/7585611/ and https://patchwork.kernel.org/patch/7582351/), reported by Victor, Stebalien and alan.d (https://forums.grsecurity.net/viewtopic.php?f=1&t=4284)
+
+ arch/x86/include/asm/fpu/internal.h                |    2 +-
+ arch/x86/include/asm/fpu/types.h                   |    1 -
+ arch/x86/kernel/apic/apic.c                        |    4 ++-
+ arch/x86/kernel/fpu/init.c                         |   36 --------------------
+ arch/x86/kernel/process_64.c                       |    6 +--
+ arch/x86/kernel/vsmp_64.c                          |   13 +++++--
+ drivers/acpi/video_detect.c                        |    2 +-
+ drivers/lguest/core.c                              |    2 +-
+ fs/btrfs/file.c                                    |   10 ++++--
+ fs/btrfs/inode.c                                   |   12 ++++++
+ .../disable_size_overflow_hash.data                |    5 ++-
+ .../size_overflow_plugin/size_overflow_hash.data   |    7 +---
+ 12 files changed, 42 insertions(+), 58 deletions(-)
+
+commit 5482e7eb4ba3c5cc90472ccdb1bfe2cec64413e2
+Merge: 81e2642 682ba19
+Author: Brad Spengler <spender@grsecurity.net>
+Date:   Mon Nov 9 18:19:48 2015 -0500
+
+    Merge branch 'pax-test' into grsec-test
+    
+    Conflicts:
+       drivers/pci/pci-sysfs.c
+
+commit 682ba19ce305f501c9bc5c42a76f2c7442aa22fc
+Merge: 7755256 1c02865
+Author: Brad Spengler <spender@grsecurity.net>
+Date:   Mon Nov 9 18:18:24 2015 -0500
+
+    Merge branch 'linux-4.2.y' into pax-test
+
 commit 81e26429b7a36f0c75de3ab42754256720c0a159
 Author: Brad Spengler <spender@grsecurity.net>
 Date:   Mon Nov 9 07:37:30 2015 -0500
diff --git a/test/grsecurity-3.1-4.2.6-201511092040.patch b/test/grsecurity-3.1-4.2.6-201511092040.patch
new file mode 100644 (file)
index 0000000..49aefe7
--- /dev/null
@@ -0,0 +1,7213 @@
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index 9de9813..1462492 100644
+--- a/Documentation/dontdiff
++++ b/Documentation/dontdiff
+@@ -3,9 +3,11 @@
+ *.bc
+ *.bin
+ *.bz2
++*.c.[012]*.*
+ *.cis
+ *.cpio
+ *.csp
++*.dbg
+ *.dsp
+ *.dvi
+ *.elf
+@@ -15,6 +17,7 @@
+ *.gcov
+ *.gen.S
+ *.gif
++*.gmo
+ *.grep
+ *.grp
+ *.gz
+@@ -51,14 +54,17 @@
+ *.tab.h
+ *.tex
+ *.ver
++*.vim
+ *.xml
+ *.xz
+ *_MODULES
++*_reg_safe.h
+ *_vga16.c
+ *~
+ \#*#
+ *.9
+-.*
++.[^g]*
++.gen*
+ .*.d
+ .mm
+ 53c700_d.h
+@@ -72,9 +78,11 @@ Image
+ Module.markers
+ Module.symvers
+ PENDING
++PERF*
+ SCCS
+ System.map*
+ TAGS
++TRACEEVENT-CFLAGS
+ aconf
+ af_names.h
+ aic7*reg.h*
+@@ -83,6 +91,7 @@ aic7*seq.h*
+ aicasm
+ aicdb.h*
+ altivec*.c
++ashldi3.S
+ asm-offsets.h
+ asm_offsets.h
+ autoconf.h*
+@@ -95,32 +104,40 @@ bounds.h
+ bsetup
+ btfixupprep
+ build
++builtin-policy.h
+ bvmlinux
+ bzImage*
+ capability_names.h
+ capflags.c
+ classlist.h*
++clut_vga16.c
++common-cmds.h
+ comp*.log
+ compile.h*
+ conf
+ config
+ config-*
+ config_data.h*
++config.c
+ config.mak
+ config.mak.autogen
++config.tmp
+ conmakehash
+ consolemap_deftbl.c*
+ cpustr.h
+ crc32table.h*
+ cscope.*
+ defkeymap.c
++devicetable-offsets.h
+ devlist.h*
+ dnotify_test
+ docproc
+ dslm
++dtc-lexer.lex.c
+ elf2ecoff
+ elfconfig.h*
+ evergreen_reg_safe.h
++exception_policy.conf
+ fixdep
+ flask.h
+ fore200e_mkfirm
+@@ -128,12 +145,15 @@ fore200e_pca_fw.c*
+ gconf
+ gconf.glade.h
+ gen-devlist
++gen-kdb_cmds.c
+ gen_crc32table
+ gen_init_cpio
+ generated
+ genheaders
+ genksyms
+ *_gray256.c
++hash
++hid-example
+ hpet_example
+ hugepage-mmap
+ hugepage-shm
+@@ -148,14 +168,14 @@ int32.c
+ int4.c
+ int8.c
+ kallsyms
+-kconfig
++kern_constants.h
+ keywords.c
+ ksym.c*
+ ksym.h*
+ kxgettext
+ lex.c
+ lex.*.c
+-linux
++lib1funcs.S
+ logo_*.c
+ logo_*_clut224.c
+ logo_*_mono.c
+@@ -165,14 +185,15 @@ mach-types.h
+ machtypes.h
+ map
+ map_hugetlb
+-media
+ mconf
++mdp
+ miboot*
+ mk_elfconfig
+ mkboot
+ mkbugboot
+ mkcpustr
+ mkdep
++mkpiggy
+ mkprep
+ mkregtable
+ mktables
+@@ -188,6 +209,8 @@ oui.c*
+ page-types
+ parse.c
+ parse.h
++parse-events*
++pasyms.h
+ patches*
+ pca200e.bin
+ pca200e_ecd.bin2
+@@ -197,6 +220,7 @@ perf-archive
+ piggyback
+ piggy.gzip
+ piggy.S
++pmu-*
+ pnmtologo
+ ppc_defs.h*
+ pss_boot.h
+@@ -206,7 +230,12 @@ r200_reg_safe.h
+ r300_reg_safe.h
+ r420_reg_safe.h
+ r600_reg_safe.h
++randomize_layout_hash.h
++randomize_layout_seed.h
++realmode.lds
++realmode.relocs
+ recordmcount
++regdb.c
+ relocs
+ rlim_names.h
+ rn50_reg_safe.h
+@@ -216,8 +245,12 @@ series
+ setup
+ setup.bin
+ setup.elf
++signing_key*
++size_overflow_hash.h
+ sImage
++slabinfo
+ sm_tbl*
++sortextable
+ split-include
+ syscalltab.h
+ tables.c
+@@ -227,6 +260,7 @@ tftpboot.img
+ timeconst.h
+ times.h*
+ trix_boot.h
++user_constants.h
+ utsrelease.h*
+ vdso-syms.lds
+ vdso.lds
+@@ -238,13 +272,17 @@ vdso32.lds
+ vdso32.so.dbg
+ vdso64.lds
+ vdso64.so.dbg
++vdsox32.lds
++vdsox32-syms.lds
+ version.h*
+ vmImage
+ vmlinux
+ vmlinux-*
+ vmlinux.aout
+ vmlinux.bin.all
++vmlinux.bin.bz2
+ vmlinux.lds
++vmlinux.relocs
+ vmlinuz
+ voffset.h
+ vsyscall.lds
+@@ -252,9 +290,12 @@ vsyscall_32.lds
+ wanxlfw.inc
+ uImage
+ unifdef
++utsrelease.h
+ wakeup.bin
+ wakeup.elf
+ wakeup.lds
++x509*
+ zImage*
+ zconf.hash.c
++zconf.lex.c
+ zoffset.h
+diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
+index 13f888a..250729b 100644
+--- a/Documentation/kbuild/makefiles.txt
++++ b/Documentation/kbuild/makefiles.txt
+@@ -23,10 +23,11 @@ This document describes the Linux kernel Makefiles.
+       === 4 Host Program support
+          --- 4.1 Simple Host Program
+          --- 4.2 Composite Host Programs
+-         --- 4.3 Using C++ for host programs
+-         --- 4.4 Controlling compiler options for host programs
+-         --- 4.5 When host programs are actually built
+-         --- 4.6 Using hostprogs-$(CONFIG_FOO)
++         --- 4.3 Defining shared libraries
++         --- 4.4 Using C++ for host programs
++         --- 4.5 Controlling compiler options for host programs
++         --- 4.6 When host programs are actually built
++         --- 4.7 Using hostprogs-$(CONFIG_FOO)
+       === 5 Kbuild clean infrastructure
+@@ -643,7 +644,29 @@ Both possibilities are described in the following.
+       Finally, the two .o files are linked to the executable, lxdialog.
+       Note: The syntax <executable>-y is not permitted for host-programs.
+---- 4.3 Using C++ for host programs
++--- 4.3 Defining shared libraries
++
++      Objects with extension .so are considered shared libraries, and
++      will be compiled as position independent objects.
++      Kbuild provides support for shared libraries, but the usage
++      shall be restricted.
++      In the following example the libkconfig.so shared library is used
++      to link the executable conf.
++
++      Example:
++              #scripts/kconfig/Makefile
++              hostprogs-y     := conf
++              conf-objs       := conf.o libkconfig.so
++              libkconfig-objs := expr.o type.o
++
++      Shared libraries always require a corresponding -objs line, and
++      in the example above the shared library libkconfig is composed by
++      the two objects expr.o and type.o.
++      expr.o and type.o will be built as position independent code and
++      linked as a shared library libkconfig.so. C++ is not supported for
++      shared libraries.
++
++--- 4.4 Using C++ for host programs
+       kbuild offers support for host programs written in C++. This was
+       introduced solely to support kconfig, and is not recommended
+@@ -666,7 +689,7 @@ Both possibilities are described in the following.
+               qconf-cxxobjs := qconf.o
+               qconf-objs    := check.o
+---- 4.4 Controlling compiler options for host programs
++--- 4.5 Controlling compiler options for host programs
+       When compiling host programs, it is possible to set specific flags.
+       The programs will always be compiled utilising $(HOSTCC) passed
+@@ -694,7 +717,7 @@ Both possibilities are described in the following.
+       When linking qconf, it will be passed the extra option
+       "-L$(QTDIR)/lib".
+---- 4.5 When host programs are actually built
++--- 4.6 When host programs are actually built
+       Kbuild will only build host-programs when they are referenced
+       as a prerequisite.
+@@ -725,7 +748,7 @@ Both possibilities are described in the following.
+       This will tell kbuild to build lxdialog even if not referenced in
+       any rule.
+---- 4.6 Using hostprogs-$(CONFIG_FOO)
++--- 4.7 Using hostprogs-$(CONFIG_FOO)
+       A typical pattern in a Kbuild file looks like this:
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 1d6f045..2714987 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1244,6 +1244,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+                       Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+                       Default: 1024
++      grsec_proc_gid= [GRKERNSEC_PROC_USERGROUP] Chooses GID to
++                      ignore grsecurity's /proc restrictions
++
++      grsec_sysfs_restrict= Format: 0 | 1
++                      Default: 1
++                      Disables GRKERNSEC_SYSFS_RESTRICT if enabled in config
++
+       hashdist=       [KNL,NUMA] Large hashes allocated during boot
+                       are distributed across NUMA nodes.  Defaults on
+                       for 64-bit NUMA, off otherwise.
+@@ -2364,6 +2371,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.
+@@ -2662,6 +2673,30 @@ 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.
++      pax_nouderef    [X86] disables UDEREF.  Most likely needed under certain
++                      virtualization environments that don't cope well with the
++                      expand down segment used by UDEREF on X86-32 or the frequent
++                      page table updates on X86-64.
++
++      pax_sanitize_slab=
++                      Format: { 0 | 1 | off | fast | full }
++                      Options '0' and '1' are only provided for backward
++                      compatibility, 'off' or 'fast' should be used instead.
++                      0|off : disable slab object sanitization
++                      1|fast: enable slab object sanitization excluding
++                              whitelisted slabs (default)
++                      full  : sanitize all slabs, even the whitelisted ones
++
++      pax_softmode=   0/1 to disable/enable PaX softmode on boot already.
++
++      pax_extra_latent_entropy
++                      Enable a very simple form of latent entropy extraction
++                      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/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
+index 6fccb69..60c7c7a 100644
+--- a/Documentation/sysctl/kernel.txt
++++ b/Documentation/sysctl/kernel.txt
+@@ -41,6 +41,7 @@ show up in /proc/sys/kernel:
+ - kptr_restrict
+ - kstack_depth_to_print       [ X86 only ]
+ - l2cr                        [ PPC only ]
++- modify_ldt                  [ X86 only ]
+ - modprobe                    ==> Documentation/debugging-modules.txt
+ - modules_disabled
+ - msg_next_id               [ sysv ipc ]
+@@ -391,6 +392,20 @@ This flag controls the L2 cache of G3 processor boards. If
+ ==============================================================
++modify_ldt: (X86 only)
++
++Enables (1) or disables (0) the modify_ldt syscall. Modifying the LDT
++(Local Descriptor Table) may be needed to run a 16-bit or segmented code
++such as Dosemu or Wine. This is done via a system call which is not needed
++to run portable applications, and which can sometimes be abused to exploit
++some weaknesses of the architecture, opening new vulnerabilities.
++
++This sysctl allows one to increase the system's security by disabling the
++system call, or to restore compatibility with specific applications when it
++was already disabled.
++
++==============================================================
++
+ modules_disabled:
+ A toggle value indicating if modules are allowed to be loaded
+diff --git a/Makefile b/Makefile
+index 9ef3739..20b7716 100644
+--- a/Makefile
++++ b/Makefile
+@@ -298,7 +298,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+ HOSTCC       = gcc
+ HOSTCXX      = g++
+ HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89
+-HOSTCXXFLAGS = -O2
++HOSTCFLAGS   = -W -Wno-unused-parameter -Wno-missing-field-initializers -fno-delete-null-pointer-checks
++HOSTCFLAGS  += $(call cc-option, -Wno-empty-body)
++HOSTCXXFLAGS = -O2 -Wall -W -Wno-array-bounds
+ ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
+ HOSTCFLAGS  += -Wno-unused-value -Wno-unused-parameter \
+@@ -434,8 +436,8 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
+ # Rules shared between *config targets and build targets
+ # Basic helpers built in scripts/
+-PHONY += scripts_basic
+-scripts_basic:
++PHONY += scripts_basic gcc-plugins
++scripts_basic: gcc-plugins
+       $(Q)$(MAKE) $(build)=scripts/basic
+       $(Q)rm -f .tmp_quiet_recordmcount
+@@ -615,6 +617,74 @@ endif
+ # Tell gcc to never replace conditional load with a non-conditional one
+ KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)
++ifndef DISABLE_PAX_PLUGINS
++ifeq ($(call cc-ifversion, -ge, 0408, y), y)
++PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCXX)" "$(HOSTCXX)" "$(CC)")
++else
++PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)")
++endif
++ifneq ($(PLUGINCC),)
++ifdef CONFIG_PAX_CONSTIFY_PLUGIN
++CONSTIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/constify_plugin.so -DCONSTIFY_PLUGIN
++endif
++ifdef CONFIG_PAX_MEMORY_STACKLEAK
++STACKLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/stackleak_plugin.so -DSTACKLEAK_PLUGIN
++STACKLEAK_PLUGIN_CFLAGS += -fplugin-arg-stackleak_plugin-track-lowest-sp=100
++endif
++ifdef CONFIG_KALLOCSTAT_PLUGIN
++KALLOCSTAT_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kallocstat_plugin.so
++endif
++ifdef CONFIG_PAX_KERNEXEC_PLUGIN
++KERNEXEC_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kernexec_plugin.so
++KERNEXEC_PLUGIN_CFLAGS += -fplugin-arg-kernexec_plugin-method=$(CONFIG_PAX_KERNEXEC_PLUGIN_METHOD) -DKERNEXEC_PLUGIN
++KERNEXEC_PLUGIN_AFLAGS := -DKERNEXEC_PLUGIN
++endif
++ifdef CONFIG_GRKERNSEC_RANDSTRUCT
++RANDSTRUCT_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/randomize_layout_plugin.so -DRANDSTRUCT_PLUGIN
++ifdef CONFIG_GRKERNSEC_RANDSTRUCT_PERFORMANCE
++RANDSTRUCT_PLUGIN_CFLAGS += -fplugin-arg-randomize_layout_plugin-performance-mode
++endif
++endif
++ifdef CONFIG_CHECKER_PLUGIN
++ifeq ($(call cc-ifversion, -ge, 0406, y), y)
++CHECKER_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/checker_plugin.so -DCHECKER_PLUGIN
++endif
++endif
++COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so
++ifdef CONFIG_PAX_SIZE_OVERFLOW
++SIZE_OVERFLOW_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/size_overflow_plugin/size_overflow_plugin.so -DSIZE_OVERFLOW_PLUGIN
++endif
++ifdef CONFIG_PAX_LATENT_ENTROPY
++LATENT_ENTROPY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/latent_entropy_plugin.so -DLATENT_ENTROPY_PLUGIN
++endif
++ifdef CONFIG_PAX_MEMORY_STRUCTLEAK
++STRUCTLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/structleak_plugin.so -DSTRUCTLEAK_PLUGIN
++endif
++INITIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/initify_plugin.so -DINITIFY_PLUGIN
++GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) $(KALLOCSTAT_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) $(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(SIZE_OVERFLOW_PLUGIN_CFLAGS) $(LATENT_ENTROPY_PLUGIN_CFLAGS) $(STRUCTLEAK_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(INITIFY_PLUGIN_CFLAGS)
++GCC_PLUGINS_CFLAGS += $(RANDSTRUCT_PLUGIN_CFLAGS)
++GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS)
++export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS CONSTIFY_PLUGIN LATENT_ENTROPY_PLUGIN_CFLAGS
++ifeq ($(KBUILD_EXTMOD),)
++gcc-plugins:
++      $(Q)$(MAKE) $(build)=tools/gcc
++else
++gcc-plugins: ;
++endif
++else
++gcc-plugins:
++ifeq ($(call cc-ifversion, -ge, 0405, y), y)
++      $(error Your gcc installation does not support plugins.  If the necessary headers for plugin support are missing, they should be installed.  On Debian, apt-get install gcc-<ver>-plugin-dev.  If you choose to ignore this error and lessen the improvements provided by this patch, re-run make with the DISABLE_PAX_PLUGINS=y argument.))
++else
++      $(Q)echo "warning, your gcc version does not support plugins, you should upgrade it to gcc 4.5 at least"
++endif
++      $(Q)echo "PAX_MEMORY_STACKLEAK, constification, PAX_LATENT_ENTROPY and other features will be less secure.  PAX_SIZE_OVERFLOW will not be active."
++endif
++endif
++
+ ifdef CONFIG_READABLE_ASM
+ # Disable optimizations that make assembler listings hard to read.
+ # reorder blocks reorders the control in the function
+@@ -714,7 +784,7 @@ KBUILD_CFLAGS   += $(call cc-option, -gsplit-dwarf, -g)
+ else
+ KBUILD_CFLAGS += -g
+ endif
+-KBUILD_AFLAGS += -Wa,-gdwarf-2
++KBUILD_AFLAGS += -Wa,--gdwarf-2
+ endif
+ ifdef CONFIG_DEBUG_INFO_DWARF4
+ KBUILD_CFLAGS += $(call cc-option, -gdwarf-4,)
+@@ -886,7 +956,7 @@ export mod_sign_cmd
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y                += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
++core-y                += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
+ vmlinux-dirs  := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+                    $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+@@ -936,6 +1006,8 @@ endif
+ # The actual objects are generated when descending,
+ # make sure no implicit rule kicks in
++$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
+ # Handle descending into subdirectories listed in $(vmlinux-dirs)
+@@ -945,7 +1017,7 @@ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
+ # Error messages still appears in the original language
+ PHONY += $(vmlinux-dirs)
+-$(vmlinux-dirs): prepare scripts
++$(vmlinux-dirs): gcc-plugins prepare scripts
+       $(Q)$(MAKE) $(build)=$@
+ define filechk_kernel.release
+@@ -988,10 +1060,13 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
+ archprepare: archheaders archscripts prepare1 scripts_basic
++prepare0: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++prepare0: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ prepare0: archprepare FORCE
+       $(Q)$(MAKE) $(build)=.
+ # All the preparing..
++prepare: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+ prepare: prepare0
+ # Generate some files
+@@ -1099,6 +1174,8 @@ all: modules
+ # using awk while concatenating to the final file.
+ PHONY += modules
++modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
+       $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order
+       @$(kecho) '  Building modules, stage 2.';
+@@ -1114,7 +1191,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
+ # Target to prepare building external modules
+ PHONY += modules_prepare
+-modules_prepare: prepare scripts
++modules_prepare: gcc-plugins prepare scripts
+ # Target to install modules
+ PHONY += modules_install
+@@ -1180,7 +1257,10 @@ MRPROPER_FILES += .config .config.old .version .old_version \
+                 Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+                 signing_key.priv signing_key.x509 x509.genkey         \
+                 extra_certificates signing_key.x509.keyid             \
+-                signing_key.x509.signer vmlinux-gdb.py
++                signing_key.x509.signer vmlinux-gdb.py \
++                tools/gcc/size_overflow_plugin/size_overflow_hash_aux.h \
++                tools/gcc/size_overflow_plugin/size_overflow_hash.h \
++                tools/gcc/randomize_layout_seed.h
+ # clean - Delete most, but leave enough to build external modules
+ #
+@@ -1219,7 +1299,7 @@ distclean: mrproper
+       @find $(srctree) $(RCS_FIND_IGNORE) \
+               \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+               -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+-              -o -name '.*.rej' -o -name '*%'  -o -name 'core' \) \
++              -o -name '.*.rej' -o -name '*.so' -o -name '*%' -o -name 'core' \) \
+               -type f -print | xargs rm -f
+@@ -1385,6 +1465,8 @@ PHONY += $(module-dirs) modules
+ $(module-dirs): crmodverdir $(objtree)/Module.symvers
+       $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
++modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ modules: $(module-dirs)
+       @$(kecho) '  Building modules, stage 2.';
+       $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+@@ -1525,17 +1607,21 @@ else
+         target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
+ endif
+-%.s: %.c prepare scripts FORCE
++%.s: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.s: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.s: %.c gcc-plugins prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.i: %.c prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.c prepare scripts FORCE
++%.o: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.o: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.o: %.c gcc-plugins prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.lst: %.c prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.s: %.S prepare scripts FORCE
++%.s: %.S gcc-plugins prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.S prepare scripts FORCE
++%.o: %.S gcc-plugins prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.symtypes: %.c prepare scripts FORCE
+       $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+@@ -1547,11 +1633,15 @@ endif
+       $(build)=$(build-dir)
+ # Make sure the latest headers are built for Documentation
+ Documentation/: headers_install
+-%/: prepare scripts FORCE
++%/: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%/: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%/: gcc-plugins prepare scripts FORCE
+       $(cmd_crmodverdir)
+       $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+       $(build)=$(build-dir)
+-%.ko: prepare scripts FORCE
++%.ko: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.ko: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.ko: gcc-plugins prepare scripts FORCE
+       $(cmd_crmodverdir)
+       $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
+       $(build)=$(build-dir) $(@:.ko=.o)
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 8f8eafb..3405f46 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -239,4 +239,14 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
+ #define atomic_dec(v) atomic_sub(1,(v))
+ #define atomic64_dec(v) atomic64_sub(1,(v))
++#define atomic64_read_unchecked(v)            atomic64_read(v)
++#define atomic64_set_unchecked(v, i)          atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v)          atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v)   atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v)          atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v)             atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v)      atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v)             atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n)   atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* _ALPHA_ATOMIC_H */
+diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h
+index ad368a9..fbe0f25 100644
+--- a/arch/alpha/include/asm/cache.h
++++ b/arch/alpha/include/asm/cache.h
+@@ -4,19 +4,19 @@
+ #ifndef __ARCH_ALPHA_CACHE_H
+ #define __ARCH_ALPHA_CACHE_H
++#include <linux/const.h>
+ /* Bytes per L1 (data) cache line. */
+ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
+-# define L1_CACHE_BYTES     64
+ # define L1_CACHE_SHIFT     6
+ #else
+ /* Both EV4 and EV5 are write-through, read-allocate,
+    direct-mapped, physical.
+ */
+-# define L1_CACHE_BYTES     32
+ # define L1_CACHE_SHIFT     5
+ #endif
++#define L1_CACHE_BYTES     (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES    L1_CACHE_BYTES
+ #endif
+diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
+index 968d999..d36b2df 100644
+--- a/arch/alpha/include/asm/elf.h
++++ b/arch/alpha/include/asm/elf.h
+@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #define ELF_ET_DYN_BASE               (TASK_UNMAPPED_BASE + 0x1000000)
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
++
++#define PAX_DELTA_MMAP_LEN    (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
++#define PAX_DELTA_STACK_LEN   (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
++#endif
++
+ /* $0 is set by ld.so to a pointer to a function which might be 
+    registered using atexit.  This provides a mean for the dynamic
+    linker to call DT_FINI functions for shared libraries that have
+diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
+index aab14a0..b4fa3e7 100644
+--- a/arch/alpha/include/asm/pgalloc.h
++++ b/arch/alpha/include/asm/pgalloc.h
+@@ -29,6 +29,12 @@ pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+       pgd_set(pgd, pmd);
+ }
++static inline void
++pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
++{
++      pgd_populate(mm, pgd, pmd);
++}
++
+ extern pgd_t *pgd_alloc(struct mm_struct *mm);
+ static inline void
+diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
+index a9a1195..e9b8417 100644
+--- a/arch/alpha/include/asm/pgtable.h
++++ b/arch/alpha/include/asm/pgtable.h
+@@ -101,6 +101,17 @@ struct vm_area_struct;
+ #define PAGE_SHARED   __pgprot(_PAGE_VALID | __ACCESS_BITS)
+ #define PAGE_COPY     __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
+ #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC   __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
++# define PAGE_COPY_NOEXEC     __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++#else
++# define PAGE_SHARED_NOEXEC   PAGE_SHARED
++# define PAGE_COPY_NOEXEC     PAGE_COPY
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL   __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
+diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
+index 2fd00b7..cfd5069 100644
+--- a/arch/alpha/kernel/module.c
++++ b/arch/alpha/kernel/module.c
+@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
+       /* The small sections were sorted to the end of the segment.
+          The following should definitely cover them.  */
+-      gp = (u64)me->module_core + me->core_size - 0x8000;
++      gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
+       got = sechdrs[me->arch.gotsecindex].sh_addr;
+       for (i = 0; i < n; i++) {
+diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
+index 36dc91a..6769cb0 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -1295,10 +1295,11 @@ SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p)
+    generic version except that we know how to honor ADDR_LIMIT_32BIT.  */
+ static unsigned long
+-arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
+-                       unsigned long limit)
++arch_get_unmapped_area_1(struct file *filp, unsigned long addr, unsigned long len,
++                       unsigned long limit, unsigned long flags)
+ {
+       struct vm_unmapped_area_info info;
++      unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+       info.flags = 0;
+       info.length = len;
+@@ -1306,6 +1307,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
+       info.high_limit = limit;
+       info.align_mask = 0;
+       info.align_offset = 0;
++      info.threadstack_offset = offset;
+       return vm_unmapped_area(&info);
+ }
+@@ -1338,20 +1340,24 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+          merely specific addresses, but regions of memory -- perhaps
+          this feature should be incorporated into all ports?  */
++#ifdef CONFIG_PAX_RANDMMAP
++      if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+       if (addr) {
+-              addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
++              addr = arch_get_unmapped_area_1 (filp, PAGE_ALIGN(addr), len, limit, flags);
+               if (addr != (unsigned long) -ENOMEM)
+                       return addr;
+       }
+       /* Next, try allocating at TASK_UNMAPPED_BASE.  */
+-      addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
+-                                       len, limit);
++      addr = arch_get_unmapped_area_1 (filp, PAGE_ALIGN(current->mm->mmap_base), len, limit, flags);
++
+       if (addr != (unsigned long) -ENOMEM)
+               return addr;
+       /* Finally, try allocating in low memory.  */
+-      addr = arch_get_unmapped_area_1 (PAGE_SIZE, len, limit);
++      addr = arch_get_unmapped_area_1 (filp, PAGE_SIZE, len, limit, flags);
+       return addr;
+ }
+diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
+index 4a905bd..0a4da53 100644
+--- a/arch/alpha/mm/fault.c
++++ b/arch/alpha/mm/fault.c
+@@ -52,6 +52,124 @@ __load_new_mm_context(struct mm_struct *next_mm)
+       __reload_thread(pcb);
+ }
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (regs->pc = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when patched PLT trampoline was detected
++ *         3 when unpatched PLT trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++
++#ifdef CONFIG_PAX_EMUPLT
++      int err;
++
++      do { /* PaX: patched PLT emulation #1 */
++              unsigned int ldah, ldq, jmp;
++
++              err = get_user(ldah, (unsigned int *)regs->pc);
++              err |= get_user(ldq, (unsigned int *)(regs->pc+4));
++              err |= get_user(jmp, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++
++              if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
++                  (ldq & 0xFFFF0000U) == 0xA77B0000U &&
++                  jmp == 0x6BFB0000U)
++              {
++                      unsigned long r27, addr;
++                      unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++                      unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
++
++                      addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++                      err = get_user(r27, (unsigned long *)addr);
++                      if (err)
++                              break;
++
++                      regs->r27 = r27;
++                      regs->pc = r27;
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: patched PLT emulation #2 */
++              unsigned int ldah, lda, br;
++
++              err = get_user(ldah, (unsigned int *)regs->pc);
++              err |= get_user(lda, (unsigned int *)(regs->pc+4));
++              err |= get_user(br, (unsigned int *)(regs->pc+8));
++
++              if (err)
++                      break;
++
++              if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
++                  (lda & 0xFFFF0000U) == 0xA77B0000U &&
++                  (br & 0xFFE00000U) == 0xC3E00000U)
++              {
++                      unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
++                      unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++                      unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
++
++                      regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++                      regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++                      return 2;
++              }
++      } while (0);
++
++      do { /* PaX: unpatched PLT emulation */
++              unsigned int br;
++
++              err = get_user(br, (unsigned int *)regs->pc);
++
++              if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
++                      unsigned int br2, ldq, nop, jmp;
++                      unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
++
++                      addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++                      err = get_user(br2, (unsigned int *)addr);
++                      err |= get_user(ldq, (unsigned int *)(addr+4));
++                      err |= get_user(nop, (unsigned int *)(addr+8));
++                      err |= get_user(jmp, (unsigned int *)(addr+12));
++                      err |= get_user(resolver, (unsigned long *)(addr+16));
++
++                      if (err)
++                              break;
++
++                      if (br2 == 0xC3600000U &&
++                          ldq == 0xA77B000CU &&
++                          nop == 0x47FF041FU &&
++                          jmp == 0x6B7B0000U)
++                      {
++                              regs->r28 = regs->pc+4;
++                              regs->r27 = addr+16;
++                              regs->pc = resolver;
++                              return 3;
++                      }
++              }
++      } while (0);
++#endif
++
++      return 1;
++}
++
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int *)pc+i))
++                      printk(KERN_CONT "???????? ");
++              else
++                      printk(KERN_CONT "%08x ", c);
++      }
++      printk("\n");
++}
++#endif
+ /*
+  * This routine handles page faults.  It determines the address,
+@@ -132,8 +250,29 @@ retry:
+  good_area:
+       si_code = SEGV_ACCERR;
+       if (cause < 0) {
+-              if (!(vma->vm_flags & VM_EXEC))
++              if (!(vma->vm_flags & VM_EXEC)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++                      if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
++                              goto bad_area;
++
++                      up_read(&mm->mmap_sem);
++                      switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_PAX_EMUPLT
++                      case 2:
++                      case 3:
++                              return;
++#endif
++
++                      }
++                      pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
++                      do_group_exit(SIGKILL);
++#else
+                       goto bad_area;
++#endif
++
++              }
+       } else if (!cause) {
+               /* Allow reads even for write-only mappings */
+               if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
+index bd4670d..920c97a 100644
+--- a/arch/arc/Kconfig
++++ b/arch/arc/Kconfig
+@@ -485,6 +485,7 @@ config ARC_DBG_TLB_MISS_COUNT
+       bool "Profile TLB Misses"
+       default n
+       select DEBUG_FS
++      depends on !GRKERNSEC_KMEM
+       help
+         Counts number of I and D TLB Misses and exports them via Debugfs
+         The counters can be cleared via Debugfs as well
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index ede2526..9e12300 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1770,7 +1770,7 @@ config ALIGNMENT_TRAP
+ config UACCESS_WITH_MEMCPY
+       bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()"
+-      depends on MMU
++      depends on MMU && !PAX_MEMORY_UDEREF
+       default y if CPU_FEROCEON
+       help
+         Implement faster copy_to_user and clear_user methods for CPU
+@@ -2006,6 +2006,7 @@ config KEXEC
+       bool "Kexec system call (EXPERIMENTAL)"
+       depends on (!SMP || PM_SLEEP_SMP)
+       depends on !CPU_V7M
++      depends on !GRKERNSEC_KMEM
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index a2e16f9..b26e911 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -7,6 +7,7 @@ config ARM_PTDUMP
+       depends on DEBUG_KERNEL
+       depends on MMU
+       select DEBUG_FS
++      depends on !GRKERNSEC_KMEM
+       ---help---
+         Say Y here if you want to show the kernel pagetable layout in a
+         debugfs file. This information is only useful for kernel developers
+diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
+index e22c119..abe7041 100644
+--- a/arch/arm/include/asm/atomic.h
++++ b/arch/arm/include/asm/atomic.h
+@@ -18,17 +18,41 @@
+ #include <asm/barrier.h>
+ #include <asm/cmpxchg.h>
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i)        { (i) }
+ #ifdef __KERNEL__
++#ifdef CONFIG_THUMB2_KERNEL
++#define REFCOUNT_TRAP_INSN "bkpt      0xf1"
++#else
++#define REFCOUNT_TRAP_INSN "bkpt      0xf103"
++#endif
++
++#define _ASM_EXTABLE(from, to)                \
++"     .pushsection __ex_table,\"a\"\n"\
++"     .align  3\n"                    \
++"     .long   " #from ", " #to"\n"    \
++"     .popsection"
++
+ /*
+  * On ARM, ordinary assignment (str instruction) doesn't clear the local
+  * strex/ldrex monitor on some implementations. The reason we can use it for
+  * atomic_set() is the clrex or dummy strex done on every exception return.
+  */
+ #define atomic_read(v)        ACCESS_ONCE((v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++      return ACCESS_ONCE(v->counter);
++}
+ #define atomic_set(v,i)       (((v)->counter) = (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++      v->counter = i;
++}
+ #if __LINUX_ARM_ARCH__ >= 6
+@@ -38,26 +62,50 @@
+  * to ensure that the update happens.
+  */
+-#define ATOMIC_OP(op, c_op, asm_op)                                   \
+-static inline void atomic_##op(int i, atomic_t *v)                    \
++#ifdef CONFIG_PAX_REFCOUNT
++#define __OVERFLOW_POST                       \
++      "       bvc     3f\n"           \
++      "2:     " REFCOUNT_TRAP_INSN "\n"\
++      "3:\n"
++#define __OVERFLOW_POST_RETURN                \
++      "       bvc     3f\n"           \
++"     mov     %0, %1\n"               \
++      "2:     " REFCOUNT_TRAP_INSN "\n"\
++      "3:\n"
++#define __OVERFLOW_EXTABLE            \
++      "4:\n"                          \
++      _ASM_EXTABLE(2b, 4b)
++#else
++#define __OVERFLOW_POST
++#define __OVERFLOW_POST_RETURN
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, c_op, asm_op, post_op, extable)               \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t *v)  \
+ {                                                                     \
+       unsigned long tmp;                                              \
+       int result;                                                     \
+                                                                       \
+       prefetchw(&v->counter);                                         \
+-      __asm__ __volatile__("@ atomic_" #op "\n"                       \
++      __asm__ __volatile__("@ atomic_" #op #suffix "\n"               \
+ "1:   ldrex   %0, [%3]\n"                                             \
+ "     " #asm_op "     %0, %0, %4\n"                                   \
++      post_op                                                         \
+ "     strex   %1, %0, [%3]\n"                                         \
+ "     teq     %1, #0\n"                                               \
+-"     bne     1b"                                                     \
++"     bne     1b\n"                                                   \
++      extable                                                         \
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)               \
+       : "r" (&v->counter), "Ir" (i)                                   \
+       : "cc");                                                        \
+ }                                                                     \
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op)                            \
+-static inline int atomic_##op##_return(int i, atomic_t *v)            \
++#define ATOMIC_OP(op, c_op, asm_op) __ATOMIC_OP(op, _unchecked, c_op, asm_op, , )\
++                                  __ATOMIC_OP(op, , c_op, asm_op##s, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC_OP_RETURN(op, suffix, c_op, asm_op, post_op, extable)        \
++static inline int atomic_##op##_return##suffix(int i, atomic##suffix##_t *v)\
+ {                                                                     \
+       unsigned long tmp;                                              \
+       int result;                                                     \
+@@ -65,12 +113,14 @@ static inline int atomic_##op##_return(int i, atomic_t *v)                \
+       smp_mb();                                                       \
+       prefetchw(&v->counter);                                         \
+                                                                       \
+-      __asm__ __volatile__("@ atomic_" #op "_return\n"                \
++      __asm__ __volatile__("@ atomic_" #op "_return" #suffix "\n"     \
+ "1:   ldrex   %0, [%3]\n"                                             \
+ "     " #asm_op "     %0, %0, %4\n"                                   \
++      post_op                                                         \
+ "     strex   %1, %0, [%3]\n"                                         \
+ "     teq     %1, #0\n"                                               \
+-"     bne     1b"                                                     \
++"     bne     1b\n"                                                   \
++      extable                                                         \
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)               \
+       : "r" (&v->counter), "Ir" (i)                                   \
+       : "cc");                                                        \
+@@ -80,6 +130,9 @@ static inline int atomic_##op##_return(int i, atomic_t *v)          \
+       return result;                                                  \
+ }
++#define ATOMIC_OP_RETURN(op, c_op, asm_op) __ATOMIC_OP_RETURN(op, _unchecked, c_op, asm_op, , )\
++                                         __ATOMIC_OP_RETURN(op, , c_op, asm_op##s, __OVERFLOW_POST_RETURN, __OVERFLOW_EXTABLE)
++
+ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+ {
+       int oldval;
+@@ -115,12 +168,24 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+       __asm__ __volatile__ ("@ atomic_add_unless\n"
+ "1:   ldrex   %0, [%4]\n"
+ "     teq     %0, %5\n"
+-"     beq     2f\n"
+-"     add     %1, %0, %6\n"
++"     beq     4f\n"
++"     adds    %1, %0, %6\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"     bvc     3f\n"
++"2:   " REFCOUNT_TRAP_INSN "\n"
++"3:\n"
++#endif
++
+ "     strex   %2, %1, [%4]\n"
+ "     teq     %2, #0\n"
+ "     bne     1b\n"
+-"2:"
++"4:"
++
++#ifdef CONFIG_PAX_REFCOUNT
++      _ASM_EXTABLE(2b, 4b)
++#endif
++
+       : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
+       : "r" (&v->counter), "r" (u), "r" (a)
+       : "cc");
+@@ -131,14 +196,36 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+       return oldval;
+ }
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *ptr, int old, int new)
++{
++      unsigned long oldval, res;
++
++      smp_mb();
++
++      do {
++              __asm__ __volatile__("@ atomic_cmpxchg_unchecked\n"
++              "ldrex  %1, [%3]\n"
++              "mov    %0, #0\n"
++              "teq    %1, %4\n"
++              "strexeq %0, %5, [%3]\n"
++                  : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++                  : "r" (&ptr->counter), "Ir" (old), "r" (new)
++                  : "cc");
++      } while (res);
++
++      smp_mb();
++
++      return oldval;
++}
++
+ #else /* ARM_ARCH_6 */
+ #ifdef CONFIG_SMP
+ #error SMP not supported on pre-ARMv6 CPUs
+ #endif
+-#define ATOMIC_OP(op, c_op, asm_op)                                   \
+-static inline void atomic_##op(int i, atomic_t *v)                    \
++#define __ATOMIC_OP(op, suffix, c_op, asm_op)                         \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t *v)  \
+ {                                                                     \
+       unsigned long flags;                                            \
+                                                                       \
+@@ -147,8 +234,11 @@ static inline void atomic_##op(int i, atomic_t *v)                        \
+       raw_local_irq_restore(flags);                                   \
+ }                                                                     \
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op)                            \
+-static inline int atomic_##op##_return(int i, atomic_t *v)            \
++#define ATOMIC_OP(op, c_op, asm_op) __ATOMIC_OP(op, , c_op, asm_op)   \
++                                  __ATOMIC_OP(op, _unchecked, c_op, asm_op)
++
++#define __ATOMIC_OP_RETURN(op, suffix, c_op, asm_op)                  \
++static inline int atomic_##op##_return##suffix(int i, atomic##suffix##_t *v)\
+ {                                                                     \
+       unsigned long flags;                                            \
+       int val;                                                        \
+@@ -161,6 +251,9 @@ static inline int atomic_##op##_return(int i, atomic_t *v)         \
+       return val;                                                     \
+ }
++#define ATOMIC_OP_RETURN(op, c_op, asm_op) __ATOMIC_OP_RETURN(op, , c_op, asm_op)\
++                                         __ATOMIC_OP_RETURN(op, _unchecked, c_op, asm_op)
++
+ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+ {
+       int ret;
+@@ -175,6 +268,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+       return ret;
+ }
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, int new)
++{
++      return atomic_cmpxchg((atomic_t *)v, old, new);
++}
++
+ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+       int c, old;
+@@ -196,16 +294,38 @@ ATOMIC_OPS(sub, -=, sub)
+ #undef ATOMIC_OPS
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++      return xchg(&v->counter, new);
++}
+ #define atomic_inc(v)         atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++      atomic_add_unchecked(1, v);
++}
+ #define atomic_dec(v)         atomic_sub(1, v)
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++      atomic_sub_unchecked(1, v);
++}
+ #define atomic_inc_and_test(v)        (atomic_add_return(1, v) == 0)
++static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++      return atomic_add_return_unchecked(1, v) == 0;
++}
+ #define atomic_dec_and_test(v)        (atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return(v)    (atomic_add_return(1, v))
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++      return atomic_add_return_unchecked(1, v);
++}
+ #define atomic_dec_return(v)    (atomic_sub_return(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+@@ -216,6 +336,14 @@ typedef struct {
+       long long counter;
+ } atomic64_t;
++#ifdef CONFIG_PAX_REFCOUNT
++typedef struct {
++      long long counter;
++} atomic64_unchecked_t;
++#else
++typedef atomic64_t atomic64_unchecked_t;
++#endif
++
+ #define ATOMIC64_INIT(i) { (i) }
+ #ifdef CONFIG_ARM_LPAE
+@@ -232,6 +360,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+       return result;
+ }
++static inline long long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++      long long result;
++
++      __asm__ __volatile__("@ atomic64_read_unchecked\n"
++"     ldrd    %0, %H0, [%1]"
++      : "=&r" (result)
++      : "r" (&v->counter), "Qo" (v->counter)
++      );
++
++      return result;
++}
++
+ static inline void atomic64_set(atomic64_t *v, long long i)
+ {
+       __asm__ __volatile__("@ atomic64_set\n"
+@@ -240,6 +381,15 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+       : "r" (&v->counter), "r" (i)
+       );
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long long i)
++{
++      __asm__ __volatile__("@ atomic64_set_unchecked\n"
++"     strd    %2, %H2, [%1]"
++      : "=Qo" (v->counter)
++      : "r" (&v->counter), "r" (i)
++      );
++}
+ #else
+ static inline long long atomic64_read(const atomic64_t *v)
+ {
+@@ -254,6 +404,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+       return result;
+ }
++static inline long long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++      long long result;
++
++      __asm__ __volatile__("@ atomic64_read_unchecked\n"
++"     ldrexd  %0, %H0, [%1]"
++      : "=&r" (result)
++      : "r" (&v->counter), "Qo" (v->counter)
++      );
++
++      return result;
++}
++
+ static inline void atomic64_set(atomic64_t *v, long long i)
+ {
+       long long tmp;
+@@ -268,29 +431,57 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+       : "r" (&v->counter), "r" (i)
+       : "cc");
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long long i)
++{
++      long long tmp;
++
++      prefetchw(&v->counter);
++      __asm__ __volatile__("@ atomic64_set_unchecked\n"
++"1:   ldrexd  %0, %H0, [%2]\n"
++"     strexd  %0, %3, %H3, [%2]\n"
++"     teq     %0, #0\n"
++"     bne     1b"
++      : "=&r" (tmp), "=Qo" (v->counter)
++      : "r" (&v->counter), "r" (i)
++      : "cc");
++}
+ #endif
+-#define ATOMIC64_OP(op, op1, op2)                                     \
+-static inline void atomic64_##op(long long i, atomic64_t *v)          \
++#undef __OVERFLOW_POST_RETURN
++#define __OVERFLOW_POST_RETURN                \
++      "       bvc     3f\n"           \
++"     mov     %0, %1\n"               \
++"     mov     %H0, %H1\n"             \
++      "2:     " REFCOUNT_TRAP_INSN "\n"\
++      "3:\n"
++
++#define __ATOMIC64_OP(op, suffix, op1, op2, post_op, extable)         \
++static inline void atomic64_##op##suffix(long long i, atomic64##suffix##_t *v)\
+ {                                                                     \
+       long long result;                                               \
+       unsigned long tmp;                                              \
+                                                                       \
+       prefetchw(&v->counter);                                         \
+-      __asm__ __volatile__("@ atomic64_" #op "\n"                     \
++      __asm__ __volatile__("@ atomic64_" #op #suffix "\n"             \
+ "1:   ldrexd  %0, %H0, [%3]\n"                                        \
+ "     " #op1 " %Q0, %Q0, %Q4\n"                                       \
+ "     " #op2 " %R0, %R0, %R4\n"                                       \
++      post_op                                                         \
+ "     strexd  %1, %0, %H0, [%3]\n"                                    \
+ "     teq     %1, #0\n"                                               \
+-"     bne     1b"                                                     \
++"     bne     1b\n"                                                   \
++      extable                                                         \
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)               \
+       : "r" (&v->counter), "r" (i)                                    \
+       : "cc");                                                        \
+ }                                                                     \
+-#define ATOMIC64_OP_RETURN(op, op1, op2)                              \
+-static inline long long atomic64_##op##_return(long long i, atomic64_t *v) \
++#define ATOMIC64_OP(op, op1, op2) __ATOMIC64_OP(op, _unchecked, op1, op2, , ) \
++                                __ATOMIC64_OP(op, , op1, op2##s, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, op1, op2, post_op, extable)  \
++static inline long long atomic64_##op##_return##suffix(long long i, atomic64##suffix##_t *v) \
+ {                                                                     \
+       long long result;                                               \
+       unsigned long tmp;                                              \
+@@ -298,13 +489,15 @@ static inline long long atomic64_##op##_return(long long i, atomic64_t *v) \
+       smp_mb();                                                       \
+       prefetchw(&v->counter);                                         \
+                                                                       \
+-      __asm__ __volatile__("@ atomic64_" #op "_return\n"              \
++      __asm__ __volatile__("@ atomic64_" #op "_return" #suffix "\n"   \
+ "1:   ldrexd  %0, %H0, [%3]\n"                                        \
+ "     " #op1 " %Q0, %Q0, %Q4\n"                                       \
+ "     " #op2 " %R0, %R0, %R4\n"                                       \
++      post_op                                                         \
+ "     strexd  %1, %0, %H0, [%3]\n"                                    \
+ "     teq     %1, #0\n"                                               \
+-"     bne     1b"                                                     \
++"     bne     1b\n"                                                   \
++      extable                                                         \
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)               \
+       : "r" (&v->counter), "r" (i)                                    \
+       : "cc");                                                        \
+@@ -314,6 +507,9 @@ static inline long long atomic64_##op##_return(long long i, atomic64_t *v) \
+       return result;                                                  \
+ }
++#define ATOMIC64_OP_RETURN(op, op1, op2) __ATOMIC64_OP_RETURN(op, _unchecked, op1, op2, , ) \
++                                       __ATOMIC64_OP_RETURN(op, , op1, op2##s, __OVERFLOW_POST_RETURN, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC64_OPS(op, op1, op2)                                    \
+       ATOMIC64_OP(op, op1, op2)                                       \
+       ATOMIC64_OP_RETURN(op, op1, op2)
+@@ -323,7 +519,12 @@ ATOMIC64_OPS(sub, subs, sbc)
+ #undef ATOMIC64_OPS
+ #undef ATOMIC64_OP_RETURN
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_EXTABLE
++#undef __OVERFLOW_POST_RETURN
++#undef __OVERFLOW_POST
+ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+                                       long long new)
+@@ -351,6 +552,31 @@ static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old,
+       return oldval;
+ }
++static inline long long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *ptr, long long old,
++                                      long long new)
++{
++      long long oldval;
++      unsigned long res;
++
++      smp_mb();
++
++      do {
++              __asm__ __volatile__("@ atomic64_cmpxchg_unchecked\n"
++              "ldrexd         %1, %H1, [%3]\n"
++              "mov            %0, #0\n"
++              "teq            %1, %4\n"
++              "teqeq          %H1, %H4\n"
++              "strexdeq       %0, %5, %H5, [%3]"
++              : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++              : "r" (&ptr->counter), "r" (old), "r" (new)
++              : "cc");
++      } while (res);
++
++      smp_mb();
++
++      return oldval;
++}
++
+ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
+ {
+       long long result;
+@@ -376,21 +602,35 @@ static inline long long atomic64_xchg(atomic64_t *ptr, long long new)
+ static inline long long atomic64_dec_if_positive(atomic64_t *v)
+ {
+       long long result;
+-      unsigned long tmp;
++      u64 tmp;
+       smp_mb();
+       prefetchw(&v->counter);
+       __asm__ __volatile__("@ atomic64_dec_if_positive\n"
+-"1:   ldrexd  %0, %H0, [%3]\n"
+-"     subs    %Q0, %Q0, #1\n"
+-"     sbc     %R0, %R0, #0\n"
++"1:   ldrexd  %1, %H1, [%3]\n"
++"     subs    %Q0, %Q1, #1\n"
++"     sbcs    %R0, %R1, #0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"     bvc     3f\n"
++"     mov     %Q0, %Q1\n"
++"     mov     %R0, %R1\n"
++"2:   " REFCOUNT_TRAP_INSN "\n"
++"3:\n"
++#endif
++
+ "     teq     %R0, #0\n"
+-"     bmi     2f\n"
++"     bmi     4f\n"
+ "     strexd  %1, %0, %H0, [%3]\n"
+ "     teq     %1, #0\n"
+ "     bne     1b\n"
+-"2:"
++"4:\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++      _ASM_EXTABLE(2b, 4b)
++#endif
++
+       : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+       : "r" (&v->counter)
+       : "cc");
+@@ -414,13 +654,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+ "     teq     %0, %5\n"
+ "     teqeq   %H0, %H5\n"
+ "     moveq   %1, #0\n"
+-"     beq     2f\n"
++"     beq     4f\n"
+ "     adds    %Q0, %Q0, %Q6\n"
+-"     adc     %R0, %R0, %R6\n"
++"     adcs    %R0, %R0, %R6\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"     bvc     3f\n"
++"2:   " REFCOUNT_TRAP_INSN "\n"
++"3:\n"
++#endif
++
+ "     strexd  %2, %0, %H0, [%4]\n"
+ "     teq     %2, #0\n"
+ "     bne     1b\n"
+-"2:"
++"4:\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++      _ASM_EXTABLE(2b, 4b)
++#endif
++
+       : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
+       : "r" (&v->counter), "r" (u), "r" (a)
+       : "cc");
+@@ -433,10 +685,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+ #define atomic64_add_negative(a, v)   (atomic64_add_return((a), (v)) < 0)
+ #define atomic64_inc(v)                       atomic64_add(1LL, (v))
++#define atomic64_inc_unchecked(v)     atomic64_add_unchecked(1LL, (v))
+ #define atomic64_inc_return(v)                atomic64_add_return(1LL, (v))
++#define atomic64_inc_return_unchecked(v)      atomic64_add_return_unchecked(1LL, (v))
+ #define atomic64_inc_and_test(v)      (atomic64_inc_return(v) == 0)
+ #define atomic64_sub_and_test(a, v)   (atomic64_sub_return((a), (v)) == 0)
+ #define atomic64_dec(v)                       atomic64_sub(1LL, (v))
++#define atomic64_dec_unchecked(v)     atomic64_sub_unchecked(1LL, (v))
+ #define atomic64_dec_return(v)                atomic64_sub_return(1LL, (v))
+ #define atomic64_dec_and_test(v)      (atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_not_zero(v)      atomic64_add_unless((v), 1LL, 0LL)
+diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
+index 6c2327e..85beac4 100644
+--- a/arch/arm/include/asm/barrier.h
++++ b/arch/arm/include/asm/barrier.h
+@@ -67,7 +67,7 @@
+ do {                                                                  \
+       compiletime_assert_atomic_type(*p);                             \
+       smp_mb();                                                       \
+-      ACCESS_ONCE(*p) = (v);                                          \
++      ACCESS_ONCE_RW(*p) = (v);                                       \
+ } while (0)
+ #define smp_load_acquire(p)                                           \
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+index 75fe66b..ba3dee4 100644
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -4,8 +4,10 @@
+ #ifndef __ASMARM_CACHE_H
+ #define __ASMARM_CACHE_H
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT                CONFIG_ARM_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
+@@ -24,5 +26,6 @@
+ #endif
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
++#define __read_only __attribute__ ((__section__(".data..read_only")))
+ #endif
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index 4812cda..9da8116 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -116,7 +116,7 @@ struct cpu_cache_fns {
+       void (*dma_unmap_area)(const void *, size_t, int);
+       void (*dma_flush_range)(const void *, const void *);
+-};
++} __no_const;
+ /*
+  * Select the calling method
+diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h
+index 5233151..87a71fa 100644
+--- a/arch/arm/include/asm/checksum.h
++++ b/arch/arm/include/asm/checksum.h
+@@ -37,7 +37,19 @@ __wsum
+ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
+ __wsum
+-csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
++__csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
++
++static inline __wsum
++csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr)
++{
++      __wsum ret;
++      pax_open_userland();
++      ret = __csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
++      pax_close_userland();
++      return ret;
++}
++
++
+ /*
+  *    Fold a partial checksum without adding pseudo headers
+diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
+index 1692a05..1835802 100644
+--- a/arch/arm/include/asm/cmpxchg.h
++++ b/arch/arm/include/asm/cmpxchg.h
+@@ -107,6 +107,10 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
+       (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr),           \
+                                  sizeof(*(ptr)));                     \
+ })
++#define xchg_unchecked(ptr, x) ({                                     \
++      (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr),           \
++                                 sizeof(*(ptr)));                     \
++})
+ #include <asm-generic/cmpxchg-local.h>
+diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
+index 0f84249..8e83c55 100644
+--- a/arch/arm/include/asm/cpuidle.h
++++ b/arch/arm/include/asm/cpuidle.h
+@@ -32,7 +32,7 @@ struct device_node;
+ struct cpuidle_ops {
+       int (*suspend)(int cpu, unsigned long arg);
+       int (*init)(struct device_node *, int cpu);
+-};
++} __no_const;
+ struct of_cpuidle_method {
+       const char *method;
+diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
+index 6ddbe44..b5e38b1a 100644
+--- a/arch/arm/include/asm/domain.h
++++ b/arch/arm/include/asm/domain.h
+@@ -48,18 +48,37 @@
+  * Domain types
+  */
+ #define DOMAIN_NOACCESS       0
+-#define DOMAIN_CLIENT 1
+ #ifdef CONFIG_CPU_USE_DOMAINS
++#define DOMAIN_USERCLIENT     1
++#define DOMAIN_KERNELCLIENT   1
+ #define DOMAIN_MANAGER        3
++#define DOMAIN_VECTORS                DOMAIN_USER
+ #else
++
++#ifdef CONFIG_PAX_KERNEXEC
+ #define DOMAIN_MANAGER        1
++#define DOMAIN_KERNEXEC       3
++#else
++#define DOMAIN_MANAGER        1
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++#define DOMAIN_USERCLIENT     0
++#define DOMAIN_UDEREF         1
++#define DOMAIN_VECTORS                DOMAIN_KERNEL
++#else
++#define DOMAIN_USERCLIENT     1
++#define DOMAIN_VECTORS                DOMAIN_USER
++#endif
++#define DOMAIN_KERNELCLIENT   1
++
+ #endif
+ #define domain_val(dom,type)  ((type) << (2*(dom)))
+ #ifndef __ASSEMBLY__
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+ static inline void set_domain(unsigned val)
+ {
+       asm volatile(
+@@ -68,15 +87,7 @@ static inline void set_domain(unsigned val)
+       isb();
+ }
+-#define modify_domain(dom,type)                                       \
+-      do {                                                    \
+-      struct thread_info *thread = current_thread_info();     \
+-      unsigned int domain = thread->cpu_domain;               \
+-      domain &= ~domain_val(dom, DOMAIN_MANAGER);             \
+-      thread->cpu_domain = domain | domain_val(dom, type);    \
+-      set_domain(thread->cpu_domain);                         \
+-      } while (0)
+-
++extern void modify_domain(unsigned int dom, unsigned int type);
+ #else
+ 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 d2315ff..f60b47b 100644
+--- a/arch/arm/include/asm/elf.h
++++ b/arch/arm/include/asm/elf.h
+@@ -117,7 +117,14 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+    the loader.  We need to make sure that it is out of the way of the program
+    that it will "exec", and that there is sufficient room for the brk.  */
+-#define ELF_ET_DYN_BASE       (TASK_SIZE / 3 * 2)
++#define ELF_ET_DYN_BASE               (TASK_SIZE / 3 * 2)
++
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   0x00008000UL
++
++#define PAX_DELTA_MMAP_LEN    ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
++#define PAX_DELTA_STACK_LEN   ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
++#endif
+ /* 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 
+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
++++ b/arch/arm/include/asm/fncpy.h
+@@ -81,7 +81,9 @@
+       BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) ||             \
+               (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+                                                                       \
++      pax_open_kernel();                                              \
+       memcpy(dest_buf, (void const *)(__funcp_address & ~1), size);   \
++      pax_close_kernel();                                             \
+       flush_icache_range((unsigned long)(dest_buf),                   \
+               (unsigned long)(dest_buf) + (size));                    \
+                                                                       \
+diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
+index 5eed828..365e018 100644
+--- a/arch/arm/include/asm/futex.h
++++ b/arch/arm/include/asm/futex.h
+@@ -46,6 +46,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+               return -EFAULT;
++      pax_open_userland();
++
+       smp_mb();
+       /* Prefetching cannot fault */
+       prefetchw(uaddr);
+@@ -63,6 +65,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+       : "cc", "memory");
+       smp_mb();
++      pax_close_userland();
++
+       *uval = val;
+       return ret;
+ }
+@@ -94,6 +98,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+               return -EFAULT;
+       preempt_disable();
++      pax_open_userland();
++
+       __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+       "1:     " TUSER(ldr) "  %1, [%4]\n"
+       "       teq     %1, %2\n"
+@@ -104,6 +110,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+       : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+       : "cc", "memory");
++      pax_close_userland();
++
+       *uval = val;
+       preempt_enable();
+@@ -131,6 +139,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+       preempt_disable();
+ #endif
+       pagefault_disable();
++      pax_open_userland();
+       switch (op) {
+       case FUTEX_OP_SET:
+@@ -152,6 +161,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+               ret = -ENOSYS;
+       }
++      pax_close_userland();
+       pagefault_enable();
+ #ifndef CONFIG_SMP
+       preempt_enable();
+diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
+index 83eb2f7..ed77159 100644
+--- a/arch/arm/include/asm/kmap_types.h
++++ b/arch/arm/include/asm/kmap_types.h
+@@ -4,6 +4,6 @@
+ /*
+  * This is the "bare minimum".  AIO seems to require this.
+  */
+-#define KM_TYPE_NR 16
++#define KM_TYPE_NR 17
+ #endif
+diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h
+index 9e614a1..3302cca 100644
+--- a/arch/arm/include/asm/mach/dma.h
++++ b/arch/arm/include/asm/mach/dma.h
+@@ -22,7 +22,7 @@ struct dma_ops {
+       int     (*residue)(unsigned int, dma_t *);              /* optional */
+       int     (*setspeed)(unsigned int, dma_t *, int);        /* optional */
+       const char *type;
+-};
++} __do_const;
+ struct dma_struct {
+       void            *addr;          /* single DMA address           */
+diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
+index f98c7f3..e5c626d 100644
+--- a/arch/arm/include/asm/mach/map.h
++++ b/arch/arm/include/asm/mach/map.h
+@@ -23,17 +23,19 @@ struct map_desc {
+ /* types 0-3 are defined in asm/io.h */
+ enum {
+-      MT_UNCACHED = 4,
+-      MT_CACHECLEAN,
+-      MT_MINICLEAN,
++      MT_UNCACHED_RW = 4,
++      MT_CACHECLEAN_RO,
++      MT_MINICLEAN_RO,
+       MT_LOW_VECTORS,
+       MT_HIGH_VECTORS,
+-      MT_MEMORY_RWX,
++      __MT_MEMORY_RWX,
+       MT_MEMORY_RW,
+-      MT_ROM,
+-      MT_MEMORY_RWX_NONCACHED,
++      MT_MEMORY_RX,
++      MT_ROM_RX,
++      MT_MEMORY_RW_NONCACHED,
++      MT_MEMORY_RX_NONCACHED,
+       MT_MEMORY_RW_DTCM,
+-      MT_MEMORY_RWX_ITCM,
++      MT_MEMORY_RX_ITCM,
+       MT_MEMORY_RW_SO,
+       MT_MEMORY_DMA_READY,
+ };
+diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
+index 563b92f..689d58e 100644
+--- a/arch/arm/include/asm/outercache.h
++++ b/arch/arm/include/asm/outercache.h
+@@ -39,7 +39,7 @@ struct outer_cache_fns {
+       /* This is an ARM L2C thing */
+       void (*write_sec)(unsigned long, unsigned);
+       void (*configure)(const struct l2x0_regs *);
+-};
++} __no_const;
+ extern struct outer_cache_fns outer_cache;
+diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
+index 4355f0e..cd9168e 100644
+--- a/arch/arm/include/asm/page.h
++++ b/arch/arm/include/asm/page.h
+@@ -23,6 +23,7 @@
+ #else
++#include <linux/compiler.h>
+ #include <asm/glue.h>
+ /*
+@@ -114,7 +115,7 @@ struct cpu_user_fns {
+       void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
+       void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
+                       unsigned long vaddr, struct vm_area_struct *vma);
+-};
++} __no_const;
+ #ifdef MULTI_USER
+ extern struct cpu_user_fns cpu_user;
+diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
+index 19cfab5..3f5c7e9 100644
+--- a/arch/arm/include/asm/pgalloc.h
++++ b/arch/arm/include/asm/pgalloc.h
+@@ -17,6 +17,7 @@
+ #include <asm/processor.h>
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
++#include <asm/system_info.h>
+ #define check_pgt_cache()             do { } while (0)
+@@ -43,6 +44,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+       set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+ }
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++      pud_populate(mm, pud, pmd);
++}
++
+ #else /* !CONFIG_ARM_LPAE */
+ /*
+@@ -51,6 +57,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ #define pmd_alloc_one(mm,addr)                ({ BUG(); ((pmd_t *)2); })
+ #define pmd_free(mm, pmd)             do { } while (0)
+ #define pud_populate(mm,pmd,pte)      BUG()
++#define pud_populate_kernel(mm,pmd,pte)       BUG()
+ #endif        /* CONFIG_ARM_LPAE */
+@@ -128,6 +135,19 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+       __free_page(pte);
+ }
++static inline void __section_update(pmd_t *pmdp, unsigned long addr, pmdval_t prot)
++{
++#ifdef CONFIG_ARM_LPAE
++      pmdp[0] = __pmd(pmd_val(pmdp[0]) | prot);
++#else
++      if (addr & SECTION_SIZE)
++              pmdp[1] = __pmd(pmd_val(pmdp[1]) | prot);
++      else
++              pmdp[0] = __pmd(pmd_val(pmdp[0]) | prot);
++#endif
++      flush_pmd_entry(pmdp);
++}
++
+ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
+                                 pmdval_t prot)
+ {
+diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
+index 5e68278..1869bae 100644
+--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
++++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
+@@ -27,7 +27,7 @@
+ /*
+  *   - section
+  */
+-#define PMD_SECT_PXN    (_AT(pmdval_t, 1) << 0)     /* v7 */
++#define PMD_SECT_PXN          (_AT(pmdval_t, 1) << 0)     /* v7 */
+ #define PMD_SECT_BUFFERABLE   (_AT(pmdval_t, 1) << 2)
+ #define PMD_SECT_CACHEABLE    (_AT(pmdval_t, 1) << 3)
+ #define PMD_SECT_XN           (_AT(pmdval_t, 1) << 4)         /* v6 */
+@@ -39,6 +39,7 @@
+ #define PMD_SECT_nG           (_AT(pmdval_t, 1) << 17)        /* v6 */
+ #define PMD_SECT_SUPER                (_AT(pmdval_t, 1) << 18)        /* v6 */
+ #define PMD_SECT_AF           (_AT(pmdval_t, 0))
++#define PMD_SECT_RDONLY               (_AT(pmdval_t, 0))
+ #define PMD_SECT_UNCACHED     (_AT(pmdval_t, 0))
+ #define PMD_SECT_BUFFERED     (PMD_SECT_BUFFERABLE)
+@@ -68,6 +69,7 @@
+  *   - extended small page/tiny page
+  */
+ #define PTE_EXT_XN            (_AT(pteval_t, 1) << 0)         /* v6 */
++#define PTE_EXT_PXN           (_AT(pteval_t, 1) << 2)         /* v7 */
+ #define PTE_EXT_AP_MASK               (_AT(pteval_t, 3) << 4)
+ #define PTE_EXT_AP0           (_AT(pteval_t, 1) << 4)
+ #define PTE_EXT_AP1           (_AT(pteval_t, 2) << 4)
+diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
+index aeddd28..207745c 100644
+--- a/arch/arm/include/asm/pgtable-2level.h
++++ b/arch/arm/include/asm/pgtable-2level.h
+@@ -127,6 +127,9 @@
+ #define L_PTE_SHARED          (_AT(pteval_t, 1) << 10)        /* shared(v6), coherent(xsc3) */
+ #define L_PTE_NONE            (_AT(pteval_t, 1) << 11)
++/* Two-level page tables only have PXN in the PGD, not in the PTE. */
++#define L_PTE_PXN             (_AT(pteval_t, 0))
++
+ /*
+  * These are the memory types, defined to be compatible with
+  * pre-ARMv6 CPUs cacheable and bufferable bits: n/a,n/a,C,B
+diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
+index a745a2a..481350a 100644
+--- a/arch/arm/include/asm/pgtable-3level.h
++++ b/arch/arm/include/asm/pgtable-3level.h
+@@ -80,6 +80,7 @@
+ #define L_PTE_USER            (_AT(pteval_t, 1) << 6)         /* AP[1] */
+ #define L_PTE_SHARED          (_AT(pteval_t, 3) << 8)         /* SH[1:0], inner shareable */
+ #define L_PTE_YOUNG           (_AT(pteval_t, 1) << 10)        /* AF */
++#define L_PTE_PXN             (_AT(pteval_t, 1) << 53)        /* PXN */
+ #define L_PTE_XN              (_AT(pteval_t, 1) << 54)        /* XN */
+ #define L_PTE_DIRTY           (_AT(pteval_t, 1) << 55)
+ #define L_PTE_SPECIAL         (_AT(pteval_t, 1) << 56)
+@@ -91,10 +92,12 @@
+ #define L_PMD_SECT_SPLITTING  (_AT(pmdval_t, 1) << 56)
+ #define L_PMD_SECT_NONE               (_AT(pmdval_t, 1) << 57)
+ #define L_PMD_SECT_RDONLY     (_AT(pteval_t, 1) << 58)
++#define PMD_SECT_RDONLY               PMD_SECT_AP2
+ /*
+  * To be used in assembly code with the upper page attributes.
+  */
++#define L_PTE_PXN_HIGH                (1 << (53 - 32))
+ #define L_PTE_XN_HIGH         (1 << (54 - 32))
+ #define L_PTE_DIRTY_HIGH      (1 << (55 - 32))
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index f403541..b10df68 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -33,6 +33,9 @@
+ #include <asm/pgtable-2level.h>
+ #endif
++#define ktla_ktva(addr)               (addr)
++#define ktva_ktla(addr)               (addr)
++
+ /*
+  * Just any arbitrary offset to the start of the vmalloc VM area: the
+  * current 8MB value just means that there will be a 8MB "hole" after the
+@@ -48,6 +51,9 @@
+ #define LIBRARY_TEXT_START    0x0c000000
+ #ifndef __ASSEMBLY__
++extern pteval_t __supported_pte_mask;
++extern pmdval_t __supported_pmd_mask;
++
+ extern void __pte_error(const char *file, int line, pte_t);
+ extern void __pmd_error(const char *file, int line, pmd_t);
+ extern void __pgd_error(const char *file, int line, pgd_t);
+@@ -56,6 +62,48 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+ #define pmd_ERROR(pmd)                __pmd_error(__FILE__, __LINE__, pmd)
+ #define pgd_ERROR(pgd)                __pgd_error(__FILE__, __LINE__, pgd)
++#define  __HAVE_ARCH_PAX_OPEN_KERNEL
++#define  __HAVE_ARCH_PAX_CLOSE_KERNEL
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++#include <asm/domain.h>
++#include <linux/thread_info.h>
++#include <linux/preempt.h>
++
++static inline int test_domain(int domain, int domaintype)
++{
++      return ((current_thread_info()->cpu_domain) & domain_val(domain, 3)) == domain_val(domain, domaintype);
++}
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++static inline unsigned long pax_open_kernel(void) {
++#ifdef CONFIG_ARM_LPAE
++      /* TODO */
++#else
++      preempt_disable();
++      BUG_ON(test_domain(DOMAIN_KERNEL, DOMAIN_KERNEXEC));
++      modify_domain(DOMAIN_KERNEL, DOMAIN_KERNEXEC);
++#endif
++      return 0;
++}
++
++static inline unsigned long pax_close_kernel(void) {
++#ifdef CONFIG_ARM_LPAE
++      /* TODO */
++#else
++      BUG_ON(test_domain(DOMAIN_KERNEL, DOMAIN_MANAGER));
++      /* DOMAIN_MANAGER = "client" under KERNEXEC */
++      modify_domain(DOMAIN_KERNEL, DOMAIN_MANAGER);
++      preempt_enable_no_resched();
++#endif
++      return 0;
++}
++#else
++static inline unsigned long pax_open_kernel(void) { return 0; }
++static inline unsigned long pax_close_kernel(void) { return 0; }
++#endif
++
+ /*
+  * This is the lowest virtual address we can permit any user space
+  * mapping to be mapped at.  This is particularly important for
+@@ -75,8 +123,8 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+ /*
+  * The pgprot_* and protection_map entries will be fixed up in runtime
+  * to include the cachable and bufferable bits based on memory policy,
+- * as well as any architecture dependent bits like global/ASID and SMP
+- * shared mapping bits.
++ * as well as any architecture dependent bits like global/ASID, PXN,
++ * and SMP shared mapping bits.
+  */
+ #define _L_PTE_DEFAULT        L_PTE_PRESENT | L_PTE_YOUNG
+@@ -307,7 +355,7 @@ static inline pte_t pte_mknexec(pte_t pte)
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+       const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
+-              L_PTE_NONE | L_PTE_VALID;
++              L_PTE_NONE | L_PTE_VALID | __supported_pte_mask;
+       pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
+       return pte;
+ }
+diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
+index c25ef3e..735f14b 100644
+--- a/arch/arm/include/asm/psci.h
++++ b/arch/arm/include/asm/psci.h
+@@ -32,7 +32,7 @@ struct psci_operations {
+       int (*affinity_info)(unsigned long target_affinity,
+                       unsigned long lowest_affinity_level);
+       int (*migrate_info_type)(void);
+-};
++} __no_const;
+ extern struct psci_operations psci_ops;
+ extern struct smp_operations psci_smp_ops;
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index 2f3ac1b..67182ae0 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -108,7 +108,7 @@ struct smp_operations {
+       int  (*cpu_disable)(unsigned int cpu);
+ #endif
+ #endif
+-};
++} __no_const;
+ struct of_cpu_method {
+       const char *method;
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index bd32ede..bd90a0b 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -74,9 +74,9 @@ struct thread_info {
+       .flags          = 0,                                            \
+       .preempt_count  = INIT_PREEMPT_COUNT,                           \
+       .addr_limit     = KERNEL_DS,                                    \
+-      .cpu_domain     = domain_val(DOMAIN_USER, DOMAIN_MANAGER) |     \
+-                        domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |   \
+-                        domain_val(DOMAIN_IO, DOMAIN_CLIENT),         \
++      .cpu_domain     = domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) |  \
++                        domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT) |      \
++                        domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT),   \
+ }
+ #define init_thread_info      (init_thread_union.thread_info)
+@@ -152,7 +152,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define TIF_SYSCALL_AUDIT     9
+ #define TIF_SYSCALL_TRACEPOINT        10
+ #define TIF_SECCOMP           11      /* seccomp syscall filtering active */
+-#define TIF_NOHZ              12      /* in adaptive nohz mode */
++/* within 8 bits of TIF_SYSCALL_TRACE
++ *  to meet flexible second operand requirements
++ */
++#define TIF_GRSEC_SETXID      12
++#define TIF_NOHZ              13      /* in adaptive nohz mode */
+ #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 *,
+ #define _TIF_SYSCALL_TRACEPOINT       (1 << TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_SECCOMP          (1 << TIF_SECCOMP)
+ #define _TIF_USING_IWMMXT     (1 << TIF_USING_IWMMXT)
++#define _TIF_GRSEC_SETXID     (1 << TIF_GRSEC_SETXID)
+ /* Checks for any syscall work in entry-common.S */
+ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+-                         _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
++                         _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | _TIF_GRSEC_SETXID)
+ /*
+  * Change these and you break ASM code in entry-common.S
+diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
+index 5f833f7..76e6644 100644
+--- a/arch/arm/include/asm/tls.h
++++ b/arch/arm/include/asm/tls.h
+@@ -3,6 +3,7 @@
+ #include <linux/compiler.h>
+ #include <asm/thread_info.h>
++#include <asm/pgtable.h>
+ #ifdef __ASSEMBLY__
+ #include <asm/asm-offsets.h>
+@@ -89,7 +90,9 @@ static inline void set_tls(unsigned long val)
+                        * at 0xffff0fe0 must be used instead.  (see
+                        * entry-armv.S for details)
+                        */
++                      pax_open_kernel();
+                       *((unsigned int *)0xffff0ff0) = val;
++                      pax_close_kernel();
+ #endif
+               }
+diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
+index 74b17d0..7e6da4b 100644
+--- a/arch/arm/include/asm/uaccess.h
++++ b/arch/arm/include/asm/uaccess.h
+@@ -18,6 +18,7 @@
+ #include <asm/domain.h>
+ #include <asm/unified.h>
+ #include <asm/compiler.h>
++#include <asm/pgtable.h>
+ #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ #include <asm-generic/uaccess-unaligned.h>
+@@ -70,11 +71,38 @@ extern int __put_user_bad(void);
+ static inline void set_fs(mm_segment_t fs)
+ {
+       current_thread_info()->addr_limit = fs;
+-      modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
++      modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_KERNELCLIENT : DOMAIN_MANAGER);
+ }
+ #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)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      if (segment_eq(get_fs(), USER_DS)) {
++              BUG_ON(test_domain(DOMAIN_USER, DOMAIN_UDEREF));
++              modify_domain(DOMAIN_USER, DOMAIN_UDEREF);
++      }
++#endif
++
++}
++
++static inline void pax_close_userland(void)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      if (segment_eq(get_fs(), USER_DS)) {
++              BUG_ON(test_domain(DOMAIN_USER, DOMAIN_NOACCESS));
++              modify_domain(DOMAIN_USER, DOMAIN_NOACCESS);
++      }
++#endif
++
++}
++
+ #define __addr_ok(addr) ({ \
+       unsigned long flag; \
+       __asm__("cmp %2, %0; movlo %0, #0" \
+@@ -198,8 +226,12 @@ extern int __get_user_64t_4(void *);
+ #define get_user(x, p)                                                        \
+       ({                                                              \
++              int __e;                                                \
+               might_fault();                                          \
+-              __get_user_check(x, p);                                 \
++              pax_open_userland();                                    \
++              __e = __get_user_check((x), (p));                       \
++              pax_close_userland();                                   \
++              __e;                                                    \
+        })
+ extern int __put_user_1(void *, unsigned int);
+@@ -244,8 +276,12 @@ extern int __put_user_8(void *, unsigned long long);
+ #define put_user(x, p)                                                        \
+       ({                                                              \
++              int __e;                                                \
+               might_fault();                                          \
+-              __put_user_check(x, p);                                 \
++              pax_open_userland();                                    \
++              __e = __put_user_check((x), (p));                       \
++              pax_close_userland();                                   \
++              __e;                                                    \
+        })
+ #else /* CONFIG_MMU */
+@@ -269,6 +305,7 @@ static inline void set_fs(mm_segment_t fs)
+ #endif /* CONFIG_MMU */
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size)   (__range_ok(addr, size) == 0)
+ #define user_addr_max() \
+@@ -286,13 +323,17 @@ static inline void set_fs(mm_segment_t fs)
+ #define __get_user(x, ptr)                                            \
+ ({                                                                    \
+       long __gu_err = 0;                                              \
++      pax_open_userland();                                            \
+       __get_user_err((x), (ptr), __gu_err);                           \
++      pax_close_userland();                                           \
+       __gu_err;                                                       \
+ })
+ #define __get_user_error(x, ptr, err)                                 \
+ ({                                                                    \
++      pax_open_userland();                                            \
+       __get_user_err((x), (ptr), err);                                \
++      pax_close_userland();                                           \
+       (void) 0;                                                       \
+ })
+@@ -368,13 +409,17 @@ do {                                                                     \
+ #define __put_user(x, ptr)                                            \
+ ({                                                                    \
+       long __pu_err = 0;                                              \
++      pax_open_userland();                                            \
+       __put_user_err((x), (ptr), __pu_err);                           \
++      pax_close_userland();                                           \
+       __pu_err;                                                       \
+ })
+ #define __put_user_error(x, ptr, err)                                 \
+ ({                                                                    \
++      pax_open_userland();                                            \
+       __put_user_err((x), (ptr), err);                                \
++      pax_close_userland();                                           \
+       (void) 0;                                                       \
+ })
+@@ -474,11 +519,44 @@ do {                                                                     \
+ #ifdef CONFIG_MMU
+-extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+-extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+-extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
+-extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
+-extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
++extern unsigned long __must_check __size_overflow(3) ___copy_from_user(void *to, const void __user *from, unsigned long n);
++extern unsigned long __must_check __size_overflow(3) ___copy_to_user(void __user *to, const void *from, unsigned long n);
++
++static inline unsigned long __must_check __size_overflow(3) __copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++      unsigned long ret;
++
++      check_object_size(to, n, false);
++      pax_open_userland();
++      ret = ___copy_from_user(to, from, n);
++      pax_close_userland();
++      return ret;
++}
++
++static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
++{
++      unsigned long ret;
++
++      check_object_size(from, n, true);
++      pax_open_userland();
++      ret = ___copy_to_user(to, from, n);
++      pax_close_userland();
++      return ret;
++}
++
++extern unsigned long __must_check __size_overflow(3) __copy_to_user_std(void __user *to, const void *from, unsigned long n);
++extern unsigned long __must_check __size_overflow(2) ___clear_user(void __user *addr, unsigned long n);
++extern unsigned long __must_check __size_overflow(2) __clear_user_std(void __user *addr, unsigned long n);
++
++static inline unsigned long __must_check __clear_user(void __user *addr, unsigned long n)
++{
++      unsigned long ret;
++      pax_open_userland();
++      ret = ___clear_user(addr, n);
++      pax_close_userland();
++      return ret;
++}
++
+ #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)
+@@ -487,6 +565,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)
+ {
++      if ((long)n < 0)
++              return n;
++
+       if (access_ok(VERIFY_READ, from, n))
+               n = __copy_from_user(to, from, n);
+       else /* security hole - plug it */
+@@ -496,6 +577,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)
+ {
++      if ((long)n < 0)
++              return n;
++
+       if (access_ok(VERIFY_WRITE, to, n))
+               n = __copy_to_user(to, from, n);
+       return n;
+diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
+index 5af0ed1..cea83883 100644
+--- a/arch/arm/include/uapi/asm/ptrace.h
++++ b/arch/arm/include/uapi/asm/ptrace.h
+@@ -92,7 +92,7 @@
+  * ARMv7 groups of PSR bits
+  */
+ #define APSR_MASK     0xf80f0000      /* N, Z, C, V, Q and GE flags */
+-#define PSR_ISET_MASK 0x01000010      /* ISA state (J, T) mask */
++#define PSR_ISET_MASK 0x01000020      /* ISA state (J, T) mask */
+ #define PSR_IT_MASK   0x0600fc00      /* If-Then execution state mask */
+ #define PSR_ENDIAN_MASK       0x00000200      /* Endianness state mask */
+diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
+index 5e5a51a..b21eeef 100644
+--- a/arch/arm/kernel/armksyms.c
++++ b/arch/arm/kernel/armksyms.c
+@@ -58,7 +58,7 @@ EXPORT_SYMBOL(arm_delay_ops);
+       /* networking */
+ EXPORT_SYMBOL(csum_partial);
+-EXPORT_SYMBOL(csum_partial_copy_from_user);
++EXPORT_SYMBOL(__csum_partial_copy_from_user);
+ EXPORT_SYMBOL(csum_partial_copy_nocheck);
+ EXPORT_SYMBOL(__csum_ipv6_magic);
+@@ -97,9 +97,9 @@ EXPORT_SYMBOL(mmiocpy);
+ #ifdef CONFIG_MMU
+ EXPORT_SYMBOL(copy_page);
+-EXPORT_SYMBOL(__copy_from_user);
+-EXPORT_SYMBOL(__copy_to_user);
+-EXPORT_SYMBOL(__clear_user);
++EXPORT_SYMBOL(___copy_from_user);
++EXPORT_SYMBOL(___copy_to_user);
++EXPORT_SYMBOL(___clear_user);
+ EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
+diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
+index 318da33..373689f 100644
+--- a/arch/arm/kernel/cpuidle.c
++++ b/arch/arm/kernel/cpuidle.c
+@@ -19,7 +19,7 @@ extern struct of_cpuidle_method __cpuidle_method_of_table[];
+ static const struct of_cpuidle_method __cpuidle_method_of_table_sentinel
+       __used __section(__cpuidle_method_of_table_end);
+-static struct cpuidle_ops cpuidle_ops[NR_CPUS];
++static struct cpuidle_ops cpuidle_ops[NR_CPUS] __read_only;
+ /**
+  * arm_cpuidle_simple_enter() - a wrapper to cpu_do_idle()
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+index cb4fb1e..dc7fcaf 100644
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -50,6 +50,87 @@
+ 9997:
+       .endm
++      .macro  pax_enter_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      @ make aligned space for saved DACR
++      sub     sp, sp, #8
++      @ save regs
++      stmdb   sp!, {r1, r2}
++      @ read DACR from cpu_domain into r1
++      mov     r2, sp
++      @ assume 8K pages, since we have to split the immediate in two
++      bic     r2, r2, #(0x1fc0)
++      bic     r2, r2, #(0x3f)
++      ldr     r1, [r2, #TI_CPU_DOMAIN]
++      @ store old DACR on stack
++      str     r1, [sp, #8]
++#ifdef CONFIG_PAX_KERNEXEC
++      @ set type of DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++      bic     r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++      orr     r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      @ set current DOMAIN_USER to DOMAIN_NOACCESS
++      bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++#endif
++      @ write r1 to current_thread_info()->cpu_domain
++      str     r1, [r2, #TI_CPU_DOMAIN]
++      @ write r1 to DACR
++      mcr     p15, 0, r1, c3, c0, 0
++      @ instruction sync
++      instr_sync
++      @ restore regs
++      ldmia   sp!, {r1, r2}
++#endif
++      .endm
++
++      .macro  pax_open_userland
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      @ save regs
++      stmdb   sp!, {r0, r1}
++      @ read DACR from cpu_domain into r1
++      mov     r0, sp
++      @ assume 8K pages, since we have to split the immediate in two
++      bic     r0, r0, #(0x1fc0)
++      bic     r0, r0, #(0x3f)
++      ldr     r1, [r0, #TI_CPU_DOMAIN]
++      @ set current DOMAIN_USER to DOMAIN_CLIENT
++      bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++      orr     r1, r1, #(domain_val(DOMAIN_USER, DOMAIN_UDEREF))
++      @ write r1 to current_thread_info()->cpu_domain
++      str     r1, [r0, #TI_CPU_DOMAIN]
++      @ write r1 to DACR
++      mcr     p15, 0, r1, c3, c0, 0
++      @ instruction sync
++      instr_sync
++      @ restore regs
++      ldmia   sp!, {r0, r1}
++#endif
++      .endm
++
++      .macro  pax_close_userland
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      @ save regs
++      stmdb   sp!, {r0, r1}
++      @ read DACR from cpu_domain into r1
++      mov     r0, sp
++      @ assume 8K pages, since we have to split the immediate in two
++      bic     r0, r0, #(0x1fc0)
++      bic     r0, r0, #(0x3f)
++      ldr     r1, [r0, #TI_CPU_DOMAIN]
++      @ set current DOMAIN_USER to DOMAIN_NOACCESS
++      bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++      @ write r1 to current_thread_info()->cpu_domain
++      str     r1, [r0, #TI_CPU_DOMAIN]
++      @ write r1 to DACR
++      mcr     p15, 0, r1, c3, c0, 0
++      @ instruction sync
++      instr_sync
++      @ restore regs
++      ldmia   sp!, {r0, r1}
++#endif
++      .endm
++
+       .macro  pabt_helper
+       @ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
+ #ifdef MULTI_PABORT
+@@ -92,11 +173,15 @@
+  * Invalid mode handlers
+  */
+       .macro  inv_entry, reason
++
++      pax_enter_kernel
++
+       sub     sp, sp, #S_FRAME_SIZE
+  ARM( stmib   sp, {r1 - lr}           )
+  THUMB(       stmia   sp, {r0 - r12}          )
+  THUMB(       str     sp, [sp, #S_SP]         )
+  THUMB(       str     lr, [sp, #S_LR]         )
++
+       mov     r1, #\reason
+       .endm
+@@ -152,7 +237,11 @@ ENDPROC(__und_invalid)
+       .macro  svc_entry, stack_hole=0, trace=1
+  UNWIND(.fnstart              )
+  UNWIND(.save {r0 - pc}               )
++
++      pax_enter_kernel
++
+       sub     sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++
+ #ifdef CONFIG_THUMB2_KERNEL
+  SPFIX(       str     r0, [sp]        )       @ temporarily saved
+  SPFIX(       mov     r0, sp          )
+@@ -167,7 +256,12 @@ ENDPROC(__und_invalid)
+       ldmia   r0, {r3 - r5}
+       add     r7, sp, #S_SP - 4       @ here for interlock avoidance
+       mov     r6, #-1                 @  ""  ""      ""       ""
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      @ offset sp by 8 as done in pax_enter_kernel
++      add     r2, sp, #(S_FRAME_SIZE + \stack_hole + 4)
++#else
+       add     r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++#endif
+  SPFIX(       addeq   r2, r2, #4      )
+       str     r3, [sp, #-4]!          @ save the "real" r0 copied
+                                       @ from the exception stack
+@@ -371,6 +465,9 @@ ENDPROC(__fiq_abt)
+       .macro  usr_entry, trace=1
+  UNWIND(.fnstart      )
+  UNWIND(.cantunwind   )       @ don't unwind the user space
++
++      pax_enter_kernel_user
++
+       sub     sp, sp, #S_FRAME_SIZE
+  ARM( stmib   sp, {r1 - r12}  )
+  THUMB(       stmia   sp, {r0 - r12}  )
+@@ -481,7 +578,9 @@ __und_usr:
+       tst     r3, #PSR_T_BIT                  @ Thumb mode?
+       bne     __und_usr_thumb
+       sub     r4, r2, #4                      @ ARM instr at LR - 4
++      pax_open_userland
+ 1:    ldrt    r0, [r4]
++      pax_close_userland
+  ARM_BE8(rev  r0, r0)                         @ little endian instruction
+       @ r0 = 32-bit ARM instruction which caused the exception
+@@ -515,11 +614,15 @@ __und_usr_thumb:
+  */
+       .arch   armv6t2
+ #endif
++      pax_open_userland
+ 2:    ldrht   r5, [r4]
++      pax_close_userland
+ ARM_BE8(rev16 r5, r5)                         @ little endian instruction
+       cmp     r5, #0xe800                     @ 32bit instruction if xx != 0
+       blo     __und_usr_fault_16              @ 16bit undefined instruction
++      pax_open_userland
+ 3:    ldrht   r0, [r2]
++      pax_close_userland
+ ARM_BE8(rev16 r0, r0)                         @ little endian instruction
+       add     r2, r2, #2                      @ r2 is PC + 2, make it PC + 4
+       str     r2, [sp, #S_PC]                 @ it's a 2x16bit instr, update
+@@ -549,7 +652,8 @@ ENDPROC(__und_usr)
+  */
+       .pushsection .text.fixup, "ax"
+       .align  2
+-4:    str     r4, [sp, #S_PC]                 @ retry current instruction
++4:    pax_close_userland
++      str     r4, [sp, #S_PC]                 @ retry current instruction
+       ret     r9
+       .popsection
+       .pushsection __ex_table,"a"
+@@ -769,7 +873,7 @@ ENTRY(__switch_to)
+  THUMB(       str     lr, [ip], #4               )
+       ldr     r4, [r2, #TI_TP_VALUE]
+       ldr     r5, [r2, #TI_TP_VALUE + 4]
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+       ldr     r6, [r2, #TI_CPU_DOMAIN]
+ #endif
+       switch_tls r1, r4, r5, r3, r7
+@@ -778,7 +882,7 @@ ENTRY(__switch_to)
+       ldr     r8, =__stack_chk_guard
+       ldr     r7, [r7, #TSK_STACK_CANARY]
+ #endif
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+       mcr     p15, 0, r6, c3, c0, 0           @ Set domain register
+ #endif
+       mov     r5, r0
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index b48dd4f..9f9a72f 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -11,18 +11,46 @@
+ #include <asm/assembler.h>
+ #include <asm/unistd.h>
+ #include <asm/ftrace.h>
++#include <asm/domain.h>
+ #include <asm/unwind.h>
++#include "entry-header.S"
++
+ #ifdef CONFIG_NEED_RET_TO_USER
+ #include <mach/entry-macro.S>
+ #else
+       .macro  arch_ret_to_user, tmp1, tmp2
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      @ save regs
++      stmdb   sp!, {r1, r2}
++        @ read DACR from cpu_domain into r1
++        mov     r2, sp
++        @ assume 8K pages, since we have to split the immediate in two
++        bic     r2, r2, #(0x1fc0)
++        bic     r2, r2, #(0x3f)
++        ldr     r1, [r2, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_KERNEXEC
++        @ set type of DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++        bic     r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++        orr     r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++        @ set current DOMAIN_USER to DOMAIN_UDEREF
++        bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++        orr     r1, r1, #(domain_val(DOMAIN_USER, DOMAIN_UDEREF))
++#endif
++        @ write r1 to current_thread_info()->cpu_domain
++        str     r1, [r2, #TI_CPU_DOMAIN]
++        @ write r1 to DACR
++        mcr     p15, 0, r1, c3, c0, 0
++        @ instruction sync
++        instr_sync
++      @ restore regs
++      ldmia   sp!, {r1, r2}
++#endif
+       .endm
+ #endif
+-#include "entry-header.S"
+-
+-
+       .align  5
+ /*
+  * This is the fast syscall return path.  We do as little as
+@@ -174,6 +202,12 @@ ENTRY(vector_swi)
+  USER(        ldr     scno, [lr, #-4]         )       @ get SWI instruction
+ #endif
++      /*
++       * do this here to avoid a performance hit of wrapping the code above
++       * that directly dereferences userland to parse the SWI instruction
++       */
++      pax_enter_kernel_user
++
+       adr     tbl, sys_call_table             @ load syscall table pointer
+ #if defined(CONFIG_OABI_COMPAT)
+diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
+index 1a0045a..9b4f34d 100644
+--- a/arch/arm/kernel/entry-header.S
++++ b/arch/arm/kernel/entry-header.S
+@@ -196,6 +196,60 @@
+       msr     cpsr_c, \rtemp                  @ switch back to the SVC mode
+       .endm
++      .macro  pax_enter_kernel_user
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      @ save regs
++      stmdb   sp!, {r0, r1}
++      @ read DACR from cpu_domain into r1
++      mov     r0, sp
++      @ assume 8K pages, since we have to split the immediate in two
++      bic     r0, r0, #(0x1fc0)
++      bic     r0, r0, #(0x3f)
++      ldr     r1, [r0, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      @ set current DOMAIN_USER to DOMAIN_NOACCESS
++      bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++#endif
++#ifdef CONFIG_PAX_KERNEXEC
++      @ set current DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++      bic     r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++      orr     r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++      @ write r1 to current_thread_info()->cpu_domain
++      str     r1, [r0, #TI_CPU_DOMAIN]
++      @ write r1 to DACR
++      mcr     p15, 0, r1, c3, c0, 0
++      @ instruction sync
++      instr_sync
++      @ restore regs
++      ldmia   sp!, {r0, r1}
++#endif
++      .endm
++
++      .macro  pax_exit_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      @ save regs
++      stmdb   sp!, {r0, r1}
++      @ read old DACR from stack into r1
++      ldr     r1, [sp, #(8 + S_SP)]
++      sub     r1, r1, #8
++      ldr     r1, [r1]
++
++      @ write r1 to current_thread_info()->cpu_domain
++      mov     r0, sp
++      @ assume 8K pages, since we have to split the immediate in two
++      bic     r0, r0, #(0x1fc0)
++      bic     r0, r0, #(0x3f)
++      str     r1, [r0, #TI_CPU_DOMAIN]
++      @ write r1 to DACR
++      mcr     p15, 0, r1, c3, c0, 0
++      @ instruction sync
++      instr_sync
++      @ restore regs
++      ldmia   sp!, {r0, r1}
++#endif
++      .endm
++
+ #ifndef CONFIG_THUMB2_KERNEL
+       .macro  svc_exit, rpsr, irq = 0
+       .if     \irq != 0
+@@ -215,6 +269,9 @@
+       blne    trace_hardirqs_off
+ #endif
+       .endif
++
++      pax_exit_kernel
++
+       msr     spsr_cxsf, \rpsr
+ #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
+       @ We must avoid clrex due to Cortex-A15 erratum #830321
+@@ -291,6 +348,9 @@
+       blne    trace_hardirqs_off
+ #endif
+       .endif
++
++      pax_exit_kernel
++
+       ldr     lr, [sp, #S_SP]                 @ top of the stack
+       ldrd    r0, r1, [sp, #S_LR]             @ calling lr and pc
+diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
+index 059c3da..8e45cfc 100644
+--- a/arch/arm/kernel/fiq.c
++++ b/arch/arm/kernel/fiq.c
+@@ -95,7 +95,10 @@ void set_fiq_handler(void *start, unsigned int length)
+       void *base = vectors_page;
+       unsigned offset = FIQ_OFFSET;
++      pax_open_kernel();
+       memcpy(base + offset, start, length);
++      pax_close_kernel();
++
+       if (!cache_is_vipt_nonaliasing())
+               flush_icache_range((unsigned long)base + offset, offset +
+                                  length);
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 29e2991..7bc5757 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -467,7 +467,7 @@ __enable_mmu:
+       mov     r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+                     domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+                     domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+-                    domain_val(DOMAIN_IO, DOMAIN_CLIENT))
++                    domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT))
+       mcr     p15, 0, r5, c3, c0, 0           @ load domain access register
+       mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
+ #endif
+diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
+index 097e2e2..3927085 100644
+--- a/arch/arm/kernel/module-plts.c
++++ b/arch/arm/kernel/module-plts.c
+@@ -30,17 +30,12 @@ struct plt_entries {
+       u32     lit[PLT_ENT_COUNT];
+ };
+-static bool in_init(const struct module *mod, u32 addr)
+-{
+-      return addr - (u32)mod->module_init < mod->init_size;
+-}
+-
+ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
+ {
+       struct plt_entries *plt, *plt_end;
+       int c, *count;
+-      if (in_init(mod, loc)) {
++      if (within_module_init(loc, mod)) {
+               plt = (void *)mod->arch.init_plt->sh_addr;
+               plt_end = (void *)plt + mod->arch.init_plt->sh_size;
+               count = &mod->arch.init_plt_count;
+diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
+index efdddcb..35e58f6 100644
+--- a/arch/arm/kernel/module.c
++++ b/arch/arm/kernel/module.c
+@@ -38,17 +38,47 @@
+ #endif
+ #ifdef CONFIG_MMU
+-void *module_alloc(unsigned long size)
++static inline void *__module_alloc(unsigned long size, pgprot_t prot)
+ {
+-      void *p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+-                              GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
++      void *p;
++
++      if (!size || (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && PAGE_ALIGN(size) > MODULES_END - MODULES_VADDR))
++              return NULL;
++
++      p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
++                              GFP_KERNEL, prot, 0, NUMA_NO_NODE,
+                               __builtin_return_address(0));
+       if (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p)
+               return p;
+       return __vmalloc_node_range(size, 1,  VMALLOC_START, VMALLOC_END,
+-                              GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
++                              GFP_KERNEL, prot, 0, NUMA_NO_NODE,
+                               __builtin_return_address(0));
+ }
++
++void *module_alloc(unsigned long size)
++{
++
++#ifdef CONFIG_PAX_KERNEXEC
++      return __module_alloc(size, PAGE_KERNEL);
++#else
++      return __module_alloc(size, PAGE_KERNEL_EXEC);
++#endif
++
++}
++
++#ifdef CONFIG_PAX_KERNEXEC
++void module_memfree_exec(void *module_region)
++{
++      module_memfree(module_region);
++}
++EXPORT_SYMBOL(module_memfree_exec);
++
++void *module_alloc_exec(unsigned long size)
++{
++      return __module_alloc(size, PAGE_KERNEL_EXEC);
++}
++EXPORT_SYMBOL(module_alloc_exec);
++#endif
+ #endif
+ int
+diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
+index 69bda1a..755113a 100644
+--- a/arch/arm/kernel/patch.c
++++ b/arch/arm/kernel/patch.c
+@@ -66,6 +66,7 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
+       else
+               __acquire(&patch_lock);
++      pax_open_kernel();
+       if (thumb2 && __opcode_is_thumb16(insn)) {
+               *(u16 *)waddr = __opcode_to_mem_thumb16(insn);
+               size = sizeof(u16);
+@@ -97,6 +98,7 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
+               *(u32 *)waddr = insn;
+               size = sizeof(u32);
+       }
++      pax_close_kernel();
+       if (waddr != addr) {
+               flush_kernel_vmap_range(waddr, twopage ? size / 2 : size);
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index f192a2a..1a40523 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -105,8 +105,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", (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,
+@@ -283,12 +283,6 @@ unsigned long get_wchan(struct task_struct *p)
+       return 0;
+ }
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-      unsigned long range_end = mm->brk + 0x02000000;
+-      return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+-}
+-
+ #ifdef CONFIG_MMU
+ #ifdef CONFIG_KUSER_HELPERS
+ /*
+@@ -304,7 +298,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);
+       return 0;
+ }
+ arch_initcall(gate_vma_init);
+@@ -333,91 +327,13 @@ const char *arch_vma_name(struct vm_area_struct *vma)
+       return is_gate_vma(vma) ? "[vectors]" : NULL;
+ }
+-/* If possible, provide a placement hint at a random offset from the
+- * stack for the sigpage and vdso pages.
+- */
+-static unsigned long sigpage_addr(const struct mm_struct *mm,
+-                                unsigned int npages)
+-{
+-      unsigned long offset;
+-      unsigned long first;
+-      unsigned long last;
+-      unsigned long addr;
+-      unsigned int slots;
+-
+-      first = PAGE_ALIGN(mm->start_stack);
+-
+-      last = TASK_SIZE - (npages << PAGE_SHIFT);
+-
+-      /* No room after stack? */
+-      if (first > last)
+-              return 0;
+-
+-      /* Just enough room? */
+-      if (first == last)
+-              return first;
+-
+-      slots = ((last - first) >> PAGE_SHIFT) + 1;
+-
+-      offset = get_random_int() % slots;
+-
+-      addr = first + (offset << PAGE_SHIFT);
+-
+-      return addr;
+-}
+-
+-static struct page *signal_page;
+-extern struct page *get_signal_page(void);
+-
+-static const struct vm_special_mapping sigpage_mapping = {
+-      .name = "[sigpage]",
+-      .pages = &signal_page,
+-};
+-
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+       struct mm_struct *mm = current->mm;
+-      struct vm_area_struct *vma;
+-      unsigned long npages;
+-      unsigned long addr;
+-      unsigned long hint;
+-      int ret = 0;
+-
+-      if (!signal_page)
+-              signal_page = get_signal_page();
+-      if (!signal_page)
+-              return -ENOMEM;
+-
+-      npages = 1; /* for sigpage */
+-      npages += vdso_total_pages;
+       down_write(&mm->mmap_sem);
+-      hint = sigpage_addr(mm, npages);
+-      addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0);
+-      if (IS_ERR_VALUE(addr)) {
+-              ret = addr;
+-              goto up_fail;
+-      }
+-
+-      vma = _install_special_mapping(mm, addr, PAGE_SIZE,
+-              VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+-              &sigpage_mapping);
+-
+-      if (IS_ERR(vma)) {
+-              ret = PTR_ERR(vma);
+-              goto up_fail;
+-      }
+-
+-      mm->context.sigpage = addr;
+-
+-      /* Unlike the sigpage, failure to install the vdso is unlikely
+-       * to be fatal to the process, so no error check needed
+-       * here.
+-       */
+-      arm_install_vdso(mm, addr + PAGE_SIZE);
+-
+- 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 f90fdf4..24e8c84 100644
+--- a/arch/arm/kernel/psci.c
++++ b/arch/arm/kernel/psci.c
+@@ -26,7 +26,7 @@
+ #include <asm/psci.h>
+ #include <asm/system_misc.h>
+-struct psci_operations psci_ops;
++struct psci_operations psci_ops __read_only;
+ static int (*invoke_psci_fn)(u32, u32, u32, u32);
+ typedef int (*psci_initcall_t)(const struct device_node *);
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index ef9119f..31995a3 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -928,10 +928,19 @@ static void tracehook_report_syscall(struct pt_regs *regs,
+       regs->ARM_ip = ip;
+ }
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
+ {
+       current_thread_info()->syscall = scno;
++#ifdef CONFIG_GRKERNSEC_SETXID
++      if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++              gr_delayed_cred_worker();
++#endif
++
+       /* Do the secure computing check first; failures should be fast. */
+ #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
+       if (secure_computing() == -1)
+diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
+index 3826935..8ed63ed 100644
+--- a/arch/arm/kernel/reboot.c
++++ b/arch/arm/kernel/reboot.c
+@@ -122,6 +122,7 @@ void machine_power_off(void)
+       if (pm_power_off)
+               pm_power_off();
++      while (1);
+ }
+ /*
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index 36c18b7..0d78292 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -108,21 +108,23 @@ EXPORT_SYMBOL(elf_hwcap);
+ unsigned int elf_hwcap2 __read_mostly;
+ EXPORT_SYMBOL(elf_hwcap2);
++pteval_t __supported_pte_mask __read_only;
++pmdval_t __supported_pmd_mask __read_only;
+ #ifdef MULTI_CPU
+-struct processor processor __read_mostly;
++struct processor processor __read_only;
+ #endif
+ #ifdef MULTI_TLB
+-struct cpu_tlb_fns cpu_tlb __read_mostly;
++struct cpu_tlb_fns cpu_tlb __read_only;
+ #endif
+ #ifdef MULTI_USER
+-struct cpu_user_fns cpu_user __read_mostly;
++struct cpu_user_fns cpu_user __read_only;
+ #endif
+ #ifdef MULTI_CACHE
+-struct cpu_cache_fns cpu_cache __read_mostly;
++struct cpu_cache_fns cpu_cache __read_only;
+ #endif
+ #ifdef CONFIG_OUTER_CACHE
+-struct outer_cache_fns outer_cache __read_mostly;
++struct outer_cache_fns outer_cache __read_only;
+ EXPORT_SYMBOL(outer_cache);
+ #endif
+@@ -253,9 +255,13 @@ static int __get_cpu_architecture(void)
+                * Register 0 and check for VMSAv7 or PMSAv7 */
+               unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0);
+               if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
+-                  (mmfr0 & 0x000000f0) >= 0x00000030)
++                  (mmfr0 & 0x000000f0) >= 0x00000030) {
+                       cpu_arch = CPU_ARCH_ARMv7;
+-              else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
++                      if ((mmfr0 & 0x0000000f) == 0x00000005 || (mmfr0 & 0x0000000f) == 0x00000004) {
++                              __supported_pte_mask |= L_PTE_PXN;
++                              __supported_pmd_mask |= PMD_PXNTABLE;
++                      }
++              } else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
+                        (mmfr0 & 0x000000f0) == 0x00000020)
+                       cpu_arch = CPU_ARCH_ARMv6;
+               else
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+index 586eef2..61aabd4 100644
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -24,8 +24,6 @@
+ extern const unsigned long sigreturn_codes[7];
+-static unsigned long signal_return_offset;
+-
+ #ifdef CONFIG_CRUNCH
+ static int preserve_crunch_context(struct crunch_sigframe __user *frame)
+ {
+@@ -390,8 +388,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
+               {
+@@ -597,33 +594,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 3d6b782..8b3baeb 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -76,7 +76,7 @@ enum ipi_msg_type {
+ static DECLARE_COMPLETION(cpu_running);
+-static struct smp_operations smp_ops;
++static struct smp_operations smp_ops __read_only;
+ void __init smp_set_ops(struct smp_operations *ops)
+ {
+diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
+index b10e136..cb5edf9 100644
+--- a/arch/arm/kernel/tcm.c
++++ b/arch/arm/kernel/tcm.c
+@@ -64,7 +64,7 @@ static struct map_desc itcm_iomap[] __initdata = {
+               .virtual        = ITCM_OFFSET,
+               .pfn            = __phys_to_pfn(ITCM_OFFSET),
+               .length         = 0,
+-              .type           = MT_MEMORY_RWX_ITCM,
++              .type           = MT_MEMORY_RX_ITCM,
+       }
+ };
+@@ -362,7 +362,9 @@ no_dtcm:
+               start = &__sitcm_text;
+               end   = &__eitcm_text;
+               ram   = &__itcm_start;
++              pax_open_kernel();
+               memcpy(start, ram, itcm_code_sz);
++              pax_close_kernel();
+               pr_debug("CPU ITCM: copied code from %p - %p\n",
+                        start, end);
+               itcm_present = true;
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index d358226..bfd4019 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -65,7 +65,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
+-      printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
++      printk("[<%08lx>] (%pA) from [<%08lx>] (%pA)\n", where, (void *)where, from, (void *)from);
+ #else
+       printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+ #endif
+@@ -267,6 +267,8 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+ static int die_owner = -1;
+ static unsigned int die_nest_count;
++extern void gr_handle_kernel_exploit(void);
++
+ static unsigned long oops_begin(void)
+ {
+       int cpu;
+@@ -309,6 +311,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");
++
++      gr_handle_kernel_exploit();
++
+       if (signr)
+               do_exit(signr);
+ }
+@@ -870,7 +875,11 @@ void __init early_trap_init(void *vectors_base)
+       kuser_init(vectors_base);
+       flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+-      modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
++
++#ifndef CONFIG_PAX_MEMORY_UDEREF
++      modify_domain(DOMAIN_USER, DOMAIN_USERCLIENT);
++#endif
++
+ #else /* ifndef CONFIG_CPU_V7M */
+       /*
+        * on V7-M there is no need to copy the vector table to a dedicated
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index 8b60fde..8d986dd 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -37,7 +37,7 @@
+ #endif
+ #if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
+-      defined(CONFIG_GENERIC_BUG)
++      defined(CONFIG_GENERIC_BUG) || defined(CONFIG_PAX_REFCOUNT)
+ #define ARM_EXIT_KEEP(x)      x
+ #define ARM_EXIT_DISCARD(x)
+ #else
+@@ -120,6 +120,8 @@ SECTIONS
+ #ifdef CONFIG_DEBUG_RODATA
+       . = ALIGN(1<<SECTION_SHIFT);
+ #endif
++      _etext = .;                     /* End of text section */
++
+       RO_DATA(PAGE_SIZE)
+       . = ALIGN(4);
+@@ -150,8 +152,6 @@ SECTIONS
+       NOTES
+-      _etext = .;                     /* End of text and rodata section */
+-
+ #ifndef CONFIG_XIP_KERNEL
+ # ifdef CONFIG_ARM_KERNMEM_PERMS
+       . = ALIGN(1<<SECTION_SHIFT);
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index f9c341c..7430436 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -57,7 +57,7 @@ static unsigned long hyp_default_vectors;
+ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
+ /* The VMID used in the VTTBR */
+-static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
++static atomic64_unchecked_t kvm_vmid_gen = ATOMIC64_INIT(1);
+ static u8 kvm_next_vmid;
+ static DEFINE_SPINLOCK(kvm_vmid_lock);
+@@ -372,7 +372,7 @@ void force_vm_exit(const cpumask_t *mask)
+  */
+ static bool need_new_vmid_gen(struct kvm *kvm)
+ {
+-      return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen));
++      return unlikely(kvm->arch.vmid_gen != atomic64_read_unchecked(&kvm_vmid_gen));
+ }
+ /**
+@@ -405,7 +405,7 @@ static void update_vttbr(struct kvm *kvm)
+       /* First user of a new VMID generation? */
+       if (unlikely(kvm_next_vmid == 0)) {
+-              atomic64_inc(&kvm_vmid_gen);
++              atomic64_inc_unchecked(&kvm_vmid_gen);
+               kvm_next_vmid = 1;
+               /*
+@@ -422,7 +422,7 @@ static void update_vttbr(struct kvm *kvm)
+               kvm_call_hyp(__kvm_flush_vm_context);
+       }
+-      kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
++      kvm->arch.vmid_gen = atomic64_read_unchecked(&kvm_vmid_gen);
+       kvm->arch.vmid = kvm_next_vmid;
+       kvm_next_vmid++;
+@@ -1110,7 +1110,7 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
+ /**
+  * Initialize Hyp-mode and memory mappings on all CPUs.
+  */
+-int kvm_arch_init(void *opaque)
++int kvm_arch_init(const void *opaque)
+ {
+       int err;
+       int ret, cpu;
+diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
+index 1710fd7..ec3e014 100644
+--- a/arch/arm/lib/clear_user.S
++++ b/arch/arm/lib/clear_user.S
+@@ -12,14 +12,14 @@
+               .text
+-/* Prototype: int __clear_user(void *addr, size_t sz)
++/* Prototype: int ___clear_user(void *addr, size_t sz)
+  * Purpose  : clear some user memory
+  * Params   : addr - user memory address to clear
+  *          : sz   - number of bytes to clear
+  * Returns  : number of bytes NOT cleared
+  */
+ ENTRY(__clear_user_std)
+-WEAK(__clear_user)
++WEAK(___clear_user)
+               stmfd   sp!, {r1, lr}
+               mov     r2, #0
+               cmp     r1, #4
+@@ -44,7 +44,7 @@ WEAK(__clear_user)
+ USER(         strnebt r2, [r0])
+               mov     r0, #0
+               ldmfd   sp!, {r1, pc}
+-ENDPROC(__clear_user)
++ENDPROC(___clear_user)
+ ENDPROC(__clear_user_std)
+               .pushsection .text.fixup,"ax"
+diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
+index 7a235b9..73a0556 100644
+--- a/arch/arm/lib/copy_from_user.S
++++ b/arch/arm/lib/copy_from_user.S
+@@ -17,7 +17,7 @@
+ /*
+  * Prototype:
+  *
+- *    size_t __copy_from_user(void *to, const void *from, size_t n)
++ *    size_t ___copy_from_user(void *to, const void *from, size_t n)
+  *
+  * Purpose:
+  *
+@@ -89,11 +89,11 @@
+       .text
+-ENTRY(__copy_from_user)
++ENTRY(___copy_from_user)
+ #include "copy_template.S"
+-ENDPROC(__copy_from_user)
++ENDPROC(___copy_from_user)
+       .pushsection .fixup,"ax"
+       .align 0
+diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
+index 6ee2f67..d1cce76 100644
+--- a/arch/arm/lib/copy_page.S
++++ b/arch/arm/lib/copy_page.S
+@@ -10,6 +10,7 @@
+  *  ASM optimised string functions
+  */
+ #include <linux/linkage.h>
++#include <linux/const.h>
+ #include <asm/assembler.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
+diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
+index 9648b06..19c333c 100644
+--- a/arch/arm/lib/copy_to_user.S
++++ b/arch/arm/lib/copy_to_user.S
+@@ -17,7 +17,7 @@
+ /*
+  * Prototype:
+  *
+- *    size_t __copy_to_user(void *to, const void *from, size_t n)
++ *    size_t ___copy_to_user(void *to, const void *from, size_t n)
+  *
+  * Purpose:
+  *
+@@ -93,11 +93,11 @@
+       .text
+ ENTRY(__copy_to_user_std)
+-WEAK(__copy_to_user)
++WEAK(___copy_to_user)
+ #include "copy_template.S"
+-ENDPROC(__copy_to_user)
++ENDPROC(___copy_to_user)
+ ENDPROC(__copy_to_user_std)
+       .pushsection .text.fixup,"ax"
+diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
+index 1d0957e..f708846 100644
+--- a/arch/arm/lib/csumpartialcopyuser.S
++++ b/arch/arm/lib/csumpartialcopyuser.S
+@@ -57,8 +57,8 @@
+  *  Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+  */
+-#define FN_ENTRY      ENTRY(csum_partial_copy_from_user)
+-#define FN_EXIT               ENDPROC(csum_partial_copy_from_user)
++#define FN_ENTRY      ENTRY(__csum_partial_copy_from_user)
++#define FN_EXIT               ENDPROC(__csum_partial_copy_from_user)
+ #include "csumpartialcopygeneric.S"
+diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
+index 8044591..c9b2609 100644
+--- a/arch/arm/lib/delay.c
++++ b/arch/arm/lib/delay.c
+@@ -29,7 +29,7 @@
+ /*
+  * Default to the loop-based delay implementation.
+  */
+-struct arm_delay_ops arm_delay_ops = {
++struct arm_delay_ops arm_delay_ops __read_only = {
+       .delay          = __loop_delay,
+       .const_udelay   = __loop_const_udelay,
+       .udelay         = __loop_udelay,
+diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
+index 4b39af2..9ae747d 100644
+--- a/arch/arm/lib/uaccess_with_memcpy.c
++++ b/arch/arm/lib/uaccess_with_memcpy.c
+@@ -85,7 +85,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
+       return 1;
+ }
+-static unsigned long noinline
++static unsigned long noinline __size_overflow(3)
+ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
+ {
+       int atomic;
+@@ -136,7 +136,7 @@ out:
+ }
+ unsigned long
+-__copy_to_user(void __user *to, const void *from, unsigned long n)
++___copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+       /*
+        * This test is stubbed out of the main function above to keep
+@@ -150,7 +150,7 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
+       return __copy_to_user_memcpy(to, from, n);
+ }
+       
+-static unsigned long noinline
++static unsigned long noinline __size_overflow(2)
+ __clear_user_memset(void __user *addr, unsigned long n)
+ {
+       if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+@@ -190,7 +190,7 @@ out:
+       return n;
+ }
+-unsigned long __clear_user(void __user *addr, unsigned long n)
++unsigned long ___clear_user(void __user *addr, unsigned long n)
+ {
+       /* See rational for this in __copy_to_user() above. */
+       if (n < 64)
+diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
+index f572219..2cf36d5 100644
+--- a/arch/arm/mach-exynos/suspend.c
++++ b/arch/arm/mach-exynos/suspend.c
+@@ -732,8 +732,10 @@ void __init exynos_pm_init(void)
+       tmp |= pm_data->wake_disable_mask;
+       pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
+-      exynos_pm_syscore_ops.suspend   = pm_data->pm_suspend;
+-      exynos_pm_syscore_ops.resume    = pm_data->pm_resume;
++      pax_open_kernel();
++      *(void **)&exynos_pm_syscore_ops.suspend        = pm_data->pm_suspend;
++      *(void **)&exynos_pm_syscore_ops.resume = pm_data->pm_resume;
++      pax_close_kernel();
+       register_syscore_ops(&exynos_pm_syscore_ops);
+       suspend_set_ops(&exynos_suspend_ops);
+diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
+index e46e9ea..9141c83 100644
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -117,7 +117,7 @@ static void __init armada_370_coherency_init(struct device_node *np)
+ /*
+  * This ioremap hook is used on Armada 375/38x to ensure that PCIe
+- * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
++ * memory areas are mapped as MT_UNCACHED_RW instead of MT_DEVICE. This
+  * is needed as a workaround for a deadlock issue between the PCIe
+  * interface and the cache controller.
+  */
+@@ -130,7 +130,7 @@ armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+       mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
+       if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
+-              mtype = MT_UNCACHED;
++              mtype = MT_UNCACHED_RW;
+       return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index b6443a4..20a0b74 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -569,7 +569,7 @@ static int n8x0_menelaus_late_init(struct device *dev)
+ }
+ #endif
+-struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
++struct menelaus_platform_data n8x0_menelaus_platform_data __initconst = {
+       .late_init = n8x0_menelaus_late_init,
+ };
+diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+index 79f49d9..70bf184 100644
+--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
++++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+@@ -86,7 +86,7 @@ struct cpu_pm_ops {
+       void (*resume)(void);
+       void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+       void (*hotplug_restart)(void);
+-};
++} __no_const;
+ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+ static struct powerdomain *mpuss_pd;
+@@ -105,7 +105,7 @@ static void dummy_cpu_resume(void)
+ static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+ {}
+-struct cpu_pm_ops omap_pm_ops = {
++static struct cpu_pm_ops omap_pm_ops __read_only = {
+       .finish_suspend         = default_finish_suspend,
+       .resume                 = dummy_cpu_resume,
+       .scu_prepare            = dummy_scu_prepare,
+diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
+index 5305ec7..6d74045 100644
+--- a/arch/arm/mach-omap2/omap-smp.c
++++ b/arch/arm/mach-omap2/omap-smp.c
+@@ -19,6 +19,7 @@
+ #include <linux/device.h>
+ #include <linux/smp.h>
+ #include <linux/io.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include <asm/smp_scu.h>
+diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
+index e1d2e99..d9b3177 100644
+--- a/arch/arm/mach-omap2/omap-wakeupgen.c
++++ b/arch/arm/mach-omap2/omap-wakeupgen.c
+@@ -330,7 +330,7 @@ static int irq_cpu_hotplug_notify(struct notifier_block *self,
+       return NOTIFY_OK;
+ }
+-static struct notifier_block __refdata irq_hotplug_notifier = {
++static struct notifier_block irq_hotplug_notifier = {
+       .notifier_call = irq_cpu_hotplug_notify,
+ };
+diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
+index 4cb8fd9..5ce65bc 100644
+--- a/arch/arm/mach-omap2/omap_device.c
++++ b/arch/arm/mach-omap2/omap_device.c
+@@ -504,7 +504,7 @@ void omap_device_delete(struct omap_device *od)
+ struct platform_device __init *omap_device_build(const char *pdev_name,
+                                                int pdev_id,
+                                                struct omap_hwmod *oh,
+-                                               void *pdata, int pdata_len)
++                                               const void *pdata, int pdata_len)
+ {
+       struct omap_hwmod *ohs[] = { oh };
+@@ -532,7 +532,7 @@ struct platform_device __init *omap_device_build(const char *pdev_name,
+ struct platform_device __init *omap_device_build_ss(const char *pdev_name,
+                                                   int pdev_id,
+                                                   struct omap_hwmod **ohs,
+-                                                  int oh_cnt, void *pdata,
++                                                  int oh_cnt, const void *pdata,
+                                                   int pdata_len)
+ {
+       int ret = -ENOMEM;
+diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h
+index 78c02b3..c94109a 100644
+--- a/arch/arm/mach-omap2/omap_device.h
++++ b/arch/arm/mach-omap2/omap_device.h
+@@ -72,12 +72,12 @@ int omap_device_idle(struct platform_device *pdev);
+ /* Core code interface */
+ struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
+-                                        struct omap_hwmod *oh, void *pdata,
++                                        struct omap_hwmod *oh, const void *pdata,
+                                         int pdata_len);
+ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+                                        struct omap_hwmod **oh, int oh_cnt,
+-                                       void *pdata, int pdata_len);
++                                       const void *pdata, int pdata_len);
+ struct omap_device *omap_device_alloc(struct platform_device *pdev,
+                                     struct omap_hwmod **ohs, int oh_cnt);
+diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
+index 486cc4d..8d1a0b7 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -199,10 +199,10 @@ struct omap_hwmod_soc_ops {
+       int (*init_clkdm)(struct omap_hwmod *oh);
+       void (*update_context_lost)(struct omap_hwmod *oh);
+       int (*get_context_lost)(struct omap_hwmod *oh);
+-};
++} __no_const;
+ /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
+-static struct omap_hwmod_soc_ops soc_ops;
++static struct omap_hwmod_soc_ops soc_ops __read_only;
+ /* omap_hwmod_list contains all registered struct omap_hwmods */
+ static LIST_HEAD(omap_hwmod_list);
+diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c
+index 95fee54..cfa9cf1 100644
+--- a/arch/arm/mach-omap2/powerdomains43xx_data.c
++++ b/arch/arm/mach-omap2/powerdomains43xx_data.c
+@@ -10,6 +10,7 @@
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <asm/pgtable.h>
+ #include "powerdomain.h"
+@@ -129,7 +130,9 @@ static int am43xx_check_vcvp(void)
+ void __init am43xx_powerdomains_init(void)
+ {
+-      omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp;
++      pax_open_kernel();
++      *(void **)&omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp;
++      pax_close_kernel();
+       pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+       pwrdm_register_pwrdms(powerdomains_am43xx);
+       pwrdm_complete_init();
+diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
+index ff0a68c..b312aa0 100644
+--- a/arch/arm/mach-omap2/wd_timer.c
++++ b/arch/arm/mach-omap2/wd_timer.c
+@@ -110,7 +110,9 @@ static int __init omap_init_wdt(void)
+       struct omap_hwmod *oh;
+       char *oh_name = "wd_timer2";
+       char *dev_name = "omap_wdt";
+-      struct omap_wd_timer_platform_data pdata;
++      static struct omap_wd_timer_platform_data pdata = {
++              .read_reset_sources = prm_read_reset_sources
++      };
+       if (!cpu_class_is_omap2() || of_have_populated_dt())
+               return 0;
+@@ -121,8 +123,6 @@ static int __init omap_init_wdt(void)
+               return -EINVAL;
+       }
+-      pdata.read_reset_sources = prm_read_reset_sources;
+-
+       pdev = omap_device_build(dev_name, id, oh, &pdata,
+                                sizeof(struct omap_wd_timer_platform_data));
+       WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
+diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
+index b0790fc..71eb21f 100644
+--- a/arch/arm/mach-shmobile/platsmp-apmu.c
++++ b/arch/arm/mach-shmobile/platsmp-apmu.c
+@@ -22,6 +22,7 @@
+ #include <asm/proc-fns.h>
+ #include <asm/smp_plat.h>
+ #include <asm/suspend.h>
++#include <asm/pgtable.h>
+ #include "common.h"
+ #include "platsmp-apmu.h"
+@@ -233,6 +234,8 @@ static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
+ void __init shmobile_smp_apmu_suspend_init(void)
+ {
+-      shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
++      pax_open_kernel();
++      *(void **)&shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
++      pax_close_kernel();
+ }
+ #endif
+diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
+index 34608fc..344d7c0 100644
+--- a/arch/arm/mach-shmobile/pm-r8a7740.c
++++ b/arch/arm/mach-shmobile/pm-r8a7740.c
+@@ -11,6 +11,7 @@
+ #include <linux/console.h>
+ #include <linux/io.h>
+ #include <linux/suspend.h>
++#include <asm/pgtable.h>
+ #include "common.h"
+ #include "pm-rmobile.h"
+@@ -117,7 +118,9 @@ static int r8a7740_enter_suspend(suspend_state_t suspend_state)
+ static void r8a7740_suspend_init(void)
+ {
+-      shmobile_suspend_ops.enter = r8a7740_enter_suspend;
++      pax_open_kernel();
++      *(void **)&shmobile_suspend_ops.enter = r8a7740_enter_suspend;
++      pax_close_kernel();
+ }
+ #else
+ static void r8a7740_suspend_init(void) {}
+diff --git a/arch/arm/mach-shmobile/pm-sh73a0.c b/arch/arm/mach-shmobile/pm-sh73a0.c
+index a7e4668..83334f33 100644
+--- a/arch/arm/mach-shmobile/pm-sh73a0.c
++++ b/arch/arm/mach-shmobile/pm-sh73a0.c
+@@ -9,6 +9,7 @@
+  */
+ #include <linux/suspend.h>
++#include <asm/pgtable.h>
+ #include "common.h"
+ #ifdef CONFIG_SUSPEND
+@@ -20,7 +21,9 @@ static int sh73a0_enter_suspend(suspend_state_t suspend_state)
+ static void sh73a0_suspend_init(void)
+ {
+-      shmobile_suspend_ops.enter = sh73a0_enter_suspend;
++      pax_open_kernel();
++      *(void **)&shmobile_suspend_ops.enter = sh73a0_enter_suspend;
++      pax_close_kernel();
+ }
+ #else
+ static void sh73a0_suspend_init(void) {}
+diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
+index 7469347..1ecc350 100644
+--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
++++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
+@@ -177,7 +177,7 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+       bool entered_lp2 = false;
+       if (tegra_pending_sgi())
+-              ACCESS_ONCE(abort_flag) = true;
++              ACCESS_ONCE_RW(abort_flag) = true;
+       cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
+index 3b9098d..15b390f 100644
+--- a/arch/arm/mach-tegra/irq.c
++++ b/arch/arm/mach-tegra/irq.c
+@@ -20,6 +20,7 @@
+ #include <linux/cpu_pm.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c
+index 8538910..2f39bc4 100644
+--- a/arch/arm/mach-ux500/pm.c
++++ b/arch/arm/mach-ux500/pm.c
+@@ -10,6 +10,7 @@
+  */
+ #include <linux/kernel.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
+diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
+index f66816c..228b951 100644
+--- a/arch/arm/mach-zynq/platsmp.c
++++ b/arch/arm/mach-zynq/platsmp.c
+@@ -24,6 +24,7 @@
+ #include <linux/io.h>
+ #include <asm/cacheflush.h>
+ #include <asm/smp_scu.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include "common.h"
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index 7c6b976..055db09 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -446,6 +446,7 @@ config CPU_32v5
+ config CPU_32v6
+       bool
++      select CPU_USE_DOMAINS if CPU_V6 && MMU && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+       select TLS_REG_EMUL if !CPU_32v6K && !MMU
+ config CPU_32v6K
+@@ -600,6 +601,7 @@ config CPU_CP15_MPU
+ config CPU_USE_DOMAINS
+       bool
++      depends on !ARM_LPAE && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+       help
+         This option enables or disables the use of domain switching
+         via the set_fs() function.
+@@ -818,7 +820,7 @@ config NEED_KUSER_HELPERS
+ config KUSER_HELPERS
+       bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+-      depends on MMU
++      depends on MMU && (!(CPU_V6 || CPU_V6K || CPU_V7) || GRKERNSEC_OLD_ARM_USERLAND)
+       default y
+       help
+         Warning: disabling this option may break user programs.
+@@ -832,7 +834,7 @@ config KUSER_HELPERS
+         See Documentation/arm/kernel_user_helpers.txt for details.
+         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 9769f1e..16aaa55 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -216,10 +216,12 @@ union offset_union {
+ #define __get16_unaligned_check(ins,val,addr)                 \
+       do {                                                    \
+               unsigned int err = 0, v, a = addr;              \
++              pax_open_userland();                            \
+               __get8_unaligned_check(ins,v,a,err);            \
+               val =  v << ((BE) ? 8 : 0);                     \
+               __get8_unaligned_check(ins,v,a,err);            \
+               val |= v << ((BE) ? 0 : 8);                     \
++              pax_close_userland();                           \
+               if (err)                                        \
+                       goto fault;                             \
+       } while (0)
+@@ -233,6 +235,7 @@ union offset_union {
+ #define __get32_unaligned_check(ins,val,addr)                 \
+       do {                                                    \
+               unsigned int err = 0, v, a = addr;              \
++              pax_open_userland();                            \
+               __get8_unaligned_check(ins,v,a,err);            \
+               val =  v << ((BE) ? 24 :  0);                   \
+               __get8_unaligned_check(ins,v,a,err);            \
+@@ -241,6 +244,7 @@ union offset_union {
+               val |= v << ((BE) ?  8 : 16);                   \
+               __get8_unaligned_check(ins,v,a,err);            \
+               val |= v << ((BE) ?  0 : 24);                   \
++              pax_close_userland();                           \
+               if (err)                                        \
+                       goto fault;                             \
+       } while (0)
+@@ -254,6 +258,7 @@ union offset_union {
+ #define __put16_unaligned_check(ins,val,addr)                 \
+       do {                                                    \
+               unsigned int err = 0, v = val, a = addr;        \
++              pax_open_userland();                            \
+               __asm__( FIRST_BYTE_16                          \
+        ARM(   "1:     "ins"   %1, [%2], #1\n" )               \
+        THUMB( "1:     "ins"   %1, [%2]\n"     )               \
+@@ -273,6 +278,7 @@ union offset_union {
+               "       .popsection\n"                          \
+               : "=r" (err), "=&r" (v), "=&r" (a)              \
+               : "0" (err), "1" (v), "2" (a));                 \
++              pax_close_userland();                           \
+               if (err)                                        \
+                       goto fault;                             \
+       } while (0)
+@@ -286,6 +292,7 @@ union offset_union {
+ #define __put32_unaligned_check(ins,val,addr)                 \
+       do {                                                    \
+               unsigned int err = 0, v = val, a = addr;        \
++              pax_open_userland();                            \
+               __asm__( FIRST_BYTE_32                          \
+        ARM(   "1:     "ins"   %1, [%2], #1\n" )               \
+        THUMB( "1:     "ins"   %1, [%2]\n"     )               \
+@@ -315,6 +322,7 @@ union offset_union {
+               "       .popsection\n"                          \
+               : "=r" (err), "=&r" (v), "=&r" (a)              \
+               : "0" (err), "1" (v), "2" (a));                 \
++              pax_close_userland();                           \
+               if (err)                                        \
+                       goto fault;                             \
+       } while (0)
+diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
+index 71b3d33..8af9ade 100644
+--- a/arch/arm/mm/cache-l2x0.c
++++ b/arch/arm/mm/cache-l2x0.c
+@@ -44,7 +44,7 @@ struct l2c_init_data {
+       void (*configure)(void __iomem *);
+       void (*unlock)(void __iomem *, unsigned);
+       struct outer_cache_fns outer_cache;
+-};
++} __do_const;
+ #define CACHE_LINE_SIZE               32
+diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
+index 845769e..4278fd7 100644
+--- a/arch/arm/mm/context.c
++++ b/arch/arm/mm/context.c
+@@ -43,7 +43,7 @@
+ #define NUM_USER_ASIDS                ASID_FIRST_VERSION
+ static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
+-static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
++static atomic64_unchecked_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
+ static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
+ static DEFINE_PER_CPU(atomic64_t, active_asids);
+@@ -178,7 +178,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ {
+       static u32 cur_idx = 1;
+       u64 asid = atomic64_read(&mm->context.id);
+-      u64 generation = atomic64_read(&asid_generation);
++      u64 generation = atomic64_read_unchecked(&asid_generation);
+       if (asid != 0) {
+               /*
+@@ -208,7 +208,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+        */
+       asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
+       if (asid == NUM_USER_ASIDS) {
+-              generation = atomic64_add_return(ASID_FIRST_VERSION,
++              generation = atomic64_add_return_unchecked(ASID_FIRST_VERSION,
+                                                &asid_generation);
+               flush_context(cpu);
+               asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
+@@ -240,14 +240,14 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
+       cpu_set_reserved_ttbr0();
+       asid = atomic64_read(&mm->context.id);
+-      if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
++      if (!((asid ^ atomic64_read_unchecked(&asid_generation)) >> ASID_BITS)
+           && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
+               goto switch_mm_fastpath;
+       raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+       /* Check that our ASID belongs to the current generation. */
+       asid = atomic64_read(&mm->context.id);
+-      if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
++      if ((asid ^ atomic64_read_unchecked(&asid_generation)) >> ASID_BITS) {
+               asid = new_context(mm, cpu);
+               atomic64_set(&mm->context.id, asid);
+       }
+diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
+index 0d629b8..01867c8 100644
+--- a/arch/arm/mm/fault.c
++++ b/arch/arm/mm/fault.c
+@@ -25,6 +25,7 @@
+ #include <asm/system_misc.h>
+ #include <asm/system_info.h>
+ #include <asm/tlbflush.h>
++#include <asm/sections.h>
+ #include "fault.h"
+@@ -138,6 +139,31 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+       if (fixup_exception(regs))
+               return;
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      if (addr < TASK_SIZE) {
++              if (current->signal->curr_ip)
++                      printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++              else
++                      printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++      }
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++      if ((fsr & FSR_WRITE) &&
++          (((unsigned long)_stext <= addr && addr < init_mm.end_code) ||
++           (MODULES_VADDR <= addr && addr < MODULES_END)))
++      {
++              if (current->signal->curr_ip)
++                      printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()));
++              else
++                      printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()));
++      }
++#endif
++
+       /*
+        * No handler, we'll have to terminate things with extreme prejudice.
+        */
+@@ -173,6 +199,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
+       }
+ #endif
++#ifdef CONFIG_PAX_PAGEEXEC
++      if (fsr & FSR_LNX_PF) {
++              pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
++              do_group_exit(SIGKILL);
++      }
++#endif
++
+       tsk->thread.address = addr;
+       tsk->thread.error_code = fsr;
+       tsk->thread.trap_no = 14;
+@@ -400,6 +433,33 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ #endif                                        /* CONFIG_MMU */
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++      long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 20; i++) {
++              unsigned char c;
++              if (get_user(c, (__force unsigned char __user *)pc+i))
++                      printk(KERN_CONT "?? ");
++              else
++                      printk(KERN_CONT "%02x ", c);
++      }
++      printk("\n");
++
++      printk(KERN_ERR "PAX: bytes at SP-4: ");
++      for (i = -1; i < 20; i++) {
++              unsigned long c;
++              if (get_user(c, (__force unsigned long __user *)sp+i))
++                      printk(KERN_CONT "???????? ");
++              else
++                      printk(KERN_CONT "%08lx ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * First Level Translation Fault Handler
+  *
+@@ -547,9 +607,22 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+       const struct fsr_info *inf = fsr_info + fsr_fs(fsr);
+       struct siginfo info;
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++      if (addr < TASK_SIZE && is_domain_fault(fsr)) {
++              if (current->signal->curr_ip)
++                      printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++              else
++                      printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++              goto die;
++      }
++#endif
++
+       if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
+               return;
++die:
+       pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
+               inf->name, fsr, addr);
+       show_pte(current->mm, addr);
+@@ -574,15 +647,104 @@ 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;
++      unsigned long pc = instruction_pointer(regs);
++
++      if (user_mode(regs)) {
++              unsigned long sigpage = current->mm->context.sigpage;
++
++              if (sigpage <= pc && pc < sigpage + 7*4) {
++                      if (pc < sigpage + 3*4)
++                              sys_sigreturn(regs);
++                      else
++                              sys_rt_sigreturn(regs);
++                      return;
++              }
++              if (pc == 0xffff0f60UL) {
++                      /*
++                       * PaX: __kuser_cmpxchg64 emulation
++                       */
++                      // TODO
++                      //regs->ARM_pc = regs->ARM_lr;
++                      //return;
++              }
++              if (pc == 0xffff0fa0UL) {
++                      /*
++                       * PaX: __kuser_memory_barrier emulation
++                       */
++                      // dmb(); implied by the exception
++                      regs->ARM_pc = regs->ARM_lr;
++                      return;
++              }
++              if (pc == 0xffff0fc0UL) {
++                      /*
++                       * PaX: __kuser_cmpxchg emulation
++                       */
++                      // TODO
++                      //long new;
++                      //int op;
++
++                      //op = FUTEX_OP_SET << 28;
++                      //new = futex_atomic_op_inuser(op, regs->ARM_r2);
++                      //regs->ARM_r0 = old != new;
++                      //regs->ARM_pc = regs->ARM_lr;
++                      //return;
++              }
++              if (pc == 0xffff0fe0UL) {
++                      /*
++                       * PaX: __kuser_get_tls emulation
++                       */
++                      regs->ARM_r0 = current_thread_info()->tp_value[0];
++                      regs->ARM_pc = regs->ARM_lr;
++                      return;
++              }
++      }
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++      else if (is_domain_fault(ifsr) || is_xn_fault(ifsr)) {
++              if (current->signal->curr_ip)
++                      printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
++                                      pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
++              else
++                      printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", current->comm, task_pid_nr(current),
++                                      from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
++                                      pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
++              goto die;
++      }
++#endif
++
++#ifdef CONFIG_PAX_REFCOUNT
++      if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) {
++#ifdef CONFIG_THUMB2_KERNEL
++              unsigned short bkpt;
++
++              if (!probe_kernel_address(pc, bkpt) && cpu_to_le16(bkpt) == 0xbef1) {
++#else
++              unsigned int bkpt;
++
++              if (!probe_kernel_address(pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) {
++#endif
++                      current->thread.error_code = ifsr;
++                      current->thread.trap_no = 0;
++                      pax_report_refcount_overflow(regs);
++                      fixup_exception(regs);
++                      return;
++              }
++      }
++#endif
+       if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+               return;
++die:
+       pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+               inf->name, ifsr, addr);
+diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
+index cf08bdf..772656c 100644
+--- a/arch/arm/mm/fault.h
++++ b/arch/arm/mm/fault.h
+@@ -3,6 +3,7 @@
+ /*
+  * Fault status register encodings.  We steal bit 31 for our own purposes.
++ * Set when the FSR value is from an instruction fault.
+  */
+ #define FSR_LNX_PF            (1 << 31)
+ #define FSR_WRITE             (1 << 11)
+@@ -22,6 +23,17 @@ static inline int fsr_fs(unsigned int fsr)
+ }
+ #endif
++/* valid for LPAE and !LPAE */
++static inline int is_xn_fault(unsigned int fsr)
++{
++      return ((fsr_fs(fsr) & 0x3c) == 0xc);
++}
++
++static inline int is_domain_fault(unsigned int fsr)
++{
++      return ((fsr_fs(fsr) & 0xD) == 0x9);
++}
++
+ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+ unsigned long search_exception_table(unsigned long addr);
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index 8a63b4c..6b04370 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -710,7 +710,46 @@ void free_tcmmem(void)
+ {
+ #ifdef CONFIG_HAVE_TCM
+       extern char __tcm_start, __tcm_end;
++#endif
++#ifdef CONFIG_PAX_KERNEXEC
++      unsigned long addr;
++      pgd_t *pgd;
++      pud_t *pud;
++      pmd_t *pmd;
++      int cpu_arch = cpu_architecture();
++      unsigned int cr = get_cr();
++
++      if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
++              /* make pages tables, etc before .text NX */
++              for (addr = PAGE_OFFSET; addr < (unsigned long)_stext; addr += SECTION_SIZE) {
++                      pgd = pgd_offset_k(addr);
++                      pud = pud_offset(pgd, addr);
++                      pmd = pmd_offset(pud, addr);
++                      __section_update(pmd, addr, PMD_SECT_XN);
++              }
++              /* make init NX */
++              for (addr = (unsigned long)__init_begin; addr < (unsigned long)_sdata; addr += SECTION_SIZE) {
++                      pgd = pgd_offset_k(addr);
++                      pud = pud_offset(pgd, addr);
++                      pmd = pmd_offset(pud, addr);
++                      __section_update(pmd, addr, PMD_SECT_XN);
++              }
++              /* make kernel code/rodata RX */
++              for (addr = (unsigned long)_stext; addr < (unsigned long)__init_begin; addr += SECTION_SIZE) {
++                      pgd = pgd_offset_k(addr);
++                      pud = pud_offset(pgd, addr);
++                      pmd = pmd_offset(pud, addr);
++#ifdef CONFIG_ARM_LPAE
++                      __section_update(pmd, addr, PMD_SECT_RDONLY);
++#else
++                      __section_update(pmd, addr, PMD_SECT_APX|PMD_SECT_AP_WRITE);
++#endif
++              }
++      }
++#endif
++
++#ifdef CONFIG_HAVE_TCM
+       poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
+       free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link");
+ #endif
+diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
+index 0c81056..97279f7 100644
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -405,9 +405,9 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached)
+       unsigned int mtype;
+       if (cached)
+-              mtype = MT_MEMORY_RWX;
++              mtype = MT_MEMORY_RX;
+       else
+-              mtype = MT_MEMORY_RWX_NONCACHED;
++              mtype = MT_MEMORY_RX_NONCACHED;
+       return __arm_ioremap_caller(phys_addr, size, mtype,
+                       __builtin_return_address(0));
+diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
+index 407dc78..047ce9d 100644
+--- a/arch/arm/mm/mmap.c
++++ b/arch/arm/mm/mmap.c
+@@ -59,6 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+       struct vm_area_struct *vma;
+       int do_align = 0;
+       int aliasing = cache_is_vipt_aliasing();
++      unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+       struct vm_unmapped_area_info info;
+       /*
+@@ -81,6 +82,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+       if (len > TASK_SIZE)
+               return -ENOMEM;
++#ifdef CONFIG_PAX_RANDMMAP
++      if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+       if (addr) {
+               if (do_align)
+                       addr = COLOUR_ALIGN(addr, pgoff);
+@@ -88,8 +93,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+                       addr = PAGE_ALIGN(addr);
+               vma = find_vma(mm, addr);
+-              if (TASK_SIZE - len >= addr &&
+-                  (!vma || addr + len <= vma->vm_start))
++              if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+                       return addr;
+       }
+@@ -99,6 +103,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+       info.high_limit = TASK_SIZE;
+       info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+       info.align_offset = pgoff << PAGE_SHIFT;
++      info.threadstack_offset = offset;
+       return vm_unmapped_area(&info);
+ }
+@@ -112,6 +117,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+       unsigned long addr = addr0;
+       int do_align = 0;
+       int aliasing = cache_is_vipt_aliasing();
++      unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+       struct vm_unmapped_area_info info;
+       /*
+@@ -132,6 +138,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+               return addr;
+       }
++#ifdef CONFIG_PAX_RANDMMAP
++      if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+       /* requesting a specific address */
+       if (addr) {
+               if (do_align)
+@@ -139,8 +149,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+               else
+                       addr = PAGE_ALIGN(addr);
+               vma = find_vma(mm, addr);
+-              if (TASK_SIZE - len >= addr &&
+-                              (!vma || addr + len <= vma->vm_start))
++              if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+                       return addr;
+       }
+@@ -150,6 +159,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+       info.high_limit = mm->mmap_base;
+       info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+       info.align_offset = pgoff << PAGE_SHIFT;
++      info.threadstack_offset = offset;
+       addr = vm_unmapped_area(&info);
+       /*
+@@ -183,14 +193,30 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+       unsigned long random_factor = 0UL;
++#ifdef CONFIG_PAX_RANDMMAP
++      if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+       if (current->flags & PF_RANDOMIZE)
+               random_factor = arch_mmap_rnd();
+       if (mmap_is_legacy()) {
+               mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
++
++#ifdef CONFIG_PAX_RANDMMAP
++              if (mm->pax_flags & MF_PAX_RANDMMAP)
++                      mm->mmap_base += mm->delta_mmap;
++#endif
++
+               mm->get_unmapped_area = arch_get_unmapped_area;
+       } else {
+               mm->mmap_base = mmap_base(random_factor);
++
++#ifdef CONFIG_PAX_RANDMMAP
++              if (mm->pax_flags & MF_PAX_RANDMMAP)
++                      mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++#endif
++
+               mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+       }
+ }
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index 870838a..070df1d 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -41,6 +41,22 @@
+ #include "mm.h"
+ #include "tcm.h"
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++void modify_domain(unsigned int dom, unsigned int type)
++{
++      struct thread_info *thread = current_thread_info();
++      unsigned int domain = thread->cpu_domain;
++      /*
++       * DOMAIN_MANAGER might be defined to some other value,
++       * use the arch-defined constant
++       */
++      domain &= ~domain_val(dom, 3);
++      thread->cpu_domain = domain | domain_val(dom, type);
++      set_domain(thread->cpu_domain);
++}
++EXPORT_SYMBOL(modify_domain);
++#endif
++
+ /*
+  * empty_zero_page is a special page that is used for
+  * zero-initialized data and COW.
+@@ -242,7 +258,15 @@ __setup("noalign", noalign_setup);
+ #define PROT_PTE_S2_DEVICE    PROT_PTE_DEVICE
+ #define PROT_SECT_DEVICE      PMD_TYPE_SECT|PMD_SECT_AP_WRITE
+-static struct mem_type mem_types[] = {
++#ifdef CONFIG_PAX_KERNEXEC
++#define L_PTE_KERNEXEC                L_PTE_RDONLY
++#define PMD_SECT_KERNEXEC     PMD_SECT_RDONLY
++#else
++#define L_PTE_KERNEXEC                L_PTE_DIRTY
++#define PMD_SECT_KERNEXEC     PMD_SECT_AP_WRITE
++#endif
++
++static struct mem_type mem_types[] __read_only = {
+       [MT_DEVICE] = {           /* Strongly ordered / ARMv6 shared device */
+               .prot_pte       = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+                                 L_PTE_SHARED,
+@@ -271,19 +295,19 @@ static struct mem_type mem_types[] = {
+               .prot_sect      = PROT_SECT_DEVICE,
+               .domain         = DOMAIN_IO,
+       },
+-      [MT_UNCACHED] = {
++      [MT_UNCACHED_RW] = {
+               .prot_pte       = PROT_PTE_DEVICE,
+               .prot_l1        = PMD_TYPE_TABLE,
+               .prot_sect      = PMD_TYPE_SECT | PMD_SECT_XN,
+               .domain         = DOMAIN_IO,
+       },
+-      [MT_CACHECLEAN] = {
+-              .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
++      [MT_CACHECLEAN_RO] = {
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_RDONLY,
+               .domain    = DOMAIN_KERNEL,
+       },
+ #ifndef CONFIG_ARM_LPAE
+-      [MT_MINICLEAN] = {
+-              .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
++      [MT_MINICLEAN_RO] = {
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE | PMD_SECT_XN | PMD_SECT_RDONLY,
+               .domain    = DOMAIN_KERNEL,
+       },
+ #endif
+@@ -291,15 +315,15 @@ 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,
+-              .domain    = DOMAIN_USER,
++              .domain    = DOMAIN_VECTORS,
+       },
+       [MT_HIGH_VECTORS] = {
+               .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,
+       },
+-      [MT_MEMORY_RWX] = {
++      [__MT_MEMORY_RWX] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+@@ -312,17 +336,30 @@ static struct mem_type mem_types[] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_KERNEL,
+       },
+-      [MT_ROM] = {
+-              .prot_sect = PMD_TYPE_SECT,
++      [MT_MEMORY_RX] = {
++              .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC,
++              .prot_l1   = PMD_TYPE_TABLE,
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
++              .domain    = DOMAIN_KERNEL,
++      },
++      [MT_ROM_RX] = {
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_RDONLY,
+               .domain    = DOMAIN_KERNEL,
+       },
+-      [MT_MEMORY_RWX_NONCACHED] = {
++      [MT_MEMORY_RW_NONCACHED] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_MT_BUFFERABLE,
+               .prot_l1   = PMD_TYPE_TABLE,
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+               .domain    = DOMAIN_KERNEL,
+       },
++      [MT_MEMORY_RX_NONCACHED] = {
++              .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC |
++                              L_PTE_MT_BUFFERABLE,
++              .prot_l1   = PMD_TYPE_TABLE,
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
++              .domain    = DOMAIN_KERNEL,
++      },
+       [MT_MEMORY_RW_DTCM] = {
+               .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+                               L_PTE_XN,
+@@ -330,9 +367,10 @@ static struct mem_type mem_types[] = {
+               .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+               .domain    = DOMAIN_KERNEL,
+       },
+-      [MT_MEMORY_RWX_ITCM] = {
+-              .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
++      [MT_MEMORY_RX_ITCM] = {
++              .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC,
+               .prot_l1   = PMD_TYPE_TABLE,
++              .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
+               .domain    = DOMAIN_KERNEL,
+       },
+       [MT_MEMORY_RW_SO] = {
+@@ -544,9 +582,14 @@ static void __init build_mem_type_table(void)
+                * Mark cache clean areas and XIP ROM read only
+                * from SVC mode and no access from userspace.
+                */
+-              mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+-              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;
++              mem_types[MT_ROM_RX].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#ifdef CONFIG_PAX_KERNEXEC
++              mem_types[MT_MEMORY_RX].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++              mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++              mem_types[MT_MEMORY_RX_ITCM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#endif
++              mem_types[MT_MINICLEAN_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++              mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ #endif
+               /*
+@@ -563,13 +606,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;
+-                      mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
+-                      mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
++                      mem_types[__MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
++                      mem_types[__MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
+                       mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
+                       mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
++                      mem_types[MT_MEMORY_RX].prot_sect |= PMD_SECT_S;
++                      mem_types[MT_MEMORY_RX].prot_pte |= L_PTE_SHARED;
+                       mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
+-                      mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
+-                      mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
++                      mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= PMD_SECT_S;
++                      mem_types[MT_MEMORY_RW_NONCACHED].prot_pte |= L_PTE_SHARED;
++                      mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_S;
++                      mem_types[MT_MEMORY_RX_NONCACHED].prot_pte |= L_PTE_SHARED;
+               }
+       }
+@@ -580,15 +627,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 */
+-                      mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
++                      mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |=
++                              PMD_SECT_BUFFERED;
++                      mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |=
+                               PMD_SECT_BUFFERED;
+               } else {
+                       /* For both ARMv6 and non-TEX-remapping ARMv7 */
+-                      mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
++                      mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |=
++                              PMD_SECT_TEX(1);
++                      mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |=
+                               PMD_SECT_TEX(1);
+               }
+       } else {
+-              mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
++              mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
++              mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+       }
+ #ifdef CONFIG_ARM_LPAE
+@@ -609,6 +661,8 @@ static void __init build_mem_type_table(void)
+       user_pgprot |= PTE_EXT_PXN;
+ #endif
++      user_pgprot |= __supported_pte_mask;
++
+       for (i = 0; i < 16; i++) {
+               pteval_t v = pgprot_val(protection_map[i]);
+               protection_map[i] = __pgprot(v | user_pgprot);
+@@ -626,21 +680,24 @@ 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;
+-      mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
+-      mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
++      mem_types[__MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
++      mem_types[__MT_MEMORY_RWX].prot_pte |= kern_pgprot;
+       mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
+       mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
++      mem_types[MT_MEMORY_RX].prot_sect |= ecc_mask | cp->pmd;
++      mem_types[MT_MEMORY_RX].prot_pte |= kern_pgprot;
+       mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
+-      mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
+-      mem_types[MT_ROM].prot_sect |= cp->pmd;
++      mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= ecc_mask;
++      mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= ecc_mask;
++      mem_types[MT_ROM_RX].prot_sect |= cp->pmd;
+       switch (cp->pmd) {
+       case PMD_SECT_WT:
+-              mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
++              mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_WT;
+               break;
+       case PMD_SECT_WB:
+       case PMD_SECT_WBWA:
+-              mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
++              mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_WB;
+               break;
+       }
+       pr_info("Memory policy: %sData cache %s\n",
+@@ -854,7 +911,7 @@ static void __init create_mapping(struct map_desc *md)
+               return;
+       }
+-      if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
++      if ((md->type == MT_DEVICE || md->type == MT_ROM_RX) &&
+           md->virtual >= PAGE_OFFSET &&
+           (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
+               pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
+@@ -1224,18 +1281,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 * 2] __read_only __aligned(PAGE_SIZE);
++
+ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ {
+       struct map_desc map;
+       unsigned long addr;
+-      void *vectors;
+-      /*
+-       * Allocate the vector page early.
+-       */
+-      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));
+@@ -1248,7 +1302,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+       map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+       map.virtual = MODULES_VADDR;
+       map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+-      map.type = MT_ROM;
++      map.type = MT_ROM_RX;
+       create_mapping(&map);
+ #endif
+@@ -1259,14 +1313,14 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+       map.virtual = FLUSH_BASE;
+       map.length = SZ_1M;
+-      map.type = MT_CACHECLEAN;
++      map.type = MT_CACHECLEAN_RO;
+       create_mapping(&map);
+ #endif
+ #ifdef FLUSH_BASE_MINICACHE
+       map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
+       map.virtual = FLUSH_BASE_MINICACHE;
+       map.length = SZ_1M;
+-      map.type = MT_MINICLEAN;
++      map.type = MT_MINICLEAN_RO;
+       create_mapping(&map);
+ #endif
+@@ -1275,7 +1329,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+        * location (0xffff0000).  If we aren't using high-vectors, also
+        * create a mapping at the low-vectors virtual address.
+        */
+-      map.pfn = __phys_to_pfn(virt_to_phys(vectors));
++      map.pfn = __phys_to_pfn(virt_to_phys(&vectors));
+       map.virtual = 0xffff0000;
+       map.length = PAGE_SIZE;
+ #ifdef CONFIG_KUSER_HELPERS
+@@ -1335,8 +1389,10 @@ static void __init kmap_init(void)
+ static void __init map_lowmem(void)
+ {
+       struct memblock_region *reg;
++#ifndef CONFIG_PAX_KERNEXEC
+       phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+       phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
++#endif
+       /* Map all the lowmem memory banks. */
+       for_each_memblock(memory, reg) {
+@@ -1349,11 +1405,48 @@ static void __init map_lowmem(void)
+               if (start >= end)
+                       break;
++#ifdef CONFIG_PAX_KERNEXEC
++              map.pfn = __phys_to_pfn(start);
++              map.virtual = __phys_to_virt(start);
++              map.length = end - start;
++
++              if (map.virtual <= (unsigned long)_stext && ((unsigned long)_end < (map.virtual + map.length))) {
++                      struct map_desc kernel;
++                      struct map_desc initmap;
++
++                      /* when freeing initmem we will make this RW */
++                      initmap.pfn = __phys_to_pfn(__pa(__init_begin));
++                      initmap.virtual = (unsigned long)__init_begin;
++                      initmap.length = _sdata - __init_begin;
++                      initmap.type = __MT_MEMORY_RWX;
++                      create_mapping(&initmap);
++
++                      /* when freeing initmem we will make this RX */
++                      kernel.pfn = __phys_to_pfn(__pa(_stext));
++                      kernel.virtual = (unsigned long)_stext;
++                      kernel.length = __init_begin - _stext;
++                      kernel.type = __MT_MEMORY_RWX;
++                      create_mapping(&kernel);
++
++                      if (map.virtual < (unsigned long)_stext) {
++                              map.length = (unsigned long)_stext - map.virtual;
++                              map.type = __MT_MEMORY_RWX;
++                              create_mapping(&map);
++                      }
++
++                      map.pfn = __phys_to_pfn(__pa(_sdata));
++                      map.virtual = (unsigned long)_sdata;
++                      map.length = end - __pa(_sdata);
++              }
++
++              map.type = MT_MEMORY_RW;
++              create_mapping(&map);
++#else
+               if (end < kernel_x_start) {
+                       map.pfn = __phys_to_pfn(start);
+                       map.virtual = __phys_to_virt(start);
+                       map.length = end - start;
+-                      map.type = MT_MEMORY_RWX;
++                      map.type = __MT_MEMORY_RWX;
+                       create_mapping(&map);
+               } else if (start >= kernel_x_end) {
+@@ -1377,7 +1470,7 @@ static void __init map_lowmem(void)
+                       map.pfn = __phys_to_pfn(kernel_x_start);
+                       map.virtual = __phys_to_virt(kernel_x_start);
+                       map.length = kernel_x_end - kernel_x_start;
+-                      map.type = MT_MEMORY_RWX;
++                      map.type = __MT_MEMORY_RWX;
+                       create_mapping(&map);
+@@ -1390,6 +1483,7 @@ static void __init map_lowmem(void)
+                               create_mapping(&map);
+                       }
+               }
++#endif
+       }
+ }
+diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
+index c011e22..92a0260 100644
+--- a/arch/arm/net/bpf_jit_32.c
++++ b/arch/arm/net/bpf_jit_32.c
+@@ -20,6 +20,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/hwcap.h>
+ #include <asm/opcodes.h>
++#include <asm/pgtable.h>
+ #include "bpf_jit_32.h"
+@@ -72,54 +73,38 @@ struct jit_ctx {
+ #endif
+ };
++#ifdef CONFIG_GRKERNSEC_BPF_HARDEN
++int bpf_jit_enable __read_only;
++#else
+ int bpf_jit_enable __read_mostly;
++#endif
+-static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret,
+-                    unsigned int size)
+-{
+-      void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size);
+-
+-      if (!ptr)
+-              return -EFAULT;
+-      memcpy(ret, ptr, size);
+-      return 0;
+-}
+-
+-static u64 jit_get_skb_b(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+ {
+       u8 ret;
+       int err;
+-      if (offset < 0)
+-              err = call_neg_helper(skb, offset, &ret, 1);
+-      else
+-              err = skb_copy_bits(skb, offset, &ret, 1);
++      err = skb_copy_bits(skb, offset, &ret, 1);
+       return (u64)err << 32 | ret;
+ }
+-static u64 jit_get_skb_h(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+ {
+       u16 ret;
+       int err;
+-      if (offset < 0)
+-              err = call_neg_helper(skb, offset, &ret, 2);
+-      else
+-              err = skb_copy_bits(skb, offset, &ret, 2);
++      err = skb_copy_bits(skb, offset, &ret, 2);
+       return (u64)err << 32 | ntohs(ret);
+ }
+-static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+ {
+       u32 ret;
+       int err;
+-      if (offset < 0)
+-              err = call_neg_helper(skb, offset, &ret, 4);
+-      else
+-              err = skb_copy_bits(skb, offset, &ret, 4);
++      err = skb_copy_bits(skb, offset, &ret, 4);
+       return (u64)err << 32 | ntohl(ret);
+ }
+@@ -199,8 +184,10 @@ static void jit_fill_hole(void *area, unsigned int size)
+ {
+       u32 *ptr;
+       /* We are guaranteed to have aligned memory. */
++      pax_open_kernel();
+       for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
+               *ptr++ = __opcode_to_mem_arm(ARM_INST_UDF);
++      pax_close_kernel();
+ }
+ static void build_prologue(struct jit_ctx *ctx)
+@@ -556,6 +543,9 @@ static int build_body(struct jit_ctx *ctx)
+               case BPF_LD | BPF_B | BPF_ABS:
+                       load_order = 0;
+ load:
++                      /* the interpreter will deal with the negative K */
++                      if ((int)k < 0)
++                              return -ENOTSUPP;
+                       emit_mov_i(r_off, k, ctx);
+ load_common:
+                       ctx->seen |= SEEN_DATA | SEEN_CALL;
+@@ -570,18 +560,6 @@ load_common:
+                               condt = ARM_COND_HI;
+                       }
+-                      /*
+-                       * test for negative offset, only if we are
+-                       * currently scheduled to take the fast
+-                       * path. this will update the flags so that
+-                       * the slowpath instruction are ignored if the
+-                       * offset is negative.
+-                       *
+-                       * for loard_order == 0 the HI condition will
+-                       * make loads at offset 0 take the slow path too.
+-                       */
+-                      _emit(condt, ARM_CMP_I(r_off, 0), ctx);
+-
+                       _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+                             ctx);
+diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
+index 5b217f4..c23f40e 100644
+--- a/arch/arm/plat-iop/setup.c
++++ b/arch/arm/plat-iop/setup.c
+@@ -24,7 +24,7 @@ static struct map_desc iop3xx_std_desc[] __initdata = {
+               .virtual        = IOP3XX_PERIPHERAL_VIRT_BASE,
+               .pfn            = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
+               .length         = IOP3XX_PERIPHERAL_SIZE,
+-              .type           = MT_UNCACHED,
++              .type           = MT_UNCACHED_RW,
+        },
+ };
+diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
+index a5bc92d..0bb4730 100644
+--- a/arch/arm/plat-omap/sram.c
++++ b/arch/arm/plat-omap/sram.c
+@@ -93,6 +93,8 @@ void __init omap_map_sram(unsigned long start, unsigned long size,
+        * Looks like we need to preserve some bootloader code at the
+        * beginning of SRAM for jumping to flash for reboot to work...
+        */
++      pax_open_kernel();
+       memset_io(omap_sram_base + omap_sram_skip, 0,
+                 omap_sram_size - omap_sram_skip);
++      pax_close_kernel();
+ }
+diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
+index d6285ef..b684dac 100644
+--- a/arch/arm64/Kconfig.debug
++++ b/arch/arm64/Kconfig.debug
+@@ -10,6 +10,7 @@ config ARM64_PTDUMP
+       bool "Export kernel pagetable layout to userspace via debugfs"
+       depends on DEBUG_KERNEL
+       select DEBUG_FS
++      depends on !GRKERNSEC_KMEM
+         help
+         Say Y here if you want to show the kernel pagetable layout in a
+         debugfs file. This information is only useful for kernel developers
+diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
+index 7047051..44e8675 100644
+--- a/arch/arm64/include/asm/atomic.h
++++ b/arch/arm64/include/asm/atomic.h
+@@ -252,5 +252,15 @@ static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
+ #define atomic64_dec_and_test(v)      (atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_not_zero(v)      atomic64_add_unless((v), 1LL, 0LL)
++#define atomic64_read_unchecked(v)            atomic64_read(v)
++#define atomic64_set_unchecked(v, i)          atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v)          atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v)   atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v)          atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v)             atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v)      atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v)             atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n)   atomic64_cmpxchg((v), (o), (n))
++
+ #endif
+ #endif
+diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
+index 0fa47c4..b167938 100644
+--- a/arch/arm64/include/asm/barrier.h
++++ b/arch/arm64/include/asm/barrier.h
+@@ -44,7 +44,7 @@
+ do {                                                                  \
+       compiletime_assert_atomic_type(*p);                             \
+       barrier();                                                      \
+-      ACCESS_ONCE(*p) = (v);                                          \
++      ACCESS_ONCE_RW(*p) = (v);                                       \
+ } while (0)
+ #define smp_load_acquire(p)                                           \
+diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
+index 4fde8c1..441f84f 100644
+--- a/arch/arm64/include/asm/percpu.h
++++ b/arch/arm64/include/asm/percpu.h
+@@ -135,16 +135,16 @@ static inline void __percpu_write(void *ptr, unsigned long val, int size)
+ {
+       switch (size) {
+       case 1:
+-              ACCESS_ONCE(*(u8 *)ptr) = (u8)val;
++              ACCESS_ONCE_RW(*(u8 *)ptr) = (u8)val;
+               break;
+       case 2:
+-              ACCESS_ONCE(*(u16 *)ptr) = (u16)val;
++              ACCESS_ONCE_RW(*(u16 *)ptr) = (u16)val;
+               break;
+       case 4:
+-              ACCESS_ONCE(*(u32 *)ptr) = (u32)val;
++              ACCESS_ONCE_RW(*(u32 *)ptr) = (u32)val;
+               break;
+       case 8:
+-              ACCESS_ONCE(*(u64 *)ptr) = (u64)val;
++              ACCESS_ONCE_RW(*(u64 *)ptr) = (u64)val;
+               break;
+       default:
+               BUILD_BUG();
+diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
+index 7642056..bffc904 100644
+--- a/arch/arm64/include/asm/pgalloc.h
++++ b/arch/arm64/include/asm/pgalloc.h
+@@ -46,6 +46,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+       set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+ }
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++      pud_populate(mm, pud, pmd);
++}
++
+ #endif        /* CONFIG_PGTABLE_LEVELS > 2 */
+ #if CONFIG_PGTABLE_LEVELS > 3
+diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
+index 07e1ba44..ec8cbbb 100644
+--- a/arch/arm64/include/asm/uaccess.h
++++ b/arch/arm64/include/asm/uaccess.h
+@@ -99,6 +99,7 @@ static inline void set_fs(mm_segment_t fs)
+       flag;                                                           \
+ })
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size)   __range_ok(addr, size)
+ #define user_addr_max                 get_fs
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index d16a1ce..a5acc60 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -134,7 +134,7 @@ static void __dma_free_coherent(struct device *dev, size_t size,
+                                       phys_to_page(paddr),
+                                       size >> PAGE_SHIFT);
+       if (!freed)
+-              swiotlb_free_coherent(dev, size, vaddr, dma_handle);
++              swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs);
+ }
+ static void *__dma_alloc(struct device *dev, size_t size,
+diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h
+index c3a58a1..78fbf54 100644
+--- a/arch/avr32/include/asm/cache.h
++++ b/arch/avr32/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ASM_AVR32_CACHE_H
+ #define __ASM_AVR32_CACHE_H
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
+index 0388ece..87c8df1 100644
+--- a/arch/avr32/include/asm/elf.h
++++ b/arch/avr32/include/asm/elf.h
+@@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpregset_t;
+    the loader.  We need to make sure that it is out of the way of the program
+    that it will "exec", and that there is sufficient room for the brk.  */
+-#define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
++#define ELF_ET_DYN_BASE               (TASK_SIZE / 3 * 2)
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   0x00001000UL
++
++#define PAX_DELTA_MMAP_LEN    15
++#define PAX_DELTA_STACK_LEN   15
++#endif
+ /* This yields a mask that user programs can use to figure out what
+    instruction set this CPU supports.  This could be done in user space,
+diff --git a/arch/avr32/include/asm/kmap_types.h b/arch/avr32/include/asm/kmap_types.h
+index 479330b..53717a8 100644
+--- a/arch/avr32/include/asm/kmap_types.h
++++ b/arch/avr32/include/asm/kmap_types.h
+@@ -2,9 +2,9 @@
+ #define __ASM_AVR32_KMAP_TYPES_H
+ #ifdef CONFIG_DEBUG_HIGHMEM
+-# define KM_TYPE_NR 29
++# define KM_TYPE_NR 30
+ #else
+-# define KM_TYPE_NR 14
++# define KM_TYPE_NR 15
+ #endif
+ #endif /* __ASM_AVR32_KMAP_TYPES_H */
+diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
+index c035339..e1fa594 100644
+--- a/arch/avr32/mm/fault.c
++++ b/arch/avr32/mm/fault.c
+@@ -41,6 +41,23 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
+ int exception_trace = 1;
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 20; i++) {
++              unsigned char c;
++              if (get_user(c, (unsigned char *)pc+i))
++                      printk(KERN_CONT "???????? ");
++              else
++                      printk(KERN_CONT "%02x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * This routine handles page faults. It determines the address and the
+  * problem, and then passes it off to one of the appropriate routines.
+@@ -178,6 +195,16 @@ bad_area:
+       up_read(&mm->mmap_sem);
+       if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++              if (mm->pax_flags & MF_PAX_PAGEEXEC) {
++                      if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
++                              pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
++                              do_group_exit(SIGKILL);
++                      }
++              }
++#endif
++
+               if (exception_trace && printk_ratelimit())
+                       printk("%s%s[%d]: segfault at %08lx pc %08lx "
+                              "sp %08lx ecr %lu\n",
+diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug
+index f3337ee..15b6f8d 100644
+--- a/arch/blackfin/Kconfig.debug
++++ b/arch/blackfin/Kconfig.debug
+@@ -18,6 +18,7 @@ config DEBUG_VERBOSE
+ config DEBUG_MMRS
+       tristate "Generate Blackfin MMR tree"
+       select DEBUG_FS
++      depends on !GRKERNSEC_KMEM
+       help
+         Create a tree of Blackfin MMRs via the debugfs tree.  If
+         you enable this, you will find all MMRs laid out in the
+diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
+index 568885a..f8008df 100644
+--- a/arch/blackfin/include/asm/cache.h
++++ b/arch/blackfin/include/asm/cache.h
+@@ -7,6 +7,7 @@
+ #ifndef __ARCH_BLACKFIN_CACHE_H
+ #define __ARCH_BLACKFIN_CACHE_H
++#include <linux/const.h>
+ #include <linux/linkage.h>    /* for asmlinkage */
+ /*
+@@ -14,7 +15,7 @@
+  * Blackfin loads 32 bytes for cache
+  */
+ #define L1_CACHE_SHIFT        5
+-#define L1_CACHE_BYTES        (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES        (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES       L1_CACHE_BYTES
+ #define ARCH_DMA_MINALIGN     L1_CACHE_BYTES
+diff --git a/arch/cris/include/arch-v10/arch/cache.h b/arch/cris/include/arch-v10/arch/cache.h
+index aea2718..3639a60 100644
+--- a/arch/cris/include/arch-v10/arch/cache.h
++++ b/arch/cris/include/arch-v10/arch/cache.h
+@@ -1,8 +1,9 @@
+ #ifndef _ASM_ARCH_CACHE_H
+ #define _ASM_ARCH_CACHE_H
++#include <linux/const.h>
+ /* Etrax 100LX have 32-byte cache-lines. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ #endif /* _ASM_ARCH_CACHE_H */
+diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
+index 7caf25d..ee65ac5 100644
+--- a/arch/cris/include/arch-v32/arch/cache.h
++++ b/arch/cris/include/arch-v32/arch/cache.h
+@@ -1,11 +1,12 @@
+ #ifndef _ASM_CRIS_ARCH_CACHE_H
+ #define _ASM_CRIS_ARCH_CACHE_H
++#include <linux/const.h>
+ #include <arch/hwregs/dma.h>
+ /* A cache-line is 32 bytes. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
+diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
+index 102190a..5334cea 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -181,6 +181,16 @@ static inline void atomic64_dec(atomic64_t *v)
+ #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
+ #define atomic64_xchg(v, new)         (__xchg_64(new, &(v)->counter))
++#define atomic64_read_unchecked(v)            atomic64_read(v)
++#define atomic64_set_unchecked(v, i)          atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v)          atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v)   atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v)          atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v)             atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v)      atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v)             atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n)   atomic64_cmpxchg((v), (o), (n))
++
+ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+       int c, old;
+diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h
+index 2797163..c2a401df9 100644
+--- a/arch/frv/include/asm/cache.h
++++ b/arch/frv/include/asm/cache.h
+@@ -12,10 +12,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
++#include <linux/const.h>
+ /* bytes per L1 cache line */
+ #define L1_CACHE_SHIFT                (CONFIG_FRV_L1_CACHE_SHIFT)
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define __cacheline_aligned   __attribute__((aligned(L1_CACHE_BYTES)))
+ #define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
+index 43901f2..0d8b865 100644
+--- a/arch/frv/include/asm/kmap_types.h
++++ b/arch/frv/include/asm/kmap_types.h
+@@ -2,6 +2,6 @@
+ #ifndef _ASM_KMAP_TYPES_H
+ #define _ASM_KMAP_TYPES_H
+-#define KM_TYPE_NR 17
++#define KM_TYPE_NR 18
+ #endif
+diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
+index 836f147..4cf23f5 100644
+--- a/arch/frv/mm/elf-fdpic.c
++++ b/arch/frv/mm/elf-fdpic.c
+@@ -61,6 +61,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ {
+       struct vm_area_struct *vma;
+       struct vm_unmapped_area_info info;
++      unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+       if (len > TASK_SIZE)
+               return -ENOMEM;
+@@ -73,8 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+       if (addr) {
+               addr = PAGE_ALIGN(addr);
+               vma = find_vma(current->mm, addr);
+-              if (TASK_SIZE - len >= addr &&
+-                  (!vma || addr + len <= vma->vm_start))
++              if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+                       goto success;
+       }
+@@ -85,6 +85,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+       info.high_limit = (current->mm->start_stack - 0x00200000);
+       info.align_mask = 0;
+       info.align_offset = 0;
++      info.threadstack_offset = offset;
+       addr = vm_unmapped_area(&info);
+       if (!(addr & ~PAGE_MASK))
+               goto success;
+diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h
+index 69952c18..4fa2908 100644
+--- a/arch/hexagon/include/asm/cache.h
++++ b/arch/hexagon/include/asm/cache.h
+@@ -21,9 +21,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
++#include <linux/const.h>
++
+ /* Bytes per L1 cache line */
+-#define L1_CACHE_SHIFT                (5)
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_SHIFT                5
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define ARCH_DMA_MINALIGN     L1_CACHE_BYTES
+diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
+index 42a91a7..29d446e 100644
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
+@@ -518,6 +518,7 @@ source "drivers/sn/Kconfig"
+ config KEXEC
+       bool "kexec system call"
+       depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
++      depends on !GRKERNSEC_KMEM
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
+index 970d0bd..e750b9b 100644
+--- a/arch/ia64/Makefile
++++ b/arch/ia64/Makefile
+@@ -98,5 +98,6 @@ endef
+ archprepare: make_nr_irqs_h FORCE
+ PHONY += make_nr_irqs_h FORCE
++make_nr_irqs_h: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+ make_nr_irqs_h: FORCE
+       $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h
+diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
+index 0bf0350..2ad1957 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -193,4 +193,14 @@ atomic64_add_negative (__s64 i, atomic64_t *v)
+ #define atomic64_inc(v)                       atomic64_add(1, (v))
+ #define atomic64_dec(v)                       atomic64_sub(1, (v))
++#define atomic64_read_unchecked(v)            atomic64_read(v)
++#define atomic64_set_unchecked(v, i)          atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v)          atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v)   atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v)          atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v)             atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v)      atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v)             atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n)   atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* _ASM_IA64_ATOMIC_H */
+diff --git a/arch/ia64/include/asm/barrier.h b/arch/ia64/include/asm/barrier.h
+index 843ba43..fa118fb 100644
+--- a/arch/ia64/include/asm/barrier.h
++++ b/arch/ia64/include/asm/barrier.h
+@@ -66,7 +66,7 @@
+ do {                                                                  \
+       compiletime_assert_atomic_type(*p);                             \
+       barrier();                                                      \
+-      ACCESS_ONCE(*p) = (v);                                          \
++      ACCESS_ONCE_RW(*p) = (v);                                       \
+ } while (0)
+ #define smp_load_acquire(p)                                           \
+diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
+index 988254a..e1ee885 100644
+--- a/arch/ia64/include/asm/cache.h
++++ b/arch/ia64/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_IA64_CACHE_H
+ #define _ASM_IA64_CACHE_H
++#include <linux/const.h>
+ /*
+  * Copyright (C) 1998-2000 Hewlett-Packard Co
+@@ -9,7 +10,7 @@
+ /* Bytes per L1 (data) cache line.  */
+ #define L1_CACHE_SHIFT                CONFIG_IA64_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ #ifdef CONFIG_SMP
+ # define SMP_CACHE_SHIFT      L1_CACHE_SHIFT
+diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
+index 5a83c5c..4d7f553 100644
+--- a/arch/ia64/include/asm/elf.h
++++ b/arch/ia64/include/asm/elf.h
+@@ -42,6 +42,13 @@
+  */
+ #define ELF_ET_DYN_BASE               (TASK_UNMAPPED_BASE + 0x800000000UL)
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
++
++#define PAX_DELTA_MMAP_LEN    (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
++#define PAX_DELTA_STACK_LEN   (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
++#endif
++
+ #define PT_IA_64_UNWIND               0x70000001
+ /* IA-64 relocations: */
+diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
+index f5e70e9..624fad5 100644
+--- a/arch/ia64/include/asm/pgalloc.h
++++ b/arch/ia64/include/asm/pgalloc.h
+@@ -39,6 +39,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
+       pgd_val(*pgd_entry) = __pa(pud);
+ }
++static inline void
++pgd_populate_kernel(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
++{
++      pgd_populate(mm, pgd_entry, pud);
++}
++
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
+@@ -57,6 +63,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
+       pud_val(*pud_entry) = __pa(pmd);
+ }
++static inline void
++pud_populate_kernel(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
++{
++      pud_populate(mm, pud_entry, pmd);
++}
++
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+       return quicklist_alloc(0, GFP_KERNEL, NULL);
+diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
+index 9f3ed9e..c99b418 100644
+--- a/arch/ia64/include/asm/pgtable.h
++++ b/arch/ia64/include/asm/pgtable.h
+@@ -12,7 +12,7 @@
+  *    David Mosberger-Tang <davidm@hpl.hp.com>
+  */
+-
++#include <linux/const.h>
+ #include <asm/mman.h>
+ #include <asm/page.h>
+ #include <asm/processor.h>
+@@ -139,6 +139,17 @@
+ #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
+ #define PAGE_COPY     __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
+ #define PAGE_COPY_EXEC        __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC   __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
++# define PAGE_COPY_NOEXEC     __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
++#else
++# define PAGE_SHARED_NOEXEC   PAGE_SHARED
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++# define PAGE_COPY_NOEXEC     PAGE_COPY
++#endif
++
+ #define PAGE_GATE     __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
+ #define PAGE_KERNEL   __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
+ #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
+diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
+index 45698cd..e8e2dbc 100644
+--- a/arch/ia64/include/asm/spinlock.h
++++ b/arch/ia64/include/asm/spinlock.h
+@@ -71,7 +71,7 @@ static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
+       unsigned short  *p = (unsigned short *)&lock->lock + 1, tmp;
+       asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
+-      ACCESS_ONCE(*p) = (tmp + 2) & ~1;
++      ACCESS_ONCE_RW(*p) = (tmp + 2) & ~1;
+ }
+ static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock)
+diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
+index 4f3fb6cc..254055e 100644
+--- a/arch/ia64/include/asm/uaccess.h
++++ b/arch/ia64/include/asm/uaccess.h
+@@ -70,6 +70,7 @@
+        && ((segment).seg == KERNEL_DS.seg                                             \
+            || likely(REGION_OFFSET((unsigned long) (addr)) < RGN_MAP_LIMIT)));        \
+ })
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size)   __access_ok((addr), (size), get_fs())
+ /*
+@@ -241,12 +242,24 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use
+ static inline unsigned long
+ __copy_to_user (void __user *to, const void *from, unsigned long count)
+ {
++      if (count > INT_MAX)
++              return count;
++
++      if (!__builtin_constant_p(count))
++              check_object_size(from, count, true);
++
+       return __copy_user(to, (__force void __user *) from, count);
+ }
+ static inline unsigned long
+ __copy_from_user (void *to, const void __user *from, unsigned long count)
+ {
++      if (count > INT_MAX)
++              return count;
++
++      if (!__builtin_constant_p(count))
++              check_object_size(to, count, false);
++
+       return __copy_user((__force void __user *) to, from, count);
+ }
+@@ -256,10 +269,13 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
+ ({                                                                                    \
+       void __user *__cu_to = (to);                                                    \
+       const void *__cu_from = (from);                                                 \
+-      long __cu_len = (n);                                                            \
++      unsigned long __cu_len = (n);                                                   \
+                                                                                       \
+-      if (__access_ok(__cu_to, __cu_len, get_fs()))                                   \
++      if (__cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) {          \
++              if (!__builtin_constant_p(n))                                           \
++                      check_object_size(__cu_from, __cu_len, true);                   \
+               __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len);   \
++      }                                                                               \
+       __cu_len;                                                                       \
+ })
+@@ -267,11 +283,14 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
+ ({                                                                                    \
+       void *__cu_to = (to);                                                           \
+       const void __user *__cu_from = (from);                                          \
+-      long __cu_len = (n);                                                            \
++      unsigned long __cu_len = (n);                                                   \
+                                                                                       \
+       __chk_user_ptr(__cu_from);                                                      \
+-      if (__access_ok(__cu_from, __cu_len, get_fs()))                                 \
++      if (__cu_len <= INT_MAX  && __access_ok(__cu_from, __cu_len, get_fs())) {       \
++              if (!__builtin_constant_p(n))                                           \
++                      check_object_size(__cu_to, __cu_len, false);                    \
+               __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len);   \
++      }                                                                               \
+       __cu_len;                                                                       \
+ })
+diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
+index b15933c..098b1c8 100644
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -484,15 +484,39 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
+ }
+ static inline int
++in_init_rx (const struct module *mod, uint64_t addr)
++{
++      return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
++}
++
++static inline int
++in_init_rw (const struct module *mod, uint64_t addr)
++{
++      return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
++}
++
++static inline int
+ in_init (const struct module *mod, uint64_t addr)
+ {
+-      return addr - (uint64_t) mod->module_init < mod->init_size;
++      return in_init_rx(mod, addr) || in_init_rw(mod, addr);
++}
++
++static inline int
++in_core_rx (const struct module *mod, uint64_t addr)
++{
++      return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
++}
++
++static inline int
++in_core_rw (const struct module *mod, uint64_t addr)
++{
++      return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
+ }
+ static inline int
+ in_core (const struct module *mod, uint64_t addr)
+ {
+-      return addr - (uint64_t) mod->module_core < mod->core_size;
++      return in_core_rx(mod, addr) || in_core_rw(mod, addr);
+ }
+ static inline int
+@@ -675,7 +699,14 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
+               break;
+             case RV_BDREL:
+-              val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
++              if (in_init_rx(mod, val))
++                      val -= (uint64_t) mod->module_init_rx;
++              else if (in_init_rw(mod, val))
++                      val -= (uint64_t) mod->module_init_rw;
++              else if (in_core_rx(mod, val))
++                      val -= (uint64_t) mod->module_core_rx;
++              else if (in_core_rw(mod, val))
++                      val -= (uint64_t) mod->module_core_rw;
+               break;
+             case RV_LTV:
+@@ -810,15 +841,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
+                *     addresses have been selected...
+                */
+               uint64_t gp;
+-              if (mod->core_size > MAX_LTOFF)
++              if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
+                       /*
+                        * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
+                        * at the end of the module.
+                        */
+-                      gp = mod->core_size - MAX_LTOFF / 2;
++                      gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
+               else
+-                      gp = mod->core_size / 2;
+-              gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
++                      gp = (mod->core_size_rx + mod->core_size_rw) / 2;
++              gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
+               mod->arch.gp = gp;
+               DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
+       }
+diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
+index c39c3cd..3c77738 100644
+--- a/arch/ia64/kernel/palinfo.c
++++ b/arch/ia64/kernel/palinfo.c
+@@ -980,7 +980,7 @@ static int palinfo_cpu_callback(struct notifier_block *nfb,
+       return NOTIFY_OK;
+ }
+-static struct notifier_block __refdata palinfo_cpu_notifier =
++static struct notifier_block palinfo_cpu_notifier =
+ {
+       .notifier_call = palinfo_cpu_callback,
+       .priority = 0,
+diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
+index 41e33f8..65180b2a 100644
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -28,6 +28,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+       unsigned long align_mask = 0;
+       struct mm_struct *mm = current->mm;
+       struct vm_unmapped_area_info info;
++      unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+       if (len > RGN_MAP_LIMIT)
+               return -ENOMEM;
+@@ -43,6 +44,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+       if (REGION_NUMBER(addr) == RGN_HPAGE)
+               addr = 0;
+ #endif
++
++#ifdef CONFIG_PAX_RANDMMAP
++      if (mm->pax_flags & MF_PAX_RANDMMAP)
++              addr = mm->free_area_cache;
++      else
++#endif
++
+       if (!addr)
+               addr = TASK_UNMAPPED_BASE;
+@@ -61,6 +69,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+       info.high_limit = TASK_SIZE;
+       info.align_mask = align_mask;
+       info.align_offset = 0;
++      info.threadstack_offset = offset;
+       return vm_unmapped_area(&info);
+ }
+diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
+index dc506b0..39baade 100644
+--- a/arch/ia64/kernel/vmlinux.lds.S
++++ b/arch/ia64/kernel/vmlinux.lds.S
+@@ -171,7 +171,7 @@ SECTIONS {
+       /* Per-cpu data: */
+       . = ALIGN(PERCPU_PAGE_SIZE);
+       PERCPU_VADDR(SMP_CACHE_BYTES, PERCPU_ADDR, :percpu)
+-      __phys_per_cpu_start = __per_cpu_load;
++      __phys_per_cpu_start = per_cpu_load;
+       /*
+        * ensure percpu data fits
+        * into percpu page size
+diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
+index 70b40d1..01a9a28 100644
+--- a/arch/ia64/mm/fault.c
++++ b/arch/ia64/mm/fault.c
+@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned long address)
+       return pte_present(pte);
+ }
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 8; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int *)pc+i))
++                      printk(KERN_CONT "???????? ");
++              else
++                      printk(KERN_CONT "%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ #     define VM_READ_BIT      0
+ #     define VM_WRITE_BIT     1
+ #     define VM_EXEC_BIT      2
+@@ -151,8 +168,21 @@ retry:
+       if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
+               goto bad_area;
+-      if ((vma->vm_flags & mask) != mask)
++      if ((vma->vm_flags & mask) != mask) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++              if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
++                      if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
++                              goto bad_area;
++
++                      up_read(&mm->mmap_sem);
++                      pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
++                      do_group_exit(SIGKILL);
++              }
++#endif
++
+               goto bad_area;
++      }
+       /*
+        * If for any reason at all we couldn't handle the fault, make
+diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
+index f50d4b3..c7975ee 100644
+--- a/arch/ia64/mm/hugetlbpage.c
++++ b/arch/ia64/mm/hugetlbpage.c
+@@ -138,6 +138,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
+               unsigned long pgoff, unsigned long flags)
+ {
+       struct vm_unmapped_area_info info;
++      unsigned long offset = gr_rand_threadstack_offset(current->mm, file, flags);
+       if (len > RGN_MAP_LIMIT)
+               return -ENOMEM;
+@@ -161,6 +162,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
+       info.high_limit = HPAGE_REGION_BASE + RGN_MAP_LIMIT;
+       info.align_mask = PAGE_MASK & (HPAGE_SIZE - 1);
+       info.align_offset = 0;
++      info.threadstack_offset = offset;
+       return vm_unmapped_area(&info);
+ }
+diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
+index 97e48b0..fc59c36 100644
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -119,6 +119,19 @@ ia64_init_addr_space (void)
+               vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
+               vma->vm_end = vma->vm_start + PAGE_SIZE;
+               vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++              if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
++                      vma->vm_flags &= ~VM_EXEC;
++
++#ifdef CONFIG_PAX_MPROTECT
++                      if (current->mm->pax_flags & MF_PAX_MPROTECT)
++                              vma->vm_flags &= ~VM_MAYEXEC;
++#endif
++
++              }
++#endif
++
+               vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+               down_write(&current->mm->mmap_sem);
+               if (insert_vm_struct(current->mm, vma)) {
+@@ -279,7 +292,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;
+-      gate_vma.vm_page_prot = __P101;
++      gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
+       return 0;
+ }
+diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h
+index 40b3ee98..8c2c112 100644
+--- a/arch/m32r/include/asm/cache.h
++++ b/arch/m32r/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef _ASM_M32R_CACHE_H
+ #define _ASM_M32R_CACHE_H
++#include <linux/const.h>
++
+ /* L1 cache line size */
+ #define L1_CACHE_SHIFT                4
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ #endif  /* _ASM_M32R_CACHE_H */
+diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
+index 82abd15..d95ae5d 100644
+--- a/arch/m32r/lib/usercopy.c
++++ b/arch/m32r/lib/usercopy.c
+@@ -14,6 +14,9 @@
+ unsigned long
+ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++      if ((long)n < 0)
++              return n;
++
+       prefetch(from);
+       if (access_ok(VERIFY_WRITE, to, n))
+               __copy_user(to,from,n);
+@@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
+ unsigned long
+ __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++      if ((long)n < 0)
++              return n;
++
+       prefetchw(to);
+       if (access_ok(VERIFY_READ, from, n))
+               __copy_user_zeroing(to,from,n);
+diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
+index 0395c51..5f26031 100644
+--- a/arch/m68k/include/asm/cache.h
++++ b/arch/m68k/include/asm/cache.h
+@@ -4,9 +4,11 @@
+ #ifndef __ARCH_M68K_CACHE_H
+ #define __ARCH_M68K_CACHE_H
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+ #define        L1_CACHE_SHIFT  4
+-#define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
++#define        L1_CACHE_BYTES  (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define ARCH_DMA_MINALIGN     L1_CACHE_BYTES
+diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h
+index 5a696e5..070490d 100644
+--- a/arch/metag/include/asm/barrier.h
++++ b/arch/metag/include/asm/barrier.h
+@@ -90,7 +90,7 @@ static inline void fence(void)
+ do {                                                                  \
+       compiletime_assert_atomic_type(*p);                             \
+       smp_mb();                                                       \
+-      ACCESS_ONCE(*p) = (v);                                          \
++      ACCESS_ONCE_RW(*p) = (v);                                       \
+ } while (0)
+ #define smp_load_acquire(p)                                           \
+diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
+index 53f0f6c..2dc07fd 100644
+--- a/arch/metag/mm/hugetlbpage.c
++++ b/arch/metag/mm/hugetlbpage.c
+@@ -189,6 +189,7 @@ hugetlb_get_unmapped_area_new_pmd(unsigned long len)
+       info.high_limit = TASK_SIZE;
+       info.align_mask = PAGE_MASK & HUGEPT_MASK;
+       info.align_offset = 0;
++      info.threadstack_offset = 0;
+       return vm_unmapped_area(&info);
+ }
+diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
+index 4efe96a..60e8699 100644
+--- a/arch/microblaze/include/asm/cache.h
++++ b/arch/microblaze/include/asm/cache.h
+@@ -13,11 +13,12 @@
+ #ifndef _ASM_MICROBLAZE_CACHE_H
+ #define _ASM_MICROBLAZE_CACHE_H
++#include <linux/const.h>
+ #include <asm/registers.h>
+ #define L1_CACHE_SHIFT 5
+ /* word-granular cache in microblaze */
+-#define L1_CACHE_BYTES        (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES        (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES       L1_CACHE_BYTES
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index 199a835..822b487 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -2591,6 +2591,7 @@ source "kernel/Kconfig.preempt"
+ config KEXEC
+       bool "Kexec system call"
++      depends on !GRKERNSEC_KMEM
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
+index d8960d4..77dbd31 100644
+--- a/arch/mips/cavium-octeon/dma-octeon.c
++++ b/arch/mips/cavium-octeon/dma-octeon.c
+@@ -199,7 +199,7 @@ static void octeon_dma_free_coherent(struct device *dev, size_t size,
+       if (dma_release_from_coherent(dev, order, vaddr))
+               return;
+-      swiotlb_free_coherent(dev, size, vaddr, dma_handle);
++      swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs);
+ }
+ static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr)
+diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
+index 26d4363..3c9a82e 100644
+--- a/arch/mips/include/asm/atomic.h
++++ b/arch/mips/include/asm/atomic.h
+@@ -22,15 +22,39 @@
+ #include <asm/cmpxchg.h>
+ #include <asm/war.h>
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i)          { (i) }
++#ifdef CONFIG_64BIT
++#define _ASM_EXTABLE(from, to)                \
++"     .section __ex_table,\"a\"\n"    \
++"     .dword  " #from ", " #to"\n"    \
++"     .previous\n"
++#else
++#define _ASM_EXTABLE(from, to)                \
++"     .section __ex_table,\"a\"\n"    \
++"     .word   " #from ", " #to"\n"    \
++"     .previous\n"
++#endif
++
+ /*
+  * atomic_read - read atomic variable
+  * @v: pointer of type atomic_t
+  *
+  * Atomically reads the value of @v.
+  */
+-#define atomic_read(v)                ACCESS_ONCE((v)->counter)
++static inline int atomic_read(const atomic_t *v)
++{
++      return ACCESS_ONCE(v->counter);
++}
++
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++      return ACCESS_ONCE(v->counter);
++}
+ /*
+  * atomic_set - set atomic variable
+@@ -39,47 +63,77 @@
+  *
+  * Atomically sets the value of @v to @i.
+  */
+-#define atomic_set(v, i)              ((v)->counter = (i))
++static inline void atomic_set(atomic_t *v, int i)
++{
++      v->counter = i;
++}
+-#define ATOMIC_OP(op, c_op, asm_op)                                         \
+-static __inline__ void atomic_##op(int i, atomic_t * v)                             \
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++      v->counter = i;
++}
++
++#ifdef CONFIG_PAX_REFCOUNT
++#define __OVERFLOW_POST                               \
++      "       b       4f              \n"     \
++      "       .set    noreorder       \n"     \
++      "3:     b       5f              \n"     \
++      "       move    %0, %1          \n"     \
++      "       .set    reorder         \n"
++#define __OVERFLOW_EXTABLE    \
++      "3:\n"                  \
++      _ASM_EXTABLE(2b, 3b)
++#else
++#define __OVERFLOW_POST
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, asm_op, extable)                            \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t * v)       \
+ {                                                                           \
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {                            \
+               int temp;                                                     \
+                                                                             \
+               __asm__ __volatile__(                                         \
+-              "       .set    arch=r4000                              \n"   \
+-              "1:     ll      %0, %1          # atomic_" #op "        \n"   \
+-              "       " #asm_op " %0, %2                              \n"   \
++              "       .set    mips3                                   \n"   \
++              "1:     ll      %0, %1          # atomic_" #op #suffix "\n"   \
++              "2:     " #asm_op " %0, %2                              \n"   \
+               "       sc      %0, %1                                  \n"   \
+               "       beqzl   %0, 1b                                  \n"   \
++              extable                                                       \
+               "       .set    mips0                                   \n"   \
+               : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)          \
+               : "Ir" (i));                                                  \
+       } else if (kernel_uses_llsc) {                                        \
+               int temp;                                                     \
+                                                                             \
+-              do {                                                          \
+-                      __asm__ __volatile__(                                 \
+-                      "       .set    "MIPS_ISA_LEVEL"                \n"   \
+-                      "       ll      %0, %1          # atomic_" #op "\n"   \
+-                      "       " #asm_op " %0, %2                      \n"   \
+-                      "       sc      %0, %1                          \n"   \
+-                      "       .set    mips0                           \n"   \
+-                      : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)      \
+-                      : "Ir" (i));                                          \
+-              } while (unlikely(!temp));                                    \
++              __asm__ __volatile__(                                         \
++              "       .set    "MIPS_ISA_LEVEL"                        \n"   \
++              "1:     ll      %0, %1          # atomic_" #op #suffix "\n"   \
++              "2:     " #asm_op " %0, %2                              \n"   \
++              "       sc      %0, %1                                  \n"   \
++              "       beqz    %0, 1b                                  \n"   \
++                      extable                                               \
++              "       .set    mips0                                   \n"   \
++              : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)          \
++              : "Ir" (i));                                                  \
+       } else {                                                              \
+               unsigned long flags;                                          \
+                                                                             \
+               raw_local_irq_save(flags);                                    \
+-              v->counter c_op i;                                            \
++              __asm__ __volatile__(                                         \
++              "2:     " #asm_op " %0, %1                              \n"   \
++              extable                                                       \
++              : "+r" (v->counter) : "Ir" (i));                              \
+               raw_local_irq_restore(flags);                                 \
+       }                                                                     \
+ }
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op)                                  \
+-static __inline__ int atomic_##op##_return(int i, atomic_t * v)                     \
++#define ATOMIC_OP(op, asm_op) __ATOMIC_OP(op, _unchecked, asm_op##u, )              \
++                            __ATOMIC_OP(op, , asm_op, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC_OP_RETURN(op, suffix, asm_op, post_op, extable)            \
++static inline int atomic_##op##_return##suffix(int i, atomic##suffix##_t * v) \
+ {                                                                           \
+       int result;                                                           \
+                                                                             \
+@@ -89,12 +143,15 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v)                 \
+               int temp;                                                     \
+                                                                             \
+               __asm__ __volatile__(                                         \
+-              "       .set    arch=r4000                              \n"   \
+-              "1:     ll      %1, %2          # atomic_" #op "_return \n"   \
+-              "       " #asm_op " %0, %1, %3                          \n"   \
++              "       .set    mips3                                   \n"   \
++              "1:     ll      %1, %2  # atomic_" #op "_return" #suffix"\n"  \
++              "2:     " #asm_op " %0, %1, %3                          \n"   \
+               "       sc      %0, %2                                  \n"   \
+               "       beqzl   %0, 1b                                  \n"   \
+-              "       " #asm_op " %0, %1, %3                          \n"   \
++              post_op                                                       \
++              extable                                                       \
++              "4:     " #asm_op " %0, %1, %3                          \n"   \
++              "5:                                                     \n"   \
+               "       .set    mips0                                   \n"   \
+               : "=&r" (result), "=&r" (temp),                               \
+                 "+" GCC_OFF_SMALL_ASM() (v->counter)                        \
+@@ -102,26 +159,33 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v)                \
+       } else if (kernel_uses_llsc) {                                        \
+               int temp;                                                     \
+                                                                             \
+-              do {                                                          \
+-                      __asm__ __volatile__(                                 \
+-                      "       .set    "MIPS_ISA_LEVEL"                \n"   \
+-                      "       ll      %1, %2  # atomic_" #op "_return \n"   \
+-                      "       " #asm_op " %0, %1, %3                  \n"   \
+-                      "       sc      %0, %2                          \n"   \
+-                      "       .set    mips0                           \n"   \
+-                      : "=&r" (result), "=&r" (temp),                       \
+-                        "+" GCC_OFF_SMALL_ASM() (v->counter)                \
+-                      : "Ir" (i));                                          \
+-              } while (unlikely(!result));                                  \
++              __asm__ __volatile__(                                         \
++              "       .set    "MIPS_ISA_LEVEL"                        \n"   \
++              "1:     ll      %1, %2  # atomic_" #op "_return" #suffix "\n" \
++              "2:     " #asm_op " %0, %1, %3                          \n"   \
++              "       sc      %0, %2                                  \n"   \
++              post_op                                                       \
++              extable                                                       \
++              "4:     " #asm_op " %0, %1, %3                          \n"   \
++              "5:                                                     \n"   \
++              "       .set    mips0                                   \n"   \
++              : "=&r" (result), "=&r" (temp),                               \
++                "+" GCC_OFF_SMALL_ASM() (v->counter)                        \
++              : "Ir" (i));                                                  \
+                                                                             \
+               result = temp; result c_op i;                                 \
+       } else {                                                              \
+               unsigned long flags;                                          \
+                                                                             \
+               raw_local_irq_save(flags);                                    \
+-              result = v->counter;                                          \
+-              result c_op i;                                                \
+-              v->counter = result;                                          \
++              __asm__ __volatile__(                                         \
++              "       lw      %0, %1                                  \n"   \
++              "2:     " #asm_op " %0, %1, %2                          \n"   \
++              "       sw      %0, %1                                  \n"   \
++              "3:                                                     \n"   \
++              extable                                                       \
++              : "=&r" (result), "+" GCC_OFF_SMALL_ASM() (v->counter)        \
++              : "Ir" (i));                                                  \
+               raw_local_irq_restore(flags);                                 \
+       }                                                                     \
+                                                                             \
+@@ -130,16 +194,21 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v)                \
+       return result;                                                        \
+ }
+-#define ATOMIC_OPS(op, c_op, asm_op)                                        \
+-      ATOMIC_OP(op, c_op, asm_op)                                           \
+-      ATOMIC_OP_RETURN(op, c_op, asm_op)
++#define ATOMIC_OP_RETURN(op, asm_op) __ATOMIC_OP_RETURN(op, _unchecked, asm_op##u, , )        \
++                                   __ATOMIC_OP_RETURN(op, , asm_op, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
+-ATOMIC_OPS(add, +=, addu)
+-ATOMIC_OPS(sub, -=, subu)
++#define ATOMIC_OPS(op, asm_op)                                                      \
++      ATOMIC_OP(op, asm_op)                                                 \
++      ATOMIC_OP_RETURN(op, asm_op)
++
++ATOMIC_OPS(add, add)
++ATOMIC_OPS(sub, sub)
+ #undef ATOMIC_OPS
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+ /*
+  * atomic_sub_if_positive - conditionally subtract integer from atomic variable
+@@ -149,7 +218,7 @@ ATOMIC_OPS(sub, -=, subu)
+  * Atomically test @v and subtract @i if @v is greater or equal than @i.
+  * The function returns the old value of @v minus @i.
+  */
+-static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
++static __inline__ int atomic_sub_if_positive(int i, atomic_t *v)
+ {
+       int result;
+@@ -159,7 +228,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+               int temp;
+               __asm__ __volatile__(
+-              "       .set    arch=r4000                              \n"
++              "       .set    "MIPS_ISA_LEVEL"                        \n"
+               "1:     ll      %1, %2          # atomic_sub_if_positive\n"
+               "       subu    %0, %1, %3                              \n"
+               "       bltz    %0, 1f                                  \n"
+@@ -208,8 +277,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+       return result;
+ }
+-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
++{
++      return cmpxchg(&v->counter, old, new);
++}
++
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old,
++                                         int new)
++{
++      return cmpxchg(&(v->counter), old, new);
++}
++
++static inline int atomic_xchg(atomic_t *v, int new)
++{
++      return xchg(&v->counter, new);
++}
++
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++      return xchg(&(v->counter), new);
++}
+ /**
+  * __atomic_add_unless - add unless the number is a given value
+@@ -237,6 +324,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ #define atomic_dec_return(v) atomic_sub_return(1, (v))
+ #define atomic_inc_return(v) atomic_add_return(1, (v))
++static __inline__ int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++      return atomic_add_return_unchecked(1, v);
++}
+ /*
+  * atomic_sub_and_test - subtract value from variable and test result
+@@ -258,6 +349,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+  * other cases.
+  */
+ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
++static __inline__ int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++      return atomic_add_return_unchecked(1, v) == 0;
++}
+ /*
+  * atomic_dec_and_test - decrement by 1 and test
+@@ -282,6 +377,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+  * Atomically increments @v by 1.
+  */
+ #define atomic_inc(v) atomic_add(1, (v))
++static __inline__ void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++      atomic_add_unchecked(1, v);
++}
+ /*
+  * atomic_dec - decrement and test
+@@ -290,6 +389,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+  * Atomically decrements @v by 1.
+  */
+ #define atomic_dec(v) atomic_sub(1, (v))
++static __inline__ void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++      atomic_sub_unchecked(1, v);
++}
+ /*
+  * atomic_add_negative - add and test if negative
+@@ -311,54 +414,77 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+  * @v: pointer of type atomic64_t
+  *
+  */
+-#define atomic64_read(v)      ACCESS_ONCE((v)->counter)
++static inline long atomic64_read(const atomic64_t *v)
++{
++      return ACCESS_ONCE(v->counter);
++}
++
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++      return ACCESS_ONCE(v->counter);
++}
+ /*
+  * atomic64_set - set atomic variable
+  * @v: pointer of type atomic64_t
+  * @i: required value
+  */
+-#define atomic64_set(v, i)    ((v)->counter = (i))
++static inline void atomic64_set(atomic64_t *v, long i)
++{
++      v->counter = i;
++}
+-#define ATOMIC64_OP(op, c_op, asm_op)                                       \
+-static __inline__ void atomic64_##op(long i, atomic64_t * v)                \
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++      v->counter = i;
++}
++
++#define __ATOMIC64_OP(op, suffix, asm_op, extable)                          \
++static inline void atomic64_##op##suffix(long i, atomic64##suffix##_t * v)    \
+ {                                                                           \
+       if (kernel_uses_llsc && R10000_LLSC_WAR) {                            \
+               long temp;                                                    \
+                                                                             \
+               __asm__ __volatile__(                                         \
+-              "       .set    arch=r4000                              \n"   \
+-              "1:     lld     %0, %1          # atomic64_" #op "      \n"   \
+-              "       " #asm_op " %0, %2                              \n"   \
++              "       .set    "MIPS_ISA_LEVEL"                        \n"   \
++              "1:     lld     %0, %1          # atomic64_" #op #suffix "\n" \
++              "2:     " #asm_op " %0, %2                              \n"   \
+               "       scd     %0, %1                                  \n"   \
+               "       beqzl   %0, 1b                                  \n"   \
++              extable                                                       \
+               "       .set    mips0                                   \n"   \
+               : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)          \
+               : "Ir" (i));                                                  \
+       } else if (kernel_uses_llsc) {                                        \
+               long temp;                                                    \
+                                                                             \
+-              do {                                                          \
+-                      __asm__ __volatile__(                                 \
+-                      "       .set    "MIPS_ISA_LEVEL"                \n"   \
+-                      "       lld     %0, %1          # atomic64_" #op "\n" \
+-                      "       " #asm_op " %0, %2                      \n"   \
+-                      "       scd     %0, %1                          \n"   \
+-                      "       .set    mips0                           \n"   \
+-                      : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)      \
+-                      : "Ir" (i));                                          \
+-              } while (unlikely(!temp));                                    \
++              __asm__ __volatile__(                                         \
++              "       .set    "MIPS_ISA_LEVEL"                        \n"   \
++              "1:     lld     %0, %1          # atomic64_" #op #suffix "\n" \
++              "2:     " #asm_op " %0, %2                              \n"   \
++              "       scd     %0, %1                                  \n"   \
++              "       beqz    %0, 1b                                  \n"   \
++                      extable                                               \
++              "       .set    mips0                                   \n"   \
++              : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)          \
++              : "Ir" (i));                                                  \
+       } else {                                                              \
+               unsigned long flags;                                          \
+                                                                             \
+               raw_local_irq_save(flags);                                    \
+-              v->counter c_op i;                                            \
++              __asm__ __volatile__(                                         \
++              "2:     " #asm_op " %0, %1                              \n"   \
++              extable                                                       \
++              : "+" GCC_OFF_SMALL_ASM() (v->counter) : "Ir" (i));           \
+               raw_local_irq_restore(flags);                                 \
+       }                                                                     \
+ }
+-#define ATOMIC64_OP_RETURN(op, c_op, asm_op)                                \
+-static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)       \
++#define ATOMIC64_OP(op, asm_op) __ATOMIC64_OP(op, _unchecked, asm_op##u, )    \
++                              __ATOMIC64_OP(op, , asm_op, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, asm_op, post_op, extable)          \
++static inline long atomic64_##op##_return##suffix(long i, atomic64##suffix##_t * v)\
+ {                                                                           \
+       long result;                                                          \
+                                                                             \
+@@ -368,12 +494,15 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)          \
+               long temp;                                                    \
+                                                                             \
+               __asm__ __volatile__(                                         \
+-              "       .set    arch=r4000                              \n"   \
++              "       .set    mips3                                   \n"   \
+               "1:     lld     %1, %2          # atomic64_" #op "_return\n"  \
+-              "       " #asm_op " %0, %1, %3                          \n"   \
++              "2:     " #asm_op " %0, %1, %3                          \n"   \
+               "       scd     %0, %2                                  \n"   \
+               "       beqzl   %0, 1b                                  \n"   \
+-              "       " #asm_op " %0, %1, %3                          \n"   \
++              post_op                                                       \
++              extable                                                       \
++              "4:     " #asm_op " %0, %1, %3                          \n"   \
++              "5:                                                     \n"   \
+               "       .set    mips0                                   \n"   \
+               : "=&r" (result), "=&r" (temp),                               \
+                 "+" GCC_OFF_SMALL_ASM() (v->counter)                        \
+@@ -381,27 +510,35 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)          \
+       } else if (kernel_uses_llsc) {                                        \
+               long temp;                                                    \
+                                                                             \
+-              do {                                                          \
+-                      __asm__ __volatile__(                                 \
+-                      "       .set    "MIPS_ISA_LEVEL"                \n"   \
+-                      "       lld     %1, %2  # atomic64_" #op "_return\n"  \
+-                      "       " #asm_op " %0, %1, %3                  \n"   \
+-                      "       scd     %0, %2                          \n"   \
+-                      "       .set    mips0                           \n"   \
+-                      : "=&r" (result), "=&r" (temp),                       \
+-                        "=" GCC_OFF_SMALL_ASM() (v->counter)                \
+-                      : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter)          \
+-                      : "memory");                                          \
+-              } while (unlikely(!result));                                  \
++              __asm__ __volatile__(                                         \
++              "       .set    "MIPS_ISA_LEVEL"                        \n"   \
++              "1:     lld     %1, %2  # atomic64_" #op "_return" #suffix "\n"\
++              "2:     " #asm_op " %0, %1, %3                          \n"   \
++              "       scd     %0, %2                                  \n"   \
++              "       beqz    %0, 1b                                  \n"   \
++              post_op                                                       \
++              extable                                                       \
++              "4:     " #asm_op " %0, %1, %3                          \n"   \
++              "5:                                                     \n"   \
++              "       .set    mips0                                   \n"   \
++              : "=&r" (result), "=&r" (temp),                               \
++                "=" GCC_OFF_SMALL_ASM() (v->counter)                        \
++              : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter)                  \
++              : "memory");                                                  \
+                                                                             \
+               result = temp; result c_op i;                                 \
+       } else {                                                              \
+               unsigned long flags;                                          \
+                                                                             \
+               raw_local_irq_save(flags);                                    \
+-              result = v->counter;                                          \
+-              result c_op i;                                                \
+-              v->counter = result;                                          \
++              __asm__ __volatile__(                                         \
++              "       ld      %0, %1                                  \n"   \
++              "2:     " #asm_op " %0, %1, %2                          \n"   \
++              "       sd      %0, %1                                  \n"   \
++              "3:                                                     \n"   \
++              extable                                                       \
++              : "=&r" (result), "+" GCC_OFF_SMALL_ASM() (v->counter)        \
++              : "Ir" (i));                                                  \
+               raw_local_irq_restore(flags);                                 \
+       }                                                                     \
+                                                                             \
+@@ -410,16 +547,23 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)          \
+       return result;                                                        \
+ }
+-#define ATOMIC64_OPS(op, c_op, asm_op)                                              \
+-      ATOMIC64_OP(op, c_op, asm_op)                                         \
+-      ATOMIC64_OP_RETURN(op, c_op, asm_op)
++#define ATOMIC64_OP_RETURN(op, asm_op) __ATOMIC64_OP_RETURN(op, _unchecked, asm_op##u, , )    \
++                                     __ATOMIC64_OP_RETURN(op, , asm_op, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
+-ATOMIC64_OPS(add, +=, daddu)
+-ATOMIC64_OPS(sub, -=, dsubu)
++#define ATOMIC64_OPS(op, asm_op)                                              \
++      ATOMIC64_OP(op, asm_op)                                                 \
++      ATOMIC64_OP_RETURN(op, asm_op)
++
++ATOMIC64_OPS(add, dadd)
++ATOMIC64_OPS(sub, dsub)
+ #undef ATOMIC64_OPS
+ #undef ATOMIC64_OP_RETURN
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_EXTABLE
++#undef __OVERFLOW_POST
+ /*
+  * atomic64_sub_if_positive - conditionally subtract integer from atomic
+@@ -430,7 +574,7 @@ ATOMIC64_OPS(sub, -=, dsubu)
+  * Atomically test @v and subtract @i if @v is greater or equal than @i.
+  * The function returns the old value of @v minus @i.
+  */
+-static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
++static __inline__ long atomic64_sub_if_positive(long i, atomic64_t *v)
+ {
+       long result;
+@@ -440,7 +584,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+               long temp;
+               __asm__ __volatile__(
+-              "       .set    arch=r4000                              \n"
++              "       .set    "MIPS_ISA_LEVEL"                        \n"
+               "1:     lld     %1, %2          # atomic64_sub_if_positive\n"
+               "       dsubu   %0, %1, %3                              \n"
+               "       bltz    %0, 1f                                  \n"
+@@ -489,9 +633,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+       return result;
+ }
+-#define atomic64_cmpxchg(v, o, n) \
+-      ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
++{
++      return cmpxchg(&v->counter, old, new);
++}
++
++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old,
++                                            long new)
++{
++      return cmpxchg(&(v->counter), old, new);
++}
++
++static inline long atomic64_xchg(atomic64_t *v, long new)
++{
++      return xchg(&v->counter, new);
++}
++
++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new)
++{
++      return xchg(&(v->counter), new);
++}
+ /**
+  * atomic64_add_unless - add unless the number is a given value
+@@ -521,6 +682,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ #define atomic64_dec_return(v) atomic64_sub_return(1, (v))
+ #define atomic64_inc_return(v) atomic64_add_return(1, (v))
++#define atomic64_inc_return_unchecked(v) atomic64_add_return_unchecked(1, (v))
+ /*
+  * atomic64_sub_and_test - subtract value from variable and test result
+@@ -542,6 +704,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+  * other cases.
+  */
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
++#define atomic64_inc_and_test_unchecked(v) atomic64_add_return_unchecked(1, (v)) == 0)
+ /*
+  * atomic64_dec_and_test - decrement by 1 and test
+@@ -566,6 +729,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+  * Atomically increments @v by 1.
+  */
+ #define atomic64_inc(v) atomic64_add(1, (v))
++#define atomic64_inc_unchecked(v) atomic64_add_unchecked(1, (v))
+ /*
+  * atomic64_dec - decrement and test
+@@ -574,6 +738,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+  * Atomically decrements @v by 1.
+  */
+ #define atomic64_dec(v) atomic64_sub(1, (v))
++#define atomic64_dec_unchecked(v) atomic64_sub_unchecked(1, (v))
+ /*
+  * atomic64_add_negative - add and test if negative
+diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
+index 7ecba84..21774af 100644
+--- a/arch/mips/include/asm/barrier.h
++++ b/arch/mips/include/asm/barrier.h
+@@ -133,7 +133,7 @@
+ do {                                                                  \
+       compiletime_assert_atomic_type(*p);                             \
+       smp_mb();                                                       \
+-      ACCESS_ONCE(*p) = (v);                                          \
++      ACCESS_ONCE_RW(*p) = (v);                                       \
+ } while (0)
+ #define smp_load_acquire(p)                                           \
+diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
+index b4db69f..8f3b093 100644
+--- a/arch/mips/include/asm/cache.h
++++ b/arch/mips/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #ifndef _ASM_CACHE_H
+ #define _ASM_CACHE_H
++#include <linux/const.h>
+ #include <kmalloc.h>
+ #define L1_CACHE_SHIFT                CONFIG_MIPS_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES                (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES                (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_SHIFT               L1_CACHE_SHIFT
+ #define SMP_CACHE_BYTES               L1_CACHE_BYTES
+diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
+index f19e890..a4f8177 100644
+--- a/arch/mips/include/asm/elf.h
++++ b/arch/mips/include/asm/elf.h
+@@ -417,6 +417,13 @@ extern const char *__elf_platform;
+ #define ELF_ET_DYN_BASE               (TASK_SIZE / 3 * 2)
+ #endif
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN    (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN   (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+ struct linux_binprm;
+ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+diff --git a/arch/mips/include/asm/exec.h b/arch/mips/include/asm/exec.h
+index c1f6afa..38cc6e9 100644
+--- a/arch/mips/include/asm/exec.h
++++ b/arch/mips/include/asm/exec.h
+@@ -12,6 +12,6 @@
+ #ifndef _ASM_EXEC_H
+ #define _ASM_EXEC_H
+-extern unsigned long arch_align_stack(unsigned long sp);
++#define arch_align_stack(x) ((x) & ~0xfUL)
+ #endif /* _ASM_EXEC_H */
+diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h
+index 9e8ef59..1139d6b 100644
+--- a/arch/mips/include/asm/hw_irq.h
++++ b/arch/mips/include/asm/hw_irq.h
+@@ -10,7 +10,7 @@
+ #include <linux/atomic.h>
+-extern atomic_t irq_err_count;
++extern atomic_unchecked_t irq_err_count;
+ /*
+  * interrupt-retrigger: NOP for now. This may not be appropriate for all
+diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
+index 8feaed6..1bd8a64 100644
+--- a/arch/mips/include/asm/local.h
++++ b/arch/mips/include/asm/local.h
+@@ -13,15 +13,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
+@@ -71,6 +81,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;
+@@ -118,6 +173,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 89dd7fe..a123c97 100644
+--- a/arch/mips/include/asm/page.h
++++ b/arch/mips/include/asm/page.h
+@@ -118,7 +118,7 @@ extern void copy_user_highpage(struct page *to, struct page *from,
+   #ifdef CONFIG_CPU_MIPS32
+     typedef struct { unsigned long pte_low, pte_high; } pte_t;
+     #define pte_val(x)          ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+-    #define __pte(x)    ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
++    #define __pte(x)    ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
+   #else
+      typedef struct { unsigned long long pte; } pte_t;
+      #define pte_val(x) ((x).pte)
+diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
+index b336037..5b874cc 100644
+--- a/arch/mips/include/asm/pgalloc.h
++++ b/arch/mips/include/asm/pgalloc.h
+@@ -37,6 +37,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+       set_pud(pud, __pud((unsigned long)pmd));
+ }
++
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++      pud_populate(mm, pud, pmd);
++}
+ #endif
+ /*
+diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
+index ae85694..4cdbba8 100644
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -20,6 +20,9 @@
+ #include <asm/io.h>
+ #include <asm/pgtable-bits.h>
++#define ktla_ktva(addr)               (addr)
++#define ktva_ktla(addr)               (addr)
++
+ struct mm_struct;
+ struct vm_area_struct;
+diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
+index 9c0014e..5101ef5 100644
+--- a/arch/mips/include/asm/thread_info.h
++++ b/arch/mips/include/asm/thread_info.h
+@@ -100,6 +100,9 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_SECCOMP           4       /* secure computing */
+ #define TIF_NOTIFY_RESUME     5       /* callback before returning to user */
+ #define TIF_RESTORE_SIGMASK   9       /* restore signal mask in do_signal() */
++/* li takes a 32bit immediate */
++#define TIF_GRSEC_SETXID      10      /* update credentials on syscall entry/exit */
++
+ #define TIF_USEDFPU           16      /* FPU was used by this task this quantum (SMP) */
+ #define TIF_MEMDIE            18      /* is terminating due to OOM killer */
+ #define TIF_NOHZ              19      /* in adaptive nohz mode */
+@@ -135,14 +138,16 @@ static inline struct thread_info *current_thread_info(void)
+ #define _TIF_USEDMSA          (1<<TIF_USEDMSA)
+ #define _TIF_MSA_CTX_LIVE     (1<<TIF_MSA_CTX_LIVE)
+ #define _TIF_SYSCALL_TRACEPOINT       (1<<TIF_SYSCALL_TRACEPOINT)
++#define _TIF_GRSEC_SETXID     (1<<TIF_GRSEC_SETXID)
+ #define _TIF_WORK_SYSCALL_ENTRY       (_TIF_NOHZ | _TIF_SYSCALL_TRACE |       \
+                                _TIF_SYSCALL_AUDIT | \
+-                               _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
++                               _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
++                               _TIF_GRSEC_SETXID)
+ /* work to do in syscall_trace_leave() */
+ #define _TIF_WORK_SYSCALL_EXIT        (_TIF_NOHZ | _TIF_SYSCALL_TRACE |       \
+-                               _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
++                               _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT | _TIF_GRSEC_SETXID)
+ /* work to do on interrupt/exception return */
+ #define _TIF_WORK_MASK                \
+@@ -150,7 +155,7 @@ static inline struct thread_info *current_thread_info(void)
+ /* work to do on any return to u-space */
+ #define _TIF_ALLWORK_MASK     (_TIF_NOHZ | _TIF_WORK_MASK |           \
+                                _TIF_WORK_SYSCALL_EXIT |               \
+-                               _TIF_SYSCALL_TRACEPOINT)
++                               _TIF_SYSCALL_TRACEPOINT | _TIF_GRSEC_SETXID)
+ /*
+  * We stash processor id into a COP0 register to retrieve it fast
+diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
+index 5305d69..1da2bf5 100644
+--- a/arch/mips/include/asm/uaccess.h
++++ b/arch/mips/include/asm/uaccess.h
+@@ -146,6 +146,7 @@ static inline bool eva_kernel_access(void)
+       __ok == 0;                                                      \
+ })
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size)                                   \
+       likely(__access_ok((addr), (size), __access_mask))
+diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
+index 1188e00..41cf144 100644
+--- a/arch/mips/kernel/binfmt_elfn32.c
++++ b/arch/mips/kernel/binfmt_elfn32.c
+@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #undef ELF_ET_DYN_BASE
+ #define ELF_ET_DYN_BASE               (TASK32_SIZE / 3 * 2)
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN    (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN   (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #include <asm/processor.h>
+ #include <linux/module.h>
+ #include <linux/elfcore.h>
+diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
+index 9287678..f870e47 100644
+--- a/arch/mips/kernel/binfmt_elfo32.c
++++ b/arch/mips/kernel/binfmt_elfo32.c
+@@ -70,6 +70,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #undef ELF_ET_DYN_BASE
+ #define ELF_ET_DYN_BASE               (TASK32_SIZE / 3 * 2)
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE   (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN    (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN   (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #include <asm/processor.h>
+ #include <linux/module.h>
+diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
+index 74f6752..f3d7a47 100644
+--- a/arch/mips/kernel/i8259.c
++++ b/arch/mips/kernel/i8259.c
+@@ -205,7 +205,7 @@ spurious_8259A_irq:
+                       printk(KERN_DEBUG "spurious 8259A interrupt: IRQ%d.\n", irq);
+                       spurious_irq_mask |= irqmask;
+               }
+-              atomic_inc(&irq_err_count);
++              atomic_inc_unchecked(&irq_err_count);
+               /*
+                * Theoretically we do not have to handle this IRQ,
+                * but in Linux this does not cause problems and is
+diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
+index 44a1f79..2bd6aa3 100644
+--- a/arch/mips/kernel/irq-gt641xx.c
++++ b/arch/mips/kernel/irq-gt641xx.c
+@@ -110,7 +110,7 @@ void gt641xx_irq_dispatch(void)
+               }
+       }
+-      atomic_inc(&irq_err_count);
++      atomic_inc_unchecked(&irq_err_count);
+ }
+ void __init gt641xx_irq_init(void)
+diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
+index 8eb5af8..2baf465 100644
+--- a/arch/mips/kernel/irq.c
++++ b/arch/mips/kernel/irq.c
+@@ -34,17 +34,17 @@ void ack_bad_irq(unsigned int irq)
+       printk("unexpected IRQ # %d\n", irq);
+ }
+-atomic_t irq_err_count;
++atomic_unchecked_t irq_err_count;
+ int arch_show_interrupts(struct seq_file *p, int prec)
+ {
+-      seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
++      seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read_unchecked(&irq_err_count));
+       return 0;
+ }
+ asmlinkage void spurious_interrupt(void)
+ {
+-      atomic_inc(&irq_err_count);
++      atomic_inc_unchecked(&irq_err_count);
+ }
+ void __init init_IRQ(void)
+@@ -58,6 +58,8 @@ void __init init_IRQ(void)
+ }
+ #ifdef CONFIG_DEBUG_STACKOVERFLOW
++
++extern void gr_handle_kernel_exploit(void);
+ static inline void check_stack_overflow(void)
+ {
+       unsigned long sp;
+@@ -73,6 +75,7 @@ static inline void check_stack_overflow(void)
+               printk("do_IRQ: stack overflow: %ld\n",
+                      sp - sizeof(struct thread_info));
+               dump_stack();
++              gr_handle_kernel_exploit();
+       }
+ }
+ #else
+diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
+index 0614717..002fa43 100644
+--- a/arch/mips/kernel/pm-cps.c
++++ b/arch/mips/kernel/pm-cps.c
+@@ -172,7 +172,7 @@ int cps_pm_enter_state(enum cps_pm_state state)
+       nc_core_ready_count = nc_addr;
+       /* Ensure ready_count is zero-initialised before the assembly runs */
+-      ACCESS_ONCE(*nc_core_ready_count) = 0;
++      ACCESS_ONCE_RW(*nc_core_ready_count) = 0;
+       coupled_barrier(&per_cpu(pm_barrier, core), online);
+       /* Run the generated entry code */
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index f2975d4..f61d355 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -541,18 +541,6 @@ out:
+       return pc;
+ }
+-/*
+- * Don't forget that the stack pointer must be aligned on a 8 bytes
+- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
+- */
+-unsigned long arch_align_stack(unsigned long sp)
+-{
+-      if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+-              sp -= get_random_int() & ~PAGE_MASK;
+-
+-      return sp & ALMASK;
+-}
+-
+ static void arch_dump_stack(void *info)
+ {
+       struct pt_regs *regs;
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+index e933a30..0d02625 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -785,6 +785,10 @@ long arch_ptrace(struct task_struct *child, long request,
+       return ret;
+ }
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /*
+  * Notification of system call entry/exit
+  * - triggered by current->work.syscall_trace
+@@ -803,6 +807,11 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
+           tracehook_report_syscall_entry(regs))
+               ret = -1;
++#ifdef CONFIG_GRKERNSEC_SETXID
++      if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++              gr_delayed_cred_worker();
++#endif
++
+       if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+               trace_sys_enter(regs, regs->regs[2]);
+diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
+index 2242bdd..b284048 100644
+--- a/arch/mips/kernel/sync-r4k.c
++++ b/arch/mips/kernel/sync-r4k.c
+@@ -18,8 +18,8 @@
+ #include <asm/mipsregs.h>
+ static atomic_t count_start_flag = ATOMIC_INIT(0);
+-static atomic_t count_count_start = ATOMIC_INIT(0);
+-static atomic_t count_count_stop = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_start = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_stop = ATOMIC_INIT(0);
+ static atomic_t count_reference = ATOMIC_INIT(0);
+ #define COUNTON 100
+@@ -58,13 +58,13 @@ void synchronise_count_master(int cpu)
+       for (i = 0; i < NR_LOOPS; i++) {
+               /* slaves loop on '!= 2' */
+-              while (atomic_read(&count_count_start) != 1)
++              while (atomic_read_unchecked(&count_count_start) != 1)
+                       mb();
+-              atomic_set(&count_count_stop, 0);
++              atomic_set_unchecked(&count_count_stop, 0);
+               smp_wmb();
+               /* this lets the slaves write their count register */
+-              atomic_inc(&count_count_start);
++              atomic_inc_unchecked(&count_count_start);
+               /*
+                * Everyone initialises count in the last loop:
+@@ -75,11 +75,11 @@ void synchronise_count_master(int cpu)
+               /*
+                * Wait for all slaves to leave the synchronization point:
+                */
+-              while (atomic_read(&count_count_stop) != 1)
++              while (atomic_read_unchecked(&count_count_stop) != 1)
+                       mb();
+-              atomic_set(&count_count_start, 0);
++              atomic_set_unchecked(&count_count_start, 0);
+               smp_wmb();
+-              atomic_inc(&count_count_stop);
++              atomic_inc_unchecked(&count_count_stop);
+       }
+       /* Arrange for an interrupt in a short while */
+       write_c0_compare(read_c0_count() + COUNTON);
+@@ -112,8 +112,8 @@ void synchronise_count_slave(int cpu)
+       initcount = atomic_read(&count_reference);
+       for (i = 0; i < NR_LOOPS; i++) {
+-              atomic_inc(&count_count_start);
+-              while (atomic_read(&count_count_start) != 2)
++              atomic_inc_unchecked(&count_count_start);
++              while (atomic_read_unchecked(&count_count_start) != 2)
+                       mb();
+               /*
+@@ -122,8 +122,8 @@ void synchronise_count_slave(int cpu)
+               if (i == NR_LOOPS-1)
+                       write_c0_count(initcount);
+-              atomic_inc(&count_count_stop);
+-              while (atomic_read(&count_count_stop) != 2)
++              atomic_inc_unchecked(&count_count_stop);
++              while (atomic_read_unchecked(&count_count_stop) != 2)
+                       mb();
+       }
+       /* Arrange for an interrupt in a short while */
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index 8ea28e6..c8873d5 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -697,7 +697,18 @@ asmlinkage void do_ov(struct pt_regs *regs)
+       siginfo_t info;
+       prev_state = exception_enter();
+-      die_if_kernel("Integer overflow", regs);
++      if (unlikely(!user_mode(regs))) {
++
++#ifdef CONFIG_PAX_REFCOUNT
++              if (fixup_exception(regs)) {
++                      pax_report_refcount_overflow(regs);
++                      exception_exit(prev_state);
++                      return;
++              }
++#endif
++
++              die("Integer overflow", regs);
++      }
+       info.si_code = FPE_INTOVF;
+       info.si_signo = SIGFPE;
+diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
+index cd4c129..290c518 100644
+--- a/arch/mips/kvm/mips.c
++++ b/arch/mips/kvm/mips.c
+@@ -1016,7 +1016,7 @@ long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
+       return r;
+ }
+-int kvm_arch_init(void *opaque)
++int kvm_arch_init(const void *opaque)
+ {
+       if (kvm_mips_callbacks) {
+               kvm_err("kvm: module already exists\n");
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+index 852a41c..75b9d38 100644
+--- a/arch/mips/mm/fault.c
++++ b/arch/mips/mm/fault.c
+@@ -31,6 +31,23 @@
+ int show_unhandled_signals = 1;
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++      unsigned long i;
++
++      printk(KERN_ERR "PAX: bytes at PC: ");
++      for (i = 0; i < 5; i++) {
++              unsigned int c;
++              if (get_user(c, (unsigned int *)pc+i))
++                      printk(KERN_CONT "???????? ");
++              else
++                      printk(KERN_CONT "%08x ", c);
++      }
++      printk("\n");
++}
++#endif
++
+ /*
+  * This routine handles page faults.  It determines the address,
+  * and the problem, and then passes it off to one of the appropriate
+@@ -207,6 +224,14 @@ bad_area:
+ bad_area_nosemaphore:
+       /* User mode accesses just cause a SIGSEGV */
+       if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++              if (cpu_has_rixi && (mm->pax_flags & MF_PAX_PAGEEXEC) && !write && address == instruction_pointer(regs)) {
++                      pax_report_fault(regs, (void *)address, (void *)user_stack_pointer(regs));
++                      do_group_exit(SIGKILL);
++              }
++#endif
++
+               tsk->thread.cp0_badvaddr = address;
+               tsk->thread.error_code = write;
+               if (show_unhandled_signals &&
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index 5c81fdd..db158d3 100644
+--- a/arch/mips/mm/mmap.c
++++ b/arch/mips/mm/mmap.c
+@@ -59,6 +59,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+       struct vm_area_struct *vma;
+       unsigned long addr = addr0;
+       int do_color_align;
++      unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+       struct vm_unmapped_area_info info;
+       if (unlikely(len > TASK_SIZE))
+@@ -84,6 +85,11 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+               do_color_align = 1;
+       /* requesting a specific address */
++
++#ifdef CONFIG_PAX_RANDMMAP
++      if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+       if (addr) {
+               if (do_color_align)
+                       addr = COLOUR_ALIGN(addr, pgoff);
+@@ -91,14 +97,14 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+                       addr = PAGE_ALIGN(addr);
+               vma = find_vma(mm, addr);
+-              if (TASK_SIZE - len >= addr &&
+-                  (!vma || addr + len <= vma->vm_start))
++              if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+                       return addr;
+       }
+       info.length = len;
+       info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
+       info.align_offset = pgoff << PAGE_SHIFT;
++      info.threadstack_offset = offset;
+       if (dir == DOWN) {
+               info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+@@ -160,45 +166,34 @@ void arch_pic
\ No newline at end of file
diff --git a/test/grsecurity-3.1-4.2.6-201511092040.patch.sig b/test/grsecurity-3.1-4.2.6-201511092040.patch.sig
new file mode 100644 (file)
index 0000000..076b7fd
Binary files /dev/null and b/test/grsecurity-3.1-4.2.6-201511092040.patch.sig differ