summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '4.7.0/4420_grsecurity-3.1-4.7-201608151842.patch')
-rw-r--r--4.7.0/4420_grsecurity-3.1-4.7-201608151842.patch216193
1 files changed, 216193 insertions, 0 deletions
diff --git a/4.7.0/4420_grsecurity-3.1-4.7-201608151842.patch b/4.7.0/4420_grsecurity-3.1-4.7-201608151842.patch
new file mode 100644
index 0000000..9857890
--- /dev/null
+++ b/4.7.0/4420_grsecurity-3.1-4.7-201608151842.patch
@@ -0,0 +1,216193 @@
+diff --git a/.gitignore b/.gitignore
+index 0c320bf..2be25f7 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -37,6 +37,7 @@ modules.builtin
+ Module.symvers
+ *.dwo
+ *.su
++*.c.[012]*.*
+
+ #
+ # Top-level generic files
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index 8ea834f..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
+@@ -166,12 +186,14 @@ machtypes.h
+ map
+ map_hugetlb
+ mconf
++mdp
+ miboot*
+ mk_elfconfig
+ mkboot
+ mkbugboot
+ mkcpustr
+ mkdep
++mkpiggy
+ mkprep
+ mkregtable
+ mktables
+@@ -187,6 +209,8 @@ oui.c*
+ page-types
+ parse.c
+ parse.h
++parse-events*
++pasyms.h
+ patches*
+ pca200e.bin
+ pca200e_ecd.bin2
+@@ -196,6 +220,7 @@ perf-archive
+ piggyback
+ piggy.gzip
+ piggy.S
++pmu-*
+ pnmtologo
+ ppc_defs.h*
+ pss_boot.h
+@@ -205,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
+@@ -215,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
+@@ -226,6 +260,7 @@ tftpboot.img
+ timeconst.h
+ times.h*
+ trix_boot.h
++user_constants.h
+ utsrelease.h*
+ vdso-syms.lds
+ vdso.lds
+@@ -237,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
+@@ -251,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 82b42c9..7151845 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1341,6 +1341,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ [KNL] Should the hard-lockup detector generate
+ backtraces on all cpus.
+ Format: <integer>
++ 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
+@@ -2556,6 +2562,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.
+@@ -2862,6 +2872,35 @@ 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_size_overflow_report_only
++ Enables rate-limited logging of size_overflow plugin
++ violations while disabling killing of the violating
++ task.
++
++ 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 a3683ce..5ec8bf4 100644
+--- a/Documentation/sysctl/kernel.txt
++++ b/Documentation/sysctl/kernel.txt
+@@ -42,6 +42,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 ]
+@@ -408,6 +409,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 66da9a3..69d3a1ae 100644
+--- a/Makefile
++++ b/Makefile
+@@ -302,7 +302,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 \
+@@ -554,7 +556,7 @@ ifeq ($(KBUILD_EXTMOD),)
+ # in parallel
+ PHONY += scripts
+ scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
+- asm-generic
++ asm-generic gcc-plugins
+ $(Q)$(MAKE) $(build)=$(@)
+
+ # Objects we will link into vmlinux / subdirs we need to visit
+@@ -633,6 +635,8 @@ endif
+ # Tell gcc to never replace conditional load with a non-conditional one
+ KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)
+
++include scripts/Makefile.gcc-plugins
++
+ ifdef CONFIG_READABLE_ASM
+ # Disable optimizations that make assembler listings hard to read.
+ # reorder blocks reorders the control in the function
+@@ -734,7 +738,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,)
+@@ -909,7 +913,7 @@ export mod_sign_cmd
+
+
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
++core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
+
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+@@ -1028,7 +1032,7 @@ prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
+
+ archprepare: archheaders archscripts prepare1 scripts_basic
+
+-prepare0: archprepare
++prepare0: archprepare gcc-plugins
+ $(Q)$(MAKE) $(build)=.
+
+ # All the preparing..
+@@ -1247,7 +1251,11 @@ MRPROPER_FILES += .config .config.old .version .old_version \
+ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+ signing_key.pem 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/size_overflow_plugin/disable_size_overflow_hash.h \
++ tools/gcc/randomize_layout_seed.h
+
+ # clean - Delete most, but leave enough to build external modules
+ #
+@@ -1286,7 +1294,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
+
+
+@@ -1509,6 +1517,7 @@ clean: $(clean-dirs)
+ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+ -o -name '*.symtypes' -o -name 'modules.order' \
+ -o -name modules.builtin -o -name '.tmp_*.o.*' \
++ -o -name '*.c.[012]*.*' \
+ -o -name '*.gcno' \) -type f -print | xargs rm -f
+
+ # Generate tags for editors
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 1599629..1ef557b 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -357,6 +357,20 @@ config SECCOMP_FILTER
+
+ See Documentation/prctl/seccomp_filter.txt for details.
+
++config HAVE_GCC_PLUGINS
++ bool
++ help
++ An arch should select this symbol if it supports building with
++ GCC plugins.
++
++menuconfig GCC_PLUGINS
++ bool "GCC plugins"
++ depends on HAVE_GCC_PLUGINS
++ default y
++ help
++ GCC plugins are loadable modules that provide extra features to the
++ compiler. They are useful for runtime instrumentation and static analysis.
++
+ config HAVE_CC_STACKPROTECTOR
+ bool
+ help
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 572b228..e03acdd 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -251,4 +251,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 c2ebb6f..93a0613 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 936bc8f..bb1859f 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->core_layout.base + me->core_layout.size - 0x8000;
++ gp = (u64)me->core_layout.base_rw + me->core_layout.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 ffb93f49..ced8233 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -1300,10 +1300,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;
+@@ -1311,6 +1312,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);
+ }
+
+@@ -1343,20 +1345,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 0d3e59f..4418d65 100644
+--- a/arch/arc/Kconfig
++++ b/arch/arc/Kconfig
+@@ -541,6 +541,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 90542db..769febf 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -54,6 +54,7 @@ config ARM
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
+ select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
++ select HAVE_GCC_PLUGINS
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+ select HAVE_IDE if PCI || ISA || PCMCIA
+@@ -1581,6 +1582,7 @@ config AEABI
+ config OABI_COMPAT
+ bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+ depends on AEABI && !THUMB2_KERNEL
++ depends on !GRKERNSEC
+ help
+ This option preserves the old syscall interface along with the
+ new (ARM EABI) one. It also provides a compatibility layer to
+@@ -1649,6 +1651,7 @@ config HIGHPTE
+ config CPU_SW_DOMAIN_PAN
+ bool "Enable use of CPU domains to implement privileged no-access"
+ depends on MMU && !ARM_LPAE
++ depends on !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ default y
+ help
+ Increase kernel security by ensuring that normal kernel accesses
+@@ -1725,7 +1728,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
+@@ -1980,6 +1983,7 @@ config KEXEC
+ depends on (!SMP || PM_SLEEP_SMP)
+ depends on !CPU_V7M
+ select KEXEC_CORE
++ 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
+@@ -2024,7 +2028,7 @@ config EFI_STUB
+
+ config EFI
+ bool "UEFI runtime support"
+- depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL
++ depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL && !PAX_KERNEXEC
+ select UCS2_STRING
+ select EFI_PARAMS_FROM_FDT
+ select EFI_STUB
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index 19a3dcf..4a81b0e 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/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index d50430c..01cc53b 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -103,6 +103,8 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
+ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+ endif
+
++KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
++
+ # -fstack-protector-strong triggers protection checks in this code,
+ # but it is being used too early to link to meaningful stack_chk logic.
+ nossp_flags := $(call cc-option, -fno-stack-protector)
+diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
+index 9e10c45..2feb375 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) READ_ONCE((v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+ #define atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+
+ #if __LINUX_ARM_ARCH__ >= 6
+
+@@ -38,38 +62,64 @@
+ * 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_relaxed(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##_relaxed(int i, atomic##suffix##_t *v)\
+ { \
+ unsigned long tmp; \
+ int result; \
+ \
+ 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"); \
+@@ -78,8 +128,12 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
+ }
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked_relaxed atomic_add_return_unchecked_relaxed
+ #define atomic_sub_return_relaxed atomic_sub_return_relaxed
+
++#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_relaxed(atomic_t *ptr, int old, int new)
+ {
+ int oldval;
+@@ -113,12 +167,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");
+@@ -129,14 +195,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; \
+ \
+@@ -145,8 +233,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; \
+@@ -159,6 +250,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;
+@@ -173,6 +267,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;
+@@ -201,16 +300,29 @@ ATOMIC_OP(xor, ^=, eor)
+
+ #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))
++#define atomic_xchg_unchecked(v, new) (xchg_unchecked(&((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)
++#define atomic_inc_and_test_unchecked(v) (atomic_add_return_unchecked(1, v) == 0)
+ #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return_relaxed(v) (atomic_add_return_relaxed(1, v))
++#define atomic_inc_return_unchecked_relaxed(v) (atomic_add_return_unchecked_relaxed(1, v))
+ #define atomic_dec_return_relaxed(v) (atomic_sub_return_relaxed(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+@@ -221,6 +333,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
+@@ -237,6 +357,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"
+@@ -245,6 +378,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)
+ {
+@@ -259,6 +401,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;
+@@ -273,43 +428,73 @@ 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) \
++#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_relaxed(long long i, atomic64_t *v) \
++atomic64_##op##_return##suffix##_relaxed(long long i, atomic64##suffix##_t *v) \
+ { \
+ long long result; \
+ unsigned long tmp; \
+ \
+ 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"); \
+@@ -317,6 +502,9 @@ atomic64_##op##_return_relaxed(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)
+@@ -325,6 +513,7 @@ ATOMIC64_OPS(add, adds, adc)
+ ATOMIC64_OPS(sub, subs, sbc)
+
+ #define atomic64_add_return_relaxed atomic64_add_return_relaxed
++#define atomic64_add_return_unchecked_relaxed atomic64_add_return_unchecked_relaxed
+ #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+
+ #define atomic64_andnot atomic64_andnot
+@@ -336,7 +525,12 @@ ATOMIC64_OP(xor, eor, eor)
+
+ #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_relaxed(atomic64_t *ptr, long long old, long long new)
+@@ -361,6 +555,31 @@ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
+ return oldval;
+ }
+ #define atomic64_cmpxchg_relaxed atomic64_cmpxchg_relaxed
++#define atomic64_cmpxchg_unchecked_relaxed atomic64_cmpxchg_unchecked_relaxed
++
++static inline long long
++atomic64_cmpxchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long old,
++ long long new)
++{
++ long long oldval;
++ unsigned long res;
++
++ prefetchw(&ptr->counter);
++
++ 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);
++
++ return oldval;
++}
+
+ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
+ {
+@@ -380,26 +599,60 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
+
+ return result;
+ }
++
++static inline long long atomic64_xchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long new)
++{
++ long long result;
++ unsigned long tmp;
++
++ prefetchw(&ptr->counter);
++
++ __asm__ __volatile__("@ atomic64_xchg_unchecked\n"
++"1: ldrexd %0, %H0, [%3]\n"
++" strexd %1, %4, %H4, [%3]\n"
++" teq %1, #0\n"
++" bne 1b"
++ : "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
++ : "r" (&ptr->counter), "r" (new)
++ : "cc");
++
++ return result;
++}
+ #define atomic64_xchg_relaxed atomic64_xchg_relaxed
++#define atomic64_xchg_unchecked_relaxed atomic64_xchg_unchecked_relaxed
+
+ 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");
+@@ -423,13 +676,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");
+@@ -442,10 +707,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_relaxed(v) atomic64_add_return_relaxed(1LL, (v))
++#define atomic64_inc_return_unchecked_relaxed(v) atomic64_add_return_unchecked_relaxed(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_relaxed(v) atomic64_sub_return_relaxed(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/cache.h b/arch/arm/include/asm/cache.h
+index 75fe66b..2255c86 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
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index 9156fc3..9791d17 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 524692f..a8871ec 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 97882f9..0cc6ef1 100644
+--- a/arch/arm/include/asm/cmpxchg.h
++++ b/arch/arm/include/asm/cmpxchg.h
+@@ -117,6 +117,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 baefe1d..29cb35a 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)(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 99d9f63..ec44cb5 100644
+--- a/arch/arm/include/asm/domain.h
++++ b/arch/arm/include/asm/domain.h
+@@ -42,7 +42,6 @@
+ #define DOMAIN_USER 1
+ #define DOMAIN_IO 0
+ #endif
+-#define DOMAIN_VECTORS 3
+
+ /*
+ * Domain types
+@@ -51,9 +50,28 @@
+ #define DOMAIN_CLIENT 1
+ #ifdef CONFIG_CPU_USE_DOMAINS
+ #define DOMAIN_MANAGER 3
++#define DOMAIN_VECTORS 3
++#define DOMAIN_USERCLIENT DOMAIN_CLIENT
+ #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
++
+ #endif
++#define DOMAIN_KERNELCLIENT 1
+
+ #define domain_mask(dom) ((3) << (2 * (dom)))
+ #define domain_val(dom,type) ((type) << (2 * (dom)))
+@@ -62,13 +80,19 @@
+ #define DACR_INIT \
+ (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+- domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT) | \
+ domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
++#elif defined(CONFIG_PAX_MEMORY_UDEREF)
++ /* DOMAIN_VECTORS is defined to DOMAIN_KERNEL */
++#define DACR_INIT \
++ (domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) | \
++ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT))
+ #else
+ #define DACR_INIT \
+- (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
++ (domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+- domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT) | \
+ domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+ #endif
+
+@@ -124,6 +148,17 @@ static inline void set_domain(unsigned val)
+ set_domain(domain); \
+ } while (0)
+
++#elif defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++#define modify_domain(dom,type) \
++ do { \
++ struct thread_info *thread = current_thread_info(); \
++ unsigned int domain = get_domain(); \
++ domain &= ~domain_mask(dom); \
++ domain = domain | domain_val(dom, type); \
++ thread->cpu_domain = domain; \
++ set_domain(domain); \
++ } while (0)
++
+ #else
+ static inline void modify_domain(unsigned dom, unsigned type) { }
+ #endif
+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 6795368..6c4d749 100644
+--- a/arch/arm/include/asm/futex.h
++++ b/arch/arm/include/asm/futex.h
+@@ -107,6 +107,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ return -EFAULT;
+
+ preempt_disable();
++
+ __ua_flags = uaccess_save_and_enable();
+ __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ "1: " TUSER(ldr) " %1, [%4]\n"
+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 9b7c328..2dfe68b 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 c2bf24f..69e437c 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 20febb3..8d498e1 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 d0131ee..23a0939 100644
+--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
++++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
+@@ -28,7 +28,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 */
+@@ -40,6 +40,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)
+@@ -69,6 +70,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 92fd2c8..061dae1 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 2a029bc..a0524c7 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)
+@@ -90,10 +91,12 @@
+ #define L_PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
+ #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 d622040..fcebd79 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
+
+@@ -306,7 +354,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/smp.h b/arch/arm/include/asm/smp.h
+index 3d6dc8b..1262ad3 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/string.h b/arch/arm/include/asm/string.h
+index cf4f3aa..3f68273 100644
+--- a/arch/arm/include/asm/string.h
++++ b/arch/arm/include/asm/string.h
+@@ -7,19 +7,19 @@
+ */
+
+ #define __HAVE_ARCH_STRRCHR
+-extern char * strrchr(const char * s, int c);
++extern char * strrchr(const char * s, int c) __nocapture(1);
+
+ #define __HAVE_ARCH_STRCHR
+-extern char * strchr(const char * s, int c);
++extern char * strchr(const char * s, int c) __nocapture(1);
+
+ #define __HAVE_ARCH_MEMCPY
+-extern void * memcpy(void *, const void *, __kernel_size_t);
++extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMMOVE
+-extern void * memmove(void *, const void *, __kernel_size_t);
++extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMCHR
+-extern void * memchr(const void *, int, __kernel_size_t);
++extern void * memchr(const void *, int, __kernel_size_t) __nocapture(1);
+
+ #define __HAVE_ARCH_MEMSET
+ extern void * memset(void *, int, __kernel_size_t);
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index 776757d..a552c1d 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -73,6 +73,9 @@ struct thread_info {
+ .flags = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
++ .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)
+@@ -143,6 +146,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
+ #define TIF_SECCOMP 7 /* seccomp syscall filtering active */
++/* within 8 bits of TIF_SYSCALL_TRACE
++ * to meet flexible second operand requirements
++ */
++#define TIF_GRSEC_SETXID 8
+
+ #define TIF_NOHZ 12 /* in adaptive nohz mode */
+ #define TIF_USING_IWMMXT 17
+@@ -158,10 +165,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 35c9db8..400e490 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>
+@@ -50,6 +51,59 @@ struct exception_table_entry
+ extern int fixup_exception(struct pt_regs *regs);
+
+ /*
++ * These two are intentionally not defined anywhere - if the kernel
++ * code generates any references to them, that's a bug.
++ */
++extern int __get_user_bad(void);
++extern int __put_user_bad(void);
++
++/*
++ * Note that this is actually 0x1,0000,0000
++ */
++#define KERNEL_DS 0x00000000
++#define get_ds() (KERNEL_DS)
++
++#ifdef CONFIG_MMU
++
++#define USER_DS TASK_SIZE
++#define get_fs() (current_thread_info()->addr_limit)
++
++static inline void set_fs(mm_segment_t fs)
++{
++ current_thread_info()->addr_limit = fs;
++ 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
++
++}
++
++/*
+ * These two functions allow hooking accesses to userspace to increase
+ * system integrity by ensuring that the kernel can not inadvertantly
+ * perform such accesses (eg, via list poison values) which could then
+@@ -66,6 +120,7 @@ static inline unsigned int uaccess_save_and_enable(void)
+
+ return old_domain;
+ #else
++ pax_open_userland();
+ return 0;
+ #endif
+ }
+@@ -75,35 +130,11 @@ static inline void uaccess_restore(unsigned int flags)
+ #ifdef CONFIG_CPU_SW_DOMAIN_PAN
+ /* Restore the user access mask */
+ set_domain(flags);
++#else
++ pax_close_userland();
+ #endif
+ }
+
+-/*
+- * These two are intentionally not defined anywhere - if the kernel
+- * code generates any references to them, that's a bug.
+- */
+-extern int __get_user_bad(void);
+-extern int __put_user_bad(void);
+-
+-/*
+- * Note that this is actually 0x1,0000,0000
+- */
+-#define KERNEL_DS 0x00000000
+-#define get_ds() (KERNEL_DS)
+-
+-#ifdef CONFIG_MMU
+-
+-#define USER_DS TASK_SIZE
+-#define get_fs() (current_thread_info()->addr_limit)
+-
+-static inline void set_fs(mm_segment_t fs)
+-{
+- current_thread_info()->addr_limit = fs;
+- modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
+-}
+-
+-#define segment_eq(a, b) ((a) == (b))
+-
+ #define __addr_ok(addr) ({ \
+ unsigned long flag; \
+ __asm__("cmp %2, %0; movlo %0, #0" \
+@@ -302,6 +333,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() \
+@@ -490,39 +522,46 @@ do { \
+
+
+ #ifdef CONFIG_MMU
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ arm_copy_from_user(void *to, const void __user *from, unsigned long n);
+
+-static inline unsigned long __must_check
++static inline unsigned long __must_check __size_overflow(3)
+ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+- unsigned int __ua_flags = uaccess_save_and_enable();
++ unsigned int __ua_flags;
++
++ check_object_size(to, n, false);
++ __ua_flags = uaccess_save_and_enable();
+ n = arm_copy_from_user(to, from, n);
+ uaccess_restore(__ua_flags);
+ return n;
+ }
+
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ arm_copy_to_user(void __user *to, const void *from, unsigned long n);
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
+
+ static inline unsigned long __must_check
+ __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ #ifndef CONFIG_UACCESS_WITH_MEMCPY
+- unsigned int __ua_flags = uaccess_save_and_enable();
++ unsigned int __ua_flags;
++
++ check_object_size(from, n, true);
++ __ua_flags = uaccess_save_and_enable();
+ n = arm_copy_to_user(to, from, n);
+ uaccess_restore(__ua_flags);
+ return n;
+ #else
++ check_object_size(from, n, true);
+ return arm_copy_to_user(to, from, n);
+ #endif
+ }
+
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(2)
+ arm_clear_user(void __user *addr, unsigned long n);
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(2)
+ __clear_user_std(void __user *addr, unsigned long n);
+
+ static inline unsigned long __must_check
+@@ -542,6 +581,9 @@ __clear_user(void __user *addr, unsigned long n)
+
+ 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 */
+@@ -551,6 +593,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 7e45f69..2c047db 100644
+--- a/arch/arm/kernel/armksyms.c
++++ b/arch/arm/kernel/armksyms.c
+@@ -59,7 +59,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);
+
+diff --git a/arch/arm/kernel/cpuidle.c b/arch/arm/kernel/cpuidle.c
+index a44b268e..eea8f58 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 e255050..51e1b59 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,6 +237,9 @@ ENDPROC(__und_invalid)
+ .macro svc_entry, stack_hole=0, trace=1, uaccess=1
+ UNWIND(.fnstart )
+ UNWIND(.save {r0 - pc} )
++
++ pax_enter_kernel
++
+ sub sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
+ #ifdef CONFIG_THUMB2_KERNEL
+ SPFIX( str r0, [sp] ) @ temporarily saved
+@@ -167,7 +255,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 + 8 + \stack_hole + 4)
++#else
+ add r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
++#endif
+ SPFIX( addeq r2, r2, #4 )
+ str r3, [sp, #-4]! @ save the "real" r0 copied
+ @ from the exception stack
+@@ -376,6 +469,9 @@ ENDPROC(__fiq_abt)
+ .macro usr_entry, trace=1, uaccess=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} )
+@@ -489,7 +585,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
+
+ uaccess_disable ip
+@@ -525,11 +623,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_pan @ 16bit undefined instruction
++ pax_open_userland
+ 3: ldrht r0, [r2]
++ pax_close_userland
+ ARM_BE8(rev16 r0, r0) @ little endian instruction
+ uaccess_disable ip
+ add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
+@@ -560,7 +662,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"
+@@ -782,7 +885,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)
+ mrc p15, 0, r6, c3, c0, 0 @ Get domain register
+ str r6, [r1, #TI_CPU_DOMAIN] @ Save old domain register
+ ldr r6, [r2, #TI_CPU_DOMAIN]
+@@ -793,7 +896,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 30a7228..d071196 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
+ #if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
+ /*
+@@ -36,7 +64,9 @@ ret_fast_syscall:
+ UNWIND(.cantunwind )
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne fast_work_pending
++ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+
+ /* perform architecture specific actions before user return */
+@@ -62,7 +92,9 @@ ret_fast_syscall:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne __sys_trace_return_nosave
++ tst r1, #_TIF_WORK_MASK
+ beq no_work_pending
+ UNWIND(.fnend )
+ ENDPROC(ret_fast_syscall)
+@@ -199,6 +231,12 @@ ENTRY(vector_swi)
+
+ uaccess_disable tbl
+
++ /*
++ * 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 0d22ad2..d776aa0 100644
+--- a/arch/arm/kernel/entry-header.S
++++ b/arch/arm/kernel/entry-header.S
+@@ -196,6 +196,59 @@
+ 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
+
+ .macro svc_exit, rpsr, irq = 0
+ .if \irq != 0
+@@ -217,6 +270,8 @@
+ .endif
+ uaccess_restore
+
++ pax_exit_kernel
++
+ #ifndef CONFIG_THUMB2_KERNEL
+ @ ARM mode SVC restore
+ msr spsr_cxsf, \rpsr
+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/module-plts.c b/arch/arm/kernel/module-plts.c
+index 0c7efc3..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->init_layout.base < mod->init_layout.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 4f14b5c..91ff261 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 4a803c5..6c8688f 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -114,8 +114,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,
+@@ -229,7 +229,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+ /*
+ * Copy the initial value of the domain access control register
+ * from the current thread: thread->addr_limit will have been
+@@ -333,7 +333,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);
+@@ -362,92 +362,14 @@ 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;
+
+ if (down_write_killable(&mm->mmap_sem))
+ return -EINTR;
+- 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/ptrace.c b/arch/arm/kernel/ptrace.c
+index 4d93758..c2f471f92 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 3fa867a..d610607 100644
+--- a/arch/arm/kernel/reboot.c
++++ b/arch/arm/kernel/reboot.c
+@@ -120,6 +120,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 7b53500..d25a7aa 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -113,21 +113,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
+
+@@ -258,9 +260,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 7b8f214..ece8e28 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)
+ {
+@@ -388,8 +386,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
+ {
+@@ -601,33 +598,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 8615216..f5be307 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -82,7 +82,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(const 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 bc69838..e5dfdd4 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);
+ }
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index e2c6da0..6155a88 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -44,7 +44,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
+@@ -125,6 +125,8 @@ SECTIONS
+ #ifdef CONFIG_DEBUG_ALIGN_RODATA
+ . = ALIGN(1<<SECTION_SHIFT);
+ #endif
++ _etext = .; /* End of text section */
++
+ RO_DATA(PAGE_SIZE)
+
+ . = ALIGN(4);
+@@ -155,8 +157,6 @@ SECTIONS
+
+ NOTES
+
+- _etext = .; /* End of text and rodata section */
+-
+ #ifdef CONFIG_DEBUG_RODATA
+ . = ALIGN(1<<SECTION_SHIFT);
+ #else
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index f1bde7c..6dc92ba 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -58,7 +58,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 u32 kvm_next_vmid;
+ static unsigned int kvm_vmid_bits __read_mostly;
+ static DEFINE_SPINLOCK(kvm_vmid_lock);
+@@ -389,7 +389,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));
+ }
+
+ /**
+@@ -422,7 +422,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;
+
+ /*
+@@ -439,7 +439,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++;
+ kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
+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/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
+index 1712f13..a3165dc 100644
+--- a/arch/arm/lib/csumpartialcopyuser.S
++++ b/arch/arm/lib/csumpartialcopyuser.S
+@@ -71,8 +71,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 6bd1089..e999400 100644
+--- a/arch/arm/lib/uaccess_with_memcpy.c
++++ b/arch/arm/lib/uaccess_with_memcpy.c
+@@ -84,7 +84,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)
+ {
+ unsigned long ua_flags;
+@@ -157,7 +157,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
+ return n;
+ }
+
+-static unsigned long noinline
++static unsigned long noinline __size_overflow(2)
+ __clear_user_memset(void __user *addr, unsigned long n)
+ {
+ unsigned long ua_flags;
+diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
+index f216909..7b6776e 100644
+--- a/arch/arm/mach-exynos/suspend.c
++++ b/arch/arm/mach-exynos/suspend.c
+@@ -718,8 +718,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();
++ const_cast(exynos_pm_syscore_ops.suspend) = pm_data->pm_suspend;
++ const_cast(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-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
+index afba546..9e5403d 100644
+--- a/arch/arm/mach-mmp/mmp2.c
++++ b/arch/arm/mach-mmp/mmp2.c
+@@ -98,7 +98,9 @@ void __init mmp2_init_irq(void)
+ {
+ mmp2_init_icu();
+ #ifdef CONFIG_PM
+- icu_irq_chip.irq_set_wake = mmp2_set_wake;
++ pax_open_kernel();
++ const_cast(icu_irq_chip.irq_set_wake) = mmp2_set_wake;
++ pax_close_kernel();
+ #endif
+ }
+
+diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
+index 1ccbba9..7a95c29 100644
+--- a/arch/arm/mach-mmp/pxa910.c
++++ b/arch/arm/mach-mmp/pxa910.c
+@@ -84,7 +84,9 @@ void __init pxa910_init_irq(void)
+ {
+ icu_init_irq();
+ #ifdef CONFIG_PM
+- icu_irq_chip.irq_set_wake = pxa910_set_wake;
++ pax_open_kernel();
++ const_cast(icu_irq_chip.irq_set_wake) = pxa910_set_wake;
++ pax_close_kernel();
+ #endif
+ }
+
+diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
+index e80f0dd..0262909 100644
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -163,7 +163,7 @@ exit:
+
+ /*
+ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
+- * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
++ * areas are mapped as MT_UNCACHED_RW instead of MT_DEVICE. This is
+ * needed for the HW I/O coherency mechanism to work properly without
+ * deadlock.
+ */
+@@ -171,7 +171,7 @@ static void __iomem *
+ armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+ {
+- mtype = MT_UNCACHED;
++ mtype = MT_UNCACHED_RW;
+ return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+
+@@ -181,7 +181,7 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
+
+ coherency_cpu_base = of_iomap(np, 0);
+ arch_ioremap_caller = armada_wa_ioremap_caller;
+- pci_ioremap_set_mem_type(MT_UNCACHED);
++ pci_ioremap_set_mem_type(MT_UNCACHED_RW);
+
+ /*
+ * We should switch the PL310 to I/O coherency mode only if
+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 65024af..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)
+ {}
+
+-static 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 8cd1de9..1fcee77 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_device.c b/arch/arm/mach-omap2/omap_device.c
+index f7ff3b9..e6d5420 100644
+--- a/arch/arm/mach-omap2/omap_device.c
++++ b/arch/arm/mach-omap2/omap_device.c
+@@ -515,7 +515,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 };
+
+@@ -543,7 +543,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 83cb527..e82f20f 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -200,10 +200,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..b5dd79d 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();
++ const_cast(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-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
+index 92ec8c3..3b09472 100644
+--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
++++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
+@@ -240,7 +240,7 @@ static struct platform_device smdk6410_b_pwr_5v = {
+ };
+ #endif
+
+-static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
++static const struct s3c_ide_platdata smdk6410_ide_pdata __initconst = {
+ .setup_gpio = s3c64xx_ide_setup_gpio,
+ };
+
+diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
+index aba75c8..b2b340f 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"
+
+@@ -232,6 +233,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();
++ const_cast(shmobile_suspend_ops.enter) = shmobile_smp_apmu_enter_suspend;
++ pax_close_kernel();
+ }
+ #endif
+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 7cd9865..a00b6ab 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 cb569b6..da9d9db 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -445,6 +445,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
+@@ -599,6 +600,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.
+@@ -809,7 +811,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.
+@@ -823,7 +825,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
+@@ -838,7 +840,7 @@ config KUSER_HELPERS
+
+ config VDSO
+ bool "Enable VDSO for acceleration of some system calls"
+- depends on AEABI && MMU && CPU_V7
++ depends on AEABI && MMU && CPU_V7 && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ default y if ARM_ARCH_TIMER
+ select GENERIC_TIME_VSYSCALL
+ help
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index 7d5f4c7..c6a0816 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -778,6 +778,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ u16 tinstr = 0;
+ int isize = 4;
+ int thumb2_32b = 0;
++ bool is_user_mode = user_mode(regs);
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+@@ -786,14 +787,24 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+
+ if (thumb_mode(regs)) {
+ u16 *ptr = (u16 *)(instrptr & ~1);
+- fault = probe_kernel_address(ptr, tinstr);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address(ptr, tinstr);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address(ptr, tinstr);
+ tinstr = __mem_to_opcode_thumb16(tinstr);
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+ u16 tinst2 = 0;
+- fault = probe_kernel_address(ptr + 1, tinst2);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address(ptr + 1, tinst2);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address(ptr + 1, tinst2);
+ tinst2 = __mem_to_opcode_thumb16(tinst2);
+ instr = __opcode_thumb32_compose(tinstr, tinst2);
+ thumb2_32b = 1;
+@@ -803,7 +814,12 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ }
+ } else {
+- fault = probe_kernel_address((void *)instrptr, instr);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address((void *)instrptr, instr);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address((void *)instrptr, instr);
+ instr = __mem_to_opcode_arm(instr);
+ }
+
+@@ -812,7 +828,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ goto bad_or_fault;
+ }
+
+- if (user_mode(regs))
++ if (is_user_mode)
+ goto user;
+
+ ai_sys += 1;
+diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
+index c61996c..56d36df 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 c8c8b9e..c55cc79 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);
+@@ -193,7 +193,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) {
+ u64 newasid = generation | (asid & ~ASID_MASK);
+@@ -225,7 +225,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);
+@@ -254,14 +254,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 ad58418..8267ca5 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 ((tsk->mm->pax_flags & MF_PAX_PAGEEXEC) && (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,118 @@ 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;
++#ifdef CONFIG_ARM_THUMB
++ if (regs->ARM_lr & 1) {
++ regs->ARM_cpsr |= PSR_T_BIT;
++ regs->ARM_pc &= ~0x1U;
++ } else
++ regs->ARM_cpsr &= ~PSR_T_BIT;
++#endif
++ 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;
++#ifdef CONFIG_ARM_THUMB
++ if (regs->ARM_lr & 1) {
++ regs->ARM_cpsr |= PSR_T_BIT;
++ regs->ARM_pc &= ~0x1U;
++ } else
++ regs->ARM_cpsr &= ~PSR_T_BIT;
++#endif
++ 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((const unsigned short *)pc, bkpt) && cpu_to_le16(bkpt) == 0xbef1) {
++#else
++ unsigned int bkpt;
++
++ if (!probe_kernel_address((const unsigned int *)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 05ec5e0..0b70277 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);
+ void early_abt_enable(void);
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index 370581a..b985cc1 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -747,7 +747,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 ff0eed2..f17f1c9 100644
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -411,9 +411,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 66353ca..8aad9f8 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,19 +103,21 @@ 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);
+ }
+
+ unsigned long
+-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+- const unsigned long len, const unsigned long pgoff,
+- const unsigned long flags)
++arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
+ {
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ 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);
+
+ /*
+@@ -182,14 +192,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 62f4d01..bffdcfe 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -243,7 +243,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,
+@@ -272,19 +280,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
+@@ -300,7 +308,7 @@ static struct mem_type mem_types[] = {
+ .prot_l1 = PMD_TYPE_TABLE,
+ .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,
+@@ -313,17 +321,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,
+@@ -331,9 +352,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] = {
+@@ -586,9 +608,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
+
+ /*
+@@ -605,13 +632,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;
+ }
+ }
+
+@@ -622,15 +653,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
+@@ -651,6 +687,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);
+@@ -668,21 +706,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",
+@@ -958,7 +999,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 < FIXADDR_START &&
+ (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
+ pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
+@@ -1309,18 +1350,15 @@ void __init arm_mm_memblock_reserve(void)
+ * Any other function or debugging method which may touch any device _will_
+ * crash the kernel.
+ */
++
++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);
+
+ /*
+ * Clear page table except top pmd used by early fixmaps
+@@ -1336,7 +1374,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)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+- map.type = MT_ROM;
++ map.type = MT_ROM_RX;
+ create_mapping(&map);
+ #endif
+
+@@ -1347,14 +1385,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
+
+@@ -1363,7 +1401,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
+@@ -1426,12 +1464,14 @@ static void __init kmap_init(void)
+ static void __init map_lowmem(void)
+ {
+ struct memblock_region *reg;
++#ifndef CONFIG_PAX_KERNEXEC
+ #ifdef CONFIG_XIP_KERNEL
+ phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
+ #else
+ phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+ #endif
+ 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) {
+@@ -1447,11 +1487,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) {
+@@ -1475,7 +1552,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);
+
+@@ -1488,6 +1565,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 93d0b6d..2db6d99 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);
+ }
+@@ -191,8 +176,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)
+@@ -554,6 +541,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;
+@@ -568,18 +558,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 b/arch/arm64/Kconfig
+index 5a0a691..658577c 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -76,6 +76,7 @@ config ARM64
+ select HAVE_FTRACE_MCOUNT_RECORD
+ select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_GRAPH_TRACER
++ select HAVE_GCC_PLUGINS
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_HW_BREAKPOINT if PERF_EVENTS
+ select HAVE_IRQ_TIME_ACCOUNTING
+diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
+index 0cc758c..de67415 100644
+--- a/arch/arm64/Kconfig.debug
++++ b/arch/arm64/Kconfig.debug
+@@ -6,6 +6,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 f3a3586..5763299 100644
+--- a/arch/arm64/include/asm/atomic.h
++++ b/arch/arm64/include/asm/atomic.h
+@@ -98,6 +98,8 @@
+ #define __atomic_add_unless(v, a, u) ___atomic_add_unless(v, a, u,)
+ #define atomic_andnot atomic_andnot
+
++#define atomic_inc_return_unchecked_relaxed(v) atomic_add_return_relaxed(1, (v))
++
+ /*
+ * 64-bit atomic operations.
+ */
+@@ -146,5 +148,16 @@
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#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))
++#define atomic64_xchg_unchecked(v, n) atomic64_xchg((v), (n))
++
+ #endif
+ #endif
+diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
+index 5082b30..79247453 100644
+--- a/arch/arm64/include/asm/cache.h
++++ b/arch/arm64/include/asm/cache.h
+@@ -18,8 +18,10 @@
+
+ #include <asm/cachetype.h>
+
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 7
+-#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/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
+index 0a456be..7799ff5 100644
+--- a/arch/arm64/include/asm/percpu.h
++++ b/arch/arm64/include/asm/percpu.h
+@@ -127,16 +127,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 d25f4f1..0bd8842 100644
+--- a/arch/arm64/include/asm/pgalloc.h
++++ b/arch/arm64/include/asm/pgalloc.h
+@@ -51,6 +51,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+ __pud_populate(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
+ static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
+ {
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index 46472a9..9f2efc0 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -23,6 +23,9 @@
+ #include <asm/pgtable-hwdef.h>
+ #include <asm/pgtable-prot.h>
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ /*
+ * VMALLOC range.
+ *
+diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
+index 2eb714c..6c0fdb7 100644
+--- a/arch/arm64/include/asm/string.h
++++ b/arch/arm64/include/asm/string.h
+@@ -17,40 +17,40 @@
+ #define __ASM_STRING_H
+
+ #define __HAVE_ARCH_STRRCHR
+-extern char *strrchr(const char *, int c);
++extern char *strrchr(const char *, int c) __nocapture(1);
+
+ #define __HAVE_ARCH_STRCHR
+-extern char *strchr(const char *, int c);
++extern char *strchr(const char *, int c) __nocapture(1);
+
+ #define __HAVE_ARCH_STRCMP
+-extern int strcmp(const char *, const char *);
++extern int strcmp(const char *, const char *) __nocapture(1, 2);
+
+ #define __HAVE_ARCH_STRNCMP
+-extern int strncmp(const char *, const char *, __kernel_size_t);
++extern int strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
+
+ #define __HAVE_ARCH_STRLEN
+ extern __kernel_size_t strlen(const char *);
+
+ #define __HAVE_ARCH_STRNLEN
+-extern __kernel_size_t strnlen(const char *, __kernel_size_t);
++extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1);
+
+ #define __HAVE_ARCH_MEMCPY
+-extern void *memcpy(void *, const void *, __kernel_size_t);
+-extern void *__memcpy(void *, const void *, __kernel_size_t);
++extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
++extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMMOVE
+-extern void *memmove(void *, const void *, __kernel_size_t);
+-extern void *__memmove(void *, const void *, __kernel_size_t);
++extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2);
++extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMCHR
+-extern void *memchr(const void *, int, __kernel_size_t);
++extern void *memchr(const void *, int, __kernel_size_t) __nocapture(1);
+
+ #define __HAVE_ARCH_MEMSET
+ extern void *memset(void *, int, __kernel_size_t);
+ extern void *__memset(void *, int, __kernel_size_t);
+
+ #define __HAVE_ARCH_MEMCMP
+-extern int memcmp(const void *, const void *, size_t);
++extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2);
+
+
+ #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
+index 9e397a5..6cd98e5 100644
+--- a/arch/arm64/include/asm/uaccess.h
++++ b/arch/arm64/include/asm/uaccess.h
+@@ -101,6 +101,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/kernel/process.c b/arch/arm64/kernel/process.c
+index 6cd2612..56d72e5c 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -63,7 +63,7 @@ EXPORT_SYMBOL(__stack_chk_guard);
+ /*
+ * Function pointers to optional machine specific functions
+ */
+-void (*pm_power_off)(void);
++void (* pm_power_off)(void);
+ EXPORT_SYMBOL_GPL(pm_power_off);
+
+ void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
+@@ -109,7 +109,7 @@ void machine_shutdown(void)
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this.
+ */
+-void machine_halt(void)
++void __noreturn machine_halt(void)
+ {
+ local_irq_disable();
+ smp_send_stop();
+@@ -122,12 +122,13 @@ void machine_halt(void)
+ * achieves this. When the system power is turned off, it will take all CPUs
+ * with it.
+ */
+-void machine_power_off(void)
++void __noreturn machine_power_off(void)
+ {
+ local_irq_disable();
+ smp_send_stop();
+ if (pm_power_off)
+ pm_power_off();
++ while(1);
+ }
+
+ /*
+@@ -139,7 +140,7 @@ void machine_power_off(void)
+ * executing pre-reset code, and using RAM that the primary CPU's code wishes
+ * to use. Implementing such co-ordination would be essentially impossible.
+ */
+-void machine_restart(char *cmd)
++void __noreturn machine_restart(char *cmd)
+ {
+ /* Disable interrupts first */
+ local_irq_disable();
+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
+index d9751a4..aeda309 100644
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -92,8 +92,8 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+ struct pt_regs *irq_args;
+ unsigned long orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
+
+- if (object_is_on_stack((void *)orig_sp) &&
+- object_is_on_stack((void *)frame->fp)) {
++ if (object_starts_on_stack((void *)orig_sp) &&
++ object_starts_on_stack((void *)frame->fp)) {
+ frame->sp = orig_sp;
+
+ /* orig_sp is the saved pt_regs, find the elr */
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index 2a43012..3409956 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -420,7 +420,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
+ __show_regs(regs);
+ }
+
+- return sys_ni_syscall();
++ return -ENOSYS;
+ }
+
+ static const char *esr_class_str[] = {
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index c566ec8..3e01953 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -132,7 +132,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 64f02d4..c1b0839 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -166,6 +166,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 e109ee9..a426a85 100644
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
+@@ -519,6 +519,7 @@ config KEXEC
+ bool "kexec system call"
+ depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
+ select KEXEC_CORE
++ 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 c100d78..07538cc 100644
+--- a/arch/ia64/Makefile
++++ b/arch/ia64/Makefile
+@@ -98,5 +98,6 @@ endef
+ archprepare: make_nr_irqs_h
+ PHONY += make_nr_irqs_h
+
++make_nr_irqs_h: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+ make_nr_irqs_h:
+ $(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 8dfb5f6..d58bd69 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -209,4 +209,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/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 2189d5d..420134b 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 6ab0ae7..88f1b60 100644
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
+ static inline int
+ in_init (const struct module *mod, uint64_t addr)
+ {
+- return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size;
++ return within_module_init(addr, mod);
+ }
+
+ static inline int
+ in_core (const struct module *mod, uint64_t addr)
+ {
+- return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size;
++ return within_module_core(addr, mod);
+ }
+
+ static inline int
+@@ -676,6 +676,14 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
+
+ case RV_BDREL:
+ val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base);
++ if (within_module_rx(val, &mod->init_layout))
++ val -= mod->init_layout.base_rx;
++ else if (within_module_rw(val, &mod->init_layout))
++ val -= mod->init_layout.base_rw;
++ else if (within_module_rx(val, &mod->core_layout))
++ val -= mod->core_layout.base_rx;
++ else if (within_module_rw(val, &mod->core_layout))
++ val -= mod->core_layout.base_rw;
+ break;
+
+ case RV_LTV:
+@@ -810,15 +818,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
+ * addresses have been selected...
+ */
+ uint64_t gp;
+- if (mod->core_layout.size > MAX_LTOFF)
++ if (mod->core_layout.size_rx + mod->core_layout.size_rw > MAX_LTOFF)
+ /*
+ * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
+ * at the end of the module.
+ */
+- gp = mod->core_layout.size - MAX_LTOFF / 2;
++ gp = mod->core_layout.size_rx + mod->core_layout.size_rw - MAX_LTOFF / 2;
+ else
+- gp = mod->core_layout.size / 2;
+- gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8);
++ gp = (mod->core_layout.size_rx + mod->core_layout.size_rw) / 2;
++ gp = (uint64_t) mod->core_layout.base_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 85de86d..db7f6b8 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 1841ef6..74d8330 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/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
+index db1b7da..8e13684 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/Kbuild b/arch/mips/Kbuild
+index 5c3f688..f8cc1b3 100644
+--- a/arch/mips/Kbuild
++++ b/arch/mips/Kbuild
+@@ -1,7 +1,7 @@
+ # Fail on warnings - also for files referenced in subdirs
+ # -Werror can be disabled for specific files using:
+ # CFLAGS_<file.o> := -Wno-error
+-subdir-ccflags-y := -Werror
++# subdir-ccflags-y := -Werror
+
+ # platform specific definitions
+ include arch/mips/Kbuild.platforms
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index ac91939..a1df96d 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -50,6 +50,7 @@ config MIPS
+ select HAVE_MOD_ARCH_SPECIFIC
+ select HAVE_NMI
+ select VIRT_TO_BUS
++ select HAVE_GCC_PLUGINS
+ select MODULES_USE_ELF_REL if MODULES
+ select MODULES_USE_ELF_RELA if MODULES && 64BIT
+ select CLONE_BACKWARDS
+@@ -2775,6 +2776,7 @@ source "kernel/Kconfig.preempt"
+ config KEXEC
+ bool "Kexec system call"
+ select KEXEC_CORE
++ 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 2cd45f5..d0f4900 100644
+--- a/arch/mips/cavium-octeon/dma-octeon.c
++++ b/arch/mips/cavium-octeon/dma-octeon.c
+@@ -191,7 +191,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size,
+ static void octeon_dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs)
+ {
+- 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 835b402..347a797 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) READ_ONCE((v)->counter)
++static inline int atomic_read(const atomic_t *v)
++{
++ return READ_ONCE(v->counter);
++}
++
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return READ_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) WRITE_ONCE((v)->counter, (i))
++static inline void atomic_set(atomic_t *v, int i)
++{
++ WRITE_ONCE(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)
++{
++ WRITE_ONCE(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,31 @@ 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)); \
+- \
+- result = temp; result c_op i; \
++ __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)); \
+ } 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,20 +192,25 @@ 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_OP(and, &=, and)
+-ATOMIC_OP(or, |=, or)
+-ATOMIC_OP(xor, ^=, xor)
++ATOMIC_OPS(add, add)
++ATOMIC_OPS(sub, sub)
++
++ATOMIC_OP(and, and)
++ATOMIC_OP(or, or)
++ATOMIC_OP(xor, xor)
+
+ #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
+@@ -153,7 +220,7 @@ ATOMIC_OP(xor, ^=, xor)
+ * 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;
+
+@@ -163,7 +230,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"
+@@ -212,8 +279,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
+@@ -241,6 +326,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
+@@ -262,6 +351,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
+@@ -286,6 +379,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
+@@ -294,6 +391,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
+@@ -315,54 +416,77 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * @v: pointer of type atomic64_t
+ *
+ */
+-#define atomic64_read(v) READ_ONCE((v)->counter)
++static inline long atomic64_read(const atomic64_t *v)
++{
++ return READ_ONCE(v->counter);
++}
++
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+
+ /*
+ * atomic64_set - set atomic variable
+ * @v: pointer of type atomic64_t
+ * @i: required value
+ */
+-#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i))
++static inline void atomic64_set(atomic64_t *v, long i)
++{
++ WRITE_ONCE(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)
++{
++ WRITE_ONCE(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; \
+ \
+@@ -372,12 +496,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) \
+@@ -385,27 +512,33 @@ 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)); \
+- \
+- result = temp; result c_op i; \
++ __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"); \
+ } 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); \
+ } \
+ \
+@@ -414,19 +547,27 @@ 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)
+-ATOMIC64_OP(and, &=, and)
+-ATOMIC64_OP(or, |=, or)
+-ATOMIC64_OP(xor, ^=, xor)
++#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)
++
++ATOMIC64_OP(and, and)
++ATOMIC64_OP(or, or)
++ATOMIC64_OP(xor, xor)
+
+ #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
+@@ -437,7 +578,7 @@ ATOMIC64_OP(xor, ^=, xor)
+ * 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;
+
+@@ -447,7 +588,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"
+@@ -496,9 +637,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
+@@ -528,6 +686,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
+@@ -549,6 +708,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
+@@ -573,6 +733,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
+@@ -581,6 +742,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/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 f5f4571..38cf967 100644
+--- a/arch/mips/include/asm/elf.h
++++ b/arch/mips/include/asm/elf.h
+@@ -458,6 +458,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_DLINFO \
+ do { \
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+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/irq.h b/arch/mips/include/asm/irq.h
+index 15e0fec..3ee3eec 100644
+--- a/arch/mips/include/asm/irq.h
++++ b/arch/mips/include/asm/irq.h
+@@ -11,7 +11,6 @@
+
+ #include <linux/linkage.h>
+ #include <linux/smp.h>
+-#include <linux/irqdomain.h>
+
+ #include <asm/mipsmtregs.h>
+
+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 21ed715..774a251 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 93c079a..1d6bf7c 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 7d44e88..6f28830 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 e309d8f..20eefec 100644
+--- a/arch/mips/include/asm/thread_info.h
++++ b/arch/mips/include/asm/thread_info.h
+@@ -101,6 +101,9 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
+ #define TIF_UPROBE 6 /* breakpointed or singlestepping */
+ #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 */
+@@ -137,14 +140,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 \
+@@ -153,7 +158,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 7f109d4..40b1195 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 58ad63d..051b4b7 100644
+--- a/arch/mips/kernel/binfmt_elfn32.c
++++ b/arch/mips/kernel/binfmt_elfn32.c
+@@ -36,6 +36,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 49fb881..b9ab7c2 100644
+--- a/arch/mips/kernel/binfmt_elfo32.c
++++ b/arch/mips/kernel/binfmt_elfo32.c
+@@ -40,6 +40,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/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 f25f7ea..19e1c62 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)
+@@ -61,6 +61,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;
+@@ -76,6 +78,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 adda3ff..ac067e2 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 813ed78..0acf903 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -531,18 +531,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 0dcf691..b75d89a 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -882,6 +882,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
+@@ -900,6 +904,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 4472a7f..c5905e6 100644
+--- a/arch/mips/kernel/sync-r4k.c
++++ b/arch/mips/kernel/sync-r4k.c
+@@ -18,8 +18,8 @@
+ #include <asm/mipsregs.h>
+
+ static unsigned int initcount = 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);
+
+ #define COUNTON 100
+ #define NR_LOOPS 3
+@@ -46,13 +46,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();
+
+ /* Let the slave writes its count register */
+- atomic_inc(&count_count_start);
++ atomic_inc_unchecked(&count_count_start);
+
+ /* Count will be initialised to current timer */
+ if (i == 1)
+@@ -67,11 +67,11 @@ void synchronise_count_master(int cpu)
+ /*
+ * Wait for slave 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);
+@@ -96,8 +96,8 @@ void synchronise_count_slave(int cpu)
+ */
+
+ 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();
+
+ /*
+@@ -106,8 +106,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 4a1712b..a1348b9 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -695,7 +695,18 @@ asmlinkage void do_ov(struct pt_regs *regs)
+ };
+
+ 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);
++ }
+
+ force_sig_info(SIGFPE, &info, current);
+ exception_exit(prev_state);
+diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c
+index 927dc94..27269ee 100644
+--- a/arch/mips/lib/ashldi3.c
++++ b/arch/mips/lib/ashldi3.c
+@@ -2,7 +2,11 @@
+
+ #include "libgcc.h"
+
+-long long notrace __ashldi3(long long u, word_type b)
++#ifdef CONFIG_64BIT
++DWtype notrace __ashlti3(DWtype u, word_type b)
++#else
++DWtype notrace __ashldi3(DWtype u, word_type b)
++#endif
+ {
+ DWunion uu, w;
+ word_type bm;
+@@ -11,19 +15,22 @@ long long notrace __ashldi3(long long u, word_type b)
+ return u;
+
+ uu.ll = u;
+- bm = 32 - b;
++ bm = BITS_PER_LONG - b;
+
+ if (bm <= 0) {
+ w.s.low = 0;
+- w.s.high = (unsigned int) uu.s.low << -bm;
++ w.s.high = (unsigned long) uu.s.low << -bm;
+ } else {
+- const unsigned int carries = (unsigned int) uu.s.low >> bm;
++ const unsigned long carries = (unsigned long) uu.s.low >> bm;
+
+- w.s.low = (unsigned int) uu.s.low << b;
+- w.s.high = ((unsigned int) uu.s.high << b) | carries;
++ w.s.low = (unsigned long) uu.s.low << b;
++ w.s.high = ((unsigned long) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+ }
+-
++#ifdef CONFIG_64BIT
++EXPORT_SYMBOL(__ashlti3);
++#else
+ EXPORT_SYMBOL(__ashldi3);
++#endif
+diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c
+index 9fdf1a5..6741f0e 100644
+--- a/arch/mips/lib/ashrdi3.c
++++ b/arch/mips/lib/ashrdi3.c
+@@ -2,7 +2,11 @@
+
+ #include "libgcc.h"
+
+-long long notrace __ashrdi3(long long u, word_type b)
++#ifdef CONFIG_64BIT
++DWtype notrace __ashrti3(DWtype u, word_type b)
++#else
++DWtype notrace __ashrdi3(DWtype u, word_type b)
++#endif
+ {
+ DWunion uu, w;
+ word_type bm;
+@@ -11,21 +15,24 @@ long long notrace __ashrdi3(long long u, word_type b)
+ return u;
+
+ uu.ll = u;
+- bm = 32 - b;
++ bm = BITS_PER_LONG - b;
+
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high =
+- uu.s.high >> 31;
++ uu.s.high >> (BITS_PER_LONG - 1);
+ w.s.low = uu.s.high >> -bm;
+ } else {
+- const unsigned int carries = (unsigned int) uu.s.high << bm;
++ const unsigned long carries = (unsigned long) uu.s.high << bm;
+
+ w.s.high = uu.s.high >> b;
+- w.s.low = ((unsigned int) uu.s.low >> b) | carries;
++ w.s.low = ((unsigned long) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+ }
+-
++#ifdef CONFIG_64BIT
++EXPORT_SYMBOL(__ashrti3);
++#else
+ EXPORT_SYMBOL(__ashrdi3);
++#endif
+diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
+index 05909d58..b03284b 100644
+--- a/arch/mips/lib/libgcc.h
++++ b/arch/mips/lib/libgcc.h
+@@ -5,13 +5,19 @@
+
+ typedef int word_type __attribute__ ((mode (__word__)));
+
++#ifdef CONFIG_64BIT
++typedef int DWtype __attribute__((mode(TI)));
++#else
++typedef long long DWtype;
++#endif
++
+ #ifdef __BIG_ENDIAN
+ struct DWstruct {
+- int high, low;
++ long high, low;
+ };
+ #elif defined(__LITTLE_ENDIAN)
+ struct DWstruct {
+- int low, high;
++ long low, high;
+ };
+ #else
+ #error I feel sick.
+@@ -19,7 +25,7 @@ struct DWstruct {
+
+ typedef union {
+ struct DWstruct s;
+- long long ll;
++ DWtype ll;
+ } DWunion;
+
+ #endif /* __ASM_LIBGCC_H */
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+index 4b88fa0..b16bc17 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
+@@ -205,6 +222,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/init.c b/arch/mips/mm/init.c
+index 9b58eb5..b1f2558 100644
+--- a/arch/mips/mm/init.c
++++ b/arch/mips/mm/init.c
+@@ -472,10 +472,10 @@ void __init mem_init(void)
+
+ #ifdef CONFIG_64BIT
+ if ((unsigned long) &_text > (unsigned long) CKSEG0)
+- /* The -4 is a hack so that user tools don't have to handle
++ /* The -0x2000-4 is a hack so that user tools don't have to handle
+ the overflow. */
+ kclist_add(&kcore_kseg0, (void *) CKSEG0,
+- 0x80000000 - 4, KCORE_TEXT);
++ 0x80000000 - 0x2000 - 4, KCORE_TEXT);
+ #endif
+ }
+ #endif /* !CONFIG_NEED_MULTIPLE_NODES */
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index 3530376..754dde3 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,14 +166,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/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
+index cfceaea..65deeb4 100644
+--- a/arch/mips/sgi-ip27/ip27-nmi.c
++++ b/arch/mips/sgi-ip27/ip27-nmi.c
+@@ -187,9 +187,9 @@ void
+ cont_nmi_dump(void)
+ {
+ #ifndef REAL_NMI_SIGNAL
+- static atomic_t nmied_cpus = ATOMIC_INIT(0);
++ static atomic_unchecked_t nmied_cpus = ATOMIC_INIT(0);
+
+- atomic_inc(&nmied_cpus);
++ atomic_inc_unchecked(&nmied_cpus);
+ #endif
+ /*
+ * Only allow 1 cpu to proceed
+@@ -233,7 +233,7 @@ cont_nmi_dump(void)
+ udelay(10000);
+ }
+ #else
+- while (atomic_read(&nmied_cpus) != num_online_cpus());
++ while (atomic_read_unchecked(&nmied_cpus) != num_online_cpus());
+ #endif
+
+ /*
+diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
+index 160b880..3b53fdc 100644
+--- a/arch/mips/sni/rm200.c
++++ b/arch/mips/sni/rm200.c
+@@ -270,7 +270,7 @@ spurious_8259A_irq:
+ "spurious RM200 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/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
+index 41e873b..34d33a7 100644
+--- a/arch/mips/vr41xx/common/icu.c
++++ b/arch/mips/vr41xx/common/icu.c
+@@ -653,7 +653,7 @@ static int icu_get_irq(unsigned int irq)
+
+ printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);
+
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+
+ return -1;
+ }
+diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
+index ae0e4ee..e8f0692 100644
+--- a/arch/mips/vr41xx/common/irq.c
++++ b/arch/mips/vr41xx/common/irq.c
+@@ -64,7 +64,7 @@ static void irq_dispatch(unsigned int irq)
+ irq_cascade_t *cascade;
+
+ if (irq >= NR_IRQS) {
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ return;
+ }
+
+@@ -84,7 +84,7 @@ static void irq_dispatch(unsigned int irq)
+ ret = cascade->get_irq(irq);
+ irq = ret;
+ if (ret < 0)
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ else
+ irq_dispatch(irq);
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
+diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+index 967d144..db12197 100644
+--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
++++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+@@ -11,12 +11,14 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+
++#include <linux/const.h>
++
+ /* L1 cache */
+
+ #define L1_CACHE_NWAYS 4 /* number of ways in caches */
+ #define L1_CACHE_NENTRIES 256 /* number of entries in each way */
+-#define L1_CACHE_BYTES 16 /* bytes per entry */
+ #define L1_CACHE_SHIFT 4 /* shift for bytes per entry */
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT) /* bytes per entry */
+ #define L1_CACHE_WAYDISP 0x1000 /* displacement of one way from the next */
+
+ #define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
+diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+index bcb5df2..84fabd2 100644
+--- a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
++++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+@@ -16,13 +16,15 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+
++#include <linux/const.h>
++
+ /*
+ * L1 cache
+ */
+ #define L1_CACHE_NWAYS 4 /* number of ways in caches */
+ #define L1_CACHE_NENTRIES 128 /* number of entries in each way */
+-#define L1_CACHE_BYTES 32 /* bytes per entry */
+ #define L1_CACHE_SHIFT 5 /* shift for bytes per entry */
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT) /* bytes per entry */
+ #define L1_CACHE_WAYDISP 0x1000 /* distance from one way to the next */
+
+ #define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
+diff --git a/arch/openrisc/include/asm/cache.h b/arch/openrisc/include/asm/cache.h
+index 4ce7a01..449202a 100644
+--- a/arch/openrisc/include/asm/cache.h
++++ b/arch/openrisc/include/asm/cache.h
+@@ -19,11 +19,13 @@
+ #ifndef __ASM_OPENRISC_CACHE_H
+ #define __ASM_OPENRISC_CACHE_H
+
++#include <linux/const.h>
++
+ /* FIXME: How can we replace these with values from the CPU...
+ * they shouldn't be hard-coded!
+ */
+
+-#define L1_CACHE_BYTES 16
+ #define L1_CACHE_SHIFT 4
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #endif /* __ASM_OPENRISC_CACHE_H */
+diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
+index 1d10999..5907031 100644
+--- a/arch/parisc/include/asm/atomic.h
++++ b/arch/parisc/include/asm/atomic.h
+@@ -280,6 +280,16 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
+ return dec;
+ }
+
++#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 /* !CONFIG_64BIT */
+
+
+diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
+index df0f52b..810699b 100644
+--- a/arch/parisc/include/asm/cache.h
++++ b/arch/parisc/include/asm/cache.h
+@@ -5,6 +5,7 @@
+ #ifndef __ARCH_PARISC_CACHE_H
+ #define __ARCH_PARISC_CACHE_H
+
++#include <linux/const.h>
+
+ /*
+ * PA 2.0 processors have 64 and 128-byte L2 cachelines; PA 1.1 processors
+@@ -14,6 +15,8 @@
+ #define L1_CACHE_BYTES 16
+ #define L1_CACHE_SHIFT 4
+
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
++
+ #ifndef __ASSEMBLY__
+
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
+index 78c9fd3..42fa66a 100644
+--- a/arch/parisc/include/asm/elf.h
++++ b/arch/parisc/include/asm/elf.h
+@@ -342,6 +342,13 @@ struct pt_regs; /* forward declaration... */
+
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE 0x10000UL
++
++#define PAX_DELTA_MMAP_LEN 16
++#define PAX_DELTA_STACK_LEN 16
++#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,
+ but it's not easy, and we've already done it here. */
+diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
+index f08dda3..ea6aa1b 100644
+--- a/arch/parisc/include/asm/pgalloc.h
++++ b/arch/parisc/include/asm/pgalloc.h
+@@ -61,6 +61,11 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+ (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
+ }
+
++static inline void pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
++{
++ pgd_populate(mm, pgd, pmd);
++}
++
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+ pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL, PMD_ORDER);
+@@ -96,6 +101,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+ #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
+ #define pmd_free(mm, x) do { } while (0)
+ #define pgd_populate(mm, pmd, pte) BUG()
++#define pgd_populate_kernel(mm, pmd, pte) BUG()
+
+ #endif
+
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index 291cee2..2ac33db 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -236,6 +236,17 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
+ #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
+ #define PAGE_COPY PAGE_EXECREAD
+ #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++#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_KERNEL)
+ #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
+ #define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX)
+diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
+index 0f59fd9..c502784 100644
+--- a/arch/parisc/include/asm/uaccess.h
++++ b/arch/parisc/include/asm/uaccess.h
+@@ -220,10 +220,10 @@ static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+ {
+- int sz = __compiletime_object_size(to);
++ size_t sz = __compiletime_object_size(to);
+ int ret = -EFAULT;
+
+- if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n))
++ if (likely(sz == (size_t)-1 || !__builtin_constant_p(n) || sz >= n))
+ ret = __copy_from_user(to, from, n);
+ else
+ copy_from_user_overflow();
+diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
+index a0ecdb4a..71d2069 100644
+--- a/arch/parisc/kernel/module.c
++++ b/arch/parisc/kernel/module.c
+@@ -100,14 +100,12 @@
+ * or init pieces the location is */
+ static inline int in_init(struct module *me, void *loc)
+ {
+- return (loc >= me->init_layout.base &&
+- loc <= (me->init_layout.base + me->init_layout.size));
++ within_module_init((unsigned long)loc, me);
+ }
+
+ static inline int in_core(struct module *me, void *loc)
+ {
+- return (loc >= me->core_layout.base &&
+- loc <= (me->core_layout.base + me->core_layout.size));
++ within_module_core((unsigned long)loc, me);
+ }
+
+ static inline int in_local(struct module *me, void *loc)
+@@ -367,13 +365,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
+ }
+
+ /* align things a bit */
+- me->core_layout.size = ALIGN(me->core_layout.size, 16);
+- me->arch.got_offset = me->core_layout.size;
+- me->core_layout.size += gots * sizeof(struct got_entry);
++ me->core_layout.size_rw = ALIGN(me->core_layout.size_rw, 16);
++ me->arch.got_offset = me->core_layout.size_rw;
++ me->core_layout.size_rw += gots * sizeof(struct got_entry);
+
+- me->core_layout.size = ALIGN(me->core_layout.size, 16);
+- me->arch.fdesc_offset = me->core_layout.size;
+- me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
++ me->core_layout.size_rw = ALIGN(me->core_layout.size_rw, 16);
++ me->arch.fdesc_offset = me->core_layout.size_rw;
++ me->core_layout.size_rw += fdescs * sizeof(Elf_Fdesc);
+
+ me->arch.got_max = gots;
+ me->arch.fdesc_max = fdescs;
+@@ -391,7 +389,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
+
+ BUG_ON(value == 0);
+
+- got = me->core_layout.base + me->arch.got_offset;
++ got = me->core_layout.base_rw + me->arch.got_offset;
+ for (i = 0; got[i].addr; i++)
+ if (got[i].addr == value)
+ goto out;
+@@ -409,7 +407,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
+ #ifdef CONFIG_64BIT
+ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+ {
+- Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
++ Elf_Fdesc *fdesc = me->core_layout.base_rw + me->arch.fdesc_offset;
+
+ if (!value) {
+ printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+@@ -427,7 +425,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+
+ /* Create new one */
+ fdesc->addr = value;
+- fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
++ fdesc->gp = (Elf_Addr)me->core_layout.base_rw + me->arch.got_offset;
+ return (Elf_Addr)fdesc;
+ }
+ #endif /* CONFIG_64BIT */
+@@ -847,7 +845,7 @@ register_unwind_table(struct module *me,
+
+ table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
+ end = table + sechdrs[me->arch.unwind_section].sh_size;
+- gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
++ gp = (Elf_Addr)me->core_layout.base_rw + me->arch.got_offset;
+
+ DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
+ me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
+index 0a393a0..5b3199e0 100644
+--- a/arch/parisc/kernel/sys_parisc.c
++++ b/arch/parisc/kernel/sys_parisc.c
+@@ -92,6 +92,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long task_size = TASK_SIZE;
+ int do_color_align, last_mmap;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ if (len > task_size)
+ return -ENOMEM;
+@@ -109,6 +110,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ goto found_addr;
+ }
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align && last_mmap)
+ addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+@@ -127,6 +132,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ info.high_limit = mmap_upper_limit();
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+ info.align_offset = shared_align_offset(last_mmap, pgoff);
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ found_addr:
+@@ -146,6 +152,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ unsigned long addr = addr0;
+ int do_color_align, last_mmap;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ #ifdef CONFIG_64BIT
+ /* This should only ever run for 32-bit processes. */
+@@ -170,6 +177,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ }
+
+ /* requesting a specific address */
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align && last_mmap)
+ addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+@@ -187,6 +198,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ info.high_limit = mm->mmap_base;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+ info.align_offset = shared_align_offset(last_mmap, pgoff);
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ goto found_addr;
+@@ -252,6 +264,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ mm->mmap_legacy_base = mmap_legacy_base();
+ mm->mmap_base = mmap_upper_limit();
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP) {
++ mm->mmap_legacy_base += mm->delta_mmap;
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++ }
++#endif
++
+ if (mmap_is_legacy()) {
+ mm->mmap_base = mm->mmap_legacy_base;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
+index 97d6b20..2ab0232 100644
+--- a/arch/parisc/kernel/traps.c
++++ b/arch/parisc/kernel/traps.c
+@@ -719,9 +719,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
+
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma(current->mm,regs->iaoq[0]);
+- if (vma && (regs->iaoq[0] >= vma->vm_start)
+- && (vma->vm_flags & VM_EXEC)) {
+-
++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
+ fault_address = regs->iaoq[0];
+ fault_space = regs->iasq[0];
+
+diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
+index 16dbe81..db2ed24 100644
+--- a/arch/parisc/mm/fault.c
++++ b/arch/parisc/mm/fault.c
+@@ -16,6 +16,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <linux/uaccess.h>
++#include <linux/unistd.h>
+
+ #include <asm/traps.h>
+
+@@ -50,7 +51,7 @@ int show_unhandled_signals = 1;
+ static unsigned long
+ parisc_acctyp(unsigned long code, unsigned int inst)
+ {
+- if (code == 6 || code == 16)
++ if (code == 6 || code == 7 || code == 16)
+ return VM_EXEC;
+
+ switch (inst & 0xf0000000) {
+@@ -136,6 +137,116 @@ parisc_acctyp(unsigned long code, unsigned int inst)
+ }
+ #endif
+
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
++ *
++ * returns 1 when task should be killed
++ * 2 when rt_sigreturn 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: unpatched PLT emulation */
++ unsigned int bl, depwi;
++
++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
++
++ if (err)
++ break;
++
++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
++
++ err = get_user(ldw, (unsigned int *)addr);
++ err |= get_user(bv, (unsigned int *)(addr+4));
++ err |= get_user(ldw2, (unsigned int *)(addr+8));
++
++ if (err)
++ break;
++
++ if (ldw == 0x0E801096U &&
++ bv == 0xEAC0C000U &&
++ ldw2 == 0x0E881095U)
++ {
++ unsigned int resolver, map;
++
++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
++ if (err)
++ break;
++
++ regs->gr[20] = instruction_pointer(regs)+8;
++ regs->gr[21] = map;
++ regs->gr[22] = resolver;
++ regs->iaoq[0] = resolver | 3UL;
++ regs->iaoq[1] = regs->iaoq[0] + 4;
++ return 3;
++ }
++ }
++ } while (0);
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++
++#ifndef CONFIG_PAX_EMUSIGRT
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
++ return 1;
++#endif
++
++ do { /* PaX: rt_sigreturn emulation */
++ unsigned int ldi1, ldi2, bel, nop;
++
++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
++
++ if (err)
++ break;
++
++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
++ ldi2 == 0x3414015AU &&
++ bel == 0xE4008200U &&
++ nop == 0x08000240U)
++ {
++ regs->gr[25] = (ldi1 & 2) >> 1;
++ regs->gr[20] = __NR_rt_sigreturn;
++ regs->gr[31] = regs->iaoq[1] + 16;
++ regs->sr[0] = regs->iasq[1];
++ regs->iaoq[0] = 0x100UL;
++ regs->iaoq[1] = regs->iaoq[0] + 4;
++ regs->iasq[0] = regs->sr[2];
++ regs->iasq[1] = regs->sr[2];
++ return 2;
++ }
++ } 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
++
+ int fixup_exception(struct pt_regs *regs)
+ {
+ const struct exception_table_entry *fix;
+@@ -230,8 +341,33 @@ retry:
+
+ good_area:
+
+- if ((vma->vm_flags & acc_type) != acc_type)
++ if ((vma->vm_flags & acc_type) != acc_type) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
++ (address & ~3UL) == instruction_pointer(regs))
++ {
++ up_read(&mm->mmap_sem);
++ switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_PAX_EMUPLT
++ case 3:
++ return;
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++ case 2:
++ return;
++#endif
++
++ }
++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
++ 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/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 0a9d439..2b95815 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -146,6 +146,7 @@ config PPC
+ select ARCH_USE_BUILTIN_BSWAP
+ select OLD_SIGSUSPEND
+ select OLD_SIGACTION if PPC32
++ select HAVE_GCC_PLUGINS
+ select HAVE_DEBUG_STACKOVERFLOW
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
+ select ARCH_USE_CMPXCHG_LOCKREF if PPC64
+@@ -443,6 +444,7 @@ config KEXEC
+ bool "kexec system call"
+ depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E
+ select KEXEC_CORE
++ 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/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
+index ae0751e..06b108a 100644
+--- a/arch/powerpc/include/asm/atomic.h
++++ b/arch/powerpc/include/asm/atomic.h
+@@ -9,9 +9,15 @@
+ #include <linux/types.h>
+ #include <asm/cmpxchg.h>
+ #include <asm/barrier.h>
++#include <asm/asm-compat.h>
+
+ #define ATOMIC_INIT(i) { (i) }
+
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++ PPC_LONG" " #from ", " #to"\n" \
++" .previous\n"
++
+ /*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+@@ -39,38 +45,79 @@ static __inline__ int atomic_read(const atomic_t *v)
+ return t;
+ }
+
++static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ int t;
++
++ __asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m"(v->counter));
++
++ return t;
++}
++
+ static __inline__ void atomic_set(atomic_t *v, int i)
+ {
+ __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
+ }
+
+-#define ATOMIC_OP(op, asm_op) \
+-static __inline__ void atomic_##op(int a, atomic_t *v) \
++static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
++}
++
++#ifdef CONFIG_PAX_REFCOUNT
++#define __REFCOUNT_OP(op) op##o.
++#define __OVERFLOW_PRE \
++ " mcrxr cr0\n"
++#define __OVERFLOW_POST \
++ " bf 4*cr0+so, 3f\n" \
++ "2: .long 0x00c00b00\n" \
++ "3:\n"
++#define __OVERFLOW_EXTABLE \
++ "\n4:\n" \
++ _ASM_EXTABLE(2b, 4b)
++#else
++#define __REFCOUNT_OP(op) op
++#define __OVERFLOW_PRE
++#define __OVERFLOW_POST
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, pre_op, asm_op, post_op, extable) \
++static inline void atomic_##op##suffix(int a, atomic##suffix##_t *v) \
+ { \
+ int t; \
+ \
+ __asm__ __volatile__( \
+-"1: lwarx %0,0,%3 # atomic_" #op "\n" \
++"1: lwarx %0,0,%3 # atomic_" #op #suffix "\n" \
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ PPC405_ERR77(0,%3) \
+ " stwcx. %0,0,%3 \n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+ } \
+
+-#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \
+-static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
++#define ATOMIC_OP(op, asm_op) __ATOMIC_OP(op, , , asm_op, , ) \
++ __ATOMIC_OP(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC_OP_RETURN(op, suffix, pre_op, asm_op, post_op, extable)\
++static inline int atomic_##op##_return##suffix##_relaxed(int a, atomic##suffix##_t *v)\
+ { \
+ int t; \
+ \
+ __asm__ __volatile__( \
+-"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \
++"1: lwarx %0,0,%2 # atomic_" #op "_return" #suffix "_relaxed\n"\
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ PPC405_ERR77(0, %3) \
+ " stwcx. %0,0,%3\n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+@@ -78,6 +125,9 @@ static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
+ return t; \
+ }
+
++#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) __ATOMIC_OP_RETURN(op, , , asm_op, , )\
++ __ATOMIC_OP_RETURN(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC_OPS(op, asm_op) \
+ ATOMIC_OP(op, asm_op) \
+ ATOMIC_OP_RETURN_RELAXED(op, asm_op)
+@@ -90,44 +140,34 @@ ATOMIC_OP(or, or)
+ ATOMIC_OP(xor, xor)
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked_relaxed atomic_add_return_unchecked_relaxed
+ #define atomic_sub_return_relaxed atomic_sub_return_relaxed
+
+ #undef ATOMIC_OPS
+ #undef ATOMIC_OP_RETURN_RELAXED
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+ #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+
+-static __inline__ void atomic_inc(atomic_t *v)
+-{
+- int t;
++/*
++ * atomic_inc - increment atomic variable
++ * @v: pointer of type atomic_t
++ *
++ * Automatically increments @v by 1
++ */
++#define atomic_inc(v) atomic_add(1, (v))
++#define atomic_inc_return_relaxed(v) atomic_add_return_relaxed(1, (v))
+
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_inc\n\
+- addic %0,%0,1\n"
+- PPC405_ERR77(0,%2)
+-" stwcx. %0,0,%2 \n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++ atomic_add_unchecked(1, v);
+ }
+
+-static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
++static inline int atomic_inc_return_unchecked_relaxed(atomic_unchecked_t *v)
+ {
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n"
+-" addic %0,%0,1\n"
+- PPC405_ERR77(0, %2)
+-" stwcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
++ return atomic_add_return_unchecked_relaxed(1, v);
+ }
+
+ /*
+@@ -139,42 +179,22 @@ static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
+ * other cases.
+ */
+ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+-
+-static __inline__ void atomic_dec(atomic_t *v)
+-{
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_dec\n\
+- addic %0,%0,-1\n"
+- PPC405_ERR77(0,%2)\
+-" stwcx. %0,0,%2\n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-}
+-
+-static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
++#define atomic_inc_and_test_unchecked(v) (atomic_add_return_unchecked(1, v) == 0)
++
++/*
++ * atomic_dec - decrement atomic variable
++ * @v: pointer of type atomic_t
++ *
++ * Atomically decrements @v by 1
++ */
++#define atomic_dec(v) atomic_sub(1, (v))
++#define atomic_dec_return_relaxed(v) atomic_sub_return_relaxed(1, (v))
++
++static __inline__ void atomic_dec_unchecked(atomic_unchecked_t *v)
+ {
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n"
+-" addic %0,%0,-1\n"
+- PPC405_ERR77(0, %2)
+-" stwcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
++ atomic_sub_unchecked(1, v);
+ }
+
+-#define atomic_inc_return_relaxed atomic_inc_return_relaxed
+-#define atomic_dec_return_relaxed atomic_dec_return_relaxed
+-
+ #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+ #define atomic_cmpxchg_relaxed(v, o, n) \
+ cmpxchg_relaxed(&((v)->counter), (o), (n))
+@@ -184,6 +204,13 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+ #define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
+
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, int new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++#define atomic_xchg_unchecked(v, new) (xchg_unchecked(&((v)->counter), new))
++
+ /**
+ * __atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+@@ -201,11 +228,27 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ PPC_ATOMIC_ENTRY_BARRIER
+ "1: lwarx %0,0,%1 # __atomic_add_unless\n\
+ cmpw 0,%0,%3 \n\
+- beq- 2f \n\
+- add %0,%2,%0 \n"
++ beq- 2f \n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" mcrxr cr0\n"
++" addo. %0,%2,%0\n"
++" bf 4*cr0+so, 4f\n"
++"3:.long " "0x00c00b00""\n"
++"4:\n"
++#else
++ "add %0,%2,%0 \n"
++#endif
++
+ PPC405_ERR77(0,%2)
+ " stwcx. %0,0,%1 \n\
+ bne- 1b \n"
++"5:"
++
++#ifdef CONFIG_PAX_REFCOUNT
++ _ASM_EXTABLE(3b, 5b)
++#endif
++
+ PPC_ATOMIC_EXIT_BARRIER
+ " subf %0,%2,%0 \n\
+ 2:"
+@@ -291,37 +334,59 @@ static __inline__ long atomic64_read(const atomic64_t *v)
+ return t;
+ }
+
++static __inline__ long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ long t;
++
++ __asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m"(v->counter));
++
++ return t;
++}
++
+ static __inline__ void atomic64_set(atomic64_t *v, long i)
+ {
+ __asm__ __volatile__("std%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
+ }
+
+-#define ATOMIC64_OP(op, asm_op) \
+-static __inline__ void atomic64_##op(long a, atomic64_t *v) \
++static __inline__ void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++ __asm__ __volatile__("std%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
++}
++
++#define __ATOMIC64_OP(op, suffix, pre_op, asm_op, post_op, extable) \
++static inline void atomic64_##op##suffix(long a, atomic64##suffix##_t *v)\
+ { \
+ long t; \
+ \
+ __asm__ __volatile__( \
+ "1: ldarx %0,0,%3 # atomic64_" #op "\n" \
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ " stdcx. %0,0,%3 \n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+ }
+
+-#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) \
+-static inline long \
+-atomic64_##op##_return_relaxed(long a, atomic64_t *v) \
++#define ATOMIC64_OP(op, asm_op) __ATOMIC64_OP(op, , , asm_op, , ) \
++ __ATOMIC64_OP(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, pre_op, asm_op, post_op, extable)\
++static inline long atomic64_##op##_return##suffix##_relaxed(long a, atomic64##suffix##_t *v)\
+ { \
+ long t; \
+ \
+ __asm__ __volatile__( \
+ "1: ldarx %0,0,%3 # atomic64_" #op "_return_relaxed\n" \
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ " stdcx. %0,0,%3\n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+@@ -329,6 +394,9 @@ atomic64_##op##_return_relaxed(long a, atomic64_t *v) \
+ return t; \
+ }
+
++#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) __ATOMIC64_OP_RETURN(op, , , asm_op, , )\
++ __ATOMIC64_OP_RETURN(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC64_OPS(op, asm_op) \
+ ATOMIC64_OP(op, asm_op) \
+ ATOMIC64_OP_RETURN_RELAXED(op, asm_op)
+@@ -344,38 +412,33 @@ ATOMIC64_OP(xor, xor)
+
+ #undef ATOPIC64_OPS
+ #undef ATOMIC64_OP_RETURN_RELAXED
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_EXTABLE
++#undef __OVERFLOW_POST
++#undef __OVERFLOW_PRE
++#undef __REFCOUNT_OP
+
+ #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
+
+-static __inline__ void atomic64_inc(atomic64_t *v)
+-{
+- long t;
++/*
++ * atomic64_inc - increment atomic variable
++ * @v: pointer of type atomic64_t
++ *
++ * Automatically increments @v by 1
++ */
++#define atomic64_inc(v) atomic64_add(1, (v))
++#define atomic64_inc_return_relaxed(v) atomic64_add_return_relaxed(1, (v))
+
+- __asm__ __volatile__(
+-"1: ldarx %0,0,%2 # atomic64_inc\n\
+- addic %0,%0,1\n\
+- stdcx. %0,0,%2 \n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
++static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
++{
++ atomic64_add_unchecked(1, v);
+ }
+
+-static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v)
++static inline long atomic64_inc_return_unchecked_relaxed(atomic64_unchecked_t *v)
+ {
+- long t;
+-
+- __asm__ __volatile__(
+-"1: ldarx %0,0,%2 # atomic64_inc_return_relaxed\n"
+-" addic %0,%0,1\n"
+-" stdcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
++ return atomic64_add_return_unchecked_relaxed(1, v);
+ }
+
+ /*
+@@ -388,39 +451,20 @@ static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v)
+ */
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+-static __inline__ void atomic64_dec(atomic64_t *v)
++/*
++ * atomic64_dec - decrement atomic variable
++ * @v: pointer of type atomic64_t
++ *
++ * Atomically decrements @v by 1
++ */
++#define atomic64_dec(v) atomic64_sub(1, (v))
++#define atomic64_dec_return_relaxed(v) atomic64_sub_return_relaxed(1, (v))
++
++static __inline__ void atomic64_dec_unchecked(atomic64_unchecked_t *v)
+ {
+- long t;
+-
+- __asm__ __volatile__(
+-"1: ldarx %0,0,%2 # atomic64_dec\n\
+- addic %0,%0,-1\n\
+- stdcx. %0,0,%2\n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
++ atomic64_sub_unchecked(1, v);
+ }
+
+-static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v)
+-{
+- long t;
+-
+- __asm__ __volatile__(
+-"1: ldarx %0,0,%2 # atomic64_dec_return_relaxed\n"
+-" addic %0,%0,-1\n"
+-" stdcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
+-}
+-
+-#define atomic64_inc_return_relaxed atomic64_inc_return_relaxed
+-#define atomic64_dec_return_relaxed atomic64_dec_return_relaxed
+-
+ #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
+ #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+
+@@ -457,6 +501,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
+ #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+ #define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
+
++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old, long new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++#define atomic64_xchg_unchecked(v, new) (xchg(&((v)->counter), new))
++
+ /**
+ * atomic64_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic64_t
+@@ -472,13 +523,29 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ __asm__ __volatile__ (
+ PPC_ATOMIC_ENTRY_BARRIER
+-"1: ldarx %0,0,%1 # __atomic_add_unless\n\
++"1: ldarx %0,0,%1 # atomic64_add_unless\n\
+ cmpd 0,%0,%3 \n\
+- beq- 2f \n\
+- add %0,%2,%0 \n"
++ beq- 2f \n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" mcrxr cr0\n"
++" addo. %0,%2,%0\n"
++" bf 4*cr0+so, 4f\n"
++"3:.long " "0x00c00b00""\n"
++"4:\n"
++#else
++ "add %0,%2,%0 \n"
++#endif
++
+ " stdcx. %0,0,%1 \n\
+ bne- 1b \n"
+ PPC_ATOMIC_EXIT_BARRIER
++"5:"
++
++#ifdef CONFIG_PAX_REFCOUNT
++ _ASM_EXTABLE(3b, 5b)
++#endif
++
+ " subf %0,%2,%0 \n\
+ 2:"
+ : "=&r" (t)
+diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h
+index 880db13..017716c 100644
+--- a/arch/powerpc/include/asm/book3s/32/hash.h
++++ b/arch/powerpc/include/asm/book3s/32/hash.h
+@@ -20,6 +20,7 @@
+ #define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
+ #define _PAGE_USER 0x004 /* usermode access allowed */
+ #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
++#define _PAGE_EXEC _PAGE_GUARDED
+ #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+ #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+ #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h
+index cd5e7aa..7709061 100644
+--- a/arch/powerpc/include/asm/book3s/64/pgalloc.h
++++ b/arch/powerpc/include/asm/book3s/64/pgalloc.h
+@@ -91,6 +91,11 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+ pgd_set(pgd, __pgtable_ptr_val(pud) | PGD_VAL_BITS);
+ }
+
++static inline void pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
++{
++ pgd_populate(mm, pgd, pud);
++}
++
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+ return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE), GFP_KERNEL);
+@@ -106,6 +111,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ pud_set(pud, __pgtable_ptr_val(pmd) | PUD_VAL_BITS);
+ }
+
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++ pud_populate_kernel(mm, pud, pmd);
++}
++
+ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
+ unsigned long address)
+ {
+diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
+index ffbafbf..71d037f 100644
+--- a/arch/powerpc/include/asm/cache.h
++++ b/arch/powerpc/include/asm/cache.h
+@@ -3,6 +3,8 @@
+
+ #ifdef __KERNEL__
+
++#include <asm/reg.h>
++#include <linux/const.h>
+
+ /* bytes per L1 cache line */
+ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+@@ -22,7 +24,7 @@
+ #define L1_CACHE_SHIFT 7
+ #endif
+
+-#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/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
+index ee46ffe..b36c98c 100644
+--- a/arch/powerpc/include/asm/elf.h
++++ b/arch/powerpc/include/asm/elf.h
+@@ -30,6 +30,18 @@
+
+ #define ELF_ET_DYN_BASE 0x20000000
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
++
++#ifdef __powerpc64__
++#define PAX_DELTA_MMAP_LEN (is_32bit_task() ? 16 : 28)
++#define PAX_DELTA_STACK_LEN (is_32bit_task() ? 16 : 28)
++#else
++#define PAX_DELTA_MMAP_LEN 15
++#define PAX_DELTA_STACK_LEN 15
++#endif
++#endif
++
+ #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
+
+ /*
+diff --git a/arch/powerpc/include/asm/exec.h b/arch/powerpc/include/asm/exec.h
+index 8196e9c..d83a9f3 100644
+--- a/arch/powerpc/include/asm/exec.h
++++ b/arch/powerpc/include/asm/exec.h
+@@ -4,6 +4,6 @@
+ #ifndef _ASM_POWERPC_EXEC_H
+ #define _ASM_POWERPC_EXEC_H
+
+-extern unsigned long arch_align_stack(unsigned long sp);
++#define arch_align_stack(x) ((x) & ~0xfUL)
+
+ #endif /* _ASM_POWERPC_EXEC_H */
+diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h
+index 5acabbd..7ea14fa 100644
+--- a/arch/powerpc/include/asm/kmap_types.h
++++ b/arch/powerpc/include/asm/kmap_types.h
+@@ -10,7 +10,7 @@
+ * 2 of the License, or (at your option) any later version.
+ */
+
+-#define KM_TYPE_NR 16
++#define KM_TYPE_NR 17
+
+ #endif /* __KERNEL__ */
+ #endif /* _ASM_POWERPC_KMAP_TYPES_H */
+diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
+index b8da913..c02b593 100644
+--- a/arch/powerpc/include/asm/local.h
++++ b/arch/powerpc/include/asm/local.h
+@@ -9,21 +9,65 @@ 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)
+
+ static __inline__ long local_add_return(long a, local_t *l)
+ {
+ long t;
+
+ __asm__ __volatile__(
++"1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" mcrxr cr0\n"
++" addo. %0,%1,%0\n"
++" bf 4*cr0+so, 3f\n"
++"2:.long " "0x00c00b00""\n"
++#else
++" add %0,%1,%0\n"
++#endif
++
++"3:\n"
++ PPC405_ERR77(0,%2)
++ PPC_STLCX "%0,0,%2 \n\
++ bne- 1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++ _ASM_EXTABLE(2b, 4b)
++#endif
++
++ : "=&r" (t)
++ : "r" (a), "r" (&(l->a.counter))
++ : "cc", "memory");
++
++ return t;
++}
++
++static __inline__ long local_add_return_unchecked(long a, local_unchecked_t *l)
++{
++ long t;
++
++ __asm__ __volatile__(
+ "1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n\
+ add %0,%1,%0\n"
+ PPC405_ERR77(0,%2)
+@@ -101,6 +145,8 @@ static __inline__ long local_dec_return(local_t *l)
+
+ #define local_cmpxchg(l, o, n) \
+ (cmpxchg_local(&((l)->a.counter), (o), (n)))
++#define local_cmpxchg_unchecked(l, o, n) \
++ (cmpxchg_local(&((l)->a.counter), (o), (n)))
+ #define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
+
+ /**
+diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h
+index 2563c43..d6fdd62 100644
+--- a/arch/powerpc/include/asm/mman.h
++++ b/arch/powerpc/include/asm/mman.h
+@@ -25,7 +25,7 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
+ }
+ #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
+
+-static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
++static inline pgprot_t arch_vm_get_page_prot(vm_flags_t vm_flags)
+ {
+ return (vm_flags & VM_SAO) ? __pgprot(_PAGE_SAO) : __pgprot(0);
+ }
+diff --git a/arch/powerpc/include/asm/nohash/64/pgalloc.h b/arch/powerpc/include/asm/nohash/64/pgalloc.h
+index 897d2e1..399f34f 100644
+--- a/arch/powerpc/include/asm/nohash/64/pgalloc.h
++++ b/arch/powerpc/include/asm/nohash/64/pgalloc.h
+@@ -54,6 +54,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+ #ifndef CONFIG_PPC_64K_PAGES
+
+ #define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD)
++#define pgd_populate_kernel(MM, PGD, PUD) pgd_populate((MM), (PGD), (PUD))
+
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+@@ -70,6 +71,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ pud_set(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);
++}
++
+ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+ {
+@@ -139,6 +145,7 @@ extern void __tlb_remove_table(void *_table);
+ #endif
+
+ #define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
++#define pud_populate_kernel(mm, pud, pmd) pud_populate((mm), (pud), (pmd))
+
+ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+ pte_t *pte)
+diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
+index 51db3a3..0bd72ae 100644
+--- a/arch/powerpc/include/asm/page.h
++++ b/arch/powerpc/include/asm/page.h
+@@ -230,8 +230,9 @@ extern long long virt_phys_offset;
+ * and needs to be executable. This means the whole heap ends
+ * up being executable.
+ */
+-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++#define VM_DATA_DEFAULT_FLAGS32 \
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+ #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+@@ -259,6 +260,9 @@ extern long long virt_phys_offset;
+ #define is_kernel_addr(x) ((x) >= PAGE_OFFSET)
+ #endif
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ #ifndef CONFIG_PPC_BOOK3S_64
+ /*
+ * Use the top bit of the higher-level page table entries to indicate whether
+diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
+index dd5f071..0470718 100644
+--- a/arch/powerpc/include/asm/page_64.h
++++ b/arch/powerpc/include/asm/page_64.h
+@@ -169,15 +169,18 @@ do { \
+ * stack by default, so in the absence of a PT_GNU_STACK program header
+ * we turn execute permission off.
+ */
+-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++#define VM_STACK_DEFAULT_FLAGS32 \
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+ #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
++#ifndef CONFIG_PAX_PAGEEXEC
+ #define VM_STACK_DEFAULT_FLAGS \
+ (is_32bit_task() ? \
+ VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
++#endif
+
+ #include <asm-generic/getorder.h>
+
+diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
+index ee09e99..7e580ee 100644
+--- a/arch/powerpc/include/asm/pgtable.h
++++ b/arch/powerpc/include/asm/pgtable.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_POWERPC_PGTABLE_H
+ #define _ASM_POWERPC_PGTABLE_H
+
++#include <linux/const.h>
+ #ifndef __ASSEMBLY__
+ #include <linux/mmdebug.h>
+ #include <linux/mmzone.h>
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index a0948f4..ddcf6be 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -261,6 +261,7 @@
+ #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
+ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
+ #define DSISR_NOHPTE 0x40000000 /* no translation found */
++#define DSISR_GUARDED 0x10000000 /* fetch from guarded storage */
+ #define DSISR_PROTFAULT 0x08000000 /* protection fault */
+ #define DSISR_ISSTORE 0x02000000 /* access was a store */
+ #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */
+diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
+index e1afd4c..d75924a 100644
+--- a/arch/powerpc/include/asm/smp.h
++++ b/arch/powerpc/include/asm/smp.h
+@@ -51,7 +51,7 @@ struct smp_ops_t {
+ int (*cpu_disable)(void);
+ void (*cpu_die)(unsigned int nr);
+ int (*cpu_bootable)(unsigned int nr);
+-};
++} __no_const;
+
+ extern void smp_send_debugger_break(void);
+ extern void start_secondary_resume(void);
+diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
+index 523673d..10dc784 100644
+--- a/arch/powerpc/include/asm/spinlock.h
++++ b/arch/powerpc/include/asm/spinlock.h
+@@ -27,6 +27,7 @@
+ #include <asm/asm-compat.h>
+ #include <asm/synch.h>
+ #include <asm/ppc-opcode.h>
++#include <asm/atomic.h>
+
+ #ifdef CONFIG_PPC64
+ /* use 0x800000yy when locked, where yy == CPU number */
+@@ -202,13 +203,29 @@ static inline long __arch_read_trylock(arch_rwlock_t *rw)
+ __asm__ __volatile__(
+ "1: " PPC_LWARX(%0,0,%1,1) "\n"
+ __DO_SIGN_EXTEND
+-" addic. %0,%0,1\n\
+- ble- 2f\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" mcrxr cr0\n"
++" addico. %0,%0,1\n"
++" bf 4*cr0+so, 3f\n"
++"2:.long " "0x00c00b00""\n"
++#else
++" addic. %0,%0,1\n"
++#endif
++
++"3:\n"
++ "ble- 4f\n"
+ PPC405_ERR77(0,%1)
+ " stwcx. %0,0,%1\n\
+ bne- 1b\n"
+ PPC_ACQUIRE_BARRIER
+-"2:" : "=&r" (tmp)
++"4:"
++
++#ifdef CONFIG_PAX_REFCOUNT
++ _ASM_EXTABLE(2b,4b)
++#endif
++
++ : "=&r" (tmp)
+ : "r" (&rw->lock)
+ : "cr0", "xer", "memory");
+
+@@ -284,11 +301,27 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
+ __asm__ __volatile__(
+ "# read_unlock\n\t"
+ PPC_RELEASE_BARRIER
+-"1: lwarx %0,0,%1\n\
+- addic %0,%0,-1\n"
++"1: lwarx %0,0,%1\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" mcrxr cr0\n"
++" addico. %0,%0,-1\n"
++" bf 4*cr0+so, 3f\n"
++"2:.long " "0x00c00b00""\n"
++#else
++" addic. %0,%0,-1\n"
++#endif
++
++"3:\n"
+ PPC405_ERR77(0,%1)
+ " stwcx. %0,0,%1\n\
+ bne- 1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++ _ASM_EXTABLE(2b, 4b)
++#endif
++
+ : "=&r"(tmp)
+ : "r"(&rw->lock)
+ : "cr0", "xer", "memory");
+diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
+index e40010a..d3c3d6b 100644
+--- a/arch/powerpc/include/asm/string.h
++++ b/arch/powerpc/include/asm/string.h
+@@ -15,17 +15,17 @@
+ #define __HAVE_ARCH_MEMCMP
+ #define __HAVE_ARCH_MEMCHR
+
+-extern char * strcpy(char *,const char *);
+-extern char * strncpy(char *,const char *, __kernel_size_t);
++extern char * strcpy(char *,const char *) __nocapture(2);
++extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2);
+ extern __kernel_size_t strlen(const char *);
+-extern int strcmp(const char *,const char *);
+-extern int strncmp(const char *, const char *, __kernel_size_t);
+-extern char * strcat(char *, const char *);
++extern int strcmp(const char *,const char *) __nocapture(1, 2);
++extern int strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
++extern char * strcat(char *, const char *) __nocapture(2);
+ extern void * memset(void *,int,__kernel_size_t);
+-extern void * memcpy(void *,const void *,__kernel_size_t);
+-extern void * memmove(void *,const void *,__kernel_size_t);
+-extern int memcmp(const void *,const void *,__kernel_size_t);
+-extern void * memchr(const void *,int,__kernel_size_t);
++extern void * memcpy(void *,const void *,__kernel_size_t) __nocapture(2);
++extern void * memmove(void *,const void *,__kernel_size_t) __nocapture(2);
++extern int memcmp(const void *,const void *,__kernel_size_t) __nocapture(1, 2);
++extern void * memchr(const void *,int,__kernel_size_t) __nocapture(1);
+
+ #endif /* __KERNEL__ */
+
+diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
+index 8febc3f..a4614f3 100644
+--- a/arch/powerpc/include/asm/thread_info.h
++++ b/arch/powerpc/include/asm/thread_info.h
+@@ -103,6 +103,8 @@ static inline struct thread_info *current_thread_info(void)
+ #if defined(CONFIG_PPC64)
+ #define TIF_ELF2ABI 18 /* function descriptors must die! */
+ #endif
++/* mask must be expressable within 16 bits to satisfy 'andi' instruction reqs */
++#define TIF_GRSEC_SETXID 6 /* update credentials on syscall entry/exit */
+
+ /* as above, but as bit values */
+ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+@@ -121,9 +123,10 @@ static inline struct thread_info *current_thread_info(void)
+ #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE)
+ #define _TIF_NOHZ (1<<TIF_NOHZ)
++#define _TIF_GRSEC_SETXID (1<<TIF_GRSEC_SETXID)
+ #define _TIF_SYSCALL_DOTRACE (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+ _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
+- _TIF_NOHZ)
++ _TIF_NOHZ | _TIF_GRSEC_SETXID)
+
+ #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \
+diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
+index b7c20f0..4adc0f1 100644
+--- a/arch/powerpc/include/asm/uaccess.h
++++ b/arch/powerpc/include/asm/uaccess.h
+@@ -58,6 +58,7 @@
+
+ #endif
+
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) \
+ (__chk_user_ptr(addr), \
+ __access_ok((__force unsigned long)(addr), (size), get_fs()))
+@@ -303,52 +304,6 @@ do { \
+ extern unsigned long __copy_tofrom_user(void __user *to,
+ const void __user *from, unsigned long size);
+
+-#ifndef __powerpc64__
+-
+-static inline unsigned long copy_from_user(void *to,
+- const void __user *from, unsigned long n)
+-{
+- unsigned long over;
+-
+- if (access_ok(VERIFY_READ, from, n))
+- return __copy_tofrom_user((__force void __user *)to, from, n);
+- if ((unsigned long)from < TASK_SIZE) {
+- over = (unsigned long)from + n - TASK_SIZE;
+- return __copy_tofrom_user((__force void __user *)to, from,
+- n - over) + over;
+- }
+- return n;
+-}
+-
+-static inline unsigned long copy_to_user(void __user *to,
+- const void *from, unsigned long n)
+-{
+- unsigned long over;
+-
+- if (access_ok(VERIFY_WRITE, to, n))
+- return __copy_tofrom_user(to, (__force void __user *)from, n);
+- if ((unsigned long)to < TASK_SIZE) {
+- over = (unsigned long)to + n - TASK_SIZE;
+- return __copy_tofrom_user(to, (__force void __user *)from,
+- n - over) + over;
+- }
+- return n;
+-}
+-
+-#else /* __powerpc64__ */
+-
+-#define __copy_in_user(to, from, size) \
+- __copy_tofrom_user((to), (from), (size))
+-
+-extern unsigned long copy_from_user(void *to, const void __user *from,
+- unsigned long n);
+-extern unsigned long copy_to_user(void __user *to, const void *from,
+- unsigned long n);
+-extern unsigned long copy_in_user(void __user *to, const void __user *from,
+- unsigned long n);
+-
+-#endif /* __powerpc64__ */
+-
+ static inline unsigned long __copy_from_user_inatomic(void *to,
+ const void __user *from, unsigned long n)
+ {
+@@ -372,6 +327,10 @@ static inline unsigned long __copy_from_user_inatomic(void *to,
+ if (ret == 0)
+ return 0;
+ }
++
++ if (!__builtin_constant_p(n))
++ check_object_size(to, n, false);
++
+ return __copy_tofrom_user((__force void __user *)to, from, n);
+ }
+
+@@ -398,6 +357,10 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
+ if (ret == 0)
+ return 0;
+ }
++
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n, true);
++
+ return __copy_tofrom_user(to, (__force const void __user *)from, n);
+ }
+
+@@ -415,6 +378,92 @@ static inline unsigned long __copy_to_user(void __user *to,
+ return __copy_to_user_inatomic(to, from, size);
+ }
+
++#ifndef __powerpc64__
++
++static inline unsigned long __must_check copy_from_user(void *to,
++ const void __user *from, unsigned long n)
++{
++ unsigned long over;
++
++ if ((long)n < 0)
++ return n;
++
++ if (access_ok(VERIFY_READ, from, n)) {
++ if (!__builtin_constant_p(n))
++ check_object_size(to, n, false);
++ return __copy_tofrom_user((__force void __user *)to, from, n);
++ }
++ if ((unsigned long)from < TASK_SIZE) {
++ over = (unsigned long)from + n - TASK_SIZE;
++ if (!__builtin_constant_p(n - over))
++ check_object_size(to, n - over, false);
++ return __copy_tofrom_user((__force void __user *)to, from,
++ n - over) + over;
++ }
++ return n;
++}
++
++static inline unsigned long __must_check copy_to_user(void __user *to,
++ const void *from, unsigned long n)
++{
++ unsigned long over;
++
++ if ((long)n < 0)
++ return n;
++
++ if (access_ok(VERIFY_WRITE, to, n)) {
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n, true);
++ return __copy_tofrom_user(to, (__force void __user *)from, n);
++ }
++ if ((unsigned long)to < TASK_SIZE) {
++ over = (unsigned long)to + n - TASK_SIZE;
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n - over, true);
++ return __copy_tofrom_user(to, (__force void __user *)from,
++ n - over) + over;
++ }
++ return n;
++}
++
++#else /* __powerpc64__ */
++
++#define __copy_in_user(to, from, size) \
++ __copy_tofrom_user((to), (from), (size))
++
++static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++ if ((long)n < 0 || n > INT_MAX)
++ return n;
++
++ if (!__builtin_constant_p(n))
++ check_object_size(to, n, false);
++
++ if (likely(access_ok(VERIFY_READ, from, n)))
++ n = __copy_from_user(to, from, n);
++ else
++ memset(to, 0, n);
++ return n;
++}
++
++static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
++{
++ if ((long)n < 0 || n > INT_MAX)
++ return n;
++
++ if (likely(access_ok(VERIFY_WRITE, to, n))) {
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n, true);
++ n = __copy_to_user(to, from, n);
++ }
++ return n;
++}
++
++extern unsigned long copy_in_user(void __user *to, const void __user *from,
++ unsigned long n);
++
++#endif /* __powerpc64__ */
++
+ extern unsigned long __clear_user(void __user *addr, unsigned long size);
+
+ static inline unsigned long clear_user(void __user *addr, unsigned long size)
+diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
+index 2da380f..0ba9052 100644
+--- a/arch/powerpc/kernel/Makefile
++++ b/arch/powerpc/kernel/Makefile
+@@ -14,6 +14,11 @@ CFLAGS_prom_init.o += -fPIC
+ CFLAGS_btext.o += -fPIC
+ endif
+
++CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
++CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
++CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
++CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
++
+ ifdef CONFIG_FUNCTION_TRACER
+ # Do not trace early boot code
+ CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+@@ -26,6 +31,8 @@ CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+ CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+ endif
+
++CFLAGS_REMOVE_prom_init.o += $(LATENT_ENTROPY_PLUGIN_CFLAGS)
++
+ obj-y := cputable.o ptrace.o syscalls.o \
+ irq.o align.o signal_32.o pmc.o vdso.o \
+ process.o systbl.o idle.o \
+diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
+index 488e631..6cdd928 100644
+--- a/arch/powerpc/kernel/exceptions-64e.S
++++ b/arch/powerpc/kernel/exceptions-64e.S
+@@ -1010,6 +1010,7 @@ storage_fault_common:
+ std r14,_DAR(r1)
+ std r15,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
++ bl save_nvgprs
+ mr r4,r14
+ mr r5,r15
+ ld r14,PACA_EXGEN+EX_R14(r13)
+@@ -1018,8 +1019,7 @@ storage_fault_common:
+ cmpdi r3,0
+ bne- 1f
+ b ret_from_except_lite
+-1: bl save_nvgprs
+- mr r5,r3
++1: mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ ld r4,_DAR(r1)
+ bl bad_page_fault
+diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
+index 8bcc1b4..d2acf44 100644
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1488,10 +1488,10 @@ handle_page_fault:
+ 11: ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
+ addi r3,r1,STACK_FRAME_OVERHEAD
++ bl save_nvgprs
+ bl do_page_fault
+ cmpdi r3,0
+ beq+ 12f
+- bl save_nvgprs
+ mr r5,r3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lwz r4,_DAR(r1)
+diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
+index 3cb46a3..a8c0477 100644
+--- a/arch/powerpc/kernel/irq.c
++++ b/arch/powerpc/kernel/irq.c
+@@ -461,6 +461,8 @@ void migrate_irqs(void)
+ }
+ #endif
+
++extern void gr_handle_kernel_exploit(void);
++
+ static inline void check_stack_overflow(void)
+ {
+ #ifdef CONFIG_DEBUG_STACKOVERFLOW
+@@ -473,6 +475,7 @@ static inline void check_stack_overflow(void)
+ pr_err("do_IRQ: stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
++ gr_handle_kernel_exploit();
+ }
+ #endif
+ }
+diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
+index 5a7a78f..c0e4207 100644
+--- a/arch/powerpc/kernel/module_32.c
++++ b/arch/powerpc/kernel/module_32.c
+@@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr,
+ me->arch.core_plt_section = i;
+ }
+ if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
+- pr_err("Module doesn't contain .plt or .init.plt sections.\n");
++ pr_err("Module $s doesn't contain .plt or .init.plt sections.\n", me->name);
+ return -ENOEXEC;
+ }
+
+@@ -188,11 +188,16 @@ static uint32_t do_plt_call(void *location,
+
+ pr_debug("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
+ /* Init, or core PLT? */
+- if (location >= mod->core_layout.base
+- && location < mod->core_layout.base + mod->core_layout.size)
++ if ((location >= mod->core_layout.base_rx && location < mod->core_layout.base_rx + mod->core_layout.size_rx) ||
++ (location >= mod->core_layout.base_rw && location < mod->core_layout.base_rw + mod->core_layout.size_rw))
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
+- else
++ else if ((location >= mod->init_layout.base_rx && location < mod->init_layout.base_rx + mod->init_layout.size_rx) ||
++ (location >= mod->init_layout.base_rw && location < mod->init_layout.base_rw + mod->init_layout.size_rw))
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
++ else {
++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
++ return ~0UL;
++ }
+
+ /* Find this entry, or if that fails, the next avail. entry */
+ while (entry->jump[0]) {
+@@ -301,7 +306,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
+ #ifdef CONFIG_DYNAMIC_FTRACE
+ int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs)
+ {
+- module->arch.tramp = do_plt_call(module->core_layout.base,
++ module->arch.tramp = do_plt_call(module->core_layout.base_rx,
+ (unsigned long)ftrace_caller,
+ sechdrs, module);
+ if (!module->arch.tramp)
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 0b93893..4c72fc1 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -1321,8 +1321,8 @@ void show_regs(struct pt_regs * regs)
+ * Lookup NIP late so we have the best change of getting the
+ * above info out without failing
+ */
+- printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
+- printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
++ printk("NIP ["REG"] %pA\n", regs->nip, (void *)regs->nip);
++ printk("LR ["REG"] %pA\n", regs->link, (void *)regs->link);
+ #endif
+ show_stack(current, (unsigned long *) regs->gpr[1]);
+ if (!user_mode(regs))
+@@ -1843,10 +1843,10 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
+ newsp = stack[0];
+ ip = stack[STACK_FRAME_LR_SAVE];
+ if (!firstframe || ip != lr) {
+- printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
++ printk("["REG"] ["REG"] %pA", sp, ip, (void *)ip);
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if ((ip == rth) && curr_frame >= 0) {
+- printk(" (%pS)",
++ printk(" (%pA)",
+ (void *)current->ret_stack[curr_frame].ret);
+ curr_frame--;
+ }
+@@ -1866,7 +1866,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
+ struct pt_regs *regs = (struct pt_regs *)
+ (sp + STACK_FRAME_OVERHEAD);
+ lr = regs->link;
+- printk("--- interrupt: %lx at %pS\n LR = %pS\n",
++ printk("--- interrupt: %lx at %pA\n LR = %pA\n",
+ regs->trap, (void *)regs->nip, (void *)lr);
+ firstframe = 1;
+ }
+@@ -1903,13 +1903,6 @@ void notrace __ppc64_runlatch_off(void)
+ }
+ #endif /* CONFIG_PPC64 */
+
+-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 & ~0xf;
+-}
+-
+ static inline unsigned long brk_rnd(void)
+ {
+ unsigned long rnd = 0;
+diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
+index 060b140..b67ca8c 100644
+--- a/arch/powerpc/kernel/ptrace.c
++++ b/arch/powerpc/kernel/ptrace.c
+@@ -1801,6 +1801,10 @@ static int do_seccomp(struct pt_regs *regs)
+ static inline int do_seccomp(struct pt_regs *regs) { return 0; }
+ #endif /* CONFIG_SECCOMP */
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /**
+ * do_syscall_trace_enter() - Do syscall tracing on kernel entry.
+ * @regs: the pt_regs of the task to trace (current)
+@@ -1829,6 +1833,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
+ if (do_seccomp(regs))
+ return -1;
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+ /*
+ * The tracer may decide to abort the syscall, if so tracehook
+@@ -1871,6 +1880,11 @@ void do_syscall_trace_leave(struct pt_regs *regs)
+ {
+ int step;
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ audit_syscall_exit(regs);
+
+ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
+index b6aa378..a491f51 100644
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -1000,7 +1000,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
+ /* Save user registers on the stack */
+ frame = &rt_sf->uc.uc_mcontext;
+ addr = frame;
+- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
+ sigret = 0;
+ tramp = current->mm->context.vdso_base + vdso32_rt_sigtramp;
+ } else {
+diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
+index 2552079..a290dc8a 100644
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -751,7 +751,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs
+ current->thread.fp_state.fpscr = 0;
+
+ /* Set up to return from userspace. */
+- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
+ regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
+ } else {
+ err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
+diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
+index 9229ba6..ddd4d5e 100644
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -36,6 +36,7 @@
+ #include <linux/debugfs.h>
+ #include <linux/ratelimit.h>
+ #include <linux/context_tracking.h>
++#include <linux/uaccess.h>
+
+ #include <asm/emulated_ops.h>
+ #include <asm/pgtable.h>
+@@ -142,6 +143,8 @@ static unsigned __kprobes long oops_begin(struct pt_regs *regs)
+ return flags;
+ }
+
++extern void gr_handle_kernel_exploit(void);
++
+ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
+ int signr)
+ {
+@@ -191,6 +194,9 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
+ panic("Fatal exception in interrupt");
+ if (panic_on_oops)
+ panic("Fatal exception");
++
++ gr_handle_kernel_exploit();
++
+ do_exit(signr);
+ }
+
+@@ -1138,6 +1144,26 @@ void __kprobes program_check_exception(struct pt_regs *regs)
+ enum ctx_state prev_state = exception_enter();
+ unsigned int reason = get_reason(regs);
+
++#ifdef CONFIG_PAX_REFCOUNT
++ unsigned int bkpt;
++ const struct exception_table_entry *entry;
++
++ if (reason & REASON_ILLEGAL) {
++ /* Check if PaX bad instruction */
++ if (!probe_kernel_address((void *)regs->nip, bkpt) && bkpt == 0xc00b00) {
++ current->thread.trap_nr = 0;
++ pax_report_refcount_overflow(regs);
++ /* fixup_exception() for PowerPC does not exist, simulate its job */
++ if ((entry = search_exception_tables(regs->nip)) != NULL) {
++ regs->nip = entry->fixup;
++ return;
++ }
++ /* fixup_exception() could not handle */
++ goto bail;
++ }
++ }
++#endif
++
+ /* We can now get here via a FP Unavailable exception if the core
+ * has no FPU, in that case the reason flags will be 0 */
+
+diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
+index 6767605..75520c0 100644
+--- a/arch/powerpc/kernel/vdso.c
++++ b/arch/powerpc/kernel/vdso.c
+@@ -34,6 +34,7 @@
+ #include <asm/vdso.h>
+ #include <asm/vdso_datapage.h>
+ #include <asm/setup.h>
++#include <asm/mman.h>
+
+ #undef DEBUG
+
+@@ -179,7 +180,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ vdso_base = VDSO32_MBASE;
+ #endif
+
+- current->mm->context.vdso_base = 0;
++ current->mm->context.vdso_base = ~0UL;
+
+ /* vDSO has a problem and was disabled, just don't "enable" it for the
+ * process
+@@ -200,7 +201,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ vdso_base = get_unmapped_area(NULL, vdso_base,
+ (vdso_pages << PAGE_SHIFT) +
+ ((VDSO_ALIGNMENT - 1) & PAGE_MASK),
+- 0, 0);
++ 0, MAP_PRIVATE | MAP_EXECUTABLE);
+ if (IS_ERR_VALUE(vdso_base)) {
+ rc = vdso_base;
+ goto fail_mmapsem;
+diff --git a/arch/powerpc/lib/usercopy_64.c b/arch/powerpc/lib/usercopy_64.c
+index 5eea6f3..5d10396 100644
+--- a/arch/powerpc/lib/usercopy_64.c
++++ b/arch/powerpc/lib/usercopy_64.c
+@@ -9,22 +9,6 @@
+ #include <linux/module.h>
+ #include <asm/uaccess.h>
+
+-unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+-{
+- if (likely(access_ok(VERIFY_READ, from, n)))
+- n = __copy_from_user(to, from, n);
+- else
+- memset(to, 0, n);
+- return n;
+-}
+-
+-unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+-{
+- if (likely(access_ok(VERIFY_WRITE, to, n)))
+- n = __copy_to_user(to, from, n);
+- return n;
+-}
+-
+ unsigned long copy_in_user(void __user *to, const void __user *from,
+ unsigned long n)
+ {
+@@ -35,7 +19,5 @@ unsigned long copy_in_user(void __user *to, const void __user *from,
+ return n;
+ }
+
+-EXPORT_SYMBOL(copy_from_user);
+-EXPORT_SYMBOL(copy_to_user);
+ EXPORT_SYMBOL(copy_in_user);
+
+diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
+index a67c6d7..a662e6d 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -34,6 +34,10 @@
+ #include <linux/context_tracking.h>
+ #include <linux/hugetlb.h>
+ #include <linux/uaccess.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
++#include <linux/unistd.h>
+
+ #include <asm/firmware.h>
+ #include <asm/page.h>
+@@ -68,6 +72,33 @@ static inline int notify_page_fault(struct pt_regs *regs)
+ }
+ #endif
+
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (regs->nip = fault address)
++ *
++ * returns 1 when task should be killed
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++ 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 __user *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08x ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ /*
+ * Check whether the instruction at regs->nip is a store using
+ * an update addressing form which will update r1.
+@@ -227,7 +258,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
+ * indicate errors in DSISR but can validly be set in SRR1.
+ */
+ if (trap == 0x400)
+- error_code &= 0x48200000;
++ error_code &= 0x58200000;
+ else
+ is_write = error_code & DSISR_ISSTORE;
+ #else
+@@ -384,12 +415,16 @@ good_area:
+ * "undefined". Of those that can be set, this is the only
+ * one which seems bad.
+ */
+- if (error_code & 0x10000000)
++ if (error_code & DSISR_GUARDED)
+ /* Guarded storage error. */
+ goto bad_area;
+ #endif /* CONFIG_8xx */
+
+ if (is_exec) {
++#ifdef CONFIG_PPC_STD_MMU
++ if (error_code & DSISR_GUARDED)
++ goto bad_area;
++#endif
+ /*
+ * Allow execution from readable areas if the MMU does not
+ * provide separate controls over reading and executing.
+@@ -484,6 +519,23 @@ bad_area:
+ bad_area_nosemaphore:
+ /* User mode accesses cause a SIGSEGV */
+ if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
++#ifdef CONFIG_PPC_STD_MMU
++ if (is_exec && (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))) {
++#else
++ if (is_exec && regs->nip == address) {
++#endif
++ switch (pax_handle_fetch_fault(regs)) {
++ }
++
++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
++ do_group_exit(SIGKILL);
++ }
++ }
++#endif
++
+ _exception(SIGSEGV, regs, code, address);
+ goto bail;
+ }
+diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
+index 2f1e443..de888bf 100644
+--- a/arch/powerpc/mm/mmap.c
++++ b/arch/powerpc/mm/mmap.c
+@@ -194,6 +194,10 @@ 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();
+
+@@ -205,9 +209,21 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ */
+ if (mmap_is_legacy()) {
+ mm->mmap_base = TASK_UNMAPPED_BASE;
++
++#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/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
+index 2b27458..7c7c59b 100644
+--- a/arch/powerpc/mm/slice.c
++++ b/arch/powerpc/mm/slice.c
+@@ -105,7 +105,7 @@ static int slice_area_is_free(struct mm_struct *mm, unsigned long addr,
+ if ((mm->task_size - len) < addr)
+ return 0;
+ vma = find_vma(mm, addr);
+- return (!vma || (addr + len) <= vma->vm_start);
++ return check_heap_stack_gap(vma, addr, len, 0);
+ }
+
+ static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
+@@ -276,6 +276,12 @@ static unsigned long slice_find_area_bottomup(struct mm_struct *mm,
+ info.align_offset = 0;
+
+ addr = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ addr += mm->delta_mmap;
++#endif
++
+ while (addr < TASK_SIZE) {
+ info.low_limit = addr;
+ if (!slice_scan_available(addr, available, 1, &addr))
+@@ -410,6 +416,11 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
+ if (fixed && addr > (mm->task_size - len))
+ return -ENOMEM;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!fixed && (mm->pax_flags & MF_PAX_RANDMMAP))
++ addr = 0;
++#endif
++
+ /* If hint, make sure it matches our alignment restrictions */
+ if (!fixed && addr) {
+ addr = _ALIGN_UP(addr, 1ul << pshift);
+@@ -555,10 +566,10 @@ unsigned long arch_get_unmapped_area(struct file *filp,
+ }
+
+ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
+- const unsigned long addr0,
+- const unsigned long len,
+- const unsigned long pgoff,
+- const unsigned long flags)
++ unsigned long addr0,
++ unsigned long len,
++ unsigned long pgoff,
++ unsigned long flags)
+ {
+ return slice_get_unmapped_area(addr0, len, flags,
+ current->mm->context.user_psize, 1);
+diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
+index 2936a00..2e73ed6 100644
+--- a/arch/powerpc/platforms/cell/spufs/file.c
++++ b/arch/powerpc/platforms/cell/spufs/file.c
+@@ -263,9 +263,9 @@ spufs_mem_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ return VM_FAULT_NOPAGE;
+ }
+
+-static int spufs_mem_mmap_access(struct vm_area_struct *vma,
++static ssize_t spufs_mem_mmap_access(struct vm_area_struct *vma,
+ unsigned long address,
+- void *buf, int len, int write)
++ void *buf, size_t len, int write)
+ {
+ struct spu_context *ctx = vma->vm_file->private_data;
+ unsigned long offset = address - vma->vm_start;
+diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
+index 26c5d5be..a308c28 100644
+--- a/arch/s390/Kconfig.debug
++++ b/arch/s390/Kconfig.debug
+@@ -9,6 +9,7 @@ config S390_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/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
+index 911064a..dcbb025 100644
+--- a/arch/s390/include/asm/atomic.h
++++ b/arch/s390/include/asm/atomic.h
+@@ -322,4 +322,14 @@ static inline long long atomic64_dec_if_positive(atomic64_t *v)
+ #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0)
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#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 /* __ARCH_S390_ATOMIC__ */
+diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h
+index 22da3b3..80c7915 100644
+--- a/arch/s390/include/asm/cache.h
++++ b/arch/s390/include/asm/cache.h
+@@ -9,8 +9,10 @@
+ #ifndef __ARCH_S390_CACHE_H
+ #define __ARCH_S390_CACHE_H
+
+-#define L1_CACHE_BYTES 256
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 8
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define NET_SKB_PAD 32
+
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
+diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
+index 563ab9f..65d8bd4 100644
+--- a/arch/s390/include/asm/elf.h
++++ b/arch/s390/include/asm/elf.h
+@@ -167,6 +167,13 @@ extern unsigned int vdso_enabled;
+ (STACK_TOP / 3 * 2) : \
+ (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_31BIT) ? 0x10000UL : 0x80000000UL)
++
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26)
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_31BIT) ? 15 : 26)
++#endif
++
+ /* This yields a mask that user programs can use to figure out what
+ instruction set this CPU supports. */
+
+diff --git a/arch/s390/include/asm/exec.h b/arch/s390/include/asm/exec.h
+index c4a93d6..4d2a9b4 100644
+--- a/arch/s390/include/asm/exec.h
++++ b/arch/s390/include/asm/exec.h
+@@ -7,6 +7,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/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
+index e0900dd..72d683d 100644
+--- a/arch/s390/include/asm/uaccess.h
++++ b/arch/s390/include/asm/uaccess.h
+@@ -59,6 +59,7 @@ static inline int __range_ok(unsigned long addr, unsigned long size)
+ __range_ok((unsigned long)(addr), (size)); \
+ })
+
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) __access_ok(addr, size)
+
+ /*
+@@ -272,6 +273,10 @@ static inline unsigned long __must_check
+ copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ might_fault();
++
++ if ((long)n < 0)
++ return n;
++
+ return __copy_to_user(to, from, n);
+ }
+
+@@ -301,10 +306,14 @@ __compiletime_warning("copy_from_user() buffer size is not provably correct")
+ static inline unsigned long __must_check
+ copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+- unsigned int sz = __compiletime_object_size(to);
++ size_t sz = __compiletime_object_size(to);
+
+ might_fault();
+- if (unlikely(sz != -1 && sz < n)) {
++
++ if ((long)n < 0)
++ return n;
++
++ if (unlikely(sz != (size_t)-1 && sz < n)) {
+ copy_from_user_overflow();
+ return n;
+ }
+diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
+index fbc0789..e7962a1 100644
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -163,11 +163,11 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+
+ /* Increase core size by size of got & plt and set start
+ offsets for got and plt. */
+- me->core_layout.size = ALIGN(me->core_layout.size, 4);
+- me->arch.got_offset = me->core_layout.size;
+- me->core_layout.size += me->arch.got_size;
+- me->arch.plt_offset = me->core_layout.size;
+- me->core_layout.size += me->arch.plt_size;
++ me->core_layout.size_rw = ALIGN(me->core_layout.size_rw, 4);
++ me->arch.got_offset = me->core_layout.size_rw;
++ me->core_layout.size_rw += me->arch.got_size;
++ me->arch.plt_offset = me->core_layout.size_rx;
++ me->core_layout.size_rx += me->arch.plt_size;
+ return 0;
+ }
+
+@@ -283,7 +283,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ if (info->got_initialized == 0) {
+ Elf_Addr *gotent;
+
+- gotent = me->core_layout.base + me->arch.got_offset +
++ gotent = me->core_layout.base_rw + me->arch.got_offset +
+ info->got_offset;
+ *gotent = val;
+ info->got_initialized = 1;
+@@ -306,7 +306,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ rc = apply_rela_bits(loc, val, 0, 64, 0);
+ else if (r_type == R_390_GOTENT ||
+ r_type == R_390_GOTPLTENT) {
+- val += (Elf_Addr) me->core_layout.base - loc;
++ val += (Elf_Addr) me->core_layout.base_rw - loc;
+ rc = apply_rela_bits(loc, val, 1, 32, 1);
+ }
+ break;
+@@ -319,7 +319,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
+ if (info->plt_initialized == 0) {
+ unsigned int *ip;
+- ip = me->core_layout.base + me->arch.plt_offset +
++ ip = me->core_layout.base_rx + me->arch.plt_offset +
+ info->plt_offset;
+ ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
+ ip[1] = 0x100a0004;
+@@ -338,7 +338,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ val - loc + 0xffffUL < 0x1ffffeUL) ||
+ (r_type == R_390_PLT32DBL &&
+ val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+- val = (Elf_Addr) me->core_layout.base +
++ val = (Elf_Addr) me->core_layout.base_rx +
+ me->arch.plt_offset +
+ info->plt_offset;
+ val += rela->r_addend - loc;
+@@ -360,7 +360,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ case R_390_GOTOFF32: /* 32 bit offset to GOT. */
+ case R_390_GOTOFF64: /* 64 bit offset to GOT. */
+ val = val + rela->r_addend -
+- ((Elf_Addr) me->core_layout.base + me->arch.got_offset);
++ ((Elf_Addr) me->core_layout.base_rw + me->arch.got_offset);
+ if (r_type == R_390_GOTOFF16)
+ rc = apply_rela_bits(loc, val, 0, 16, 0);
+ else if (r_type == R_390_GOTOFF32)
+@@ -370,7 +370,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
+ break;
+ case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
+ case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
+- val = (Elf_Addr) me->core_layout.base + me->arch.got_offset +
++ val = (Elf_Addr) me->core_layout.base_rw + me->arch.got_offset +
+ rela->r_addend - loc;
+ if (r_type == R_390_GOTPC)
+ rc = apply_rela_bits(loc, val, 1, 32, 0);
+diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
+index bba4fa7..9c32b3c 100644
+--- a/arch/s390/kernel/process.c
++++ b/arch/s390/kernel/process.c
+@@ -217,13 +217,6 @@ unsigned long get_wchan(struct task_struct *p)
+ return 0;
+ }
+
+-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 & ~0xf;
+-}
+-
+ static inline unsigned long brk_rnd(void)
+ {
+ return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
+diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
+index eb9df28..7b686ba 100644
+--- a/arch/s390/mm/mmap.c
++++ b/arch/s390/mm/mmap.c
+@@ -201,9 +201,9 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
+ }
+
+ static unsigned long
+-s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
+- const unsigned long len, const unsigned long pgoff,
+- const unsigned long flags)
++s390_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
+ {
+ struct mm_struct *mm = current->mm;
+ unsigned long area;
+@@ -230,6 +230,10 @@ 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();
+
+@@ -239,9 +243,21 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ */
+ if (mmap_is_legacy()) {
+ mm->mmap_base = mmap_base_legacy(random_factor);
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ mm->mmap_base += mm->delta_mmap;
++#endif
++
+ mm->get_unmapped_area = s390_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 = s390_get_unmapped_area_topdown;
+ }
+ }
+diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h
+index ae3d59f..f65f075 100644
+--- a/arch/score/include/asm/cache.h
++++ b/arch/score/include/asm/cache.h
+@@ -1,7 +1,9 @@
+ #ifndef _ASM_SCORE_CACHE_H
+ #define _ASM_SCORE_CACHE_H
+
++#include <linux/const.h>
++
+ #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_SCORE_CACHE_H */
+diff --git a/arch/score/include/asm/exec.h b/arch/score/include/asm/exec.h
+index f9f3cd5..58ff438 100644
+--- a/arch/score/include/asm/exec.h
++++ b/arch/score/include/asm/exec.h
+@@ -1,6 +1,6 @@
+ #ifndef _ASM_SCORE_EXEC_H
+ #define _ASM_SCORE_EXEC_H
+
+-extern unsigned long arch_align_stack(unsigned long sp);
++#define arch_align_stack(x) (x)
+
+ #endif /* _ASM_SCORE_EXEC_H */
+diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c
+index aae9480..93e40a4 100644
+--- a/arch/score/kernel/process.c
++++ b/arch/score/kernel/process.c
+@@ -114,8 +114,3 @@ unsigned long get_wchan(struct task_struct *task)
+
+ return task_pt_regs(task)->cp0_epc;
+ }
+-
+-unsigned long arch_align_stack(unsigned long sp)
+-{
+- return sp;
+-}
+diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
+index ef9e555..331bd29 100644
+--- a/arch/sh/include/asm/cache.h
++++ b/arch/sh/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #define __ASM_SH_CACHE_H
+ #ifdef __KERNEL__
+
++#include <linux/const.h>
+ #include <linux/init.h>
+ #include <cpu/cache.h>
+
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
+
+diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
+index 6777177..d44b592 100644
+--- a/arch/sh/mm/mmap.c
++++ b/arch/sh/mm/mmap.c
+@@ -36,6 +36,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ int do_colour_align;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ if (flags & MAP_FIXED) {
+@@ -55,6 +56,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ if (filp || (flags & MAP_SHARED))
+ do_colour_align = 1;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_colour_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+@@ -62,14 +67,13 @@ unsigned long 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;
+ }
+
+ info.flags = 0;
+ info.length = len;
+- info.low_limit = TASK_UNMAPPED_BASE;
++ info.low_limit = mm->mmap_base;
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_colour_align ? (PAGE_MASK & shm_align_mask) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
+@@ -77,14 +81,15 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ }
+
+ unsigned long
+-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+- const unsigned long len, const unsigned long pgoff,
+- const unsigned long flags)
++arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
+ {
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = addr0;
+ int do_colour_align;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ if (flags & MAP_FIXED) {
+@@ -104,6 +109,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ if (filp || (flags & MAP_SHARED))
+ do_colour_align = 1;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ /* requesting a specific address */
+ if (addr) {
+ if (do_colour_align)
+@@ -112,8 +121,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 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;
+ }
+
+@@ -135,6 +143,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ info.low_limit += mm->delta_mmap;
++#endif
++
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ }
+diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
+index 546293d..cb6ea17 100644
+--- a/arch/sparc/Kconfig
++++ b/arch/sparc/Kconfig
+@@ -39,6 +39,7 @@ config SPARC
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
+ select MODULES_USE_ELF_RELA
++ select HAVE_GCC_PLUGINS
+ select ODD_RT_SIGACTION
+ select OLD_SIGSUSPEND
+ select ARCH_HAS_SG_CHAIN
+diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
+index f2fbf9e..470e701 100644
+--- a/arch/sparc/include/asm/atomic_64.h
++++ b/arch/sparc/include/asm/atomic_64.h
+@@ -15,18 +15,38 @@
+ #define ATOMIC64_INIT(i) { (i) }
+
+ #define atomic_read(v) READ_ONCE((v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+ #define atomic64_read(v) READ_ONCE((v)->counter)
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+
+ #define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+ #define atomic64_set(v, i) WRITE_ONCE(((v)->counter), (i))
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+
+-#define ATOMIC_OP(op) \
+-void atomic_##op(int, atomic_t *); \
+-void atomic64_##op(long, atomic64_t *);
++#define __ATOMIC_OP(op, suffix) \
++void atomic_##op##suffix(int, atomic##suffix##_t *); \
++void atomic64_##op##suffix(long, atomic64##suffix##_t *);
+
+-#define ATOMIC_OP_RETURN(op) \
+-int atomic_##op##_return(int, atomic_t *); \
+-long atomic64_##op##_return(long, atomic64_t *);
++#define ATOMIC_OP(op) __ATOMIC_OP(op, ) __ATOMIC_OP(op, _unchecked)
++
++#define __ATOMIC_OP_RETURN(op, suffix) \
++int atomic_##op##_return##suffix(int, atomic##suffix##_t *); \
++long atomic64_##op##_return##suffix(long, atomic64##suffix##_t *);
++
++#define ATOMIC_OP_RETURN(op) __ATOMIC_OP_RETURN(op, ) __ATOMIC_OP_RETURN(op, _unchecked)
+
+ #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
+
+@@ -39,13 +59,23 @@ ATOMIC_OP(xor)
+
+ #undef ATOMIC_OPS
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+ #define atomic_dec_return(v) atomic_sub_return(1, v)
+ #define atomic64_dec_return(v) atomic64_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);
++}
+ #define atomic64_inc_return(v) atomic64_add_return(1, v)
++static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
++{
++ return atomic64_add_return_unchecked(1, v);
++}
+
+ /*
+ * atomic_inc_and_test - increment and test
+@@ -56,6 +86,10 @@ ATOMIC_OP(xor)
+ * 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_inc_return_unchecked(v) == 0;
++}
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+@@ -65,25 +99,60 @@ ATOMIC_OP(xor)
+ #define atomic64_dec_and_test(v) (atomic64_sub_return(1, v) == 0)
+
+ #define atomic_inc(v) atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++ atomic_add_unchecked(1, v);
++}
+ #define atomic64_inc(v) atomic64_add(1, v)
++static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
++{
++ atomic64_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 atomic64_dec(v) atomic64_sub(1, v)
++static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
++{
++ atomic64_sub_unchecked(1, v);
++}
+
+ #define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0)
+ #define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0)
+
+ #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, int new)
++{
++ return cmpxchg(&v->counter, old, new);
++}
+ #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);
++}
+
+ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+- int c, old;
++ int c, old, new;
+ c = atomic_read(v);
+ for (;;) {
+- if (unlikely(c == (u)))
++ if (unlikely(c == u))
+ break;
+- old = atomic_cmpxchg((v), c, c + (a));
++
++ asm volatile("addcc %2, %0, %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++ "tvs %%icc, 6\n"
++#endif
++
++ : "=r" (new)
++ : "0" (c), "ir" (a)
++ : "cc");
++
++ old = atomic_cmpxchg(v, c, new);
+ if (likely(old == c))
+ break;
+ c = old;
+@@ -93,21 +162,42 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+
+ #define atomic64_cmpxchg(v, o, n) \
+ ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old,
++ long new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
+ #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new)
++{
++ return xchg(&v->counter, new);
++}
+
+ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
+ {
+- long c, old;
++ long c, old, new;
+ c = atomic64_read(v);
+ for (;;) {
+- if (unlikely(c == (u)))
++ if (unlikely(c == u))
+ break;
+- old = atomic64_cmpxchg((v), c, c + (a));
++
++ asm volatile("addcc %2, %0, %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++ "tvs %%xcc, 6\n"
++#endif
++
++ : "=r" (new)
++ : "0" (c), "ir" (a)
++ : "cc");
++
++ old = atomic64_cmpxchg(v, c, new);
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+- return c != (u);
++ return c != u;
+ }
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h
+index 5bb6991..5c2132e 100644
+--- a/arch/sparc/include/asm/cache.h
++++ b/arch/sparc/include/asm/cache.h
+@@ -7,10 +7,12 @@
+ #ifndef _SPARC_CACHE_H
+ #define _SPARC_CACHE_H
+
++#include <linux/const.h>
++
+ #define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
+
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES 32
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #ifdef CONFIG_SPARC32
+ #define SMP_CACHE_BYTES_SHIFT 5
+diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
+index a24e41f..47677ff 100644
+--- a/arch/sparc/include/asm/elf_32.h
++++ b/arch/sparc/include/asm/elf_32.h
+@@ -114,6 +114,13 @@ typedef struct {
+
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE 0x10000UL
++
++#define PAX_DELTA_MMAP_LEN 16
++#define PAX_DELTA_STACK_LEN 16
++#endif
++
+ /* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. This can NOT be done in userspace
+ on Sparc. */
+diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
+index 9331083..59c0499 100644
+--- a/arch/sparc/include/asm/elf_64.h
++++ b/arch/sparc/include/asm/elf_64.h
+@@ -190,6 +190,13 @@ typedef struct {
+ #define ELF_ET_DYN_BASE 0x0000010000000000UL
+ #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
++
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28)
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29)
++#endif
++
+ extern unsigned long sparc64_elf_hwcap;
+ #define ELF_HWCAP sparc64_elf_hwcap
+
+diff --git a/arch/sparc/include/asm/pgalloc_32.h b/arch/sparc/include/asm/pgalloc_32.h
+index 0346c7e..c5c25b9 100644
+--- a/arch/sparc/include/asm/pgalloc_32.h
++++ b/arch/sparc/include/asm/pgalloc_32.h
+@@ -35,6 +35,7 @@ static inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+ }
+
+ #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD)
++#define pgd_populate_kernel(MM, PGD, PMD) pgd_populate((MM), (PGD), (PMD))
+
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm,
+ unsigned long address)
+diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h
+index 3529f13..d98a28c 100644
+--- a/arch/sparc/include/asm/pgalloc_64.h
++++ b/arch/sparc/include/asm/pgalloc_64.h
+@@ -21,6 +21,7 @@ static inline void __pgd_populate(pgd_t *pgd, pud_t *pud)
+ }
+
+ #define pgd_populate(MM, PGD, PUD) __pgd_populate(PGD, PUD)
++#define pgd_populate_kernel(MM, PGD, PMD) pgd_populate((MM), (PGD), (PMD))
+
+ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+@@ -38,6 +39,7 @@ static inline void __pud_populate(pud_t *pud, pmd_t *pmd)
+ }
+
+ #define pud_populate(MM, PUD, PMD) __pud_populate(PUD, PMD)
++#define pud_populate_kernel(MM, PUD, PMD) pud_populate((MM), (PUD), (PMD))
+
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+diff --git a/arch/sparc/include/asm/pgtable.h b/arch/sparc/include/asm/pgtable.h
+index 59ba6f6..4518128 100644
+--- a/arch/sparc/include/asm/pgtable.h
++++ b/arch/sparc/include/asm/pgtable.h
+@@ -5,4 +5,8 @@
+ #else
+ #include <asm/pgtable_32.h>
+ #endif
++
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ #endif
+diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
+index ce6f569..593b043 100644
+--- a/arch/sparc/include/asm/pgtable_32.h
++++ b/arch/sparc/include/asm/pgtable_32.h
+@@ -51,6 +51,9 @@ unsigned long __init bootmem_init(unsigned long *pages_avail);
+ #define PAGE_SHARED SRMMU_PAGE_SHARED
+ #define PAGE_COPY SRMMU_PAGE_COPY
+ #define PAGE_READONLY SRMMU_PAGE_RDONLY
++#define PAGE_SHARED_NOEXEC SRMMU_PAGE_SHARED_NOEXEC
++#define PAGE_COPY_NOEXEC SRMMU_PAGE_COPY_NOEXEC
++#define PAGE_READONLY_NOEXEC SRMMU_PAGE_RDONLY_NOEXEC
+ #define PAGE_KERNEL SRMMU_PAGE_KERNEL
+
+ /* Top-level page directory - dummy used by init-mm.
+@@ -63,18 +66,18 @@ extern unsigned long ptr_in_current_pgd;
+
+ /* xwr */
+ #define __P000 PAGE_NONE
+-#define __P001 PAGE_READONLY
+-#define __P010 PAGE_COPY
+-#define __P011 PAGE_COPY
++#define __P001 PAGE_READONLY_NOEXEC
++#define __P010 PAGE_COPY_NOEXEC
++#define __P011 PAGE_COPY_NOEXEC
+ #define __P100 PAGE_READONLY
+ #define __P101 PAGE_READONLY
+ #define __P110 PAGE_COPY
+ #define __P111 PAGE_COPY
+
+ #define __S000 PAGE_NONE
+-#define __S001 PAGE_READONLY
+-#define __S010 PAGE_SHARED
+-#define __S011 PAGE_SHARED
++#define __S001 PAGE_READONLY_NOEXEC
++#define __S010 PAGE_SHARED_NOEXEC
++#define __S011 PAGE_SHARED_NOEXEC
+ #define __S100 PAGE_READONLY
+ #define __S101 PAGE_READONLY
+ #define __S110 PAGE_SHARED
+diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
+index ae51a11..eadfd03 100644
+--- a/arch/sparc/include/asm/pgtsrmmu.h
++++ b/arch/sparc/include/asm/pgtsrmmu.h
+@@ -111,6 +111,11 @@
+ SRMMU_EXEC | SRMMU_REF)
+ #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+ SRMMU_EXEC | SRMMU_REF)
++
++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
++
+ #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
+ SRMMU_DIRTY | SRMMU_REF)
+
+diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
+index 29d64b1..4272fe8 100644
+--- a/arch/sparc/include/asm/setup.h
++++ b/arch/sparc/include/asm/setup.h
+@@ -55,8 +55,8 @@ int handle_ldf_stq(u32 insn, struct pt_regs *regs);
+ void handle_ld_nf(u32 insn, struct pt_regs *regs);
+
+ /* init_64.c */
+-extern atomic_t dcpage_flushes;
+-extern atomic_t dcpage_flushes_xcall;
++extern atomic_unchecked_t dcpage_flushes;
++extern atomic_unchecked_t dcpage_flushes_xcall;
+
+ extern int sysctl_tsb_ratio;
+ #endif
+diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h
+index 9689176..63c18ea 100644
+--- a/arch/sparc/include/asm/spinlock_64.h
++++ b/arch/sparc/include/asm/spinlock_64.h
+@@ -92,14 +92,19 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *lock, unsigned long fla
+
+ /* Multi-reader locks, these are much saner than the 32-bit Sparc ones... */
+
+-static void inline arch_read_lock(arch_rwlock_t *lock)
++static inline void arch_read_lock(arch_rwlock_t *lock)
+ {
+ unsigned long tmp1, tmp2;
+
+ __asm__ __volatile__ (
+ "1: ldsw [%2], %0\n"
+ " brlz,pn %0, 2f\n"
+-"4: add %0, 1, %1\n"
++"4: addcc %0, 1, %1\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" tvs %%icc, 6\n"
++#endif
++
+ " cas [%2], %0, %1\n"
+ " cmp %0, %1\n"
+ " bne,pn %%icc, 1b\n"
+@@ -112,10 +117,10 @@ static void inline arch_read_lock(arch_rwlock_t *lock)
+ " .previous"
+ : "=&r" (tmp1), "=&r" (tmp2)
+ : "r" (lock)
+- : "memory");
++ : "memory", "cc");
+ }
+
+-static int inline arch_read_trylock(arch_rwlock_t *lock)
++static inline int arch_read_trylock(arch_rwlock_t *lock)
+ {
+ int tmp1, tmp2;
+
+@@ -123,7 +128,12 @@ static int inline arch_read_trylock(arch_rwlock_t *lock)
+ "1: ldsw [%2], %0\n"
+ " brlz,a,pn %0, 2f\n"
+ " mov 0, %0\n"
+-" add %0, 1, %1\n"
++" addcc %0, 1, %1\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" tvs %%icc, 6\n"
++#endif
++
+ " cas [%2], %0, %1\n"
+ " cmp %0, %1\n"
+ " bne,pn %%icc, 1b\n"
+@@ -136,13 +146,18 @@ static int inline arch_read_trylock(arch_rwlock_t *lock)
+ return tmp1;
+ }
+
+-static void inline arch_read_unlock(arch_rwlock_t *lock)
++static inline void arch_read_unlock(arch_rwlock_t *lock)
+ {
+ unsigned long tmp1, tmp2;
+
+ __asm__ __volatile__(
+ "1: lduw [%2], %0\n"
+-" sub %0, 1, %1\n"
++" subcc %0, 1, %1\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++" tvs %%icc, 6\n"
++#endif
++
+ " cas [%2], %0, %1\n"
+ " cmp %0, %1\n"
+ " bne,pn %%xcc, 1b\n"
+@@ -152,7 +167,7 @@ static void inline arch_read_unlock(arch_rwlock_t *lock)
+ : "memory");
+ }
+
+-static void inline arch_write_lock(arch_rwlock_t *lock)
++static inline void arch_write_lock(arch_rwlock_t *lock)
+ {
+ unsigned long mask, tmp1, tmp2;
+
+@@ -177,7 +192,7 @@ static void inline arch_write_lock(arch_rwlock_t *lock)
+ : "memory");
+ }
+
+-static void inline arch_write_unlock(arch_rwlock_t *lock)
++static inline void arch_write_unlock(arch_rwlock_t *lock)
+ {
+ __asm__ __volatile__(
+ " stw %%g0, [%0]"
+@@ -186,7 +201,7 @@ static void inline arch_write_unlock(arch_rwlock_t *lock)
+ : "memory");
+ }
+
+-static int inline arch_write_trylock(arch_rwlock_t *lock)
++static inline int arch_write_trylock(arch_rwlock_t *lock)
+ {
+ unsigned long mask, tmp1, tmp2, result;
+
+diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
+index 229475f..2fca9163 100644
+--- a/arch/sparc/include/asm/thread_info_32.h
++++ b/arch/sparc/include/asm/thread_info_32.h
+@@ -48,6 +48,7 @@ struct thread_info {
+ struct reg_window32 reg_window[NSWINS]; /* align for ldd! */
+ unsigned long rwbuf_stkptrs[NSWINS];
+ unsigned long w_saved;
++ unsigned long lowest_stack;
+ };
+
+ /*
+diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
+index bde5982..9cbb56d 100644
+--- a/arch/sparc/include/asm/thread_info_64.h
++++ b/arch/sparc/include/asm/thread_info_64.h
+@@ -59,6 +59,8 @@ struct thread_info {
+ struct pt_regs *kern_una_regs;
+ unsigned int kern_una_insn;
+
++ unsigned long lowest_stack;
++
+ unsigned long fpregs[(7 * 256) / sizeof(unsigned long)]
+ __attribute__ ((aligned(64)));
+ };
+@@ -180,12 +182,13 @@ register struct thread_info *current_thread_info_reg asm("g6");
+ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+ /* flag bit 4 is available */
+ #define TIF_UNALIGNED 5 /* allowed to do unaligned accesses */
+-/* flag bit 6 is available */
++#define TIF_GRSEC_SETXID 6 /* update credentials on syscall entry/exit */
+ #define TIF_32BIT 7 /* 32-bit binary */
+ #define TIF_NOHZ 8 /* in adaptive nohz mode */
+ #define TIF_SECCOMP 9 /* secure computing */
+ #define TIF_SYSCALL_AUDIT 10 /* syscall auditing active */
+ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */
++
+ /* NOTE: Thread flags >= 12 should be ones we have no interest
+ * in using in assembly, else we can't use the mask as
+ * an immediate value in instructions such as andcc.
+@@ -205,12 +208,17 @@ register struct thread_info *current_thread_info_reg asm("g6");
+ #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+ #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
++#define _TIF_GRSEC_SETXID (1<<TIF_GRSEC_SETXID)
+
+ #define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
+ _TIF_DO_NOTIFY_RESUME_MASK | \
+ _TIF_NEED_RESCHED)
+ #define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING)
+
++#define _TIF_WORK_SYSCALL \
++ (_TIF_SYSCALL_TRACE | _TIF_SECCOMP | _TIF_SYSCALL_AUDIT | \
++ _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ | _TIF_GRSEC_SETXID)
++
+ #define is_32bit_task() (test_thread_flag(TIF_32BIT))
+
+ /*
+diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
+index bd56c28..4b63d83 100644
+--- a/arch/sparc/include/asm/uaccess.h
++++ b/arch/sparc/include/asm/uaccess.h
+@@ -1,5 +1,6 @@
+ #ifndef ___ASM_SPARC_UACCESS_H
+ #define ___ASM_SPARC_UACCESS_H
++
+ #if defined(__sparc__) && defined(__arch64__)
+ #include <asm/uaccess_64.h>
+ #else
+diff --git a/arch/sparc/include/asm/uaccess_32.h b/arch/sparc/include/asm/uaccess_32.h
+index 57aca27..a87e6eb 100644
+--- a/arch/sparc/include/asm/uaccess_32.h
++++ b/arch/sparc/include/asm/uaccess_32.h
+@@ -47,6 +47,7 @@
+ #define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
+ #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+ #define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) \
+ ({ (void)(type); __access_ok((unsigned long)(addr), size); })
+
+@@ -248,27 +249,46 @@ unsigned long __copy_user(void __user *to, const void __user *from, unsigned lon
+
+ static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+- if (n && __access_ok((unsigned long) to, n))
++ if ((long)n < 0)
++ return n;
++
++ if (n && __access_ok((unsigned long) to, n)) {
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n, true);
+ return __copy_user(to, (__force void __user *) from, n);
+- else
++ } else
+ return n;
+ }
+
+ static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
++ if (!__builtin_constant_p(n))
++ check_object_size(from, n, true);
++
+ return __copy_user(to, (__force void __user *) from, n);
+ }
+
+ static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+- if (n && __access_ok((unsigned long) from, n))
++ if ((long)n < 0)
++ return n;
++
++ if (n && __access_ok((unsigned long) from, n)) {
++ if (!__builtin_constant_p(n))
++ check_object_size(to, n, false);
+ return __copy_user((__force void __user *) to, from, n);
+- else
++ } else
+ return n;
+ }
+
+ static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ return __copy_user((__force void __user *) to, from, n);
+ }
+
+diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
+index e9a51d6..3ef910c 100644
+--- a/arch/sparc/include/asm/uaccess_64.h
++++ b/arch/sparc/include/asm/uaccess_64.h
+@@ -10,6 +10,7 @@
+ #include <linux/compiler.h>
+ #include <linux/string.h>
+ #include <linux/thread_info.h>
++#include <linux/kernel.h>
+ #include <asm/asi.h>
+ #include <asm/spitfire.h>
+ #include <asm-generic/uaccess-unaligned.h>
+@@ -76,6 +77,11 @@ static inline int __access_ok(const void __user * addr, unsigned long size)
+ return 1;
+ }
+
++static inline int access_ok_noprefault(int type, const void __user * addr, unsigned long size)
++{
++ return 1;
++}
++
+ static inline int access_ok(int type, const void __user * addr, unsigned long size)
+ {
+ return 1;
+@@ -210,8 +216,15 @@ unsigned long copy_from_user_fixup(void *to, const void __user *from,
+ static inline unsigned long __must_check
+ copy_from_user(void *to, const void __user *from, unsigned long size)
+ {
+- unsigned long ret = ___copy_from_user(to, from, size);
++ unsigned long ret;
+
++ if ((long)size < 0 || size > INT_MAX)
++ return size;
++
++ if (!__builtin_constant_p(size))
++ check_object_size(to, size, false);
++
++ ret = ___copy_from_user(to, from, size);
+ if (unlikely(ret))
+ ret = copy_from_user_fixup(to, from, size);
+
+@@ -227,8 +240,15 @@ unsigned long copy_to_user_fixup(void __user *to, const void *from,
+ static inline unsigned long __must_check
+ copy_to_user(void __user *to, const void *from, unsigned long size)
+ {
+- unsigned long ret = ___copy_to_user(to, from, size);
++ unsigned long ret;
+
++ if ((long)size < 0 || size > INT_MAX)
++ return size;
++
++ if (!__builtin_constant_p(size))
++ check_object_size(from, size, true);
++
++ ret = ___copy_to_user(to, from, size);
+ if (unlikely(ret))
+ ret = copy_to_user_fixup(to, from, size);
+ return ret;
+diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
+index fdb1332..1b10f89 100644
+--- a/arch/sparc/kernel/Makefile
++++ b/arch/sparc/kernel/Makefile
+@@ -4,7 +4,7 @@
+ #
+
+ asflags-y := -ansi
+-ccflags-y := -Werror
++#ccflags-y := -Werror
+
+ extra-y := head_$(BITS).o
+
+diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
+index b7780a5..28315f0 100644
+--- a/arch/sparc/kernel/process_32.c
++++ b/arch/sparc/kernel/process_32.c
+@@ -123,14 +123,14 @@ void show_regs(struct pt_regs *r)
+
+ printk("PSR: %08lx PC: %08lx NPC: %08lx Y: %08lx %s\n",
+ r->psr, r->pc, r->npc, r->y, print_tainted());
+- printk("PC: <%pS>\n", (void *) r->pc);
++ printk("PC: <%pA>\n", (void *) r->pc);
+ printk("%%G: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ r->u_regs[0], r->u_regs[1], r->u_regs[2], r->u_regs[3],
+ r->u_regs[4], r->u_regs[5], r->u_regs[6], r->u_regs[7]);
+ printk("%%O: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ r->u_regs[8], r->u_regs[9], r->u_regs[10], r->u_regs[11],
+ r->u_regs[12], r->u_regs[13], r->u_regs[14], r->u_regs[15]);
+- printk("RPC: <%pS>\n", (void *) r->u_regs[15]);
++ printk("RPC: <%pA>\n", (void *) r->u_regs[15]);
+
+ printk("%%L: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+ rw->locals[0], rw->locals[1], rw->locals[2], rw->locals[3],
+@@ -167,7 +167,7 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
+ rw = (struct reg_window32 *) fp;
+ pc = rw->ins[7];
+ printk("[%08lx : ", pc);
+- printk("%pS ] ", (void *) pc);
++ printk("%pA ] ", (void *) pc);
+ fp = rw->ins[6];
+ } while (++count < 16);
+ printk("\n");
+diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
+index fa14402..b2a7408 100644
+--- a/arch/sparc/kernel/process_64.c
++++ b/arch/sparc/kernel/process_64.c
+@@ -161,7 +161,7 @@ static void show_regwindow(struct pt_regs *regs)
+ printk("i4: %016lx i5: %016lx i6: %016lx i7: %016lx\n",
+ rwk->ins[4], rwk->ins[5], rwk->ins[6], rwk->ins[7]);
+ if (regs->tstate & TSTATE_PRIV)
+- printk("I7: <%pS>\n", (void *) rwk->ins[7]);
++ printk("I7: <%pA>\n", (void *) rwk->ins[7]);
+ }
+
+ void show_regs(struct pt_regs *regs)
+@@ -170,7 +170,7 @@ void show_regs(struct pt_regs *regs)
+
+ printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate,
+ regs->tpc, regs->tnpc, regs->y, print_tainted());
+- printk("TPC: <%pS>\n", (void *) regs->tpc);
++ printk("TPC: <%pA>\n", (void *) regs->tpc);
+ printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
+ regs->u_regs[0], regs->u_regs[1], regs->u_regs[2],
+ regs->u_regs[3]);
+@@ -183,7 +183,7 @@ void show_regs(struct pt_regs *regs)
+ printk("o4: %016lx o5: %016lx sp: %016lx ret_pc: %016lx\n",
+ regs->u_regs[12], regs->u_regs[13], regs->u_regs[14],
+ regs->u_regs[15]);
+- printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
++ printk("RPC: <%pA>\n", (void *) regs->u_regs[15]);
+ show_regwindow(regs);
+ show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]);
+ }
+@@ -278,7 +278,7 @@ void arch_trigger_all_cpu_backtrace(bool include_self)
+ ((tp && tp->task) ? tp->task->pid : -1));
+
+ if (gp->tstate & TSTATE_PRIV) {
+- printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
++ printk(" TPC[%pA] O7[%pA] I7[%pA] RPC[%pA]\n",
+ (void *) gp->tpc,
+ (void *) gp->o7,
+ (void *) gp->i7,
+diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
+index 79cc0d1..46d6233 100644
+--- a/arch/sparc/kernel/prom_common.c
++++ b/arch/sparc/kernel/prom_common.c
+@@ -144,7 +144,7 @@ static int __init prom_common_nextprop(phandle node, char *prev, char *buf)
+
+ unsigned int prom_early_allocated __initdata;
+
+-static struct of_pdt_ops prom_sparc_ops __initdata = {
++static const struct of_pdt_ops prom_sparc_ops __initconst = {
+ .nextprop = prom_common_nextprop,
+ .getproplen = prom_getproplen,
+ .getproperty = prom_getproperty,
+diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c
+index 9ddc492..27a5619 100644
+--- a/arch/sparc/kernel/ptrace_64.c
++++ b/arch/sparc/kernel/ptrace_64.c
+@@ -1060,6 +1060,10 @@ long arch_ptrace(struct task_struct *child, long request,
+ return ret;
+ }
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
+ {
+ int ret = 0;
+@@ -1070,6 +1074,11 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
+ if (test_thread_flag(TIF_NOHZ))
+ user_exit();
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ ret = tracehook_report_syscall_entry(regs);
+
+@@ -1088,6 +1097,11 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+ if (test_thread_flag(TIF_NOHZ))
+ user_exit();
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ audit_syscall_exit(regs);
+
+ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
+index 8a6151a..fa3cbb19 100644
+--- a/arch/sparc/kernel/smp_64.c
++++ b/arch/sparc/kernel/smp_64.c
+@@ -891,7 +891,7 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu)
+ return;
+
+ #ifdef CONFIG_DEBUG_DCFLUSH
+- atomic_inc(&dcpage_flushes);
++ atomic_inc_unchecked(&dcpage_flushes);
+ #endif
+
+ this_cpu = get_cpu();
+@@ -915,7 +915,7 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu)
+ xcall_deliver(data0, __pa(pg_addr),
+ (u64) pg_addr, cpumask_of(cpu));
+ #ifdef CONFIG_DEBUG_DCFLUSH
+- atomic_inc(&dcpage_flushes_xcall);
++ atomic_inc_unchecked(&dcpage_flushes_xcall);
+ #endif
+ }
+ }
+@@ -934,7 +934,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
+ preempt_disable();
+
+ #ifdef CONFIG_DEBUG_DCFLUSH
+- atomic_inc(&dcpage_flushes);
++ atomic_inc_unchecked(&dcpage_flushes);
+ #endif
+ data0 = 0;
+ pg_addr = page_address(page);
+@@ -951,7 +951,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
+ xcall_deliver(data0, __pa(pg_addr),
+ (u64) pg_addr, cpu_online_mask);
+ #ifdef CONFIG_DEBUG_DCFLUSH
+- atomic_inc(&dcpage_flushes_xcall);
++ atomic_inc_unchecked(&dcpage_flushes_xcall);
+ #endif
+ }
+ __local_flush_dcache_page(page);
+diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
+index 646988d..b88905f 100644
+--- a/arch/sparc/kernel/sys_sparc_32.c
++++ b/arch/sparc/kernel/sys_sparc_32.c
+@@ -54,7 +54,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ if (len > TASK_SIZE - PAGE_SIZE)
+ return -ENOMEM;
+ if (!addr)
+- addr = TASK_UNMAPPED_BASE;
++ addr = current->mm->mmap_base;
+
+ info.flags = 0;
+ info.length = len;
+diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
+index fe8b8ee..3f17a96 100644
+--- a/arch/sparc/kernel/sys_sparc_64.c
++++ b/arch/sparc/kernel/sys_sparc_64.c
+@@ -89,13 +89,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ struct vm_area_struct * vma;
+ unsigned long task_size = TASK_SIZE;
+ int do_color_align;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ if (flags & MAP_FIXED) {
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) &&
++ if ((filp || (flags & MAP_SHARED)) &&
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
+ return -EINVAL;
+ return addr;
+@@ -110,6 +111,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ if (filp || (flags & MAP_SHARED))
+ do_color_align = 1;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align)
+ addr = COLOR_ALIGN(addr, pgoff);
+@@ -117,22 +122,28 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ 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.flags = 0;
+ info.length = len;
+- info.low_limit = TASK_UNMAPPED_BASE;
++ info.low_limit = mm->mmap_base;
+ info.high_limit = min(task_size, VA_EXCLUDE_START);
+ info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.low_limit = VA_EXCLUDE_END;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ info.low_limit += mm->delta_mmap;
++#endif
++
+ info.high_limit = task_size;
+ addr = vm_unmapped_area(&info);
+ }
+@@ -141,15 +152,16 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ }
+
+ unsigned long
+-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+- const unsigned long len, const unsigned long pgoff,
+- const unsigned long flags)
++arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
+ {
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ unsigned long task_size = STACK_TOP32;
+ unsigned long addr = addr0;
+ int do_color_align;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ /* This should only ever run for 32-bit processes. */
+@@ -159,7 +171,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ /* We do not accept a shared mapping if it would violate
+ * cache aliasing constraints.
+ */
+- if ((flags & MAP_SHARED) &&
++ if ((filp || (flags & MAP_SHARED)) &&
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
+ return -EINVAL;
+ return addr;
+@@ -172,6 +184,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ if (filp || (flags & MAP_SHARED))
+ do_color_align = 1;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ /* requesting a specific address */
+ if (addr) {
+ if (do_color_align)
+@@ -180,8 +196,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 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;
+ }
+
+@@ -191,6 +206,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_color_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ /*
+@@ -203,6 +219,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ info.low_limit += mm->delta_mmap;
++#endif
++
+ info.high_limit = STACK_TOP32;
+ addr = vm_unmapped_area(&info);
+ }
+@@ -259,10 +281,14 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
+ EXPORT_SYMBOL(get_fb_unmapped_area);
+
+ /* Essentially the same as PowerPC. */
+-static unsigned long mmap_rnd(void)
++static unsigned long mmap_rnd(struct mm_struct *mm)
+ {
+ unsigned long rnd = 0UL;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (current->flags & PF_RANDOMIZE) {
+ unsigned long val = get_random_long();
+ if (test_thread_flag(TIF_32BIT))
+@@ -275,7 +301,7 @@ static unsigned long mmap_rnd(void)
+
+ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+- unsigned long random_factor = mmap_rnd();
++ unsigned long random_factor = mmap_rnd(mm);
+ unsigned long gap;
+
+ /*
+@@ -288,6 +314,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ gap == RLIM_INFINITY ||
+ sysctl_legacy_va_layout) {
+ 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 {
+ /* We know it's 32-bit */
+@@ -299,6 +331,12 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ gap = (task_size / 6 * 5);
+
+ mm->mmap_base = PAGE_ALIGN(task_size - gap - 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/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S
+index c4a1b5c..c5e0ef3 100644
+--- a/arch/sparc/kernel/syscalls.S
++++ b/arch/sparc/kernel/syscalls.S
+@@ -62,7 +62,7 @@ sys32_rt_sigreturn:
+ #endif
+ .align 32
+ 1: ldx [%g6 + TI_FLAGS], %l5
+- andcc %l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
++ andcc %l5, _TIF_WORK_SYSCALL, %g0
+ be,pt %icc, rtrap
+ nop
+ call syscall_trace_leave
+@@ -230,7 +230,7 @@ linux_sparc_syscall32:
+
+ srl %i3, 0, %o3 ! IEU0
+ srl %i2, 0, %o2 ! IEU0 Group
+- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
++ andcc %l0, _TIF_WORK_SYSCALL, %g0
+ bne,pn %icc, linux_syscall_trace32 ! CTI
+ mov %i0, %l5 ! IEU1
+ 5: call %l7 ! CTI Group brk forced
+@@ -254,7 +254,7 @@ linux_sparc_syscall:
+
+ mov %i3, %o3 ! IEU1
+ mov %i4, %o4 ! IEU0 Group
+- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
++ andcc %l0, _TIF_WORK_SYSCALL, %g0
+ bne,pn %icc, linux_syscall_trace ! CTI Group
+ mov %i0, %l5 ! IEU0
+ 2: call %l7 ! CTI Group brk forced
+@@ -269,7 +269,7 @@ ret_sys_call:
+
+ cmp %o0, -ERESTART_RESTARTBLOCK
+ bgeu,pn %xcc, 1f
+- andcc %l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT|_TIF_SYSCALL_TRACEPOINT|_TIF_NOHZ), %g0
++ andcc %l0, _TIF_WORK_SYSCALL, %g0
+ ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
+
+ 2:
+diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
+index 4f21df7..0a374da 100644
+--- a/arch/sparc/kernel/traps_32.c
++++ b/arch/sparc/kernel/traps_32.c
+@@ -44,6 +44,8 @@ static void instruction_dump(unsigned long *pc)
+ #define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t")
+ #define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t")
+
++extern void gr_handle_kernel_exploit(void);
++
+ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
+ {
+ static int die_counter;
+@@ -76,15 +78,17 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
+ count++ < 30 &&
+ (((unsigned long) rw) >= PAGE_OFFSET) &&
+ !(((unsigned long) rw) & 0x7)) {
+- printk("Caller[%08lx]: %pS\n", rw->ins[7],
++ printk("Caller[%08lx]: %pA\n", rw->ins[7],
+ (void *) rw->ins[7]);
+ rw = (struct reg_window32 *)rw->ins[6];
+ }
+ }
+ printk("Instruction DUMP:");
+ instruction_dump ((unsigned long *) regs->pc);
+- if(regs->psr & PSR_PS)
++ if(regs->psr & PSR_PS) {
++ gr_handle_kernel_exploit();
+ do_exit(SIGKILL);
++ }
+ do_exit(SIGSEGV);
+ }
+
+diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
+index d21cd62..00a4a17 100644
+--- a/arch/sparc/kernel/traps_64.c
++++ b/arch/sparc/kernel/traps_64.c
+@@ -79,7 +79,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
+ i + 1,
+ p->trapstack[i].tstate, p->trapstack[i].tpc,
+ p->trapstack[i].tnpc, p->trapstack[i].tt);
+- printk("TRAPLOG: TPC<%pS>\n", (void *) p->trapstack[i].tpc);
++ printk("TRAPLOG: TPC<%pA>\n", (void *) p->trapstack[i].tpc);
+ }
+ }
+
+@@ -99,6 +99,12 @@ void bad_trap(struct pt_regs *regs, long lvl)
+
+ lvl -= 0x100;
+ if (regs->tstate & TSTATE_PRIV) {
++
++#ifdef CONFIG_PAX_REFCOUNT
++ if (lvl == 6)
++ pax_report_refcount_overflow(regs);
++#endif
++
+ sprintf(buffer, "Kernel bad sw trap %lx", lvl);
+ die_if_kernel(buffer, regs);
+ }
+@@ -117,11 +123,16 @@ void bad_trap(struct pt_regs *regs, long lvl)
+ void bad_trap_tl1(struct pt_regs *regs, long lvl)
+ {
+ char buffer[32];
+-
++
+ if (notify_die(DIE_TRAP_TL1, "bad trap tl1", regs,
+ 0, lvl, SIGTRAP) == NOTIFY_STOP)
+ return;
+
++#ifdef CONFIG_PAX_REFCOUNT
++ if (lvl == 6)
++ pax_report_refcount_overflow(regs);
++#endif
++
+ dump_tl1_traplog((struct tl1_traplog *)(regs + 1));
+
+ sprintf (buffer, "Bad trap %lx at tl>0", lvl);
+@@ -1151,7 +1162,7 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
+ regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
+ printk("%s" "ERROR(%d): ",
+ (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
+- printk("TPC<%pS>\n", (void *) regs->tpc);
++ printk("TPC<%pA>\n", (void *) regs->tpc);
+ printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n",
+ (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
+ (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
+@@ -1758,7 +1769,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
+ smp_processor_id(),
+ (type & 0x1) ? 'I' : 'D',
+ regs->tpc);
+- printk(KERN_EMERG "TPC<%pS>\n", (void *) regs->tpc);
++ printk(KERN_EMERG "TPC<%pA>\n", (void *) regs->tpc);
+ panic("Irrecoverable Cheetah+ parity error.");
+ }
+
+@@ -1766,7 +1777,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
+ smp_processor_id(),
+ (type & 0x1) ? 'I' : 'D',
+ regs->tpc);
+- printk(KERN_WARNING "TPC<%pS>\n", (void *) regs->tpc);
++ printk(KERN_WARNING "TPC<%pA>\n", (void *) regs->tpc);
+ }
+
+ struct sun4v_error_entry {
+@@ -1839,8 +1850,8 @@ struct sun4v_error_entry {
+ /*0x38*/u64 reserved_5;
+ };
+
+-static atomic_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0);
+-static atomic_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0);
++static atomic_unchecked_t sun4v_resum_oflow_cnt = ATOMIC_INIT(0);
++static atomic_unchecked_t sun4v_nonresum_oflow_cnt = ATOMIC_INIT(0);
+
+ static const char *sun4v_err_type_to_str(u8 type)
+ {
+@@ -1932,7 +1943,7 @@ static void sun4v_report_real_raddr(const char *pfx, struct pt_regs *regs)
+ }
+
+ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
+- int cpu, const char *pfx, atomic_t *ocnt)
++ int cpu, const char *pfx, atomic_unchecked_t *ocnt)
+ {
+ u64 *raw_ptr = (u64 *) ent;
+ u32 attrs;
+@@ -1990,8 +2001,8 @@ static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent,
+
+ show_regs(regs);
+
+- if ((cnt = atomic_read(ocnt)) != 0) {
+- atomic_set(ocnt, 0);
++ if ((cnt = atomic_read_unchecked(ocnt)) != 0) {
++ atomic_set_unchecked(ocnt, 0);
+ wmb();
+ printk("%s: Queue overflowed %d times.\n",
+ pfx, cnt);
+@@ -2048,7 +2059,7 @@ out:
+ */
+ void sun4v_resum_overflow(struct pt_regs *regs)
+ {
+- atomic_inc(&sun4v_resum_oflow_cnt);
++ atomic_inc_unchecked(&sun4v_resum_oflow_cnt);
+ }
+
+ /* We run with %pil set to PIL_NORMAL_MAX and PSTATE_IE enabled in %pstate.
+@@ -2101,7 +2112,7 @@ void sun4v_nonresum_overflow(struct pt_regs *regs)
+ /* XXX Actually even this can make not that much sense. Perhaps
+ * XXX we should just pull the plug and panic directly from here?
+ */
+- atomic_inc(&sun4v_nonresum_oflow_cnt);
++ atomic_inc_unchecked(&sun4v_nonresum_oflow_cnt);
+ }
+
+ static void sun4v_tlb_error(struct pt_regs *regs)
+@@ -2120,9 +2131,9 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
+
+ printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
+ regs->tpc, tl);
+- printk(KERN_EMERG "SUN4V-ITLB: TPC<%pS>\n", (void *) regs->tpc);
++ printk(KERN_EMERG "SUN4V-ITLB: TPC<%pA>\n", (void *) regs->tpc);
+ printk(KERN_EMERG "SUN4V-ITLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
+- printk(KERN_EMERG "SUN4V-ITLB: O7<%pS>\n",
++ printk(KERN_EMERG "SUN4V-ITLB: O7<%pA>\n",
+ (void *) regs->u_regs[UREG_I7]);
+ printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
+ "pte[%lx] error[%lx]\n",
+@@ -2143,9 +2154,9 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
+
+ printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
+ regs->tpc, tl);
+- printk(KERN_EMERG "SUN4V-DTLB: TPC<%pS>\n", (void *) regs->tpc);
++ printk(KERN_EMERG "SUN4V-DTLB: TPC<%pA>\n", (void *) regs->tpc);
+ printk(KERN_EMERG "SUN4V-DTLB: O7[%lx]\n", regs->u_regs[UREG_I7]);
+- printk(KERN_EMERG "SUN4V-DTLB: O7<%pS>\n",
++ printk(KERN_EMERG "SUN4V-DTLB: O7<%pA>\n",
+ (void *) regs->u_regs[UREG_I7]);
+ printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
+ "pte[%lx] error[%lx]\n",
+@@ -2362,13 +2373,13 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp)
+ fp = (unsigned long)sf->fp + STACK_BIAS;
+ }
+
+- printk(" [%016lx] %pS\n", pc, (void *) pc);
++ printk(" [%016lx] %pA\n", pc, (void *) pc);
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if ((pc + 8UL) == (unsigned long) &return_to_handler) {
+ int index = tsk->curr_ret_stack;
+ if (tsk->ret_stack && index >= graph) {
+ pc = tsk->ret_stack[index - graph].ret;
+- printk(" [%016lx] %pS\n", pc, (void *) pc);
++ printk(" [%016lx] %pA\n", pc, (void *) pc);
+ graph++;
+ }
+ }
+@@ -2386,6 +2397,8 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
+ return (struct reg_window *) (fp + STACK_BIAS);
+ }
+
++extern void gr_handle_kernel_exploit(void);
++
+ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
+ {
+ static int die_counter;
+@@ -2414,7 +2427,7 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
+ while (rw &&
+ count++ < 30 &&
+ kstack_valid(tp, (unsigned long) rw)) {
+- printk("Caller[%016lx]: %pS\n", rw->ins[7],
++ printk("Caller[%016lx]: %pA\n", rw->ins[7],
+ (void *) rw->ins[7]);
+
+ rw = kernel_stack_up(rw);
+@@ -2429,8 +2442,10 @@ void __noreturn die_if_kernel(char *str, struct pt_regs *regs)
+ }
+ if (panic_on_oops)
+ panic("Fatal exception");
+- if (regs->tstate & TSTATE_PRIV)
++ if (regs->tstate & TSTATE_PRIV) {
++ gr_handle_kernel_exploit();
+ do_exit(SIGKILL);
++ }
+ do_exit(SIGSEGV);
+ }
+ EXPORT_SYMBOL(die_if_kernel);
+diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
+index 9aacb91..6415c82 100644
+--- a/arch/sparc/kernel/unaligned_64.c
++++ b/arch/sparc/kernel/unaligned_64.c
+@@ -297,7 +297,7 @@ static void log_unaligned(struct pt_regs *regs)
+ static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
+
+ if (__ratelimit(&ratelimit)) {
+- printk("Kernel unaligned access at TPC[%lx] %pS\n",
++ printk("Kernel unaligned access at TPC[%lx] %pA\n",
+ regs->tpc, (void *) regs->tpc);
+ }
+ }
+diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
+index 3269b02..64f5231 100644
+--- a/arch/sparc/lib/Makefile
++++ b/arch/sparc/lib/Makefile
+@@ -2,7 +2,7 @@
+ #
+
+ asflags-y := -ansi -DST_DIV0=0x02
+-ccflags-y := -Werror
++#ccflags-y := -Werror
+
+ lib-$(CONFIG_SPARC32) += ashrdi3.o
+ lib-$(CONFIG_SPARC32) += memcpy.o memset.o
+diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S
+index d6b0363..7fe8079 100644
+--- a/arch/sparc/lib/atomic_64.S
++++ b/arch/sparc/lib/atomic_64.S
+@@ -15,11 +15,22 @@
+ * a value and does the barriers.
+ */
+
+-#define ATOMIC_OP(op) \
+-ENTRY(atomic_##op) /* %o0 = increment, %o1 = atomic_ptr */ \
++#ifdef CONFIG_PAX_REFCOUNT
++#define __REFCOUNT_OP(op) op##cc
++#define __OVERFLOW_IOP tvs %icc, 6;
++#define __OVERFLOW_XOP tvs %xcc, 6;
++#else
++#define __REFCOUNT_OP(op) op
++#define __OVERFLOW_IOP
++#define __OVERFLOW_XOP
++#endif
++
++#define __ATOMIC_OP(op, suffix, asm_op, post_op) \
++ENTRY(atomic_##op##suffix) /* %o0 = increment, %o1 = atomic_ptr */ \
+ BACKOFF_SETUP(%o2); \
+ 1: lduw [%o1], %g1; \
+- op %g1, %o0, %g7; \
++ asm_op %g1, %o0, %g7; \
++ post_op \
+ cas [%o1], %g1, %g7; \
+ cmp %g1, %g7; \
+ bne,pn %icc, BACKOFF_LABEL(2f, 1b); \
+@@ -29,11 +40,15 @@ ENTRY(atomic_##op) /* %o0 = increment, %o1 = atomic_ptr */ \
+ 2: BACKOFF_SPIN(%o2, %o3, 1b); \
+ ENDPROC(atomic_##op); \
+
+-#define ATOMIC_OP_RETURN(op) \
+-ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \
++#define ATOMIC_OP(op) __ATOMIC_OP(op, , op, ) \
++ __ATOMIC_OP(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_IOP)
++
++#define __ATOMIC_OP_RETURN(op, suffix, asm_op, post_op) \
++ENTRY(atomic_##op##_return##suffix) /* %o0 = increment, %o1 = atomic_ptr */\
+ BACKOFF_SETUP(%o2); \
+ 1: lduw [%o1], %g1; \
+- op %g1, %o0, %g7; \
++ asm_op %g1, %o0, %g7; \
++ post_op \
+ cas [%o1], %g1, %g7; \
+ cmp %g1, %g7; \
+ bne,pn %icc, BACKOFF_LABEL(2f, 1b); \
+@@ -43,6 +58,9 @@ ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \
+ 2: BACKOFF_SPIN(%o2, %o3, 1b); \
+ ENDPROC(atomic_##op##_return);
+
++#define ATOMIC_OP_RETURN(op) __ATOMIC_OP_RETURN(op, , op, ) \
++ __ATOMIC_OP_RETURN(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_IOP)
++
+ #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
+
+ ATOMIC_OPS(add)
+@@ -53,13 +71,16 @@ ATOMIC_OP(xor)
+
+ #undef ATOMIC_OPS
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+-#define ATOMIC64_OP(op) \
+-ENTRY(atomic64_##op) /* %o0 = increment, %o1 = atomic_ptr */ \
++#define __ATOMIC64_OP(op, suffix, asm_op, post_op) \
++ENTRY(atomic64_##op##suffix) /* %o0 = increment, %o1 = atomic_ptr */ \
+ BACKOFF_SETUP(%o2); \
+ 1: ldx [%o1], %g1; \
+- op %g1, %o0, %g7; \
++ asm_op %g1, %o0, %g7; \
++ post_op \
+ casx [%o1], %g1, %g7; \
+ cmp %g1, %g7; \
+ bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \
+@@ -69,11 +90,15 @@ ENTRY(atomic64_##op) /* %o0 = increment, %o1 = atomic_ptr */ \
+ 2: BACKOFF_SPIN(%o2, %o3, 1b); \
+ ENDPROC(atomic64_##op); \
+
+-#define ATOMIC64_OP_RETURN(op) \
+-ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \
++#define ATOMIC64_OP(op) __ATOMIC64_OP(op, , op, ) \
++ __ATOMIC64_OP(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_XOP)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, asm_op, post_op) \
++ENTRY(atomic64_##op##_return##suffix) /* %o0 = increment, %o1 = atomic_ptr */\
+ BACKOFF_SETUP(%o2); \
+ 1: ldx [%o1], %g1; \
+- op %g1, %o0, %g7; \
++ asm_op %g1, %o0, %g7; \
++ post_op \
+ casx [%o1], %g1, %g7; \
+ cmp %g1, %g7; \
+ bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \
+@@ -83,6 +108,9 @@ ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \
+ 2: BACKOFF_SPIN(%o2, %o3, 1b); \
+ ENDPROC(atomic64_##op##_return);
+
++#define ATOMIC64_OP_RETURN(op) __ATOMIC64_OP_RETURN(op, , op, ) \
++ __ATOMIC64_OP_RETURN(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_XOP)
++
+ #define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op)
+
+ ATOMIC64_OPS(add)
+@@ -93,7 +121,12 @@ ATOMIC64_OP(xor)
+
+ #undef ATOMIC64_OPS
+ #undef ATOMIC64_OP_RETURN
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_XOP
++#undef __OVERFLOW_IOP
++#undef __REFCOUNT_OP
+
+ ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */
+ BACKOFF_SETUP(%o2)
+diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
+index 8eb454c..7bd92f6 100644
+--- a/arch/sparc/lib/ksyms.c
++++ b/arch/sparc/lib/ksyms.c
+@@ -101,7 +101,9 @@ EXPORT_SYMBOL(__clear_user);
+ /* Atomic counter implementation. */
+ #define ATOMIC_OP(op) \
+ EXPORT_SYMBOL(atomic_##op); \
+-EXPORT_SYMBOL(atomic64_##op);
++EXPORT_SYMBOL(atomic_##op##_unchecked); \
++EXPORT_SYMBOL(atomic64_##op); \
++EXPORT_SYMBOL(atomic64_##op##_unchecked);
+
+ #define ATOMIC_OP_RETURN(op) \
+ EXPORT_SYMBOL(atomic_##op##_return); \
+@@ -110,6 +112,8 @@ EXPORT_SYMBOL(atomic64_##op##_return);
+ #define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
+
+ ATOMIC_OPS(add)
++EXPORT_SYMBOL(atomic_add_return_unchecked);
++EXPORT_SYMBOL(atomic64_add_return_unchecked);
+ ATOMIC_OPS(sub)
+ ATOMIC_OP(and)
+ ATOMIC_OP(or)
+diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
+index 30c3ecc..736f015 100644
+--- a/arch/sparc/mm/Makefile
++++ b/arch/sparc/mm/Makefile
+@@ -2,7 +2,7 @@
+ #
+
+ asflags-y := -ansi
+-ccflags-y := -Werror
++#ccflags-y := -Werror
+
+ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o
+ obj-y += fault_$(BITS).o
+diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
+index b6c559c..cc30ea0 100644
+--- a/arch/sparc/mm/fault_32.c
++++ b/arch/sparc/mm/fault_32.c
+@@ -22,6 +22,9 @@
+ #include <linux/interrupt.h>
+ #include <linux/kdebug.h>
+ #include <linux/uaccess.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -156,6 +159,277 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault)
+ return safe_compute_effective_address(regs, insn);
+ }
+
++#ifdef CONFIG_PAX_PAGEEXEC
++#ifdef CONFIG_PAX_DLRESOLVE
++static void pax_emuplt_close(struct vm_area_struct *vma)
++{
++ vma->vm_mm->call_dl_resolve = 0UL;
++}
++
++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
++{
++ unsigned int *kaddr;
++
++ vmf->page = alloc_page(GFP_HIGHUSER);
++ if (!vmf->page)
++ return VM_FAULT_OOM;
++
++ kaddr = kmap(vmf->page);
++ memset(kaddr, 0, PAGE_SIZE);
++ kaddr[0] = 0x9DE3BFA8U; /* save */
++ flush_dcache_page(vmf->page);
++ kunmap(vmf->page);
++ return VM_FAULT_MAJOR;
++}
++
++static const struct vm_operations_struct pax_vm_ops = {
++ .close = pax_emuplt_close,
++ .fault = pax_emuplt_fault
++};
++
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
++{
++ int ret;
++
++ INIT_LIST_HEAD(&vma->anon_vma_chain);
++ vma->vm_mm = current->mm;
++ vma->vm_start = addr;
++ vma->vm_end = addr + PAGE_SIZE;
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
++ vma->vm_ops = &pax_vm_ops;
++
++ ret = insert_vm_struct(current->mm, vma);
++ if (ret)
++ return ret;
++
++ ++current->mm->total_vm;
++ return 0;
++}
++#endif
++
++/*
++ * 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 sethi1, sethi2, jmpl;
++
++ err = get_user(sethi1, (unsigned int *)regs->pc);
++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
++
++ if (err)
++ break;
++
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
++ {
++ unsigned int addr;
++
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
++ addr = regs->u_regs[UREG_G1];
++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++ regs->pc = addr;
++ regs->npc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #2 */
++ unsigned int ba;
++
++ err = get_user(ba, (unsigned int *)regs->pc);
++
++ if (err)
++ break;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30480000U) {
++ unsigned int addr;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U)
++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
++ else
++ addr = regs->pc + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
++ regs->pc = addr;
++ regs->npc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #3 */
++ unsigned int sethi, bajmpl, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->pc);
++ err |= get_user(bajmpl, (unsigned int *)(regs->pc+4));
++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ ((bajmpl & 0xFFFFE000U) == 0x81C06000U || (bajmpl & 0xFFF80000U) == 0x30480000U) &&
++ nop == 0x01000000U)
++ {
++ unsigned int addr;
++
++ addr = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G1] = addr;
++ if ((bajmpl & 0xFFFFE000U) == 0x81C06000U)
++ addr += (((bajmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++ else
++ addr = regs->pc + ((((bajmpl | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
++ regs->pc = addr;
++ regs->npc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: unpatched PLT emulation step 1 */
++ unsigned int sethi, ba, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->pc);
++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
++ nop == 0x01000000U)
++ {
++ unsigned int addr, save, call;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U)
++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
++ else
++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
++
++ err = get_user(save, (unsigned int *)addr);
++ err |= get_user(call, (unsigned int *)(addr+4));
++ err |= get_user(nop, (unsigned int *)(addr+8));
++ if (err)
++ break;
++
++#ifdef CONFIG_PAX_DLRESOLVE
++ if (save == 0x9DE3BFA8U &&
++ (call & 0xC0000000U) == 0x40000000U &&
++ nop == 0x01000000U)
++ {
++ struct vm_area_struct *vma;
++ unsigned long call_dl_resolve;
++
++ down_read(&current->mm->mmap_sem);
++ call_dl_resolve = current->mm->call_dl_resolve;
++ up_read(&current->mm->mmap_sem);
++ if (likely(call_dl_resolve))
++ goto emulate;
++
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
++
++ down_write(&current->mm->mmap_sem);
++ if (current->mm->call_dl_resolve) {
++ call_dl_resolve = current->mm->call_dl_resolve;
++ up_write(&current->mm->mmap_sem);
++ if (vma)
++ kmem_cache_free(vm_area_cachep, vma);
++ goto emulate;
++ }
++
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
++ up_write(&current->mm->mmap_sem);
++ if (vma)
++ kmem_cache_free(vm_area_cachep, vma);
++ return 1;
++ }
++
++ if (pax_insert_vma(vma, call_dl_resolve)) {
++ up_write(&current->mm->mmap_sem);
++ kmem_cache_free(vm_area_cachep, vma);
++ return 1;
++ }
++
++ current->mm->call_dl_resolve = call_dl_resolve;
++ up_write(&current->mm->mmap_sem);
++
++emulate:
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++ regs->pc = call_dl_resolve;
++ regs->npc = addr+4;
++ return 3;
++ }
++#endif
++
++ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
++ if ((save & 0xFFC00000U) == 0x05000000U &&
++ (call & 0xFFFFE000U) == 0x85C0A000U &&
++ nop == 0x01000000U)
++ {
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G2] = addr + 4;
++ addr = (save & 0x003FFFFFU) << 10;
++ addr += (((call | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
++ regs->pc = addr;
++ regs->npc = addr+4;
++ return 3;
++ }
++ }
++ } while (0);
++
++ do { /* PaX: unpatched PLT emulation step 2 */
++ unsigned int save, call, nop;
++
++ err = get_user(save, (unsigned int *)(regs->pc-4));
++ err |= get_user(call, (unsigned int *)regs->pc);
++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
++ if (err)
++ break;
++
++ if (save == 0x9DE3BFA8U &&
++ (call & 0xC0000000U) == 0x40000000U &&
++ nop == 0x01000000U)
++ {
++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
++
++ regs->u_regs[UREG_RETPC] = regs->pc;
++ regs->pc = dl_resolve;
++ regs->npc = dl_resolve+4;
++ 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 < 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
++
+ static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
+ int text_fault)
+ {
+@@ -226,6 +500,24 @@ good_area:
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ } else {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
++ 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 *)regs->u_regs[UREG_FP]);
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ /* Allow reads even for write-only mappings */
+ if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+ goto bad_area;
+diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
+index cb841a3..f2061fb 100644
+--- a/arch/sparc/mm/fault_64.c
++++ b/arch/sparc/mm/fault_64.c
+@@ -23,6 +23,9 @@
+ #include <linux/percpu.h>
+ #include <linux/context_tracking.h>
+ #include <linux/uaccess.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -76,7 +79,7 @@ static void __kprobes bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
+ printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
+ regs->tpc);
+ printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
+- printk("OOPS: RPC <%pS>\n", (void *) regs->u_regs[15]);
++ printk("OOPS: RPC <%pA>\n", (void *) regs->u_regs[15]);
+ printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
+ dump_stack();
+ unhandled_fault(regs->tpc, current, regs);
+@@ -276,6 +279,466 @@ static void noinline __kprobes bogus_32bit_fault_tpc(struct pt_regs *regs)
+ show_regs(regs);
+ }
+
++#ifdef CONFIG_PAX_PAGEEXEC
++#ifdef CONFIG_PAX_DLRESOLVE
++static void pax_emuplt_close(struct vm_area_struct *vma)
++{
++ vma->vm_mm->call_dl_resolve = 0UL;
++}
++
++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
++{
++ unsigned int *kaddr;
++
++ vmf->page = alloc_page(GFP_HIGHUSER);
++ if (!vmf->page)
++ return VM_FAULT_OOM;
++
++ kaddr = kmap(vmf->page);
++ memset(kaddr, 0, PAGE_SIZE);
++ kaddr[0] = 0x9DE3BFA8U; /* save */
++ flush_dcache_page(vmf->page);
++ kunmap(vmf->page);
++ return VM_FAULT_MAJOR;
++}
++
++static const struct vm_operations_struct pax_vm_ops = {
++ .close = pax_emuplt_close,
++ .fault = pax_emuplt_fault
++};
++
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
++{
++ int ret;
++
++ INIT_LIST_HEAD(&vma->anon_vma_chain);
++ vma->vm_mm = current->mm;
++ vma->vm_start = addr;
++ vma->vm_end = addr + PAGE_SIZE;
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
++ vma->vm_ops = &pax_vm_ops;
++
++ ret = insert_vm_struct(current->mm, vma);
++ if (ret)
++ return ret;
++
++ ++current->mm->total_vm;
++ return 0;
++}
++#endif
++
++/*
++ * PaX: decide what to do with offenders (regs->tpc = 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 sethi1, sethi2, jmpl;
++
++ err = get_user(sethi1, (unsigned int *)regs->tpc);
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
++
++ if (err)
++ break;
++
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
++ {
++ unsigned long addr;
++
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
++ addr = regs->u_regs[UREG_G1];
++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #2 */
++ unsigned int ba;
++
++ err = get_user(ba, (unsigned int *)regs->tpc);
++
++ if (err)
++ break;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30480000U) {
++ unsigned long addr;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U)
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
++ else
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #3 */
++ unsigned int sethi, bajmpl, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(bajmpl, (unsigned int *)(regs->tpc+4));
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ ((bajmpl & 0xFFFFE000U) == 0x81C06000U || (bajmpl & 0xFFF80000U) == 0x30480000U) &&
++ nop == 0x01000000U)
++ {
++ unsigned long addr;
++
++ addr = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G1] = addr;
++ if ((bajmpl & 0xFFFFE000U) == 0x81C06000U)
++ addr += (((bajmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++ else
++ addr = regs->tpc + ((((bajmpl | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #4 */
++ unsigned int sethi, mov1, call, mov2;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(mov1, (unsigned int *)(regs->tpc+4));
++ err |= get_user(call, (unsigned int *)(regs->tpc+8));
++ err |= get_user(mov2, (unsigned int *)(regs->tpc+12));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ mov1 == 0x8210000FU &&
++ (call & 0xC0000000U) == 0x40000000U &&
++ mov2 == 0x9E100001U)
++ {
++ unsigned long addr;
++
++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #5 */
++ unsigned int sethi, sethi1, sethi2, or1, or2, sllx, jmpl, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
++ err |= get_user(or1, (unsigned int *)(regs->tpc+12));
++ err |= get_user(or2, (unsigned int *)(regs->tpc+16));
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+20));
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+24));
++ err |= get_user(nop, (unsigned int *)(regs->tpc+28));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ (sethi1 & 0xFFC00000U) == 0x03000000U &&
++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
++ (or1 & 0xFFFFE000U) == 0x82106000U &&
++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
++ sllx == 0x83287020U &&
++ jmpl == 0x81C04005U &&
++ nop == 0x01000000U)
++ {
++ unsigned long addr;
++
++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
++ regs->u_regs[UREG_G1] <<= 32;
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #6 */
++ unsigned int sethi, sethi1, sethi2, sllx, or, jmpl, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(sethi1, (unsigned int *)(regs->tpc+4));
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+8));
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+12));
++ err |= get_user(or, (unsigned int *)(regs->tpc+16));
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ (sethi1 & 0xFFC00000U) == 0x03000000U &&
++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
++ sllx == 0x83287020U &&
++ (or & 0xFFFFE000U) == 0x8A116000U &&
++ jmpl == 0x81C04005U &&
++ nop == 0x01000000U)
++ {
++ unsigned long addr;
++
++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G1] <<= 32;
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: unpatched PLT emulation step 1 */
++ unsigned int sethi, ba, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
++ nop == 0x01000000U)
++ {
++ unsigned long addr;
++ unsigned int save, call;
++ unsigned int sethi1, sethi2, or1, or2, sllx, add, jmpl;
++
++ if ((ba & 0xFFC00000U) == 0x30800000U)
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
++ else
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ err = get_user(save, (unsigned int *)addr);
++ err |= get_user(call, (unsigned int *)(addr+4));
++ err |= get_user(nop, (unsigned int *)(addr+8));
++ if (err)
++ break;
++
++#ifdef CONFIG_PAX_DLRESOLVE
++ if (save == 0x9DE3BFA8U &&
++ (call & 0xC0000000U) == 0x40000000U &&
++ nop == 0x01000000U)
++ {
++ struct vm_area_struct *vma;
++ unsigned long call_dl_resolve;
++
++ down_read(&current->mm->mmap_sem);
++ call_dl_resolve = current->mm->call_dl_resolve;
++ up_read(&current->mm->mmap_sem);
++ if (likely(call_dl_resolve))
++ goto emulate;
++
++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
++
++ down_write(&current->mm->mmap_sem);
++ if (current->mm->call_dl_resolve) {
++ call_dl_resolve = current->mm->call_dl_resolve;
++ up_write(&current->mm->mmap_sem);
++ if (vma)
++ kmem_cache_free(vm_area_cachep, vma);
++ goto emulate;
++ }
++
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
++ up_write(&current->mm->mmap_sem);
++ if (vma)
++ kmem_cache_free(vm_area_cachep, vma);
++ return 1;
++ }
++
++ if (pax_insert_vma(vma, call_dl_resolve)) {
++ up_write(&current->mm->mmap_sem);
++ kmem_cache_free(vm_area_cachep, vma);
++ return 1;
++ }
++
++ current->mm->call_dl_resolve = call_dl_resolve;
++ up_write(&current->mm->mmap_sem);
++
++emulate:
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++ regs->tpc = call_dl_resolve;
++ regs->tnpc = addr+4;
++ return 3;
++ }
++#endif
++
++ /* PaX: glibc 2.4+ generates sethi/jmpl instead of save/call */
++ if ((save & 0xFFC00000U) == 0x05000000U &&
++ (call & 0xFFFFE000U) == 0x85C0A000U &&
++ nop == 0x01000000U)
++ {
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G2] = addr + 4;
++ addr = (save & 0x003FFFFFU) << 10;
++ addr += (((call | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 3;
++ }
++
++ /* PaX: 64-bit PLT stub */
++ err = get_user(sethi1, (unsigned int *)addr);
++ err |= get_user(sethi2, (unsigned int *)(addr+4));
++ err |= get_user(or1, (unsigned int *)(addr+8));
++ err |= get_user(or2, (unsigned int *)(addr+12));
++ err |= get_user(sllx, (unsigned int *)(addr+16));
++ err |= get_user(add, (unsigned int *)(addr+20));
++ err |= get_user(jmpl, (unsigned int *)(addr+24));
++ err |= get_user(nop, (unsigned int *)(addr+28));
++ if (err)
++ break;
++
++ if ((sethi1 & 0xFFC00000U) == 0x09000000U &&
++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
++ (or1 & 0xFFFFE000U) == 0x88112000U &&
++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
++ sllx == 0x89293020U &&
++ add == 0x8A010005U &&
++ jmpl == 0x89C14000U &&
++ nop == 0x01000000U)
++ {
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G4] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
++ regs->u_regs[UREG_G4] <<= 32;
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
++ regs->u_regs[UREG_G5] += regs->u_regs[UREG_G4];
++ regs->u_regs[UREG_G4] = addr + 24;
++ addr = regs->u_regs[UREG_G5];
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 3;
++ }
++ }
++ } while (0);
++
++#ifdef CONFIG_PAX_DLRESOLVE
++ do { /* PaX: unpatched PLT emulation step 2 */
++ unsigned int save, call, nop;
++
++ err = get_user(save, (unsigned int *)(regs->tpc-4));
++ err |= get_user(call, (unsigned int *)regs->tpc);
++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
++ if (err)
++ break;
++
++ if (save == 0x9DE3BFA8U &&
++ (call & 0xC0000000U) == 0x40000000U &&
++ nop == 0x01000000U)
++ {
++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ dl_resolve &= 0xFFFFFFFFUL;
++
++ regs->u_regs[UREG_RETPC] = regs->tpc;
++ regs->tpc = dl_resolve;
++ regs->tnpc = dl_resolve+4;
++ return 3;
++ }
++ } while (0);
++#endif
++
++ do { /* PaX: patched PLT emulation #7, must be AFTER the unpatched PLT emulation */
++ unsigned int sethi, ba, nop;
++
++ err = get_user(sethi, (unsigned int *)regs->tpc);
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
++
++ if (err)
++ break;
++
++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
++ (ba & 0xFFF00000U) == 0x30600000U &&
++ nop == 0x01000000U)
++ {
++ unsigned long addr;
++
++ addr = (sethi & 0x003FFFFFU) << 10;
++ regs->u_regs[UREG_G1] = addr;
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
++
++ if (test_thread_flag(TIF_32BIT))
++ addr &= 0xFFFFFFFFUL;
++
++ regs->tpc = addr;
++ regs->tnpc = addr+4;
++ return 2;
++ }
++ } 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 < 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
++
+ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
+ {
+ enum ctx_state prev_state = exception_enter();
+@@ -350,6 +813,29 @@ retry:
+ if (!vma)
+ goto bad_area;
+
++#ifdef CONFIG_PAX_PAGEEXEC
++ /* PaX: detect ITLB misses on non-exec pages */
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
++ {
++ if (address != regs->tpc)
++ goto good_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->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ /* Pure DTLB misses do not tell us whether the fault causing
+ * load/store/atomic was a write or not, it only says that there
+ * was no match. So in such a case we (carefully) read the
+diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
+index ba52e64..eee5791 100644
+--- a/arch/sparc/mm/hugetlbpage.c
++++ b/arch/sparc/mm/hugetlbpage.c
+@@ -25,8 +25,10 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+- unsigned long flags)
++ unsigned long flags,
++ unsigned long offset)
+ {
++ struct mm_struct *mm = current->mm;
+ unsigned long task_size = TASK_SIZE;
+ struct vm_unmapped_area_info info;
+
+@@ -35,15 +37,22 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+
+ info.flags = 0;
+ info.length = len;
+- info.low_limit = TASK_UNMAPPED_BASE;
++ info.low_limit = mm->mmap_base;
+ info.high_limit = min(task_size, VA_EXCLUDE_START);
+ info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
+ VM_BUG_ON(addr != -ENOMEM);
+ info.low_limit = VA_EXCLUDE_END;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ info.low_limit += mm->delta_mmap;
++#endif
++
+ info.high_limit = task_size;
+ addr = vm_unmapped_area(&info);
+ }
+@@ -52,10 +61,11 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
+ }
+
+ static unsigned long
+-hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+- const unsigned long len,
+- const unsigned long pgoff,
+- const unsigned long flags)
++hugetlb_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
++ unsigned long len,
++ unsigned long pgoff,
++ unsigned long flags,
++ unsigned long offset)
+ {
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = addr0;
+@@ -70,6 +80,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ info.high_limit = mm->mmap_base;
+ info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ /*
+@@ -82,6 +93,12 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ VM_BUG_ON(addr != -ENOMEM);
+ info.flags = 0;
+ info.low_limit = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ info.low_limit += mm->delta_mmap;
++#endif
++
+ info.high_limit = STACK_TOP32;
+ addr = vm_unmapped_area(&info);
+ }
+@@ -96,6 +113,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long task_size = TASK_SIZE;
++ unsigned long offset = gr_rand_threadstack_offset(mm, file, flags);
+
+ if (test_thread_flag(TIF_32BIT))
+ task_size = STACK_TOP32;
+@@ -111,19 +129,22 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ return addr;
+ }
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ addr = ALIGN(addr, HPAGE_SIZE);
+ 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;
+ }
+ if (mm->get_unmapped_area == arch_get_unmapped_area)
+ return hugetlb_get_unmapped_area_bottomup(file, addr, len,
+- pgoff, flags);
++ pgoff, flags, offset);
+ else
+ return hugetlb_get_unmapped_area_topdown(file, addr, len,
+- pgoff, flags);
++ pgoff, flags, offset);
+ }
+
+ pte_t *huge_pte_alloc(struct mm_struct *mm,
+diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
+index aec508e..ad807e7 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -189,9 +189,9 @@ unsigned long sparc64_kern_sec_context __read_mostly;
+ int num_kernel_image_mappings;
+
+ #ifdef CONFIG_DEBUG_DCFLUSH
+-atomic_t dcpage_flushes = ATOMIC_INIT(0);
++atomic_unchecked_t dcpage_flushes = ATOMIC_INIT(0);
+ #ifdef CONFIG_SMP
+-atomic_t dcpage_flushes_xcall = ATOMIC_INIT(0);
++atomic_unchecked_t dcpage_flushes_xcall = ATOMIC_INIT(0);
+ #endif
+ #endif
+
+@@ -199,7 +199,7 @@ inline void flush_dcache_page_impl(struct page *page)
+ {
+ BUG_ON(tlb_type == hypervisor);
+ #ifdef CONFIG_DEBUG_DCFLUSH
+- atomic_inc(&dcpage_flushes);
++ atomic_inc_unchecked(&dcpage_flushes);
+ #endif
+
+ #ifdef DCACHE_ALIASING_POSSIBLE
+@@ -459,10 +459,10 @@ void mmu_info(struct seq_file *m)
+
+ #ifdef CONFIG_DEBUG_DCFLUSH
+ seq_printf(m, "DCPageFlushes\t: %d\n",
+- atomic_read(&dcpage_flushes));
++ atomic_read_unchecked(&dcpage_flushes));
+ #ifdef CONFIG_SMP
+ seq_printf(m, "DCPageFlushesXC\t: %d\n",
+- atomic_read(&dcpage_flushes_xcall));
++ atomic_read_unchecked(&dcpage_flushes_xcall));
+ #endif /* CONFIG_SMP */
+ #endif /* CONFIG_DEBUG_DCFLUSH */
+ }
+diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
+index 4820a02..4366ab2 100644
+--- a/arch/tile/Kconfig
++++ b/arch/tile/Kconfig
+@@ -194,6 +194,7 @@ source "kernel/Kconfig.hz"
+ config KEXEC
+ bool "kexec system call"
+ select KEXEC_CORE
++ 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/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
+index b0531a6..555a389 100644
+--- a/arch/tile/include/asm/atomic_64.h
++++ b/arch/tile/include/asm/atomic_64.h
+@@ -158,6 +158,16 @@ static inline void atomic64_xor(long i, atomic64_t *v)
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#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 /* !__ASSEMBLY__ */
+
+ #endif /* _ASM_TILE_ATOMIC_64_H */
+diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
+index 6160761..00cac88 100644
+--- a/arch/tile/include/asm/cache.h
++++ b/arch/tile/include/asm/cache.h
+@@ -15,11 +15,12 @@
+ #ifndef _ASM_TILE_CACHE_H
+ #define _ASM_TILE_CACHE_H
+
++#include <linux/const.h>
+ #include <arch/chip.h>
+
+ /* bytes per L1 data cache line */
+ #define L1_CACHE_SHIFT CHIP_L1D_LOG_LINE_SIZE()
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ /* bytes per L2 cache line */
+ #define L2_CACHE_SHIFT CHIP_L2_LOG_LINE_SIZE()
+diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
+index 0a9c4265..bfb62d1 100644
+--- a/arch/tile/include/asm/uaccess.h
++++ b/arch/tile/include/asm/uaccess.h
+@@ -429,9 +429,9 @@ static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+ {
+- int sz = __compiletime_object_size(to);
++ size_t sz = __compiletime_object_size(to);
+
+- if (likely(sz == -1 || sz >= n))
++ if (likely(sz == (size_t)-1 || sz >= n))
+ n = _copy_from_user(to, from, n);
+ else
+ copy_from_user_overflow();
+diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
+index 77ceaa3..3630dea 100644
+--- a/arch/tile/mm/hugetlbpage.c
++++ b/arch/tile/mm/hugetlbpage.c
+@@ -174,6 +174,7 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
+ info.high_limit = TASK_SIZE;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
++ info.threadstack_offset = 0;
+ return vm_unmapped_area(&info);
+ }
+
+@@ -191,6 +192,7 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
+ info.high_limit = current->mm->mmap_base;
+ info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ info.align_offset = 0;
++ info.threadstack_offset = 0;
+ addr = vm_unmapped_area(&info);
+
+ /*
+diff --git a/arch/um/Makefile b/arch/um/Makefile
+index e3abe6f..33a363c 100644
+--- a/arch/um/Makefile
++++ b/arch/um/Makefile
+@@ -73,6 +73,8 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
+ -D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
+ -idirafter $(obj)/include -D__KERNEL__ -D__UM_HOST__
+
++USER_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(USER_CFLAGS))
++
+ #This will adjust *FLAGS accordingly to the platform.
+ include $(ARCH_DIR)/Makefile-os-$(OS)
+
+diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h
+index 19e1bdd..3665b77 100644
+--- a/arch/um/include/asm/cache.h
++++ b/arch/um/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef __UM_CACHE_H
+ #define __UM_CACHE_H
+
++#include <linux/const.h>
+
+ #if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+ # define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+@@ -12,6 +13,6 @@
+ # define L1_CACHE_SHIFT 5
+ #endif
+
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #endif
+diff --git a/arch/um/include/asm/kmap_types.h b/arch/um/include/asm/kmap_types.h
+index 2e0a6b1..a64d0f5 100644
+--- a/arch/um/include/asm/kmap_types.h
++++ b/arch/um/include/asm/kmap_types.h
+@@ -8,6 +8,6 @@
+
+ /* No more #include "asm/arch/kmap_types.h" ! */
+
+-#define KM_TYPE_NR 14
++#define KM_TYPE_NR 15
+
+ #endif
+diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
+index f878bec..ca09300 100644
+--- a/arch/um/include/asm/page.h
++++ b/arch/um/include/asm/page.h
+@@ -14,6 +14,9 @@
+ #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+ #define PAGE_MASK (~(PAGE_SIZE-1))
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ #ifndef __ASSEMBLY__
+
+ struct page;
+diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
+index bae8523..ba9484b 100644
+--- a/arch/um/include/asm/pgtable-3level.h
++++ b/arch/um/include/asm/pgtable-3level.h
+@@ -58,6 +58,7 @@
+ #define pud_present(x) (pud_val(x) & _PAGE_PRESENT)
+ #define pud_populate(mm, pud, pmd) \
+ set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
++#define pud_populate_kernel(mm, pud, pmd) pud_populate((mm), (pud), (pmd))
+
+ #ifdef CONFIG_64BIT
+ #define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval))
+diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
+index 034b42c7..5c186ce 100644
+--- a/arch/um/kernel/process.c
++++ b/arch/um/kernel/process.c
+@@ -343,22 +343,6 @@ int singlestepping(void * t)
+ return 2;
+ }
+
+-/*
+- * Only x86 and x86_64 have an arch_align_stack().
+- * All other arches have "#define arch_align_stack(x) (x)"
+- * in their asm/exec.h
+- * As this is included in UML from asm-um/system-generic.h,
+- * we can use it to behave as the subarch does.
+- */
+-#ifndef arch_align_stack
+-unsigned long arch_align_stack(unsigned long sp)
+-{
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+- sp -= get_random_int() % 8192;
+- return sp & ~0xf;
+-}
+-#endif
+-
+ unsigned long get_wchan(struct task_struct *p)
+ {
+ unsigned long stack_page, sp, ip;
+diff --git a/arch/unicore32/include/asm/cache.h b/arch/unicore32/include/asm/cache.h
+index ad8f795..2c7eec6 100644
+--- a/arch/unicore32/include/asm/cache.h
++++ b/arch/unicore32/include/asm/cache.h
+@@ -12,8 +12,10 @@
+ #ifndef __UNICORE_CACHE_H__
+ #define __UNICORE_CACHE_H__
+
+-#define L1_CACHE_SHIFT (5)
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#include <linux/const.h>
++
++#define L1_CACHE_SHIFT 5
++#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/x86/Kconfig b/arch/x86/Kconfig
+index d9a94da..4c060aa 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -39,14 +39,13 @@ config X86
+ select ARCH_MIGHT_HAVE_PC_SERIO
+ select ARCH_SUPPORTS_ATOMIC_RMW
+ select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT
+- select ARCH_SUPPORTS_INT128 if X86_64
++ select ARCH_SUPPORTS_INT128 if X86_64 && !PAX_SIZE_OVERFLOW
+ select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
+ select ARCH_USE_BUILTIN_BSWAP
+ select ARCH_USE_CMPXCHG_LOCKREF if X86_64
+ select ARCH_USE_QUEUED_RWLOCKS
+ select ARCH_USE_QUEUED_SPINLOCKS
+ select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH if SMP
+- select ARCH_WANTS_DYNAMIC_TASK_STRUCT
+ select ARCH_WANT_FRAME_POINTERS
+ select ARCH_WANT_IPC_PARSE_VERSION if X86_32
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+@@ -92,7 +91,7 @@ config X86
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_ARCH_TRANSPARENT_HUGEPAGE
+ select HAVE_EBPF_JIT if X86_64
+- select HAVE_CC_STACKPROTECTOR
++ select HAVE_CC_STACKPROTECTOR if X86_64 || !PAX_MEMORY_UDEREF
+ select HAVE_CMPXCHG_DOUBLE
+ select HAVE_CMPXCHG_LOCAL
+ select HAVE_CONTEXT_TRACKING if X86_64
+@@ -111,6 +110,7 @@ config X86
+ select HAVE_FUNCTION_GRAPH_FP_TEST
+ select HAVE_FUNCTION_GRAPH_TRACER
+ select HAVE_FUNCTION_TRACER
++ select HAVE_GCC_PLUGINS
+ select HAVE_GENERIC_DMA_COHERENT if X86_32
+ select HAVE_HW_BREAKPOINT
+ select HAVE_IDE
+@@ -186,11 +186,13 @@ config MMU
+ def_bool y
+
+ config ARCH_MMAP_RND_BITS_MIN
+- default 28 if 64BIT
++ default 28 if 64BIT && !PAX_PER_CPU_PGD
++ default 27 if 64BIT && PAX_PER_CPU_PGD
+ default 8
+
+ config ARCH_MMAP_RND_BITS_MAX
+- default 32 if 64BIT
++ default 32 if 64BIT && !PAX_PER_CPU_PGD
++ default 27 if 64BIT && PAX_PER_CPU_PGD
+ default 16
+
+ config ARCH_MMAP_RND_COMPAT_BITS_MIN
+@@ -292,7 +294,7 @@ config X86_64_SMP
+
+ config X86_32_LAZY_GS
+ def_bool y
+- depends on X86_32 && !CC_STACKPROTECTOR
++ depends on X86_32 && !CC_STACKPROTECTOR && !PAX_MEMORY_UDEREF
+
+ config ARCH_HWEIGHT_CFLAGS
+ string
+@@ -679,6 +681,7 @@ config SCHED_OMIT_FRAME_POINTER
+
+ menuconfig HYPERVISOR_GUEST
+ bool "Linux guest support"
++ depends on !GRKERNSEC_CONFIG_AUTO || GRKERNSEC_CONFIG_VIRT_GUEST || (GRKERNSEC_CONFIG_VIRT_HOST && GRKERNSEC_CONFIG_VIRT_XEN)
+ ---help---
+ Say Y here to enable options for running Linux under various hyper-
+ visors. This option enables basic hypervisor detection and platform
+@@ -1080,6 +1083,7 @@ config VM86
+
+ config X86_16BIT
+ bool "Enable support for 16-bit segments" if EXPERT
++ depends on !GRKERNSEC
+ default y
+ depends on MODIFY_LDT_SYSCALL
+ ---help---
+@@ -1234,6 +1238,7 @@ choice
+
+ config NOHIGHMEM
+ bool "off"
++ depends on !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
+ ---help---
+ Linux can use up to 64 Gigabytes of physical memory on x86 systems.
+ However, the address space of 32-bit x86 processors is only 4
+@@ -1270,6 +1275,7 @@ config NOHIGHMEM
+
+ config HIGHMEM4G
+ bool "4GB"
++ depends on !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
+ ---help---
+ Select this if you have a 32-bit processor and between 1 and 4
+ gigabytes of physical RAM.
+@@ -1322,7 +1328,7 @@ config PAGE_OFFSET
+ hex
+ default 0xB0000000 if VMSPLIT_3G_OPT
+ default 0x80000000 if VMSPLIT_2G
+- default 0x78000000 if VMSPLIT_2G_OPT
++ default 0x70000000 if VMSPLIT_2G_OPT
+ default 0x40000000 if VMSPLIT_1G
+ default 0xC0000000
+ depends on X86_32
+@@ -1343,7 +1349,6 @@ config X86_PAE
+
+ config ARCH_PHYS_ADDR_T_64BIT
+ def_bool y
+- depends on X86_64 || X86_PAE
+
+ config ARCH_DMA_ADDR_T_64BIT
+ def_bool y
+@@ -1474,7 +1479,7 @@ config ARCH_PROC_KCORE_TEXT
+
+ config ILLEGAL_POINTER_VALUE
+ hex
+- default 0 if X86_32
++ default 0xfffff000 if X86_32
+ default 0xdead000000000000 if X86_64
+
+ source "mm/Kconfig"
+@@ -1797,6 +1802,7 @@ source kernel/Kconfig.hz
+ config KEXEC
+ bool "kexec system call"
+ select KEXEC_CORE
++ 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
+@@ -1963,7 +1969,9 @@ config X86_NEED_RELOCS
+
+ config PHYSICAL_ALIGN
+ hex "Alignment value to which kernel should be aligned"
+- default "0x200000"
++ default "0x1000000"
++ range 0x200000 0x1000000 if PAX_KERNEXEC && X86_PAE
++ range 0x400000 0x1000000 if PAX_KERNEXEC && !X86_PAE
+ range 0x2000 0x1000000 if X86_32
+ range 0x200000 0x1000000 if X86_64
+ ---help---
+@@ -2046,6 +2054,7 @@ config COMPAT_VDSO
+ def_bool n
+ prompt "Disable the 32-bit vDSO (needed for glibc 2.3.3)"
+ depends on X86_32 || IA32_EMULATION
++ depends on !PAX_PAGEEXEC && !PAX_SEGMEXEC && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ ---help---
+ Certain buggy versions of glibc will crash if they are
+ presented with a 32-bit vDSO that is not mapped at the address
+@@ -2086,15 +2095,6 @@ choice
+
+ If unsure, select "Emulate".
+
+- config LEGACY_VSYSCALL_NATIVE
+- bool "Native"
+- help
+- Actual executable code is located in the fixed vsyscall
+- address mapping, implementing time() efficiently. Since
+- this makes the mapping executable, it can be used during
+- security vulnerability exploitation (traditionally as
+- ROP gadgets). This configuration is not recommended.
+-
+ config LEGACY_VSYSCALL_EMULATE
+ bool "Emulate"
+ help
+@@ -2175,6 +2175,22 @@ config MODIFY_LDT_SYSCALL
+
+ Saying 'N' here may make sense for embedded or server kernels.
+
++config DEFAULT_MODIFY_LDT_SYSCALL
++ bool "Allow userspace to modify the LDT by default"
++ default y
++
++ ---help---
++ 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.
++
++ For this reason this option allows one to enable or disable the
++ feature at runtime. It is recommended to say 'N' here to leave
++ the system protected, and to enable it at runtime only if needed
++ by setting the sys.kernel.modify_ldt sysctl.
++
+ source "kernel/livepatch/Kconfig"
+
+ endmenu
+diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+index 3ba5ff2..44bdacc 100644
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -329,7 +329,7 @@ config X86_PPRO_FENCE
+
+ config X86_F00F_BUG
+ def_bool y
+- depends on M586MMX || M586TSC || M586 || M486
++ depends on (M586MMX || M586TSC || M586 || M486) && !PAX_KERNEXEC
+
+ config X86_INVD_BUG
+ def_bool y
+@@ -337,7 +337,7 @@ config X86_INVD_BUG
+
+ config X86_ALIGNMENT_16
+ def_bool y
+- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+
+ config X86_INTEL_USERCOPY
+ def_bool y
+@@ -379,7 +379,7 @@ config X86_CMPXCHG64
+ # generates cmov.
+ config X86_CMOV
+ def_bool y
+- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
+
+ config X86_MINIMUM_CPU_FAMILY
+ int
+diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
+index 67eec55..1a5c1ab 100644
+--- a/arch/x86/Kconfig.debug
++++ b/arch/x86/Kconfig.debug
+@@ -55,6 +55,7 @@ config X86_PTDUMP
+ tristate "Export kernel pagetable layout to userspace via debugfs"
+ depends on DEBUG_KERNEL
+ select DEBUG_FS
++ depends on !GRKERNSEC_KMEM
+ select X86_PTDUMP_CORE
+ ---help---
+ Say Y here if you want to show the kernel pagetable layout in a
+@@ -84,6 +85,7 @@ config DEBUG_RODATA_TEST
+
+ config DEBUG_WX
+ bool "Warn on W+X mappings at boot"
++ depends on BROKEN
+ select X86_PTDUMP_CORE
+ ---help---
+ Generate a warning if any W+X mappings are found at boot.
+@@ -111,7 +113,7 @@ config DEBUG_WX
+
+ config DEBUG_SET_MODULE_RONX
+ bool "Set loadable kernel module data as NX and text as RO"
+- depends on MODULES
++ depends on MODULES && BROKEN
+ ---help---
+ This option helps catch unintended modifications to loadable
+ kernel module's text and read-only data. It also prevents execution
+@@ -353,6 +355,7 @@ config X86_DEBUG_FPU
+ config PUNIT_ATOM_DEBUG
+ tristate "ATOM Punit debug driver"
+ select DEBUG_FS
++ depends on !GRKERNSEC_KMEM
+ select IOSF_MBI
+ ---help---
+ This is a debug driver, which gets the power states
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 6fce7f0..9a4d7ce 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -75,9 +75,6 @@ ifeq ($(CONFIG_X86_32),y)
+ # CPU-specific tuning. Anything which can be shared with UML should go here.
+ include arch/x86/Makefile_32.cpu
+ KBUILD_CFLAGS += $(cflags-y)
+-
+- # temporary until string.h is fixed
+- KBUILD_CFLAGS += -ffreestanding
+ else
+ BITS := 64
+ UTS_MACHINE := x86_64
+@@ -126,6 +123,9 @@ else
+ KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args)
+ endif
+
++# temporary until string.h is fixed
++KBUILD_CFLAGS += -ffreestanding
++
+ # Make sure compiler does not have buggy stack-protector support.
+ ifdef CONFIG_CC_STACKPROTECTOR
+ cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
+@@ -199,6 +199,7 @@ archheaders:
+ $(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
+
+ archprepare:
++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
+ ifeq ($(CONFIG_KEXEC_FILE),y)
+ $(Q)$(MAKE) $(build)=arch/x86/purgatory arch/x86/purgatory/kexec-purgatory.c
+ endif
+@@ -285,3 +286,9 @@ define archhelp
+ echo ' FDARGS="..." arguments for the booted kernel'
+ echo ' FDINITRD=file initrd for the booted kernel'
+ endef
++
++define OLD_LD
++
++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
++*** Please upgrade your binutils to 2.18 or newer
++endef
+diff --git a/arch/x86/boot/bitops.h b/arch/x86/boot/bitops.h
+index 878e4b9..20537ab 100644
+--- a/arch/x86/boot/bitops.h
++++ b/arch/x86/boot/bitops.h
+@@ -26,7 +26,7 @@ static inline int variable_test_bit(int nr, const void *addr)
+ u8 v;
+ const u32 *p = (const u32 *)addr;
+
+- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
+ return v;
+ }
+
+@@ -37,7 +37,7 @@ static inline int variable_test_bit(int nr, const void *addr)
+
+ static inline void set_bit(int nr, void *addr)
+ {
+- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
+ }
+
+ #endif /* BOOT_BITOPS_H */
+diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
+index 9011a88..06aa820 100644
+--- a/arch/x86/boot/boot.h
++++ b/arch/x86/boot/boot.h
+@@ -83,7 +83,7 @@ static inline void io_delay(void)
+ static inline u16 ds(void)
+ {
+ u16 seg;
+- asm("movw %%ds,%0" : "=rm" (seg));
++ asm volatile("movw %%ds,%0" : "=rm" (seg));
+ return seg;
+ }
+
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
+index f135688..1249175 100644
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -35,6 +35,23 @@ KBUILD_CFLAGS += -mno-mmx -mno-sse
+ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
+ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
+
++ifdef CONFIG_DEBUG_INFO
++ifdef CONFIG_DEBUG_INFO_SPLIT
++KBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g)
++else
++KBUILD_CFLAGS += -g
++endif
++KBUILD_AFLAGS += -Wa,--gdwarf-2
++endif
++ifdef CONFIG_DEBUG_INFO_DWARF4
++KBUILD_CFLAGS += $(call cc-option, -gdwarf-4,)
++endif
++
++ifdef CONFIG_DEBUG_INFO_REDUCED
++KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \
++ $(call cc-option,-fno-var-tracking)
++endif
++
+ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
+ GCOV_PROFILE := n
+ UBSAN_SANITIZE :=n
+diff --git a/arch/x86/boot/compressed/efi_stub_32.S b/arch/x86/boot/compressed/efi_stub_32.S
+index a53440e..c3dbf1e 100644
+--- a/arch/x86/boot/compressed/efi_stub_32.S
++++ b/arch/x86/boot/compressed/efi_stub_32.S
+@@ -46,16 +46,13 @@ ENTRY(efi_call_phys)
+ * parameter 2, ..., param n. To make things easy, we save the return
+ * address of efi_call_phys in a global variable.
+ */
+- popl %ecx
+- movl %ecx, saved_return_addr(%edx)
+- /* get the function pointer into ECX*/
+- popl %ecx
+- movl %ecx, efi_rt_function_ptr(%edx)
++ popl saved_return_addr(%edx)
++ popl efi_rt_function_ptr(%edx)
+
+ /*
+ * 3. Call the physical function.
+ */
+- call *%ecx
++ call *efi_rt_function_ptr(%edx)
+
+ /*
+ * 4. Balance the stack. And because EAX contain the return value,
+@@ -67,15 +64,12 @@ ENTRY(efi_call_phys)
+ 1: popl %edx
+ subl $1b, %edx
+
+- movl efi_rt_function_ptr(%edx), %ecx
+- pushl %ecx
++ pushl efi_rt_function_ptr(%edx)
+
+ /*
+ * 10. Push the saved return address onto the stack and return.
+ */
+- movl saved_return_addr(%edx), %ecx
+- pushl %ecx
+- ret
++ jmpl *saved_return_addr(%edx)
+ ENDPROC(efi_call_phys)
+ .previous
+
+diff --git a/arch/x86/boot/compressed/efi_thunk_64.S b/arch/x86/boot/compressed/efi_thunk_64.S
+index 630384a..278e788 100644
+--- a/arch/x86/boot/compressed/efi_thunk_64.S
++++ b/arch/x86/boot/compressed/efi_thunk_64.S
+@@ -189,8 +189,8 @@ efi_gdt64:
+ .long 0 /* Filled out by user */
+ .word 0
+ .quad 0x0000000000000000 /* NULL descriptor */
+- .quad 0x00af9a000000ffff /* __KERNEL_CS */
+- .quad 0x00cf92000000ffff /* __KERNEL_DS */
++ .quad 0x00af9b000000ffff /* __KERNEL_CS */
++ .quad 0x00cf93000000ffff /* __KERNEL_DS */
+ .quad 0x0080890000000000 /* TS descriptor */
+ .quad 0x0000000000000000 /* TS continued */
+ efi_gdt64_end:
+diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
+index 1038524..b6acc21 100644
+--- a/arch/x86/boot/compressed/head_32.S
++++ b/arch/x86/boot/compressed/head_32.S
+@@ -169,10 +169,10 @@ preferred_addr:
+ addl %eax, %ebx
+ notl %eax
+ andl %eax, %ebx
+- cmpl $LOAD_PHYSICAL_ADDR, %ebx
++ cmpl $____LOAD_PHYSICAL_ADDR, %ebx
+ jge 1f
+ #endif
+- movl $LOAD_PHYSICAL_ADDR, %ebx
++ movl $____LOAD_PHYSICAL_ADDR, %ebx
+ 1:
+
+ /* Target address to relocate to for decompression */
+diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
+index 0d80a7a..ed3e0ff 100644
+--- a/arch/x86/boot/compressed/head_64.S
++++ b/arch/x86/boot/compressed/head_64.S
+@@ -103,10 +103,10 @@ ENTRY(startup_32)
+ addl %eax, %ebx
+ notl %eax
+ andl %eax, %ebx
+- cmpl $LOAD_PHYSICAL_ADDR, %ebx
++ cmpl $____LOAD_PHYSICAL_ADDR, %ebx
+ jge 1f
+ #endif
+- movl $LOAD_PHYSICAL_ADDR, %ebx
++ movl $____LOAD_PHYSICAL_ADDR, %ebx
+ 1:
+
+ /* Target address to relocate to for decompression */
+@@ -333,10 +333,10 @@ preferred_addr:
+ addq %rax, %rbp
+ notq %rax
+ andq %rax, %rbp
+- cmpq $LOAD_PHYSICAL_ADDR, %rbp
++ cmpq $____LOAD_PHYSICAL_ADDR, %rbp
+ jge 1f
+ #endif
+- movq $LOAD_PHYSICAL_ADDR, %rbp
++ movq $____LOAD_PHYSICAL_ADDR, %rbp
+ 1:
+
+ /* Target address to relocate to for decompression */
+@@ -444,8 +444,8 @@ gdt:
+ .long gdt
+ .word 0
+ .quad 0x0000000000000000 /* NULL descriptor */
+- .quad 0x00af9a000000ffff /* __KERNEL_CS */
+- .quad 0x00cf92000000ffff /* __KERNEL_DS */
++ .quad 0x00af9b000000ffff /* __KERNEL_CS */
++ .quad 0x00cf93000000ffff /* __KERNEL_DS */
+ .quad 0x0080890000000000 /* TS descriptor */
+ .quad 0x0000000000000000 /* TS continued */
+ gdt_end:
+diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
+index f14db4e..d2c951e 100644
+--- a/arch/x86/boot/compressed/misc.c
++++ b/arch/x86/boot/compressed/misc.c
+@@ -175,13 +175,17 @@ static void handle_relocations(void *output, unsigned long output_len)
+ int *reloc;
+ unsigned long delta, map, ptr;
+ unsigned long min_addr = (unsigned long)output;
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++ unsigned long max_addr = min_addr + (VO___bss_start - VO__text - __PAGE_OFFSET - ____LOAD_PHYSICAL_ADDR);
++#else
+ unsigned long max_addr = min_addr + (VO___bss_start - VO__text);
++#endif
+
+ /*
+ * Calculate the delta between where vmlinux was linked to load
+ * and where it was actually loaded.
+ */
+- delta = min_addr - LOAD_PHYSICAL_ADDR;
++ delta = min_addr - ____LOAD_PHYSICAL_ADDR;
+ if (!delta) {
+ debug_putstr("No relocation needed... ");
+ return;
+@@ -263,7 +267,7 @@ static void parse_elf(void *output)
+ Elf32_Ehdr ehdr;
+ Elf32_Phdr *phdrs, *phdr;
+ #endif
+- void *dest;
++ void *dest, *prev;
+ int i;
+
+ memcpy(&ehdr, output, sizeof(ehdr));
+@@ -290,11 +294,14 @@ static void parse_elf(void *output)
+ case PT_LOAD:
+ #ifdef CONFIG_RELOCATABLE
+ dest = output;
+- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
+ #else
+ dest = (void *)(phdr->p_paddr);
+ #endif
+ memmove(dest, output + phdr->p_offset, phdr->p_filesz);
++ if (i)
++ memset(prev, 0xff, dest - prev);
++ prev = dest + phdr->p_filesz;
+ break;
+ default: /* Ignore other PT_* */ break;
+ }
+@@ -326,7 +333,11 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
+ unsigned char *output,
+ unsigned long output_len)
+ {
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++ const unsigned long kernel_total_size = VO__end - VO__text - __PAGE_OFFSET - ____LOAD_PHYSICAL_ADDR;
++#else
+ const unsigned long kernel_total_size = VO__end - VO__text;
++#endif
+ unsigned char *output_orig = output;
+
+ /* Retain x86 boot parameters pointer passed from startup_32/64. */
+@@ -381,7 +392,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
+ error("Destination address too large");
+ #endif
+ #ifndef CONFIG_RELOCATABLE
+- if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
++ if ((unsigned long)output != ____LOAD_PHYSICAL_ADDR)
+ error("Wrong destination address");
+ #endif
+
+diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
+index 34b95df..e6d5fc2 100644
+--- a/arch/x86/boot/compressed/pagetable.c
++++ b/arch/x86/boot/compressed/pagetable.c
+@@ -11,6 +11,7 @@
+ */
+ #define __pa(x) ((unsigned long)(x))
+ #define __va(x) ((void *)((unsigned long)(x)))
++#undef CONFIG_PAX_KERNEXEC
+
+ #include "misc.h"
+
+diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
+index 1fd7d57..0f7d096 100644
+--- a/arch/x86/boot/cpucheck.c
++++ b/arch/x86/boot/cpucheck.c
+@@ -125,9 +125,9 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+ u32 ecx = MSR_K7_HWCR;
+ u32 eax, edx;
+
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+ eax &= ~(1 << 15);
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+ get_cpuflags(); /* Make sure it really did something */
+ err = check_cpuflags();
+@@ -140,9 +140,9 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+ u32 ecx = MSR_VIA_FCR;
+ u32 eax, edx;
+
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+ eax |= (1<<1)|(1<<7);
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+ set_bit(X86_FEATURE_CX8, cpu.flags);
+ err = check_cpuflags();
+@@ -153,12 +153,12 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
+ u32 eax, edx;
+ u32 level = 1;
+
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
+- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
+- asm("cpuid"
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
++ asm volatile("cpuid"
+ : "+a" (level), "=d" (cpu.flags[0])
+ : : "ecx", "ebx");
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
+
+ err = check_cpuflags();
+ } else if (err == 0x01 &&
+diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
+index 3dd5be3..16720a2 100644
+--- a/arch/x86/boot/header.S
++++ b/arch/x86/boot/header.S
+@@ -438,7 +438,7 @@ setup_data: .quad 0 # 64-bit physical pointer to
+ # single linked list of
+ # struct setup_data
+
+-pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
++pref_address: .quad ____LOAD_PHYSICAL_ADDR # preferred load addr
+
+ #
+ # Getting to provably safe in-place decompression is hard. Worst case
+@@ -543,7 +543,12 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
+
+ #define ZO_INIT_SIZE (ZO__end - ZO_startup_32 + ZO_z_min_extract_offset)
+
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++#define VO_INIT_SIZE (VO__end - VO__text - __PAGE_OFFSET - ____LOAD_PHYSICAL_ADDR)
++#else
+ #define VO_INIT_SIZE (VO__end - VO__text)
++#endif
++
+ #if ZO_INIT_SIZE > VO_INIT_SIZE
+ # define INIT_SIZE ZO_INIT_SIZE
+ #else
+diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
+index db75d07..8e6d0af 100644
+--- a/arch/x86/boot/memory.c
++++ b/arch/x86/boot/memory.c
+@@ -19,7 +19,7 @@
+
+ static int detect_memory_e820(void)
+ {
+- int count = 0;
++ unsigned int count = 0;
+ struct biosregs ireg, oreg;
+ struct e820entry *desc = boot_params.e820_map;
+ static struct e820entry buf; /* static so it is zeroed */
+diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
+index ba3e100..6501b8f 100644
+--- a/arch/x86/boot/video-vesa.c
++++ b/arch/x86/boot/video-vesa.c
+@@ -201,6 +201,7 @@ static void vesa_store_pm_info(void)
+
+ boot_params.screen_info.vesapm_seg = oreg.es;
+ boot_params.screen_info.vesapm_off = oreg.di;
++ boot_params.screen_info.vesapm_size = oreg.cx;
+ }
+
+ /*
+diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
+index 77780e3..86be0cb 100644
+--- a/arch/x86/boot/video.c
++++ b/arch/x86/boot/video.c
+@@ -100,7 +100,7 @@ static void store_mode_params(void)
+ static unsigned int get_entry(void)
+ {
+ char entry_buf[4];
+- int i, len = 0;
++ unsigned int i, len = 0;
+ int key;
+ unsigned int v;
+
+diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
+index 9105655..41779c1 100644
+--- a/arch/x86/crypto/aes-x86_64-asm_64.S
++++ b/arch/x86/crypto/aes-x86_64-asm_64.S
+@@ -8,6 +8,8 @@
+ * including this sentence is retained in full.
+ */
+
++#include <asm/alternative-asm.h>
++
+ .extern crypto_ft_tab
+ .extern crypto_it_tab
+ .extern crypto_fl_tab
+@@ -70,6 +72,8 @@
+ je B192; \
+ leaq 32(r9),r9;
+
++#define ret pax_force_retaddr; ret
++
+ #define epilogue(FUNC,r1,r2,r3,r4,r5,r6,r7,r8,r9) \
+ movq r1,r2; \
+ movq r3,r4; \
+diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
+index 383a6f8..a4db591 100644
+--- a/arch/x86/crypto/aesni-intel_asm.S
++++ b/arch/x86/crypto/aesni-intel_asm.S
+@@ -32,6 +32,7 @@
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+
+ /*
+ * The following macros are used to move an (un)aligned 16 byte value to/from
+@@ -218,7 +219,7 @@ enc: .octa 0x2
+ * num_initial_blocks = b mod 4
+ * encrypt the initial num_initial_blocks blocks and apply ghash on
+ * the ciphertext
+-* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
++* %r10, %r11, %r15, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+ * are clobbered
+ * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+ */
+@@ -228,8 +229,8 @@ enc: .octa 0x2
+ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ MOVADQ SHUF_MASK(%rip), %xmm14
+ mov arg7, %r10 # %r10 = AAD
+- mov arg8, %r12 # %r12 = aadLen
+- mov %r12, %r11
++ mov arg8, %r15 # %r15 = aadLen
++ mov %r15, %r11
+ pxor %xmm\i, %xmm\i
+
+ _get_AAD_loop\num_initial_blocks\operation:
+@@ -238,17 +239,17 @@ _get_AAD_loop\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+- sub $4, %r12
++ sub $4, %r15
+ jne _get_AAD_loop\num_initial_blocks\operation
+
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+
+- mov $16, %r12
++ mov $16, %r15
+ _get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+- sub $4, %r12
+- cmp %r11, %r12
++ sub $4, %r15
++ cmp %r11, %r15
+ jne _get_AAD_loop2\num_initial_blocks\operation
+
+ _get_AAD_loop2_done\num_initial_blocks\operation:
+@@ -443,7 +444,7 @@ _initial_blocks_done\num_initial_blocks\operation:
+ * num_initial_blocks = b mod 4
+ * encrypt the initial num_initial_blocks blocks and apply ghash on
+ * the ciphertext
+-* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
++* %r10, %r11, %r15, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers
+ * are clobbered
+ * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified
+ */
+@@ -453,8 +454,8 @@ _initial_blocks_done\num_initial_blocks\operation:
+ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation
+ MOVADQ SHUF_MASK(%rip), %xmm14
+ mov arg7, %r10 # %r10 = AAD
+- mov arg8, %r12 # %r12 = aadLen
+- mov %r12, %r11
++ mov arg8, %r15 # %r15 = aadLen
++ mov %r15, %r11
+ pxor %xmm\i, %xmm\i
+ _get_AAD_loop\num_initial_blocks\operation:
+ movd (%r10), \TMP1
+@@ -462,15 +463,15 @@ _get_AAD_loop\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+ pxor \TMP1, %xmm\i
+ add $4, %r10
+- sub $4, %r12
++ sub $4, %r15
+ jne _get_AAD_loop\num_initial_blocks\operation
+ cmp $16, %r11
+ je _get_AAD_loop2_done\num_initial_blocks\operation
+- mov $16, %r12
++ mov $16, %r15
+ _get_AAD_loop2\num_initial_blocks\operation:
+ psrldq $4, %xmm\i
+- sub $4, %r12
+- cmp %r11, %r12
++ sub $4, %r15
++ cmp %r11, %r15
+ jne _get_AAD_loop2\num_initial_blocks\operation
+ _get_AAD_loop2_done\num_initial_blocks\operation:
+ PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data
+@@ -1280,8 +1281,8 @@ _esb_loop_\@:
+ * poly = x^128 + x^127 + x^126 + x^121 + 1
+ *
+ *****************************************************************************/
+-ENTRY(aesni_gcm_dec)
+- push %r12
++RAP_ENTRY(aesni_gcm_dec)
++ push %r15
+ push %r13
+ push %r14
+ mov %rsp, %r14
+@@ -1291,8 +1292,8 @@ ENTRY(aesni_gcm_dec)
+ */
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp # align rsp to 64 bytes
+- mov %arg6, %r12
+- movdqu (%r12), %xmm13 # %xmm13 = HashKey
++ mov %arg6, %r15
++ movdqu (%r15), %xmm13 # %xmm13 = HashKey
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+@@ -1320,10 +1321,10 @@ ENTRY(aesni_gcm_dec)
+ movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly)
+ mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext
+ and $-16, %r13 # %r13 = %r13 - (%r13 mod 16)
+- mov %r13, %r12
+- and $(3<<4), %r12
++ mov %r13, %r15
++ and $(3<<4), %r15
+ jz _initial_num_blocks_is_0_decrypt
+- cmp $(2<<4), %r12
++ cmp $(2<<4), %r15
+ jb _initial_num_blocks_is_1_decrypt
+ je _initial_num_blocks_is_2_decrypt
+ _initial_num_blocks_is_3_decrypt:
+@@ -1373,16 +1374,16 @@ _zero_cipher_left_decrypt:
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte block
+- lea SHIFT_MASK+16(%rip), %r12
+- sub %r13, %r12
++ lea SHIFT_MASK+16(%rip), %r15
++ sub %r13, %r15
+ # adjust the shuffle mask pointer to be able to shift 16-%r13 bytes
+ # (%r13 is the number of bytes in plaintext mod 16)
+- movdqu (%r12), %xmm2 # get the appropriate shuffle mask
++ movdqu (%r15), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes
+
+ movdqa %xmm1, %xmm2
+ pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn)
+- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
++ movdqu ALL_F-SHIFT_MASK(%r15), %xmm1
+ # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0
+ pand %xmm1, %xmm2
+@@ -1411,9 +1412,9 @@ _less_than_8_bytes_left_decrypt:
+ sub $1, %r13
+ jne _less_than_8_bytes_left_decrypt
+ _multiple_of_16_bytes_decrypt:
+- mov arg8, %r12 # %r13 = aadLen (number of bytes)
+- shl $3, %r12 # convert into number of bits
+- movd %r12d, %xmm15 # len(A) in %xmm15
++ mov arg8, %r15 # %r13 = aadLen (number of bytes)
++ shl $3, %r15 # convert into number of bits
++ movd %r15d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+@@ -1452,7 +1453,8 @@ _return_T_done_decrypt:
+ mov %r14, %rsp
+ pop %r14
+ pop %r13
+- pop %r12
++ pop %r15
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_gcm_dec)
+
+@@ -1540,8 +1542,8 @@ ENDPROC(aesni_gcm_dec)
+ *
+ * poly = x^128 + x^127 + x^126 + x^121 + 1
+ ***************************************************************************/
+-ENTRY(aesni_gcm_enc)
+- push %r12
++RAP_ENTRY(aesni_gcm_enc)
++ push %r15
+ push %r13
+ push %r14
+ mov %rsp, %r14
+@@ -1551,8 +1553,8 @@ ENTRY(aesni_gcm_enc)
+ #
+ sub $VARIABLE_OFFSET, %rsp
+ and $~63, %rsp
+- mov %arg6, %r12
+- movdqu (%r12), %xmm13
++ mov %arg6, %r15
++ movdqu (%r15), %xmm13
+ movdqa SHUF_MASK(%rip), %xmm2
+ PSHUFB_XMM %xmm2, %xmm13
+
+@@ -1576,13 +1578,13 @@ ENTRY(aesni_gcm_enc)
+ movdqa %xmm13, HashKey(%rsp)
+ mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly)
+ and $-16, %r13
+- mov %r13, %r12
++ mov %r13, %r15
+
+ # Encrypt first few blocks
+
+- and $(3<<4), %r12
++ and $(3<<4), %r15
+ jz _initial_num_blocks_is_0_encrypt
+- cmp $(2<<4), %r12
++ cmp $(2<<4), %r15
+ jb _initial_num_blocks_is_1_encrypt
+ je _initial_num_blocks_is_2_encrypt
+ _initial_num_blocks_is_3_encrypt:
+@@ -1635,14 +1637,14 @@ _zero_cipher_left_encrypt:
+ sub $16, %r11
+ add %r13, %r11
+ movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks
+- lea SHIFT_MASK+16(%rip), %r12
+- sub %r13, %r12
++ lea SHIFT_MASK+16(%rip), %r15
++ sub %r13, %r15
+ # adjust the shuffle mask pointer to be able to shift 16-r13 bytes
+ # (%r13 is the number of bytes in plaintext mod 16)
+- movdqu (%r12), %xmm2 # get the appropriate shuffle mask
++ movdqu (%r15), %xmm2 # get the appropriate shuffle mask
+ PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte
+ pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn)
+- movdqu ALL_F-SHIFT_MASK(%r12), %xmm1
++ movdqu ALL_F-SHIFT_MASK(%r15), %xmm1
+ # get the appropriate mask to mask out top 16-r13 bytes of xmm0
+ pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0
+ movdqa SHUF_MASK(%rip), %xmm10
+@@ -1675,9 +1677,9 @@ _less_than_8_bytes_left_encrypt:
+ sub $1, %r13
+ jne _less_than_8_bytes_left_encrypt
+ _multiple_of_16_bytes_encrypt:
+- mov arg8, %r12 # %r12 = addLen (number of bytes)
+- shl $3, %r12
+- movd %r12d, %xmm15 # len(A) in %xmm15
++ mov arg8, %r15 # %r15 = addLen (number of bytes)
++ shl $3, %r15
++ movd %r15d, %xmm15 # len(A) in %xmm15
+ shl $3, %arg4 # len(C) in bits (*128)
+ MOVQ_R64_XMM %arg4, %xmm1
+ pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000
+@@ -1716,7 +1718,8 @@ _return_T_done_encrypt:
+ mov %r14, %rsp
+ pop %r14
+ pop %r13
+- pop %r12
++ pop %r15
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_gcm_enc)
+
+@@ -1734,6 +1737,7 @@ _key_expansion_256a:
+ pxor %xmm1, %xmm0
+ movaps %xmm0, (TKEYP)
+ add $0x10, TKEYP
++ pax_force_retaddr
+ ret
+ ENDPROC(_key_expansion_128)
+ ENDPROC(_key_expansion_256a)
+@@ -1760,6 +1764,7 @@ _key_expansion_192a:
+ shufps $0b01001110, %xmm2, %xmm1
+ movaps %xmm1, 0x10(TKEYP)
+ add $0x20, TKEYP
++ pax_force_retaddr
+ ret
+ ENDPROC(_key_expansion_192a)
+
+@@ -1780,6 +1785,7 @@ _key_expansion_192b:
+
+ movaps %xmm0, (TKEYP)
+ add $0x10, TKEYP
++ pax_force_retaddr
+ ret
+ ENDPROC(_key_expansion_192b)
+
+@@ -1793,6 +1799,7 @@ _key_expansion_256b:
+ pxor %xmm1, %xmm2
+ movaps %xmm2, (TKEYP)
+ add $0x10, TKEYP
++ pax_force_retaddr
+ ret
+ ENDPROC(_key_expansion_256b)
+
+@@ -1908,13 +1915,14 @@ ENTRY(aesni_set_key)
+ popl KEYP
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_set_key)
+
+ /*
+ * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+-ENTRY(aesni_enc)
++RAP_ENTRY(aesni_enc)
+ FRAME_BEGIN
+ #ifndef __x86_64__
+ pushl KEYP
+@@ -1932,6 +1940,7 @@ ENTRY(aesni_enc)
+ popl KEYP
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_enc)
+
+@@ -1990,6 +1999,7 @@ _aesni_enc1:
+ AESENC KEY STATE
+ movaps 0x70(TKEYP), KEY
+ AESENCLAST KEY STATE
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_enc1)
+
+@@ -2099,13 +2109,14 @@ _aesni_enc4:
+ AESENCLAST KEY STATE2
+ AESENCLAST KEY STATE3
+ AESENCLAST KEY STATE4
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_enc4)
+
+ /*
+ * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+-ENTRY(aesni_dec)
++RAP_ENTRY(aesni_dec)
+ FRAME_BEGIN
+ #ifndef __x86_64__
+ pushl KEYP
+@@ -2124,6 +2135,7 @@ ENTRY(aesni_dec)
+ popl KEYP
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_dec)
+
+@@ -2182,6 +2194,7 @@ _aesni_dec1:
+ AESDEC KEY STATE
+ movaps 0x70(TKEYP), KEY
+ AESDECLAST KEY STATE
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_dec1)
+
+@@ -2291,6 +2304,7 @@ _aesni_dec4:
+ AESDECLAST KEY STATE2
+ AESDECLAST KEY STATE3
+ AESDECLAST KEY STATE4
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_dec4)
+
+@@ -2351,6 +2365,7 @@ ENTRY(aesni_ecb_enc)
+ popl LEN
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_ecb_enc)
+
+@@ -2412,6 +2427,7 @@ ENTRY(aesni_ecb_dec)
+ popl LEN
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_ecb_dec)
+
+@@ -2456,6 +2472,7 @@ ENTRY(aesni_cbc_enc)
+ popl IVP
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_cbc_enc)
+
+@@ -2549,6 +2566,7 @@ ENTRY(aesni_cbc_dec)
+ popl IVP
+ #endif
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_cbc_dec)
+
+@@ -2578,6 +2596,7 @@ _aesni_inc_init:
+ mov $1, TCTR_LOW
+ MOVQ_R64_XMM TCTR_LOW INC
+ MOVQ_R64_XMM CTR TCTR_LOW
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_inc_init)
+
+@@ -2607,6 +2626,7 @@ _aesni_inc:
+ .Linc_low:
+ movaps CTR, IV
+ PSHUFB_XMM BSWAP_MASK IV
++ pax_force_retaddr
+ ret
+ ENDPROC(_aesni_inc)
+
+@@ -2614,7 +2634,7 @@ ENDPROC(_aesni_inc)
+ * void aesni_ctr_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ * size_t len, u8 *iv)
+ */
+-ENTRY(aesni_ctr_enc)
++RAP_ENTRY(aesni_ctr_enc)
+ FRAME_BEGIN
+ cmp $16, LEN
+ jb .Lctr_enc_just_ret
+@@ -2670,6 +2690,7 @@ ENTRY(aesni_ctr_enc)
+ movups IV, (IVP)
+ .Lctr_enc_just_ret:
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_ctr_enc)
+
+@@ -2798,6 +2819,7 @@ ENTRY(aesni_xts_crypt8)
+ movdqu STATE4, 0x70(OUTP)
+
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(aesni_xts_crypt8)
+
+diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
+index 5b7fa14..fb27be1 100644
+--- a/arch/x86/crypto/aesni-intel_glue.c
++++ b/arch/x86/crypto/aesni-intel_glue.c
+@@ -82,9 +82,9 @@ struct aesni_xts_ctx {
+
+ asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ unsigned int key_len);
+-asmlinkage void aesni_enc(struct crypto_aes_ctx *ctx, u8 *out,
++asmlinkage void aesni_enc(void *ctx, u8 *out,
+ const u8 *in);
+-asmlinkage void aesni_dec(struct crypto_aes_ctx *ctx, u8 *out,
++asmlinkage void aesni_dec(void *ctx, u8 *out,
+ const u8 *in);
+ asmlinkage void aesni_ecb_enc(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len);
+diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S b/arch/x86/crypto/blowfish-x86_64-asm_64.S
+index 246c670..4fb7603 100644
+--- a/arch/x86/crypto/blowfish-x86_64-asm_64.S
++++ b/arch/x86/crypto/blowfish-x86_64-asm_64.S
+@@ -21,6 +21,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .file "blowfish-x86_64-asm.S"
+ .text
+@@ -149,13 +150,15 @@ ENTRY(__blowfish_enc_blk)
+ jnz .L__enc_xor;
+
+ write_block();
++ pax_force_retaddr
+ ret;
+ .L__enc_xor:
+ xor_block();
++ pax_force_retaddr
+ ret;
+ ENDPROC(__blowfish_enc_blk)
+
+-ENTRY(blowfish_dec_blk)
++RAP_ENTRY(blowfish_dec_blk)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -183,6 +186,7 @@ ENTRY(blowfish_dec_blk)
+
+ movq %r11, %rbp;
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(blowfish_dec_blk)
+
+@@ -334,6 +338,7 @@ ENTRY(__blowfish_enc_blk_4way)
+
+ popq %rbx;
+ popq %rbp;
++ pax_force_retaddr
+ ret;
+
+ .L__enc_xor4:
+@@ -341,10 +346,11 @@ ENTRY(__blowfish_enc_blk_4way)
+
+ popq %rbx;
+ popq %rbp;
++ pax_force_retaddr
+ ret;
+ ENDPROC(__blowfish_enc_blk_4way)
+
+-ENTRY(blowfish_dec_blk_4way)
++RAP_ENTRY(blowfish_dec_blk_4way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -375,5 +381,6 @@ ENTRY(blowfish_dec_blk_4way)
+ popq %rbx;
+ popq %rbp;
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(blowfish_dec_blk_4way)
+diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+index aa9e8bd..0b8def4 100644
+--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+@@ -17,6 +17,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+
+@@ -192,6 +193,7 @@ roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15,
+ %rcx, (%r9));
++ pax_force_retaddr
+ ret;
+ ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+
+@@ -200,6 +202,7 @@ roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3,
+ %xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11,
+ %rax, (%r9));
++ pax_force_retaddr
+ ret;
+ ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+
+@@ -783,6 +786,7 @@ __camellia_enc_blk16:
+ %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+
+ .align 8
+@@ -870,6 +874,7 @@ __camellia_dec_blk16:
+ %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+
+ .align 8
+@@ -889,7 +894,7 @@ __camellia_dec_blk16:
+ jmp .Ldec_max24;
+ ENDPROC(__camellia_dec_blk16)
+
+-ENTRY(camellia_ecb_enc_16way)
++RAP_ENTRY(camellia_ecb_enc_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -911,10 +916,11 @@ ENTRY(camellia_ecb_enc_16way)
+ %xmm8, %rsi);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ecb_enc_16way)
+
+-ENTRY(camellia_ecb_dec_16way)
++RAP_ENTRY(camellia_ecb_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -941,10 +947,11 @@ ENTRY(camellia_ecb_dec_16way)
+ %xmm8, %rsi);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ecb_dec_16way)
+
+-ENTRY(camellia_cbc_dec_16way)
++RAP_ENTRY(camellia_cbc_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -992,6 +999,7 @@ ENTRY(camellia_cbc_dec_16way)
+ %xmm8, %rsi);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_cbc_dec_16way)
+
+@@ -1001,7 +1009,7 @@ ENDPROC(camellia_cbc_dec_16way)
+ vpslldq $8, tmp, tmp; \
+ vpsubq tmp, x, x;
+
+-ENTRY(camellia_ctr_16way)
++RAP_ENTRY(camellia_ctr_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -1105,6 +1113,7 @@ ENTRY(camellia_ctr_16way)
+ %xmm8, %rsi);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ctr_16way)
+
+@@ -1249,10 +1258,11 @@ camellia_xts_crypt_16way:
+ %xmm8, %rsi);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_xts_crypt_16way)
+
+-ENTRY(camellia_xts_enc_16way)
++RAP_ENTRY(camellia_xts_enc_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -1266,7 +1276,7 @@ ENTRY(camellia_xts_enc_16way)
+ jmp camellia_xts_crypt_16way;
+ ENDPROC(camellia_xts_enc_16way)
+
+-ENTRY(camellia_xts_dec_16way)
++RAP_ENTRY(camellia_xts_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+index 16186c1..3468f83 100644
+--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+@@ -12,6 +12,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+
+@@ -231,6 +232,7 @@ roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15,
+ %rcx, (%r9));
++ pax_force_retaddr
+ ret;
+ ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+
+@@ -239,6 +241,7 @@ roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3,
+ %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11,
+ %rax, (%r9));
++ pax_force_retaddr
+ ret;
+ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+
+@@ -823,6 +826,7 @@ __camellia_enc_blk32:
+ %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+
+ .align 8
+@@ -910,6 +914,7 @@ __camellia_dec_blk32:
+ %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+
+ .align 8
+@@ -929,7 +934,7 @@ __camellia_dec_blk32:
+ jmp .Ldec_max24;
+ ENDPROC(__camellia_dec_blk32)
+
+-ENTRY(camellia_ecb_enc_32way)
++RAP_ENTRY(camellia_ecb_enc_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+@@ -955,10 +960,11 @@ ENTRY(camellia_ecb_enc_32way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ecb_enc_32way)
+
+-ENTRY(camellia_ecb_dec_32way)
++RAP_ENTRY(camellia_ecb_dec_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+@@ -989,10 +995,11 @@ ENTRY(camellia_ecb_dec_32way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ecb_dec_32way)
+
+-ENTRY(camellia_cbc_dec_32way)
++RAP_ENTRY(camellia_cbc_dec_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+@@ -1057,6 +1064,7 @@ ENTRY(camellia_cbc_dec_32way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_cbc_dec_32way)
+
+@@ -1074,7 +1082,7 @@ ENDPROC(camellia_cbc_dec_32way)
+ vpslldq $8, tmp1, tmp1; \
+ vpsubq tmp1, x, x;
+
+-ENTRY(camellia_ctr_32way)
++RAP_ENTRY(camellia_ctr_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+@@ -1197,6 +1205,7 @@ ENTRY(camellia_ctr_32way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_ctr_32way)
+
+@@ -1364,10 +1373,11 @@ camellia_xts_crypt_32way:
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_xts_crypt_32way)
+
+-ENTRY(camellia_xts_enc_32way)
++RAP_ENTRY(camellia_xts_enc_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+@@ -1382,7 +1392,7 @@ ENTRY(camellia_xts_enc_32way)
+ jmp camellia_xts_crypt_32way;
+ ENDPROC(camellia_xts_enc_32way)
+
+-ENTRY(camellia_xts_dec_32way)
++RAP_ENTRY(camellia_xts_dec_32way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (32 blocks)
+diff --git a/arch/x86/crypto/camellia-x86_64-asm_64.S b/arch/x86/crypto/camellia-x86_64-asm_64.S
+index 310319c..9253a8f 100644
+--- a/arch/x86/crypto/camellia-x86_64-asm_64.S
++++ b/arch/x86/crypto/camellia-x86_64-asm_64.S
+@@ -21,6 +21,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .file "camellia-x86_64-asm_64.S"
+ .text
+@@ -228,16 +229,18 @@ ENTRY(__camellia_enc_blk)
+ enc_outunpack(mov, RT1);
+
+ movq RRBP, %rbp;
++ pax_force_retaddr
+ ret;
+
+ .L__enc_xor:
+ enc_outunpack(xor, RT1);
+
+ movq RRBP, %rbp;
++ pax_force_retaddr
+ ret;
+ ENDPROC(__camellia_enc_blk)
+
+-ENTRY(camellia_dec_blk)
++RAP_ENTRY(camellia_dec_blk)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -272,6 +275,7 @@ ENTRY(camellia_dec_blk)
+ dec_outunpack();
+
+ movq RRBP, %rbp;
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_dec_blk)
+
+@@ -463,6 +467,7 @@ ENTRY(__camellia_enc_blk_2way)
+
+ movq RRBP, %rbp;
+ popq %rbx;
++ pax_force_retaddr
+ ret;
+
+ .L__enc2_xor:
+@@ -470,10 +475,11 @@ ENTRY(__camellia_enc_blk_2way)
+
+ movq RRBP, %rbp;
+ popq %rbx;
++ pax_force_retaddr
+ ret;
+ ENDPROC(__camellia_enc_blk_2way)
+
+-ENTRY(camellia_dec_blk_2way)
++RAP_ENTRY(camellia_dec_blk_2way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -510,5 +516,6 @@ ENTRY(camellia_dec_blk_2way)
+
+ movq RRBP, %rbp;
+ movq RXOR, %rbx;
++ pax_force_retaddr
+ ret;
+ ENDPROC(camellia_dec_blk_2way)
+diff --git a/arch/x86/crypto/camellia_aesni_avx2_glue.c b/arch/x86/crypto/camellia_aesni_avx2_glue.c
+index 60907c1..fe8638d 100644
+--- a/arch/x86/crypto/camellia_aesni_avx2_glue.c
++++ b/arch/x86/crypto/camellia_aesni_avx2_glue.c
+@@ -27,20 +27,20 @@
+ #define CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS 32
+
+ /* 32-way AVX2/AES-NI parallel cipher functions */
+-asmlinkage void camellia_ecb_enc_32way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_ecb_enc_32way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void camellia_ecb_dec_32way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_ecb_dec_32way(void *ctx, u8 *dst,
+ const u8 *src);
+
+-asmlinkage void camellia_cbc_dec_32way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_cbc_dec_32way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void camellia_ctr_32way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void camellia_ctr_32way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+-asmlinkage void camellia_xts_enc_32way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
+-asmlinkage void camellia_xts_dec_32way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void camellia_xts_enc_32way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
++asmlinkage void camellia_xts_dec_32way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+ static const struct common_glue_ctx camellia_enc = {
+ .num_funcs = 4,
+diff --git a/arch/x86/crypto/camellia_aesni_avx_glue.c b/arch/x86/crypto/camellia_aesni_avx_glue.c
+index d96429d..18ab2e6 100644
+--- a/arch/x86/crypto/camellia_aesni_avx_glue.c
++++ b/arch/x86/crypto/camellia_aesni_avx_glue.c
+@@ -26,28 +26,28 @@
+ #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16
+
+ /* 16-way parallel cipher functions (avx/aes-ni) */
+-asmlinkage void camellia_ecb_enc_16way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_ecb_enc_16way(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(camellia_ecb_enc_16way);
+
+-asmlinkage void camellia_ecb_dec_16way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_ecb_dec_16way(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(camellia_ecb_dec_16way);
+
+-asmlinkage void camellia_cbc_dec_16way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_cbc_dec_16way(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(camellia_cbc_dec_16way);
+
+-asmlinkage void camellia_ctr_16way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void camellia_ctr_16way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(camellia_ctr_16way);
+
+-asmlinkage void camellia_xts_enc_16way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void camellia_xts_enc_16way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(camellia_xts_enc_16way);
+
+-asmlinkage void camellia_xts_dec_16way(struct camellia_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void camellia_xts_dec_16way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(camellia_xts_dec_16way);
+
+ void camellia_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
+diff --git a/arch/x86/crypto/camellia_glue.c b/arch/x86/crypto/camellia_glue.c
+index aa76cad..ffd8808 100644
+--- a/arch/x86/crypto/camellia_glue.c
++++ b/arch/x86/crypto/camellia_glue.c
+@@ -39,7 +39,7 @@
+ asmlinkage void __camellia_enc_blk(struct camellia_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+ EXPORT_SYMBOL_GPL(__camellia_enc_blk);
+-asmlinkage void camellia_dec_blk(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_dec_blk(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(camellia_dec_blk);
+
+@@ -47,7 +47,7 @@ EXPORT_SYMBOL_GPL(camellia_dec_blk);
+ asmlinkage void __camellia_enc_blk_2way(struct camellia_ctx *ctx, u8 *dst,
+ const u8 *src, bool xor);
+ EXPORT_SYMBOL_GPL(__camellia_enc_blk_2way);
+-asmlinkage void camellia_dec_blk_2way(struct camellia_ctx *ctx, u8 *dst,
++asmlinkage void camellia_dec_blk_2way(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(camellia_dec_blk_2way);
+
+@@ -1279,8 +1279,10 @@ static int camellia_setkey(struct crypto_tfm *tfm, const u8 *in_key,
+ &tfm->crt_flags);
+ }
+
+-void camellia_decrypt_cbc_2way(void *ctx, u128 *dst, const u128 *src)
++void camellia_decrypt_cbc_2way(void *ctx, u8 *_dst, const u8 *_src)
+ {
++ u128 *dst = (u128 *)_dst;
++ u128 *src = (u128 *)_src;
+ u128 iv = *src;
+
+ camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src);
+diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+index 14fa196..5de8a4a 100644
+--- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+@@ -25,6 +25,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+
+ .file "cast5-avx-x86_64-asm_64.S"
+
+@@ -282,6 +283,7 @@ __cast5_enc_blk16:
+ outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
+ outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__cast5_enc_blk16)
+
+@@ -353,6 +355,7 @@ __cast5_dec_blk16:
+ outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
+ outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
+
++ pax_force_retaddr
+ ret;
+
+ .L__skip_dec:
+@@ -360,7 +363,7 @@ __cast5_dec_blk16:
+ jmp .L__dec_tail;
+ ENDPROC(__cast5_dec_blk16)
+
+-ENTRY(cast5_ecb_enc_16way)
++RAP_ENTRY(cast5_ecb_enc_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -391,10 +394,11 @@ ENTRY(cast5_ecb_enc_16way)
+ vmovdqu RL4, (7*4*4)(%r11);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast5_ecb_enc_16way)
+
+-ENTRY(cast5_ecb_dec_16way)
++RAP_ENTRY(cast5_ecb_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -425,6 +429,7 @@ ENTRY(cast5_ecb_dec_16way)
+ vmovdqu RL4, (7*4*4)(%r11);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast5_ecb_dec_16way)
+
+@@ -436,10 +441,10 @@ ENTRY(cast5_cbc_dec_16way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ vmovdqu (0*16)(%rdx), RL1;
+ vmovdqu (1*16)(%rdx), RR1;
+@@ -453,16 +458,16 @@ ENTRY(cast5_cbc_dec_16way)
+ call __cast5_dec_blk16;
+
+ /* xor with src */
+- vmovq (%r12), RX;
++ vmovq (%r14), RX;
+ vpshufd $0x4f, RX, RX;
+ vpxor RX, RR1, RR1;
+- vpxor 0*16+8(%r12), RL1, RL1;
+- vpxor 1*16+8(%r12), RR2, RR2;
+- vpxor 2*16+8(%r12), RL2, RL2;
+- vpxor 3*16+8(%r12), RR3, RR3;
+- vpxor 4*16+8(%r12), RL3, RL3;
+- vpxor 5*16+8(%r12), RR4, RR4;
+- vpxor 6*16+8(%r12), RL4, RL4;
++ vpxor 0*16+8(%r14), RL1, RL1;
++ vpxor 1*16+8(%r14), RR2, RR2;
++ vpxor 2*16+8(%r14), RL2, RL2;
++ vpxor 3*16+8(%r14), RR3, RR3;
++ vpxor 4*16+8(%r14), RL3, RL3;
++ vpxor 5*16+8(%r14), RR4, RR4;
++ vpxor 6*16+8(%r14), RL4, RL4;
+
+ vmovdqu RR1, (0*16)(%r11);
+ vmovdqu RL1, (1*16)(%r11);
+@@ -473,9 +478,10 @@ ENTRY(cast5_cbc_dec_16way)
+ vmovdqu RR4, (6*16)(%r11);
+ vmovdqu RL4, (7*16)(%r11);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast5_cbc_dec_16way)
+
+@@ -488,10 +494,10 @@ ENTRY(cast5_ctr_16way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ vpcmpeqd RTMP, RTMP, RTMP;
+ vpsrldq $8, RTMP, RTMP; /* low: -1, high: 0 */
+@@ -531,14 +537,14 @@ ENTRY(cast5_ctr_16way)
+ call __cast5_enc_blk16;
+
+ /* dst = src ^ iv */
+- vpxor (0*16)(%r12), RR1, RR1;
+- vpxor (1*16)(%r12), RL1, RL1;
+- vpxor (2*16)(%r12), RR2, RR2;
+- vpxor (3*16)(%r12), RL2, RL2;
+- vpxor (4*16)(%r12), RR3, RR3;
+- vpxor (5*16)(%r12), RL3, RL3;
+- vpxor (6*16)(%r12), RR4, RR4;
+- vpxor (7*16)(%r12), RL4, RL4;
++ vpxor (0*16)(%r14), RR1, RR1;
++ vpxor (1*16)(%r14), RL1, RL1;
++ vpxor (2*16)(%r14), RR2, RR2;
++ vpxor (3*16)(%r14), RL2, RL2;
++ vpxor (4*16)(%r14), RR3, RR3;
++ vpxor (5*16)(%r14), RL3, RL3;
++ vpxor (6*16)(%r14), RR4, RR4;
++ vpxor (7*16)(%r14), RL4, RL4;
+ vmovdqu RR1, (0*16)(%r11);
+ vmovdqu RL1, (1*16)(%r11);
+ vmovdqu RR2, (2*16)(%r11);
+@@ -548,8 +554,9 @@ ENTRY(cast5_ctr_16way)
+ vmovdqu RR4, (6*16)(%r11);
+ vmovdqu RL4, (7*16)(%r11);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast5_ctr_16way)
+diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+index c419389..b853452 100644
+--- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+@@ -25,6 +25,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+
+ .file "cast6-avx-x86_64-asm_64.S"
+@@ -296,6 +297,7 @@ __cast6_enc_blk8:
+ outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__cast6_enc_blk8)
+
+@@ -341,10 +343,11 @@ __cast6_dec_blk8:
+ outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
+ outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__cast6_dec_blk8)
+
+-ENTRY(cast6_ecb_enc_8way)
++RAP_ENTRY(cast6_ecb_enc_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -361,10 +364,11 @@ ENTRY(cast6_ecb_enc_8way)
+ store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_ecb_enc_8way)
+
+-ENTRY(cast6_ecb_dec_8way)
++RAP_ENTRY(cast6_ecb_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -381,10 +385,11 @@ ENTRY(cast6_ecb_dec_8way)
+ store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_ecb_dec_8way)
+
+-ENTRY(cast6_cbc_dec_8way)
++RAP_ENTRY(cast6_cbc_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -392,24 +397,25 @@ ENTRY(cast6_cbc_dec_8way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ call __cast6_dec_blk8;
+
+- store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_cbc_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_cbc_dec_8way)
+
+-ENTRY(cast6_ctr_8way)
++RAP_ENTRY(cast6_ctr_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -418,25 +424,26 @@ ENTRY(cast6_ctr_8way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2,
+ RD2, RX, RKR, RKM);
+
+ call __cast6_enc_blk8;
+
+- store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_ctr_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_ctr_8way)
+
+-ENTRY(cast6_xts_enc_8way)
++RAP_ENTRY(cast6_xts_enc_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -457,10 +464,11 @@ ENTRY(cast6_xts_enc_8way)
+ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_xts_enc_8way)
+
+-ENTRY(cast6_xts_dec_8way)
++RAP_ENTRY(cast6_xts_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -481,5 +489,6 @@ ENTRY(cast6_xts_dec_8way)
+ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(cast6_xts_dec_8way)
+diff --git a/arch/x86/crypto/cast6_avx_glue.c b/arch/x86/crypto/cast6_avx_glue.c
+index 50e6847..bf7c2d8 100644
+--- a/arch/x86/crypto/cast6_avx_glue.c
++++ b/arch/x86/crypto/cast6_avx_glue.c
+@@ -41,20 +41,20 @@
+
+ #define CAST6_PARALLEL_BLOCKS 8
+
+-asmlinkage void cast6_ecb_enc_8way(struct cast6_ctx *ctx, u8 *dst,
++asmlinkage void cast6_ecb_enc_8way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void cast6_ecb_dec_8way(struct cast6_ctx *ctx, u8 *dst,
++asmlinkage void cast6_ecb_dec_8way(void *ctx, u8 *dst,
+ const u8 *src);
+
+-asmlinkage void cast6_cbc_dec_8way(struct cast6_ctx *ctx, u8 *dst,
++asmlinkage void cast6_cbc_dec_8way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void cast6_ctr_8way(struct cast6_ctx *ctx, u8 *dst, const u8 *src,
++asmlinkage void cast6_ctr_8way(void *ctx, u128 *dst, const u128 *src,
+ le128 *iv);
+
+-asmlinkage void cast6_xts_enc_8way(struct cast6_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
+-asmlinkage void cast6_xts_dec_8way(struct cast6_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void cast6_xts_enc_8way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
++asmlinkage void cast6_xts_dec_8way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+ static void cast6_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
+ {
+diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+index dc05f010..23c8bfd 100644
+--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
++++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+@@ -45,6 +45,7 @@
+
+ #include <asm/inst.h>
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
+
+@@ -309,6 +310,7 @@ do_return:
+ popq %rsi
+ popq %rdi
+ popq %rbx
++ pax_force_retaddr
+ ret
+ ENDPROC(crc_pcl)
+
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+index eed55c8..b354187 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
++++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+@@ -19,6 +19,7 @@
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+
+ .data
+
+@@ -90,6 +91,7 @@ __clmul_gf128mul_ble:
+ psrlq $1, T2
+ pxor T2, T1
+ pxor T1, DATA
++ pax_force_retaddr
+ ret
+ ENDPROC(__clmul_gf128mul_ble)
+
+@@ -104,6 +106,7 @@ ENTRY(clmul_ghash_mul)
+ PSHUFB_XMM BSWAP DATA
+ movups DATA, (%rdi)
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(clmul_ghash_mul)
+
+@@ -133,5 +136,6 @@ ENTRY(clmul_ghash_update)
+ movups DATA, (%rdi)
+ .Lupdate_just_ret:
+ FRAME_END
++ pax_force_retaddr
+ ret
+ ENDPROC(clmul_ghash_update)
+diff --git a/arch/x86/crypto/glue_helper.c b/arch/x86/crypto/glue_helper.c
+index 6a85598..fed2ada 100644
+--- a/arch/x86/crypto/glue_helper.c
++++ b/arch/x86/crypto/glue_helper.c
+@@ -165,7 +165,7 @@ __glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx,
+ src -= num_blocks - 1;
+ dst -= num_blocks - 1;
+
+- gctx->funcs[i].fn_u.cbc(ctx, dst, src);
++ gctx->funcs[i].fn_u.cbc(ctx, (u8 *)dst, (u8 *)src);
+
+ nbytes -= bsize;
+ if (nbytes < bsize)
+diff --git a/arch/x86/crypto/salsa20-x86_64-asm_64.S b/arch/x86/crypto/salsa20-x86_64-asm_64.S
+index 9279e0b..c4b3d2c 100644
+--- a/arch/x86/crypto/salsa20-x86_64-asm_64.S
++++ b/arch/x86/crypto/salsa20-x86_64-asm_64.S
+@@ -1,4 +1,5 @@
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ # enter salsa20_encrypt_bytes
+ ENTRY(salsa20_encrypt_bytes)
+@@ -789,6 +790,7 @@ ENTRY(salsa20_encrypt_bytes)
+ add %r11,%rsp
+ mov %rdi,%rax
+ mov %rsi,%rdx
++ pax_force_retaddr
+ ret
+ # bytesatleast65:
+ ._bytesatleast65:
+@@ -889,6 +891,7 @@ ENTRY(salsa20_keysetup)
+ add %r11,%rsp
+ mov %rdi,%rax
+ mov %rsi,%rdx
++ pax_force_retaddr
+ ret
+ ENDPROC(salsa20_keysetup)
+
+@@ -914,5 +917,6 @@ ENTRY(salsa20_ivsetup)
+ add %r11,%rsp
+ mov %rdi,%rax
+ mov %rsi,%rdx
++ pax_force_retaddr
+ ret
+ ENDPROC(salsa20_ivsetup)
+diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
+index 8be5718..d2bcbcd 100644
+--- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
+@@ -25,6 +25,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+
+ .file "serpent-avx-x86_64-asm_64.S"
+@@ -619,6 +620,7 @@ __serpent_enc_blk8_avx:
+ write_blocks(RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__serpent_enc_blk8_avx)
+
+@@ -673,10 +675,11 @@ __serpent_dec_blk8_avx:
+ write_blocks(RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__serpent_dec_blk8_avx)
+
+-ENTRY(serpent_ecb_enc_8way_avx)
++RAP_ENTRY(serpent_ecb_enc_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -691,10 +694,11 @@ ENTRY(serpent_ecb_enc_8way_avx)
+ store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ecb_enc_8way_avx)
+
+-ENTRY(serpent_ecb_dec_8way_avx)
++RAP_ENTRY(serpent_ecb_dec_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -709,10 +713,11 @@ ENTRY(serpent_ecb_dec_8way_avx)
+ store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ecb_dec_8way_avx)
+
+-ENTRY(serpent_cbc_dec_8way_avx)
++RAP_ENTRY(serpent_cbc_dec_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -727,10 +732,11 @@ ENTRY(serpent_cbc_dec_8way_avx)
+ store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_cbc_dec_8way_avx)
+
+-ENTRY(serpent_ctr_8way_avx)
++RAP_ENTRY(serpent_ctr_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -747,10 +753,11 @@ ENTRY(serpent_ctr_8way_avx)
+ store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ctr_8way_avx)
+
+-ENTRY(serpent_xts_enc_8way_avx)
++RAP_ENTRY(serpent_xts_enc_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -769,10 +776,11 @@ ENTRY(serpent_xts_enc_8way_avx)
+ store_xts_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_xts_enc_8way_avx)
+
+-ENTRY(serpent_xts_dec_8way_avx)
++RAP_ENTRY(serpent_xts_dec_8way_avx)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -791,5 +799,6 @@ ENTRY(serpent_xts_dec_8way_avx)
+ store_xts_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_xts_dec_8way_avx)
+diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S
+index 97c48ad..25416de 100644
+--- a/arch/x86/crypto/serpent-avx2-asm_64.S
++++ b/arch/x86/crypto/serpent-avx2-asm_64.S
+@@ -16,6 +16,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx2.S"
+
+ .file "serpent-avx2-asm_64.S"
+@@ -611,6 +612,7 @@ __serpent_enc_blk16:
+ write_blocks(RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__serpent_enc_blk16)
+
+@@ -665,10 +667,11 @@ __serpent_dec_blk16:
+ write_blocks(RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__serpent_dec_blk16)
+
+-ENTRY(serpent_ecb_enc_16way)
++RAP_ENTRY(serpent_ecb_enc_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -687,10 +690,11 @@ ENTRY(serpent_ecb_enc_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ecb_enc_16way)
+
+-ENTRY(serpent_ecb_dec_16way)
++RAP_ENTRY(serpent_ecb_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -709,10 +713,11 @@ ENTRY(serpent_ecb_dec_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ecb_dec_16way)
+
+-ENTRY(serpent_cbc_dec_16way)
++RAP_ENTRY(serpent_cbc_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -732,10 +737,11 @@ ENTRY(serpent_cbc_dec_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_cbc_dec_16way)
+
+-ENTRY(serpent_ctr_16way)
++RAP_ENTRY(serpent_ctr_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -757,10 +763,11 @@ ENTRY(serpent_ctr_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_ctr_16way)
+
+-ENTRY(serpent_xts_enc_16way)
++RAP_ENTRY(serpent_xts_enc_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -783,10 +790,11 @@ ENTRY(serpent_xts_enc_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_xts_enc_16way)
+
+-ENTRY(serpent_xts_dec_16way)
++RAP_ENTRY(serpent_xts_dec_16way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst (16 blocks)
+@@ -809,5 +817,6 @@ ENTRY(serpent_xts_dec_16way)
+ vzeroupper;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_xts_dec_16way)
+diff --git a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
+index acc066c..1559cc4 100644
+--- a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
++++ b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
+@@ -25,6 +25,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .file "serpent-sse2-x86_64-asm_64.S"
+ .text
+@@ -690,12 +691,14 @@ ENTRY(__serpent_enc_blk_8way)
+ write_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ write_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+
+ .L__enc_xor8:
+ xor_blocks(%rsi, RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ xor_blocks(%rax, RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__serpent_enc_blk_8way)
+
+@@ -750,5 +753,6 @@ ENTRY(serpent_dec_blk_8way)
+ write_blocks(%rsi, RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ write_blocks(%rax, RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(serpent_dec_blk_8way)
+diff --git a/arch/x86/crypto/serpent_avx2_glue.c b/arch/x86/crypto/serpent_avx2_glue.c
+index 870f6d8..9fed18e 100644
+--- a/arch/x86/crypto/serpent_avx2_glue.c
++++ b/arch/x86/crypto/serpent_avx2_glue.c
+@@ -27,18 +27,18 @@
+ #define SERPENT_AVX2_PARALLEL_BLOCKS 16
+
+ /* 16-way AVX2 parallel cipher functions */
+-asmlinkage void serpent_ecb_enc_16way(struct serpent_ctx *ctx, u8 *dst,
++asmlinkage void serpent_ecb_enc_16way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void serpent_ecb_dec_16way(struct serpent_ctx *ctx, u8 *dst,
++asmlinkage void serpent_ecb_dec_16way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void serpent_cbc_dec_16way(void *ctx, u128 *dst, const u128 *src);
++asmlinkage void serpent_cbc_dec_16way(void *ctx, u8 *dst, const u8 *src);
+
+ asmlinkage void serpent_ctr_16way(void *ctx, u128 *dst, const u128 *src,
+ le128 *iv);
+-asmlinkage void serpent_xts_enc_16way(struct serpent_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
+-asmlinkage void serpent_xts_dec_16way(struct serpent_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void serpent_xts_enc_16way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
++asmlinkage void serpent_xts_dec_16way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+ static const struct common_glue_ctx serpent_enc = {
+ .num_funcs = 3,
+diff --git a/arch/x86/crypto/serpent_avx_glue.c b/arch/x86/crypto/serpent_avx_glue.c
+index 6f778d3..3cf277e 100644
+--- a/arch/x86/crypto/serpent_avx_glue.c
++++ b/arch/x86/crypto/serpent_avx_glue.c
+@@ -41,28 +41,28 @@
+ #include <asm/crypto/glue_helper.h>
+
+ /* 8-way parallel cipher functions */
+-asmlinkage void serpent_ecb_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst,
++asmlinkage void serpent_ecb_enc_8way_avx(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx);
+
+-asmlinkage void serpent_ecb_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst,
++asmlinkage void serpent_ecb_dec_8way_avx(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx);
+
+-asmlinkage void serpent_cbc_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst,
++asmlinkage void serpent_cbc_dec_8way_avx(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx);
+
+-asmlinkage void serpent_ctr_8way_avx(struct serpent_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void serpent_ctr_8way_avx(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(serpent_ctr_8way_avx);
+
+-asmlinkage void serpent_xts_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void serpent_xts_enc_8way_avx(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(serpent_xts_enc_8way_avx);
+
+-asmlinkage void serpent_xts_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void serpent_xts_dec_8way_avx(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+ EXPORT_SYMBOL_GPL(serpent_xts_dec_8way_avx);
+
+ void __serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv)
+diff --git a/arch/x86/crypto/serpent_sse2_glue.c b/arch/x86/crypto/serpent_sse2_glue.c
+index 644f97a..4d069a1 100644
+--- a/arch/x86/crypto/serpent_sse2_glue.c
++++ b/arch/x86/crypto/serpent_sse2_glue.c
+@@ -45,8 +45,10 @@
+ #include <asm/crypto/serpent-sse2.h>
+ #include <asm/crypto/glue_helper.h>
+
+-static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src)
++static void serpent_decrypt_cbc_xway(void *ctx, u8 *_dst, const u8 *_src)
+ {
++ u128 *dst = (u128 *)_dst;
++ const u128 *src = (const u128 *)_src;
+ u128 ivs[SERPENT_PARALLEL_BLOCKS - 1];
+ unsigned int j;
+
+diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S
+index 96df6a3..8519a8f 100644
+--- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S
++++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S
+@@ -103,7 +103,7 @@ offset = \_offset
+
+ # JOB* sha1_mb_mgr_flush_avx2(MB_MGR *state)
+ # arg 1 : rcx : state
+-ENTRY(sha1_mb_mgr_flush_avx2)
++RAP_ENTRY(sha1_mb_mgr_flush_avx2)
+ FRAME_BEGIN
+ push %rbx
+
+@@ -226,7 +226,7 @@ ENDPROC(sha1_mb_mgr_flush_avx2)
+ #################################################################
+
+ .align 16
+-ENTRY(sha1_mb_mgr_get_comp_job_avx2)
++RAP_ENTRY(sha1_mb_mgr_get_comp_job_avx2)
+ push %rbx
+
+ ## if bit 32+3 is set, then all lanes are empty
+diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
+index 63a0d9c..a6038fd 100644
+--- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
++++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S
+@@ -98,7 +98,7 @@ lane_data = %r10
+ # JOB* submit_mb_mgr_submit_avx2(MB_MGR *state, job_sha1 *job)
+ # arg 1 : rcx : state
+ # arg 2 : rdx : job
+-ENTRY(sha1_mb_mgr_submit_avx2)
++RAP_ENTRY(sha1_mb_mgr_submit_avx2)
+ FRAME_BEGIN
+ push %rbx
+ push %r12
+diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S
+index a410950..02d2056 100644
+--- a/arch/x86/crypto/sha1_ssse3_asm.S
++++ b/arch/x86/crypto/sha1_ssse3_asm.S
+@@ -29,6 +29,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ #define CTX %rdi // arg1
+ #define BUF %rsi // arg2
+@@ -71,13 +72,14 @@
+ * param: function's name
+ */
+ .macro SHA1_VECTOR_ASM name
+- ENTRY(\name)
++ALIGN
++ RAP_ENTRY(\name)
+
+ push %rbx
+ push %rbp
+- push %r12
++ push %r14
+
+- mov %rsp, %r12
++ mov %rsp, %r14
+ sub $64, %rsp # allocate workspace
+ and $~15, %rsp # align stack
+
+@@ -99,11 +101,12 @@
+ xor %rax, %rax
+ rep stosq
+
+- mov %r12, %rsp # deallocate workspace
++ mov %r14, %rsp # deallocate workspace
+
+- pop %r12
++ pop %r14
+ pop %rbp
+ pop %rbx
++ pax_force_retaddr
+ ret
+
+ ENDPROC(\name)
+diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c
+index 1024e37..7958186 100644
+--- a/arch/x86/crypto/sha1_ssse3_glue.c
++++ b/arch/x86/crypto/sha1_ssse3_glue.c
+@@ -31,8 +31,8 @@
+ #include <crypto/sha1_base.h>
+ #include <asm/fpu/api.h>
+
+-typedef void (sha1_transform_fn)(u32 *digest, const char *data,
+- unsigned int rounds);
++typedef void (sha1_transform_fn)(struct sha1_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha1_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha1_transform_fn *sha1_xform)
+@@ -47,8 +47,7 @@ static int sha1_update(struct shash_desc *desc, const u8 *data,
+ BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0);
+
+ kernel_fpu_begin();
+- sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_xform);
++ sha1_base_do_update(desc, data, len, sha1_xform);
+ kernel_fpu_end();
+
+ return 0;
+@@ -62,29 +61,26 @@ static int sha1_finup(struct shash_desc *desc, const u8 *data,
+
+ kernel_fpu_begin();
+ if (len)
+- sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_xform);
+- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_xform);
++ sha1_base_do_update(desc, data, len, sha1_xform);
++ sha1_base_do_finalize(desc, sha1_xform);
+ kernel_fpu_end();
+
+ return sha1_base_finish(desc, out);
+ }
+
+-asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
+- unsigned int rounds);
++asmlinkage void sha1_transform_ssse3(struct sha1_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha1_update(desc, data, len,
+- (sha1_transform_fn *) sha1_transform_ssse3);
++ return sha1_update(desc, data, len, sha1_transform_ssse3);
+ }
+
+ static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- return sha1_finup(desc, data, len, out,
+- (sha1_transform_fn *) sha1_transform_ssse3);
++ return sha1_finup(desc, data, len, out, sha1_transform_ssse3);
+ }
+
+ /* Add padding and return the message digest. */
+@@ -124,21 +120,19 @@ static void unregister_sha1_ssse3(void)
+ }
+
+ #ifdef CONFIG_AS_AVX
+-asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
+- unsigned int rounds);
++asmlinkage void sha1_transform_avx(struct sha1_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha1_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha1_update(desc, data, len,
+- (sha1_transform_fn *) sha1_transform_avx);
++ return sha1_update(desc, data, len, sha1_transform_avx);
+ }
+
+ static int sha1_avx_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- return sha1_finup(desc, data, len, out,
+- (sha1_transform_fn *) sha1_transform_avx);
++ return sha1_finup(desc, data, len, out, sha1_transform_avx);
+ }
+
+ static int sha1_avx_final(struct shash_desc *desc, u8 *out)
+@@ -196,8 +190,8 @@ static inline void unregister_sha1_avx(void) { }
+ #if defined(CONFIG_AS_AVX2) && (CONFIG_AS_AVX)
+ #define SHA1_AVX2_BLOCK_OPTSIZE 4 /* optimal 4*64 bytes of SHA1 blocks */
+
+-asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
+- unsigned int rounds);
++asmlinkage void sha1_transform_avx2(struct sha1_state *digest, const u8 *data,
++ int rounds);
+
+ static bool avx2_usable(void)
+ {
+@@ -209,8 +203,8 @@ static bool avx2_usable(void)
+ return false;
+ }
+
+-static void sha1_apply_transform_avx2(u32 *digest, const char *data,
+- unsigned int rounds)
++static void sha1_apply_transform_avx2(struct sha1_state *digest, const u8 *data,
++ int rounds)
+ {
+ /* Select the optimal transform based on data block size */
+ if (rounds >= SHA1_AVX2_BLOCK_OPTSIZE)
+@@ -222,15 +216,13 @@ static void sha1_apply_transform_avx2(u32 *digest, const char *data,
+ static int sha1_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha1_update(desc, data, len,
+- (sha1_transform_fn *) sha1_apply_transform_avx2);
++ return sha1_update(desc, data, len, sha1_apply_transform_avx2);
+ }
+
+ static int sha1_avx2_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- return sha1_finup(desc, data, len, out,
+- (sha1_transform_fn *) sha1_apply_transform_avx2);
++ return sha1_finup(desc, data, len, out, sha1_apply_transform_avx2);
+ }
+
+ static int sha1_avx2_final(struct shash_desc *desc, u8 *out)
+@@ -274,21 +266,19 @@ static inline void unregister_sha1_avx2(void) { }
+ #endif
+
+ #ifdef CONFIG_AS_SHA1_NI
+-asmlinkage void sha1_ni_transform(u32 *digest, const char *data,
+- unsigned int rounds);
++asmlinkage void sha1_ni_transform(struct sha1_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha1_ni_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha1_update(desc, data, len,
+- (sha1_transform_fn *) sha1_ni_transform);
++ return sha1_update(desc, data, len, sha1_ni_transform);
+ }
+
+ static int sha1_ni_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- return sha1_finup(desc, data, len, out,
+- (sha1_transform_fn *) sha1_ni_transform);
++ return sha1_finup(desc, data, len, out, sha1_ni_transform);
+ }
+
+ static int sha1_ni_final(struct shash_desc *desc, u8 *out)
+diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S
+index 92b3b5d..8732479 100644
+--- a/arch/x86/crypto/sha256-avx-asm.S
++++ b/arch/x86/crypto/sha256-avx-asm.S
+@@ -49,6 +49,7 @@
+
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ ## assume buffers not aligned
+ #define VMOVDQ vmovdqu
+@@ -347,8 +348,7 @@ a = TMP_
+ ## arg 3 : Num blocks
+ ########################################################################
+ .text
+-ENTRY(sha256_transform_avx)
+-.align 32
++RAP_ENTRY(sha256_transform_avx)
+ pushq %rbx
+ pushq %rbp
+ pushq %r13
+@@ -460,6 +460,7 @@ done_hash:
+ popq %r13
+ popq %rbp
+ popq %rbx
++ pax_force_retaddr
+ ret
+ ENDPROC(sha256_transform_avx)
+
+diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S
+index 570ec5e..9bcfa25 100644
+--- a/arch/x86/crypto/sha256-avx2-asm.S
++++ b/arch/x86/crypto/sha256-avx2-asm.S
+@@ -50,6 +50,7 @@
+
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ ## assume buffers not aligned
+ #define VMOVDQ vmovdqu
+@@ -528,8 +529,7 @@ STACK_SIZE = _RSP + _RSP_SIZE
+ ## arg 3 : Num blocks
+ ########################################################################
+ .text
+-ENTRY(sha256_transform_rorx)
+-.align 32
++RAP_ENTRY(sha256_transform_rorx)
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+@@ -720,6 +720,7 @@ done_hash:
+ popq %r12
+ popq %rbp
+ popq %rbx
++ pax_force_retaddr
+ ret
+ ENDPROC(sha256_transform_rorx)
+
+diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S
+index 2cedc44..6fb8582 100644
+--- a/arch/x86/crypto/sha256-ssse3-asm.S
++++ b/arch/x86/crypto/sha256-ssse3-asm.S
+@@ -47,6 +47,7 @@
+ ########################################################################
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ ## assume buffers not aligned
+ #define MOVDQ movdqu
+@@ -352,9 +353,7 @@ a = TMP_
+ ## arg 2 : pointer to input data
+ ## arg 3 : Num blocks
+ ########################################################################
+-.text
+-ENTRY(sha256_transform_ssse3)
+-.align 32
++RAP_ENTRY(sha256_transform_ssse3)
+ pushq %rbx
+ pushq %rbp
+ pushq %r13
+@@ -471,6 +470,7 @@ done_hash:
+ popq %rbp
+ popq %rbx
+
++ pax_force_retaddr
+ ret
+ ENDPROC(sha256_transform_ssse3)
+
+diff --git a/arch/x86/crypto/sha256_ni_asm.S b/arch/x86/crypto/sha256_ni_asm.S
+index 748cdf2..959bb4d 100644
+--- a/arch/x86/crypto/sha256_ni_asm.S
++++ b/arch/x86/crypto/sha256_ni_asm.S
+@@ -97,7 +97,7 @@
+
+ .text
+ .align 32
+-ENTRY(sha256_ni_transform)
++RAP_ENTRY(sha256_ni_transform)
+
+ shl $6, NUM_BLKS /* convert to bytes */
+ jz .Ldone_hash
+diff --git a/arch/x86/crypto/sha256_ssse3_glue.c b/arch/x86/crypto/sha256_ssse3_glue.c
+index 3ae0f43..524beeb 100644
+--- a/arch/x86/crypto/sha256_ssse3_glue.c
++++ b/arch/x86/crypto/sha256_ssse3_glue.c
+@@ -40,9 +40,9 @@
+ #include <asm/fpu/api.h>
+ #include <linux/string.h>
+
+-asmlinkage void sha256_transform_ssse3(u32 *digest, const char *data,
+- u64 rounds);
+-typedef void (sha256_transform_fn)(u32 *digest, const char *data, u64 rounds);
++asmlinkage void sha256_transform_ssse3(struct sha256_state *digest, const u8 *data,
++ int rounds);
++typedef void (sha256_transform_fn)(struct sha256_state *digest, const u8 *data, int rounds);
+
+ static int sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha256_transform_fn *sha256_xform)
+@@ -57,8 +57,7 @@ static int sha256_update(struct shash_desc *desc, const u8 *data,
+ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
+
+ kernel_fpu_begin();
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_xform);
++ sha256_base_do_update(desc, data, len, sha256_xform);
+ kernel_fpu_end();
+
+ return 0;
+@@ -72,9 +71,8 @@ static int sha256_finup(struct shash_desc *desc, const u8 *data,
+
+ kernel_fpu_begin();
+ if (len)
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_xform);
+- sha256_base_do_finalize(desc, (sha256_block_fn *)sha256_xform);
++ sha256_base_do_update(desc, data, len, sha256_xform);
++ sha256_base_do_finalize(desc, sha256_xform);
+ kernel_fpu_end();
+
+ return sha256_base_finish(desc, out);
+@@ -146,8 +144,8 @@ static void unregister_sha256_ssse3(void)
+ }
+
+ #ifdef CONFIG_AS_AVX
+-asmlinkage void sha256_transform_avx(u32 *digest, const char *data,
+- u64 rounds);
++asmlinkage void sha256_transform_avx(struct sha256_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha256_avx_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -230,8 +228,8 @@ static inline void unregister_sha256_avx(void) { }
+ #endif
+
+ #if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX)
+-asmlinkage void sha256_transform_rorx(u32 *digest, const char *data,
+- u64 rounds);
++asmlinkage void sha256_transform_rorx(struct sha256_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha256_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -312,8 +310,8 @@ static inline void unregister_sha256_avx2(void) { }
+ #endif
+
+ #ifdef CONFIG_AS_SHA256_NI
+-asmlinkage void sha256_ni_transform(u32 *digest, const char *data,
+- u64 rounds); /*unsigned int rounds);*/
++asmlinkage void sha256_ni_transform(struct sha256_state *digest, const u8 *data,
++ int rounds); /*unsigned int rounds);*/
+
+ static int sha256_ni_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+diff --git a/arch/x86/crypto/sha512-avx-asm.S b/arch/x86/crypto/sha512-avx-asm.S
+index 565274d..779d34a 100644
+--- a/arch/x86/crypto/sha512-avx-asm.S
++++ b/arch/x86/crypto/sha512-avx-asm.S
+@@ -49,6 +49,7 @@
+
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .text
+
+@@ -277,7 +278,8 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
+ # message blocks.
+ # L is the message length in SHA512 blocks
+ ########################################################################
+-ENTRY(sha512_transform_avx)
++ALIGN
++RAP_ENTRY(sha512_transform_avx)
+ cmp $0, msglen
+ je nowork
+
+@@ -364,6 +366,7 @@ updateblock:
+ mov frame_RSPSAVE(%rsp), %rsp
+
+ nowork:
++ pax_force_retaddr
+ ret
+ ENDPROC(sha512_transform_avx)
+
+diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S
+index 1f20b35..ab1f3a8 100644
+--- a/arch/x86/crypto/sha512-avx2-asm.S
++++ b/arch/x86/crypto/sha512-avx2-asm.S
+@@ -51,6 +51,7 @@
+
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .text
+
+@@ -568,7 +569,8 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
+ # message blocks.
+ # L is the message length in SHA512 blocks
+ ########################################################################
+-ENTRY(sha512_transform_rorx)
++ALIGN
++RAP_ENTRY(sha512_transform_rorx)
+ # Allocate Stack Space
+ mov %rsp, %rax
+ sub $frame_size, %rsp
+@@ -678,6 +680,7 @@ done_hash:
+
+ # Restore Stack Pointer
+ mov frame_RSPSAVE(%rsp), %rsp
++ pax_force_retaddr
+ ret
+ ENDPROC(sha512_transform_rorx)
+
+diff --git a/arch/x86/crypto/sha512-ssse3-asm.S b/arch/x86/crypto/sha512-ssse3-asm.S
+index e610e29..83f1cde 100644
+--- a/arch/x86/crypto/sha512-ssse3-asm.S
++++ b/arch/x86/crypto/sha512-ssse3-asm.S
+@@ -48,6 +48,7 @@
+ ########################################################################
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .text
+
+@@ -275,7 +276,8 @@ frame_size = frame_GPRSAVE + GPRSAVE_SIZE
+ # message blocks.
+ # L is the message length in SHA512 blocks.
+ ########################################################################
+-ENTRY(sha512_transform_ssse3)
++ALIGN
++RAP_ENTRY(sha512_transform_ssse3)
+
+ cmp $0, msglen
+ je nowork
+@@ -363,6 +365,7 @@ updateblock:
+ mov frame_RSPSAVE(%rsp), %rsp
+
+ nowork:
++ pax_force_retaddr
+ ret
+ ENDPROC(sha512_transform_ssse3)
+
+diff --git a/arch/x86/crypto/sha512_ssse3_glue.c b/arch/x86/crypto/sha512_ssse3_glue.c
+index 0b17c83..6959deb 100644
+--- a/arch/x86/crypto/sha512_ssse3_glue.c
++++ b/arch/x86/crypto/sha512_ssse3_glue.c
+@@ -39,10 +39,10 @@
+
+ #include <linux/string.h>
+
+-asmlinkage void sha512_transform_ssse3(u64 *digest, const char *data,
+- u64 rounds);
++asmlinkage void sha512_transform_ssse3(struct sha512_state *digest, const u8 *data,
++ int rounds);
+
+-typedef void (sha512_transform_fn)(u64 *digest, const char *data, u64 rounds);
++typedef void (sha512_transform_fn)(struct sha512_state *digest, const u8 *data, int rounds);
+
+ static int sha512_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len, sha512_transform_fn *sha512_xform)
+@@ -57,8 +57,7 @@ static int sha512_update(struct shash_desc *desc, const u8 *data,
+ BUILD_BUG_ON(offsetof(struct sha512_state, state) != 0);
+
+ kernel_fpu_begin();
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_xform);
++ sha512_base_do_update(desc, data, len, sha512_xform);
+ kernel_fpu_end();
+
+ return 0;
+@@ -72,9 +71,8 @@ static int sha512_finup(struct shash_desc *desc, const u8 *data,
+
+ kernel_fpu_begin();
+ if (len)
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_xform);
+- sha512_base_do_finalize(desc, (sha512_block_fn *)sha512_xform);
++ sha512_base_do_update(desc, data, len, sha512_xform);
++ sha512_base_do_finalize(desc, sha512_xform);
+ kernel_fpu_end();
+
+ return sha512_base_finish(desc, out);
+@@ -146,8 +144,8 @@ static void unregister_sha512_ssse3(void)
+ }
+
+ #ifdef CONFIG_AS_AVX
+-asmlinkage void sha512_transform_avx(u64 *digest, const char *data,
+- u64 rounds);
++asmlinkage void sha512_transform_avx(struct sha512_state *digest, const u8 *data,
++ int rounds);
+ static bool avx_usable(void)
+ {
+ if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, NULL)) {
+@@ -229,8 +227,8 @@ static inline void unregister_sha512_avx(void) { }
+ #endif
+
+ #if defined(CONFIG_AS_AVX2) && defined(CONFIG_AS_AVX)
+-asmlinkage void sha512_transform_rorx(u64 *digest, const char *data,
+- u64 rounds);
++asmlinkage void sha512_transform_rorx(struct sha512_state *digest, const u8 *data,
++ int rounds);
+
+ static int sha512_avx2_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+index dc66273..30aba4b 100644
+--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+@@ -25,6 +25,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+
+ .file "twofish-avx-x86_64-asm_64.S"
+@@ -285,6 +286,7 @@ __twofish_enc_blk8:
+ outunpack_blocks(RC1, RD1, RA1, RB1, RK1, RX0, RY0, RK2);
+ outunpack_blocks(RC2, RD2, RA2, RB2, RK1, RX0, RY0, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__twofish_enc_blk8)
+
+@@ -325,10 +327,11 @@ __twofish_dec_blk8:
+ outunpack_blocks(RA1, RB1, RC1, RD1, RK1, RX0, RY0, RK2);
+ outunpack_blocks(RA2, RB2, RC2, RD2, RK1, RX0, RY0, RK2);
+
++ pax_force_retaddr
+ ret;
+ ENDPROC(__twofish_dec_blk8)
+
+-ENTRY(twofish_ecb_enc_8way)
++RAP_ENTRY(twofish_ecb_enc_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -345,10 +348,11 @@ ENTRY(twofish_ecb_enc_8way)
+ store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_ecb_enc_8way)
+
+-ENTRY(twofish_ecb_dec_8way)
++RAP_ENTRY(twofish_ecb_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -365,10 +369,11 @@ ENTRY(twofish_ecb_dec_8way)
+ store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_ecb_dec_8way)
+
+-ENTRY(twofish_cbc_dec_8way)
++RAP_ENTRY(twofish_cbc_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -376,24 +381,25 @@ ENTRY(twofish_cbc_dec_8way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_8way(%rdx, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+ call __twofish_dec_blk8;
+
+- store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
++ store_cbc_8way(%r14, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_cbc_dec_8way)
+
+-ENTRY(twofish_ctr_8way)
++RAP_ENTRY(twofish_ctr_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -402,25 +408,26 @@ ENTRY(twofish_ctr_8way)
+ */
+ FRAME_BEGIN
+
+- pushq %r12;
++ pushq %r14;
+
+ movq %rsi, %r11;
+- movq %rdx, %r12;
++ movq %rdx, %r14;
+
+ load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2,
+ RD2, RX0, RX1, RY0);
+
+ call __twofish_enc_blk8;
+
+- store_ctr_8way(%r12, %r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
++ store_ctr_8way(%r14, %r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+- popq %r12;
++ popq %r14;
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_ctr_8way)
+
+-ENTRY(twofish_xts_enc_8way)
++RAP_ENTRY(twofish_xts_enc_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -441,10 +448,11 @@ ENTRY(twofish_xts_enc_8way)
+ store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_xts_enc_8way)
+
+-ENTRY(twofish_xts_dec_8way)
++RAP_ENTRY(twofish_xts_dec_8way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -465,5 +473,6 @@ ENTRY(twofish_xts_dec_8way)
+ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+
+ FRAME_END
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_xts_dec_8way)
+diff --git a/arch/x86/crypto/twofish-i586-asm_32.S b/arch/x86/crypto/twofish-i586-asm_32.S
+index 694ea45..f2c1418 100644
+--- a/arch/x86/crypto/twofish-i586-asm_32.S
++++ b/arch/x86/crypto/twofish-i586-asm_32.S
+@@ -220,7 +220,7 @@
+ xor %esi, d ## D;\
+ ror $1, d ## D;
+
+-ENTRY(twofish_enc_blk)
++RAP_ENTRY(twofish_enc_blk)
+ push %ebp /* save registers according to calling convention*/
+ push %ebx
+ push %esi
+@@ -276,7 +276,7 @@ ENTRY(twofish_enc_blk)
+ ret
+ ENDPROC(twofish_enc_blk)
+
+-ENTRY(twofish_dec_blk)
++RAP_ENTRY(twofish_dec_blk)
+ push %ebp /* save registers according to calling convention*/
+ push %ebx
+ push %esi
+diff --git a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
+index 1c3b7ce..c9912c7 100644
+--- a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
++++ b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
+@@ -21,6 +21,7 @@
+ */
+
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+
+ .file "twofish-x86_64-asm-3way.S"
+ .text
+@@ -258,6 +259,7 @@ ENTRY(__twofish_enc_blk_3way)
+ popq %r13;
+ popq %r14;
+ popq %r15;
++ pax_force_retaddr
+ ret;
+
+ .L__enc_xor3:
+@@ -269,10 +271,11 @@ ENTRY(__twofish_enc_blk_3way)
+ popq %r13;
+ popq %r14;
+ popq %r15;
++ pax_force_retaddr
+ ret;
+ ENDPROC(__twofish_enc_blk_3way)
+
+-ENTRY(twofish_dec_blk_3way)
++RAP_ENTRY(twofish_dec_blk_3way)
+ /* input:
+ * %rdi: ctx, CTX
+ * %rsi: dst
+@@ -308,5 +311,6 @@ ENTRY(twofish_dec_blk_3way)
+ popq %r13;
+ popq %r14;
+ popq %r15;
++ pax_force_retaddr
+ ret;
+ ENDPROC(twofish_dec_blk_3way)
+diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S b/arch/x86/crypto/twofish-x86_64-asm_64.S
+index a350c99..080c5ab 100644
+--- a/arch/x86/crypto/twofish-x86_64-asm_64.S
++++ b/arch/x86/crypto/twofish-x86_64-asm_64.S
+@@ -22,6 +22,7 @@
+
+ #include <linux/linkage.h>
+ #include <asm/asm-offsets.h>
++#include <asm/alternative-asm.h>
+
+ #define a_offset 0
+ #define b_offset 4
+@@ -215,7 +216,7 @@
+ xor %r8d, d ## D;\
+ ror $1, d ## D;
+
+-ENTRY(twofish_enc_blk)
++RAP_ENTRY(twofish_enc_blk)
+ pushq R1
+
+ /* %rdi contains the ctx address */
+@@ -265,10 +266,11 @@ ENTRY(twofish_enc_blk)
+
+ popq R1
+ movl $1,%eax
++ pax_force_retaddr
+ ret
+ ENDPROC(twofish_enc_blk)
+
+-ENTRY(twofish_dec_blk)
++RAP_ENTRY(twofish_dec_blk)
+ pushq R1
+
+ /* %rdi contains the ctx address */
+@@ -317,5 +319,6 @@ ENTRY(twofish_dec_blk)
+
+ popq R1
+ movl $1,%eax
++ pax_force_retaddr
+ ret
+ ENDPROC(twofish_dec_blk)
+diff --git a/arch/x86/crypto/twofish_avx_glue.c b/arch/x86/crypto/twofish_avx_glue.c
+index b7a3904b..3e4d0d6 100644
+--- a/arch/x86/crypto/twofish_avx_glue.c
++++ b/arch/x86/crypto/twofish_avx_glue.c
+@@ -46,24 +46,25 @@
+ #define TWOFISH_PARALLEL_BLOCKS 8
+
+ /* 8-way parallel cipher functions */
+-asmlinkage void twofish_ecb_enc_8way(struct twofish_ctx *ctx, u8 *dst,
++asmlinkage void twofish_ecb_enc_8way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void twofish_ecb_dec_8way(struct twofish_ctx *ctx, u8 *dst,
++asmlinkage void twofish_ecb_dec_8way(void *ctx, u8 *dst,
+ const u8 *src);
+
+-asmlinkage void twofish_cbc_dec_8way(struct twofish_ctx *ctx, u8 *dst,
++asmlinkage void twofish_cbc_dec_8way(void *ctx, u8 *dst,
+ const u8 *src);
+-asmlinkage void twofish_ctr_8way(struct twofish_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void twofish_ctr_8way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+-asmlinkage void twofish_xts_enc_8way(struct twofish_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
+-asmlinkage void twofish_xts_dec_8way(struct twofish_ctx *ctx, u8 *dst,
+- const u8 *src, le128 *iv);
++asmlinkage void twofish_xts_enc_8way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
++asmlinkage void twofish_xts_dec_8way(void *ctx, u128 *dst,
++ const u128 *src, le128 *iv);
+
+-static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
++static inline void twofish_enc_blk_3way(void *_ctx, u8 *dst,
+ const u8 *src)
+ {
++ struct twofish_ctx *ctx = _ctx;
+ __twofish_enc_blk_3way(ctx, dst, src, false);
+ }
+
+diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c
+index 77e06c2..a45c27b 100644
+--- a/arch/x86/crypto/twofish_glue.c
++++ b/arch/x86/crypto/twofish_glue.c
+@@ -44,10 +44,10 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+
+-asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
++asmlinkage void twofish_enc_blk(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(twofish_enc_blk);
+-asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
++asmlinkage void twofish_dec_blk(void *ctx, u8 *dst,
+ const u8 *src);
+ EXPORT_SYMBOL_GPL(twofish_dec_blk);
+
+diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c
+index 2ebb5e9..a0b0aa9 100644
+--- a/arch/x86/crypto/twofish_glue_3way.c
++++ b/arch/x86/crypto/twofish_glue_3way.c
+@@ -36,21 +36,21 @@
+ EXPORT_SYMBOL_GPL(__twofish_enc_blk_3way);
+ EXPORT_SYMBOL_GPL(twofish_dec_blk_3way);
+
+-static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
++static inline void twofish_enc_blk_3way(void *ctx, u8 *dst,
+ const u8 *src)
+ {
+ __twofish_enc_blk_3way(ctx, dst, src, false);
+ }
+
+-static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
++static inline void twofish_enc_blk_xor_3way(void *ctx, u8 *dst,
+ const u8 *src)
+ {
+ __twofish_enc_blk_3way(ctx, dst, src, true);
+ }
+
+-void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src)
++void twofish_dec_blk_cbc_3way(void *ctx, u8 *_dst, const u8 *_src)
+ {
+- u128 ivs[2];
++ u128 ivs[2], *dst = (u128 *)_dst, *src = (u128 *)_src;
+
+ ivs[0] = src[0];
+ ivs[1] = src[1];
+@@ -118,10 +118,10 @@ static const struct common_glue_ctx twofish_ctr = {
+
+ .funcs = { {
+ .num_blocks = 3,
+- .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr_3way) }
++ .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_3way) }
+ }, {
+ .num_blocks = 1,
+- .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr) }
++ .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr) }
+ } }
+ };
+
+diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
+index fe91c25..18f6ab9 100644
+--- a/arch/x86/entry/Makefile
++++ b/arch/x86/entry/Makefile
+@@ -13,3 +13,5 @@ obj-y += vsyscall/
+
+ obj-$(CONFIG_IA32_EMULATION) += entry_64_compat.o syscall_32.o
+
++CFLAGS_REMOVE_syscall_32.o = $(RAP_PLUGIN_ABS_CFLAGS)
++CFLAGS_REMOVE_syscall_64.o = $(RAP_PLUGIN_ABS_CFLAGS)
+diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
+index 9a9e588..b900d1c 100644
+--- a/arch/x86/entry/calling.h
++++ b/arch/x86/entry/calling.h
+@@ -95,23 +95,26 @@ For 32-bit we have the following conventions - kernel is built with
+ .endm
+
+ .macro SAVE_C_REGS_HELPER offset=0 rax=1 rcx=1 r8910=1 r11=1
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq %r12, R12+\offset(%rsp)
++#endif
+ .if \r11
+- movq %r11, 6*8+\offset(%rsp)
++ movq %r11, R11+\offset(%rsp)
+ .endif
+ .if \r8910
+- movq %r10, 7*8+\offset(%rsp)
+- movq %r9, 8*8+\offset(%rsp)
+- movq %r8, 9*8+\offset(%rsp)
++ movq %r10, R10+\offset(%rsp)
++ movq %r9, R9+\offset(%rsp)
++ movq %r8, R8+\offset(%rsp)
+ .endif
+ .if \rax
+- movq %rax, 10*8+\offset(%rsp)
++ movq %rax, RAX+\offset(%rsp)
+ .endif
+ .if \rcx
+- movq %rcx, 11*8+\offset(%rsp)
++ movq %rcx, RCX+\offset(%rsp)
+ .endif
+- movq %rdx, 12*8+\offset(%rsp)
+- movq %rsi, 13*8+\offset(%rsp)
+- movq %rdi, 14*8+\offset(%rsp)
++ movq %rdx, RDX+\offset(%rsp)
++ movq %rsi, RSI+\offset(%rsp)
++ movq %rdi, RDI+\offset(%rsp)
+ .endm
+ .macro SAVE_C_REGS offset=0
+ SAVE_C_REGS_HELPER \offset, 1, 1, 1, 1
+@@ -130,67 +133,78 @@ For 32-bit we have the following conventions - kernel is built with
+ .endm
+
+ .macro SAVE_EXTRA_REGS offset=0
+- movq %r15, 0*8+\offset(%rsp)
+- movq %r14, 1*8+\offset(%rsp)
+- movq %r13, 2*8+\offset(%rsp)
+- movq %r12, 3*8+\offset(%rsp)
+- movq %rbp, 4*8+\offset(%rsp)
+- movq %rbx, 5*8+\offset(%rsp)
++ movq %r15, R15+\offset(%rsp)
++ movq %r14, R14+\offset(%rsp)
++ movq %r13, R13+\offset(%rsp)
++#ifndef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq %r12, R12+\offset(%rsp)
++#endif
++ movq %rbp, RBP+\offset(%rsp)
++ movq %rbx, RBX+\offset(%rsp)
+ .endm
+
+ .macro RESTORE_EXTRA_REGS offset=0
+- movq 0*8+\offset(%rsp), %r15
+- movq 1*8+\offset(%rsp), %r14
+- movq 2*8+\offset(%rsp), %r13
+- movq 3*8+\offset(%rsp), %r12
+- movq 4*8+\offset(%rsp), %rbp
+- movq 5*8+\offset(%rsp), %rbx
++ movq R15+\offset(%rsp), %r15
++ movq R14+\offset(%rsp), %r14
++ movq R13+\offset(%rsp), %r13
++#ifndef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq R12+\offset(%rsp), %r12
++#endif
++ movq RBP+\offset(%rsp), %rbp
++ movq RBX+\offset(%rsp), %rbx
+ .endm
+
+ .macro ZERO_EXTRA_REGS
+ xorl %r15d, %r15d
+ xorl %r14d, %r14d
+ xorl %r13d, %r13d
++#ifndef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
+ xorl %r12d, %r12d
++#endif
+ xorl %ebp, %ebp
+ xorl %ebx, %ebx
+ .endm
+
+- .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1
++ .macro RESTORE_C_REGS_HELPER rstor_rax=1, rstor_rcx=1, rstor_r11=1, rstor_r8910=1, rstor_rdx=1, rstor_r12=1
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ .if \rstor_r12
++ movq R12(%rsp), %r12
++ .endif
++#endif
+ .if \rstor_r11
+- movq 6*8(%rsp), %r11
++ movq R11(%rsp), %r11
+ .endif
+ .if \rstor_r8910
+- movq 7*8(%rsp), %r10
+- movq 8*8(%rsp), %r9
+- movq 9*8(%rsp), %r8
++ movq R10(%rsp), %r10
++ movq R9(%rsp), %r9
++ movq R8(%rsp), %r8
+ .endif
+ .if \rstor_rax
+- movq 10*8(%rsp), %rax
++ movq RAX(%rsp), %rax
+ .endif
+ .if \rstor_rcx
+- movq 11*8(%rsp), %rcx
++ movq RCX(%rsp), %rcx
+ .endif
+ .if \rstor_rdx
+- movq 12*8(%rsp), %rdx
++ movq RDX(%rsp), %rdx
+ .endif
+- movq 13*8(%rsp), %rsi
+- movq 14*8(%rsp), %rdi
++ movq RSI(%rsp), %rsi
++ movq RDI(%rsp), %rdi
+ .endm
+ .macro RESTORE_C_REGS
+- RESTORE_C_REGS_HELPER 1,1,1,1,1
++ RESTORE_C_REGS_HELPER 1,1,1,1,1,1
+ .endm
+ .macro RESTORE_C_REGS_EXCEPT_RAX
+- RESTORE_C_REGS_HELPER 0,1,1,1,1
++ RESTORE_C_REGS_HELPER 0,1,1,1,1,0
+ .endm
+ .macro RESTORE_C_REGS_EXCEPT_RCX
+- RESTORE_C_REGS_HELPER 1,0,1,1,1
++ RESTORE_C_REGS_HELPER 1,0,1,1,1,0
+ .endm
+ .macro RESTORE_C_REGS_EXCEPT_R11
+- RESTORE_C_REGS_HELPER 1,1,0,1,1
++ RESTORE_C_REGS_HELPER 1,1,0,1,1,1
+ .endm
+ .macro RESTORE_C_REGS_EXCEPT_RCX_R11
+- RESTORE_C_REGS_HELPER 1,0,0,1,1
++ RESTORE_C_REGS_HELPER 1,0,0,1,1,1
+ .endm
+
+ .macro REMOVE_PT_GPREGS_FROM_STACK addskip=0
+diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
+index ec138e5..3e47a7a 100644
+--- a/arch/x86/entry/common.c
++++ b/arch/x86/entry/common.c
+@@ -33,9 +33,7 @@
+
+ static struct thread_info *pt_regs_to_thread_info(struct pt_regs *regs)
+ {
+- unsigned long top_of_stack =
+- (unsigned long)(regs + 1) + TOP_OF_KERNEL_STACK_PADDING;
+- return (struct thread_info *)(top_of_stack - THREAD_SIZE);
++ return current_thread_info();
+ }
+
+ #ifdef CONFIG_CONTEXT_TRACKING
+@@ -49,6 +47,12 @@ __visible void enter_from_user_mode(void)
+ static inline void enter_from_user_mode(void) {}
+ #endif
+
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++asmlinkage void pax_erase_kstack(void);
++#else
++static void pax_erase_kstack(void) {}
++#endif
++
+ static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)
+ {
+ #ifdef CONFIG_X86_64
+@@ -152,6 +156,10 @@ unsigned long syscall_trace_enter_phase1(struct pt_regs *regs, u32 arch)
+ return 1; /* Something is enabled that we can't handle in phase 1 */
+ }
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /* Returns the syscall nr to run (which should match regs->orig_ax). */
+ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
+ unsigned long phase1_result)
+@@ -163,6 +171,11 @@ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
+ if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
+ BUG_ON(regs != task_pt_regs(current));
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ #ifdef CONFIG_SECCOMP
+ /*
+ * Call seccomp_phase2 before running the other hooks so that
+@@ -189,15 +202,14 @@ long syscall_trace_enter_phase2(struct pt_regs *regs, u32 arch,
+ return ret ?: regs->orig_ax;
+ }
+
+-long syscall_trace_enter(struct pt_regs *regs)
++static long syscall_trace_enter(struct pt_regs *regs)
+ {
+ u32 arch = in_ia32_syscall() ? AUDIT_ARCH_I386 : AUDIT_ARCH_X86_64;
+ unsigned long phase1_result = syscall_trace_enter_phase1(regs, arch);
+
+- if (phase1_result == 0)
+- return regs->orig_ax;
+- else
+- return syscall_trace_enter_phase2(regs, arch, phase1_result);
++ phase1_result = phase1_result ? syscall_trace_enter_phase2(regs, arch, phase1_result) : regs->orig_ax;
++ pax_erase_kstack();
++ return phase1_result;
+ }
+
+ #define EXIT_TO_USERMODE_LOOP_FLAGS \
+@@ -299,7 +311,7 @@ static void syscall_slow_exit_work(struct pt_regs *regs, u32 cached_flags)
+ step = unlikely(
+ (cached_flags & (_TIF_SINGLESTEP | _TIF_SYSCALL_EMU))
+ == _TIF_SINGLESTEP);
+- if (step || cached_flags & _TIF_SYSCALL_TRACE)
++ if (step || (cached_flags & _TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(regs, step);
+ }
+
+@@ -318,6 +330,11 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)
+ WARN(irqs_disabled(), "syscall %ld left IRQs disabled", regs->orig_ax))
+ local_irq_enable();
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ /*
+ * First do one-time work. If these work items are enabled, we
+ * want to run them exactly once per syscall exit with IRQs on.
+@@ -347,9 +364,29 @@ __visible void do_syscall_64(struct pt_regs *regs)
+ * regs->orig_ax, which changes the behavior of some syscalls.
+ */
+ if (likely((nr & __SYSCALL_MASK) < NR_syscalls)) {
++#ifdef CONFIG_PAX_RAP
++ asm volatile("movq %[param1],%%rdi\n\t"
++ "movq %[param2],%%rsi\n\t"
++ "movq %[param3],%%rdx\n\t"
++ "movq %[param4],%%rcx\n\t"
++ "movq %[param5],%%r8\n\t"
++ "movq %[param6],%%r9\n\t"
++ "call *%P[syscall]\n\t"
++ "mov %%rax,%[result]\n\t"
++ : [result] "=m" (regs->ax)
++ : [syscall] "m" (sys_call_table[nr & __SYSCALL_MASK]),
++ [param1] "m" (regs->di),
++ [param2] "m" (regs->si),
++ [param3] "m" (regs->dx),
++ [param4] "m" (regs->r10),
++ [param5] "m" (regs->r8),
++ [param6] "m" (regs->r9)
++ : "ax", "di", "si", "dx", "cx", "r8", "r9", "r10", "r11", "memory");
++#else
+ regs->ax = sys_call_table[nr & __SYSCALL_MASK](
+ regs->di, regs->si, regs->dx,
+ regs->r10, regs->r8, regs->r9);
++#endif
+ }
+
+ syscall_return_slowpath(regs);
+@@ -389,10 +426,51 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
+ * the high bits are zero. Make sure we zero-extend all
+ * of the args.
+ */
++#ifdef CONFIG_PAX_RAP
++#ifdef CONFIG_X86_64
++ asm volatile("movl %[param1],%%edi\n\t"
++ "movl %[param2],%%esi\n\t"
++ "movl %[param3],%%edx\n\t"
++ "movl %[param4],%%ecx\n\t"
++ "movl %[param5],%%r8d\n\t"
++ "movl %[param6],%%r9d\n\t"
++ "call *%P[syscall]\n\t"
++ "mov %%rax,%[result]\n\t"
++ : [result] "=m" (regs->ax)
++ : [syscall] "m" (ia32_sys_call_table[nr]),
++ [param1] "m" (regs->bx),
++ [param2] "m" (regs->cx),
++ [param3] "m" (regs->dx),
++ [param4] "m" (regs->si),
++ [param5] "m" (regs->di),
++ [param6] "m" (regs->bp)
++ : "ax", "di", "si", "dx", "cx", "r8", "r9", "r10", "r11", "memory");
++#else
++ asm volatile("pushl %[param6]\n\t"
++ "pushl %[param5]\n\t"
++ "pushl %[param4]\n\t"
++ "pushl %[param3]\n\t"
++ "pushl %[param2]\n\t"
++ "pushl %[param1]\n\t"
++ "call *%P[syscall]\n\t"
++ "addl $6*8,%%esp\n\t"
++ "mov %%eax,%[result]\n\t"
++ : [result] "=m" (regs->ax)
++ : [syscall] "m" (ia32_sys_call_table[nr]),
++ [param1] "m" (regs->bx),
++ [param2] "m" (regs->cx),
++ [param3] "m" (regs->dx),
++ [param4] "m" (regs->si),
++ [param5] "m" (regs->di),
++ [param6] "m" (regs->bp)
++ : "ax", "dx", "cx", "memory");
++#endif
++#else
+ regs->ax = ia32_sys_call_table[nr](
+ (unsigned int)regs->bx, (unsigned int)regs->cx,
+ (unsigned int)regs->dx, (unsigned int)regs->si,
+ (unsigned int)regs->di, (unsigned int)regs->bp);
++#endif
+ }
+
+ syscall_return_slowpath(regs);
+@@ -416,6 +494,7 @@ __visible long do_fast_syscall_32(struct pt_regs *regs)
+
+ unsigned long landing_pad = (unsigned long)current->mm->context.vdso +
+ vdso_image_32.sym_int80_landing_pad;
++ u32 __user *saved_bp = (u32 __force_user *)(unsigned long)(u32)regs->sp;
+
+ /*
+ * SYSENTER loses EIP, and even SYSCALL32 needs us to skip forward
+@@ -435,11 +514,9 @@ __visible long do_fast_syscall_32(struct pt_regs *regs)
+ * Micro-optimization: the pointer we're following is explicitly
+ * 32 bits, so it can't be out of range.
+ */
+- __get_user(*(u32 *)&regs->bp,
+- (u32 __user __force *)(unsigned long)(u32)regs->sp)
++ __get_user_nocheck(*(u32 *)&regs->bp, saved_bp, sizeof(u32))
+ #else
+- get_user(*(u32 *)&regs->bp,
+- (u32 __user __force *)(unsigned long)(u32)regs->sp)
++ get_user(regs->bp, saved_bp)
+ #endif
+ ) {
+
+diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
+index 983e5d3..d660273 100644
+--- a/arch/x86/entry/entry_32.S
++++ b/arch/x86/entry/entry_32.S
+@@ -147,13 +147,157 @@
+ movl \reg, PT_GS(%esp)
+ .endm
+ .macro SET_KERNEL_GS reg
++
++#ifdef CONFIG_CC_STACKPROTECTOR
+ movl $(__KERNEL_STACK_CANARY), \reg
++#elif defined(CONFIG_PAX_MEMORY_UDEREF)
++ movl $(__USER_DS), \reg
++#else
++ xorl \reg, \reg
++#endif
++
+ movl \reg, %gs
+ .endm
+
+ #endif /* CONFIG_X86_32_LAZY_GS */
+
+-.macro SAVE_ALL pt_regs_ax=%eax
++.macro pax_enter_kernel
++#ifdef CONFIG_PAX_KERNEXEC
++ call pax_enter_kernel
++#endif
++.endm
++
++.macro pax_exit_kernel
++#ifdef CONFIG_PAX_KERNEXEC
++ call pax_exit_kernel
++#endif
++.endm
++
++#ifdef CONFIG_PAX_KERNEXEC
++ENTRY(pax_enter_kernel)
++#ifdef CONFIG_PARAVIRT
++ pushl %eax
++ pushl %ecx
++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0)
++ mov %eax, %esi
++#else
++ mov %cr0, %esi
++#endif
++ bts $X86_CR0_WP_BIT, %esi
++ jnc 1f
++ mov %cs, %esi
++ cmp $__KERNEL_CS, %esi
++ jz 3f
++ ljmp $__KERNEL_CS, $3f
++1: ljmp $__KERNEXEC_KERNEL_CS, $2f
++2:
++#ifdef CONFIG_PARAVIRT
++ mov %esi, %eax
++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
++#else
++ mov %esi, %cr0
++#endif
++3:
++#ifdef CONFIG_PARAVIRT
++ popl %ecx
++ popl %eax
++#endif
++ ret
++ENDPROC(pax_enter_kernel)
++
++ENTRY(pax_exit_kernel)
++#ifdef CONFIG_PARAVIRT
++ pushl %eax
++ pushl %ecx
++#endif
++ mov %cs, %esi
++ cmp $__KERNEXEC_KERNEL_CS, %esi
++ jnz 2f
++#ifdef CONFIG_PARAVIRT
++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);
++ mov %eax, %esi
++#else
++ mov %cr0, %esi
++#endif
++ btr $X86_CR0_WP_BIT, %esi
++ ljmp $__KERNEL_CS, $1f
++1:
++#ifdef CONFIG_PARAVIRT
++ mov %esi, %eax
++ call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0);
++#else
++ mov %esi, %cr0
++#endif
++2:
++#ifdef CONFIG_PARAVIRT
++ popl %ecx
++ popl %eax
++#endif
++ ret
++ENDPROC(pax_exit_kernel)
++#endif
++
++ .macro pax_erase_kstack
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++ call pax_erase_kstack
++#endif
++ .endm
++
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++/*
++ * ebp: thread_info
++ */
++ENTRY(pax_erase_kstack)
++ pushl %edi
++ pushl %ecx
++ pushl %eax
++ pushl %ebp
++
++ GET_THREAD_INFO(%ebp)
++ mov TI_lowest_stack(%ebp), %edi
++ mov $-0xBEEF, %eax
++ std
++
++1: mov %edi, %ecx
++ and $THREAD_SIZE_asm - 1, %ecx
++ shr $2, %ecx
++ repne scasl
++ jecxz 2f
++
++ cmp $2*16, %ecx
++ jc 2f
++
++ mov $2*16, %ecx
++ repe scasl
++ jecxz 2f
++ jne 1b
++
++2: cld
++ or $2*4, %edi
++ mov %esp, %ecx
++ sub %edi, %ecx
++
++ cmp $THREAD_SIZE_asm, %ecx
++ jb 3f
++ ud2
++3:
++
++ shr $2, %ecx
++ rep stosl
++
++ mov TI_task_thread_sp0(%ebp), %edi
++ sub $128, %edi
++ mov %edi, TI_lowest_stack(%ebp)
++
++ popl %ebp
++ popl %eax
++ popl %ecx
++ popl %edi
++ ret
++ENDPROC(pax_erase_kstack)
++#endif
++
++.macro __SAVE_ALL pt_regs_ax, _DS
+ cld
+ PUSH_GS
+ pushl %fs
+@@ -166,7 +310,7 @@
+ pushl %edx
+ pushl %ecx
+ pushl %ebx
+- movl $(__USER_DS), %edx
++ movl $\_DS, %edx
+ movl %edx, %ds
+ movl %edx, %es
+ movl $(__KERNEL_PERCPU), %edx
+@@ -174,6 +318,15 @@
+ SET_KERNEL_GS %edx
+ .endm
+
++.macro SAVE_ALL pt_regs_ax=%eax
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ __SAVE_ALL \pt_regs_ax, __KERNEL_DS
++ pax_enter_kernel
++#else
++ __SAVE_ALL \pt_regs_ax, __USER_DS
++#endif
++.endm
++
+ .macro RESTORE_INT_REGS
+ popl %ebx
+ popl %ecx
+@@ -213,7 +366,7 @@ ENTRY(ret_from_fork)
+ movl %esp, %eax
+ call syscall_return_slowpath
+ jmp restore_all
+-END(ret_from_fork)
++ENDPROC(ret_from_fork)
+
+ ENTRY(ret_from_kernel_thread)
+ pushl %eax
+@@ -257,15 +410,23 @@ ret_from_intr:
+ andl $SEGMENT_RPL_MASK, %eax
+ #endif
+ cmpl $USER_RPL, %eax
++
++#ifdef CONFIG_PAX_KERNEXEC
++ jae resume_userspace
++
++ pax_exit_kernel
++ jmp resume_kernel
++#else
+ jb resume_kernel # not returning to v8086 or userspace
++#endif
+
+ ENTRY(resume_userspace)
+ DISABLE_INTERRUPTS(CLBR_ANY)
+ TRACE_IRQS_OFF
+ movl %esp, %eax
+ call prepare_exit_to_usermode
+- jmp restore_all
+-END(ret_from_exception)
++ jmp .Lsyscall_32_done
++ENDPROC(ret_from_exception)
+
+ #ifdef CONFIG_PREEMPT
+ ENTRY(resume_kernel)
+@@ -277,7 +438,7 @@ need_resched:
+ jz restore_all
+ call preempt_schedule_irq
+ jmp need_resched
+-END(resume_kernel)
++ENDPROC(resume_kernel)
+ #endif
+
+ GLOBAL(__begin_SYSENTER_singlestep_region)
+@@ -344,6 +505,10 @@ sysenter_past_esp:
+ pushl %eax /* pt_regs->orig_ax */
+ SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
+
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
++
+ /*
+ * SYSENTER doesn't filter flags, so we need to clear NT, AC
+ * and TF ourselves. To save a few cycles, we can check whether
+@@ -379,11 +544,20 @@ sysenter_past_esp:
+ ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
+ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
+
++#ifdef CONFIG_PAX_RANDKSTACK
++ movl %esp, %eax
++ call pax_randomize_kstack
++#endif
++
++ pax_erase_kstack
++
+ /* Opportunistic SYSEXIT */
+ TRACE_IRQS_ON /* User mode traces as IRQs on. */
+ movl PT_EIP(%esp), %edx /* pt_regs->ip */
+ movl PT_OLDESP(%esp), %ecx /* pt_regs->sp */
+ 1: mov PT_FS(%esp), %fs
++2: mov PT_DS(%esp), %ds
++3: mov PT_ES(%esp), %es
+ PTGS_TO_GS
+ popl %ebx /* pt_regs->bx */
+ addl $2*4, %esp /* skip pt_regs->cx and pt_regs->dx */
+@@ -409,10 +583,16 @@ sysenter_past_esp:
+ sysexit
+
+ .pushsection .fixup, "ax"
+-2: movl $0, PT_FS(%esp)
++4: movl $0, PT_FS(%esp)
++ jmp 1b
++5: movl $0, PT_DS(%esp)
++ jmp 1b
++6: movl $0, PT_ES(%esp)
+ jmp 1b
+ .popsection
+- _ASM_EXTABLE(1b, 2b)
++ _ASM_EXTABLE(1b, 4b)
++ _ASM_EXTABLE(2b, 5b)
++ _ASM_EXTABLE(3b, 6b)
+ PTGS_TO_GS_EX
+
+ .Lsysenter_fix_flags:
+@@ -455,6 +635,10 @@ ENTRY(entry_INT80_32)
+ pushl %eax /* pt_regs->orig_ax */
+ SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
+
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
++
+ /*
+ * User mode is traced as though IRQs are on, and the interrupt gate
+ * turned them off.
+@@ -465,6 +649,13 @@ ENTRY(entry_INT80_32)
+ call do_int80_syscall_32
+ .Lsyscall_32_done:
+
++#ifdef CONFIG_PAX_RANDKSTACK
++ movl %esp, %eax
++ call pax_randomize_kstack
++#endif
++
++ pax_erase_kstack
++
+ restore_all:
+ TRACE_IRQS_IRET
+ restore_all_notrace:
+@@ -508,14 +699,34 @@ ldt_ss:
+ * compensating for the offset by changing to the ESPFIX segment with
+ * a base address that matches for the difference.
+ */
+-#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8)
++#define GDT_ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)(%ebx)
+ mov %esp, %edx /* load kernel esp */
+ mov PT_OLDESP(%esp), %eax /* load userspace esp */
+ mov %dx, %ax /* eax: new kernel esp */
+ sub %eax, %edx /* offset (low word is 0) */
++#ifdef CONFIG_SMP
++ movl PER_CPU_VAR(cpu_number), %ebx
++ shll $PAGE_SHIFT_asm, %ebx
++ addl $cpu_gdt_table, %ebx
++#else
++ movl $cpu_gdt_table, %ebx
++#endif
+ shr $16, %edx
+- mov %dl, GDT_ESPFIX_SS + 4 /* bits 16..23 */
+- mov %dh, GDT_ESPFIX_SS + 7 /* bits 24..31 */
++
++#ifdef CONFIG_PAX_KERNEXEC
++ mov %cr0, %esi
++ btr $X86_CR0_WP_BIT, %esi
++ mov %esi, %cr0
++#endif
++
++ mov %dl, 4 + GDT_ESPFIX_SS /* bits 16..23 */
++ mov %dh, 7 + GDT_ESPFIX_SS /* bits 24..31 */
++
++#ifdef CONFIG_PAX_KERNEXEC
++ bts $X86_CR0_WP_BIT, %esi
++ mov %esi, %cr0
++#endif
++
+ pushl $__ESPFIX_SS
+ pushl %eax /* new kernel esp */
+ /*
+@@ -539,8 +750,15 @@ ENDPROC(entry_INT80_32)
+ */
+ #ifdef CONFIG_X86_ESPFIX32
+ /* fixup the stack */
+- mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
+- mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
++#ifdef CONFIG_SMP
++ movl PER_CPU_VAR(cpu_number), %ebx
++ shll $PAGE_SHIFT_asm, %ebx
++ addl $cpu_gdt_table, %ebx
++#else
++ movl $cpu_gdt_table, %ebx
++#endif
++ mov 4 + GDT_ESPFIX_SS, %al /* bits 16..23 */
++ mov 7 + GDT_ESPFIX_SS, %ah /* bits 24..31 */
+ shl $16, %eax
+ addl %esp, %eax /* the adjusted stack pointer */
+ pushl $__KERNEL_DS
+@@ -576,7 +794,7 @@ ENTRY(irq_entries_start)
+ jmp common_interrupt
+ .align 8
+ .endr
+-END(irq_entries_start)
++ENDPROC(irq_entries_start)
+
+ /*
+ * the CPU automatically disables interrupts when executing an IRQ vector,
+@@ -623,7 +841,7 @@ ENTRY(coprocessor_error)
+ pushl $0
+ pushl $do_coprocessor_error
+ jmp error_code
+-END(coprocessor_error)
++ENDPROC(coprocessor_error)
+
+ ENTRY(simd_coprocessor_error)
+ ASM_CLAC
+@@ -637,20 +855,20 @@ ENTRY(simd_coprocessor_error)
+ pushl $do_simd_coprocessor_error
+ #endif
+ jmp error_code
+-END(simd_coprocessor_error)
++ENDPROC(simd_coprocessor_error)
+
+ ENTRY(device_not_available)
+ ASM_CLAC
+ pushl $-1 # mark this as an int
+ pushl $do_device_not_available
+ jmp error_code
+-END(device_not_available)
++ENDPROC(device_not_available)
+
+ #ifdef CONFIG_PARAVIRT
+ ENTRY(native_iret)
+ iret
+ _ASM_EXTABLE(native_iret, iret_exc)
+-END(native_iret)
++ENDPROC(native_iret)
+ #endif
+
+ ENTRY(overflow)
+@@ -658,59 +876,59 @@ ENTRY(overflow)
+ pushl $0
+ pushl $do_overflow
+ jmp error_code
+-END(overflow)
++ENDPROC(overflow)
+
+ ENTRY(bounds)
+ ASM_CLAC
+ pushl $0
+ pushl $do_bounds
+ jmp error_code
+-END(bounds)
++ENDPROC(bounds)
+
+ ENTRY(invalid_op)
+ ASM_CLAC
+ pushl $0
+ pushl $do_invalid_op
+ jmp error_code
+-END(invalid_op)
++ENDPROC(invalid_op)
+
+ ENTRY(coprocessor_segment_overrun)
+ ASM_CLAC
+ pushl $0
+ pushl $do_coprocessor_segment_overrun
+ jmp error_code
+-END(coprocessor_segment_overrun)
++ENDPROC(coprocessor_segment_overrun)
+
+ ENTRY(invalid_TSS)
+ ASM_CLAC
+ pushl $do_invalid_TSS
+ jmp error_code
+-END(invalid_TSS)
++ENDPROC(invalid_TSS)
+
+ ENTRY(segment_not_present)
+ ASM_CLAC
+ pushl $do_segment_not_present
+ jmp error_code
+-END(segment_not_present)
++ENDPROC(segment_not_present)
+
+ ENTRY(stack_segment)
+ ASM_CLAC
+ pushl $do_stack_segment
+ jmp error_code
+-END(stack_segment)
++ENDPROC(stack_segment)
+
+ ENTRY(alignment_check)
+ ASM_CLAC
+ pushl $do_alignment_check
+ jmp error_code
+-END(alignment_check)
++ENDPROC(alignment_check)
+
+ ENTRY(divide_error)
+ ASM_CLAC
+ pushl $0 # no error code
+ pushl $do_divide_error
+ jmp error_code
+-END(divide_error)
++ENDPROC(divide_error)
+
+ #ifdef CONFIG_X86_MCE
+ ENTRY(machine_check)
+@@ -718,7 +936,7 @@ ENTRY(machine_check)
+ pushl $0
+ pushl machine_check_vector
+ jmp error_code
+-END(machine_check)
++ENDPROC(machine_check)
+ #endif
+
+ ENTRY(spurious_interrupt_bug)
+@@ -726,7 +944,7 @@ ENTRY(spurious_interrupt_bug)
+ pushl $0
+ pushl $do_spurious_interrupt_bug
+ jmp error_code
+-END(spurious_interrupt_bug)
++ENDPROC(spurious_interrupt_bug)
+
+ #ifdef CONFIG_XEN
+ ENTRY(xen_hypervisor_callback)
+@@ -825,7 +1043,7 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR,
+
+ ENTRY(mcount)
+ ret
+-END(mcount)
++ENDPROC(mcount)
+
+ ENTRY(ftrace_caller)
+ pushl %eax
+@@ -855,7 +1073,7 @@ ftrace_graph_call:
+ .globl ftrace_stub
+ ftrace_stub:
+ ret
+-END(ftrace_caller)
++ENDPROC(ftrace_caller)
+
+ ENTRY(ftrace_regs_caller)
+ pushf /* push flags before compare (in cs location) */
+@@ -953,7 +1171,7 @@ trace:
+ popl %ecx
+ popl %eax
+ jmp ftrace_stub
+-END(mcount)
++ENDPROC(mcount)
+ #endif /* CONFIG_DYNAMIC_FTRACE */
+ #endif /* CONFIG_FUNCTION_TRACER */
+
+@@ -971,7 +1189,7 @@ ENTRY(ftrace_graph_caller)
+ popl %ecx
+ popl %eax
+ ret
+-END(ftrace_graph_caller)
++ENDPROC(ftrace_graph_caller)
+
+ .globl return_to_handler
+ return_to_handler:
+@@ -990,7 +1208,7 @@ ENTRY(trace_page_fault)
+ ASM_CLAC
+ pushl $trace_do_page_fault
+ jmp error_code
+-END(trace_page_fault)
++ENDPROC(trace_page_fault)
+ #endif
+
+ ENTRY(page_fault)
+@@ -1019,16 +1237,19 @@ error_code:
+ movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
+ REG_TO_PTGS %ecx
+ SET_KERNEL_GS %ecx
+- movl $(__USER_DS), %ecx
++ movl $(__KERNEL_DS), %ecx
+ movl %ecx, %ds
+ movl %ecx, %es
++
++ pax_enter_kernel
++
+ TRACE_IRQS_OFF
+ movl %esp, %eax # pt_regs pointer
+ call *%edi
+ jmp ret_from_exception
+-END(page_fault)
++ENDPROC(page_fault)
+
+-ENTRY(debug)
++ENTRY(int1)
+ /*
+ * #DB can happen at the first instruction of
+ * entry_SYSENTER_32 or in Xen's SYSENTER prologue. If this
+@@ -1045,7 +1266,13 @@ ENTRY(debug)
+ movl %esp, %eax # pt_regs pointer
+
+ /* Are we currently on the SYSENTER stack? */
+- PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx)
++#ifdef CONFIG_SMP
++ imul $TSS_size, PER_CPU_VAR(cpu_number), %ecx
++ lea cpu_tss(%ecx), %ecx
++#else
++ movl $cpu_tss, %ecx
++#endif
++ movl CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack(%ecx), %ecx
+ subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */
+ cmpl $SIZEOF_SYSENTER_stack, %ecx
+ jb .Ldebug_from_sysenter_stack
+@@ -1062,7 +1289,7 @@ ENTRY(debug)
+ call do_debug
+ movl %ebp, %esp
+ jmp ret_from_exception
+-END(debug)
++ENDPROC(int1)
+
+ /*
+ * NMI is doubly nasty. It can happen on the first instruction of
+@@ -1087,13 +1314,22 @@ ENTRY(nmi)
+ movl %esp, %eax # pt_regs pointer
+
+ /* Are we currently on the SYSENTER stack? */
+- PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx)
++#ifdef CONFIG_SMP
++ imul $TSS_size, PER_CPU_VAR(cpu_number), %ecx
++ lea cpu_tss(%ecx), %ecx
++#else
++ movl $cpu_tss, %ecx
++#endif
++ movl CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack(%ecx), %ecx
+ subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */
+ cmpl $SIZEOF_SYSENTER_stack, %ecx
+ jb .Lnmi_from_sysenter_stack
+
+ /* Not on SYSENTER stack. */
+ call do_nmi
++
++ pax_exit_kernel
++
+ jmp restore_all_notrace
+
+ .Lnmi_from_sysenter_stack:
+@@ -1105,6 +1341,9 @@ ENTRY(nmi)
+ movl PER_CPU_VAR(cpu_current_top_of_stack), %esp
+ call do_nmi
+ movl %ebp, %esp
++
++ pax_exit_kernel
++
+ jmp restore_all_notrace
+
+ #ifdef CONFIG_X86_ESPFIX32
+@@ -1124,11 +1363,14 @@ nmi_espfix_stack:
+ FIXUP_ESPFIX_STACK # %eax == %esp
+ xorl %edx, %edx # zero error code
+ call do_nmi
++
++ pax_exit_kernel
++
+ RESTORE_REGS
+ lss 12+4(%esp), %esp # back to espfix stack
+ jmp irq_return
+ #endif
+-END(nmi)
++ENDPROC(nmi)
+
+ ENTRY(int3)
+ ASM_CLAC
+@@ -1139,17 +1381,17 @@ ENTRY(int3)
+ movl %esp, %eax # pt_regs pointer
+ call do_int3
+ jmp ret_from_exception
+-END(int3)
++ENDPROC(int3)
+
+ ENTRY(general_protection)
+ pushl $do_general_protection
+ jmp error_code
+-END(general_protection)
++ENDPROC(general_protection)
+
+ #ifdef CONFIG_KVM_GUEST
+ ENTRY(async_page_fault)
+ ASM_CLAC
+ pushl $do_async_page_fault
+ jmp error_code
+-END(async_page_fault)
++ENDPROC(async_page_fault)
+ #endif
+diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
+index 9ee0da1..2421755 100644
+--- a/arch/x86/entry/entry_64.S
++++ b/arch/x86/entry/entry_64.S
+@@ -36,6 +36,8 @@
+ #include <asm/smap.h>
+ #include <asm/pgtable_types.h>
+ #include <linux/err.h>
++#include <asm/pgtable.h>
++#include <asm/alternative-asm.h>
+
+ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
+ #include <linux/elf-em.h>
+@@ -53,6 +55,395 @@ ENTRY(native_usergs_sysret64)
+ ENDPROC(native_usergs_sysret64)
+ #endif /* CONFIG_PARAVIRT */
+
++ .macro ljmpq sel, off
++#if defined(CONFIG_MPSC) || defined(CONFIG_MCORE2) || defined (CONFIG_MATOM)
++ .byte 0x48; ljmp *1234f(%rip)
++ .pushsection .rodata
++ .align 16
++ 1234: .quad \off; .word \sel
++ .popsection
++#else
++ pushq $\sel
++ pushq $\off
++ lretq
++#endif
++ .endm
++
++ .macro pax_enter_kernel
++ pax_set_fptr_mask
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ call pax_enter_kernel
++#endif
++ .endm
++
++ .macro pax_exit_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ call pax_exit_kernel
++#endif
++ .endm
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ENTRY(pax_enter_kernel)
++ pushq %rdi
++
++#ifdef CONFIG_PARAVIRT
++ PV_SAVE_REGS(CLBR_RDI)
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++ GET_CR0_INTO_RDI
++ bts $X86_CR0_WP_BIT,%rdi
++ jnc 3f
++ mov %cs,%edi
++ cmp $__KERNEL_CS,%edi
++ jnz 2f
++1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ ALTERNATIVE "jmp 111f", "", X86_FEATURE_PCID
++ GET_CR3_INTO_RDI
++ cmp $0,%dil
++ jnz 112f
++ mov $__KERNEL_DS,%edi
++ mov %edi,%ss
++ jmp 111f
++112: cmp $1,%dil
++ jz 113f
++ ud2
++113: sub $4097,%rdi
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ mov $__UDEREF_KERNEL_DS,%edi
++ mov %edi,%ss
++111:
++#endif
++
++#ifdef CONFIG_PARAVIRT
++ PV_RESTORE_REGS(CLBR_RDI)
++#endif
++
++ popq %rdi
++ pax_force_retaddr
++ retq
++
++#ifdef CONFIG_PAX_KERNEXEC
++2: ljmpq __KERNEL_CS,1b
++3: ljmpq __KERNEXEC_KERNEL_CS,4f
++4: SET_RDI_INTO_CR0
++ jmp 1b
++#endif
++ENDPROC(pax_enter_kernel)
++
++ENTRY(pax_exit_kernel)
++ pushq %rdi
++
++#ifdef CONFIG_PARAVIRT
++ PV_SAVE_REGS(CLBR_RDI)
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++ mov %cs,%rdi
++ cmp $__KERNEXEC_KERNEL_CS,%edi
++ jz 2f
++ GET_CR0_INTO_RDI
++ bts $X86_CR0_WP_BIT,%rdi
++ jnc 4f
++1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ ALTERNATIVE "jmp 111f", "", X86_FEATURE_PCID
++ mov %ss,%edi
++ cmp $__UDEREF_KERNEL_DS,%edi
++ jnz 111f
++ GET_CR3_INTO_RDI
++ cmp $0,%dil
++ jz 112f
++ ud2
++112: add $4097,%rdi
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ mov $__KERNEL_DS,%edi
++ mov %edi,%ss
++111:
++#endif
++
++#ifdef CONFIG_PARAVIRT
++ PV_RESTORE_REGS(CLBR_RDI);
++#endif
++
++ popq %rdi
++ pax_force_retaddr
++ retq
++
++#ifdef CONFIG_PAX_KERNEXEC
++2: GET_CR0_INTO_RDI
++ btr $X86_CR0_WP_BIT,%rdi
++ jnc 4f
++ ljmpq __KERNEL_CS,3f
++3: SET_RDI_INTO_CR0
++ jmp 1b
++4: ud2
++ jmp 4b
++#endif
++ENDPROC(pax_exit_kernel)
++#endif
++
++ .macro pax_enter_kernel_user
++ pax_set_fptr_mask
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ call pax_enter_kernel_user
++#endif
++ .endm
++
++ .macro pax_exit_kernel_user
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ call pax_exit_kernel_user
++#endif
++#ifdef CONFIG_PAX_RANDKSTACK
++ pushq %rax
++ pushq %r11
++ call pax_randomize_kstack
++ popq %r11
++ popq %rax
++#endif
++ .endm
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ENTRY(pax_enter_kernel_user)
++ pushq %rdi
++ pushq %rbx
++
++#ifdef CONFIG_PARAVIRT
++ PV_SAVE_REGS(CLBR_RDI)
++#endif
++
++ ALTERNATIVE "jmp 111f", "", X86_FEATURE_PCID
++ GET_CR3_INTO_RDI
++ cmp $1,%dil
++ jnz 4f
++ sub $4097,%rdi
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ jmp 3f
++111:
++
++ GET_CR3_INTO_RDI
++ mov %rdi,%rbx
++ add $__START_KERNEL_map,%rbx
++ sub phys_base(%rip),%rbx
++
++#ifdef CONFIG_PARAVIRT
++ pushq %rdi
++ i = 0
++ .rept USER_PGD_PTRS
++ mov i*8(%rbx),%rsi
++ mov $0,%sil
++ lea i*8(%rbx),%rdi
++ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd_batched)
++ i = i + 1
++ .endr
++ popq %rdi
++#else
++ i = 0
++ .rept USER_PGD_PTRS
++ movb $0,i*8(%rbx)
++ i = i + 1
++ .endr
++#endif
++
++ SET_RDI_INTO_CR3
++
++#ifdef CONFIG_PAX_KERNEXEC
++ GET_CR0_INTO_RDI
++ bts $X86_CR0_WP_BIT,%rdi
++ SET_RDI_INTO_CR0
++#endif
++
++3:
++
++#ifdef CONFIG_PARAVIRT
++ PV_RESTORE_REGS(CLBR_RDI)
++#endif
++
++ popq %rbx
++ popq %rdi
++ pax_force_retaddr
++ retq
++4: ud2
++ENDPROC(pax_enter_kernel_user)
++
++ENTRY(pax_exit_kernel_user)
++ pushq %rdi
++ pushq %rbx
++
++#ifdef CONFIG_PARAVIRT
++ PV_SAVE_REGS(CLBR_RDI)
++#endif
++
++ GET_CR3_INTO_RDI
++ ALTERNATIVE "jmp 1f", "", X86_FEATURE_PCID
++ cmp $0,%dil
++ jnz 3f
++ add $4097,%rdi
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ jmp 2f
++1:
++
++ mov %rdi,%rbx
++
++#ifdef CONFIG_PAX_KERNEXEC
++ GET_CR0_INTO_RDI
++ btr $X86_CR0_WP_BIT,%rdi
++ jnc 3f
++ SET_RDI_INTO_CR0
++#endif
++
++ add $__START_KERNEL_map,%rbx
++ sub phys_base(%rip),%rbx
++
++#ifdef CONFIG_PARAVIRT
++ i = 0
++ .rept USER_PGD_PTRS
++ mov i*8(%rbx),%rsi
++ mov $0x67,%sil
++ lea i*8(%rbx),%rdi
++ call PARA_INDIRECT(pv_mmu_ops+PV_MMU_set_pgd_batched)
++ i = i + 1
++ .endr
++#else
++ i = 0
++ .rept USER_PGD_PTRS
++ movb $0x67,i*8(%rbx)
++ i = i + 1
++ .endr
++#endif
++
++2:
++
++#ifdef CONFIG_PARAVIRT
++ PV_RESTORE_REGS(CLBR_RDI)
++#endif
++
++ popq %rbx
++ popq %rdi
++ pax_force_retaddr
++ retq
++3: ud2
++ENDPROC(pax_exit_kernel_user)
++#endif
++
++ .macro pax_enter_kernel_nmi
++ pax_set_fptr_mask
++
++#ifdef CONFIG_PAX_KERNEXEC
++ GET_CR0_INTO_RDI
++ bts $X86_CR0_WP_BIT,%rdi
++ jc 110f
++ SET_RDI_INTO_CR0
++ or $2,%ebx
++110:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ ALTERNATIVE "jmp 111f", "", X86_FEATURE_PCID
++ GET_CR3_INTO_RDI
++ cmp $0,%dil
++ jz 111f
++ sub $4097,%rdi
++ or $4,%ebx
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ mov $__UDEREF_KERNEL_DS,%edi
++ mov %edi,%ss
++111:
++#endif
++ .endm
++
++ .macro pax_exit_kernel_nmi
++#ifdef CONFIG_PAX_KERNEXEC
++ btr $1,%ebx
++ jnc 110f
++ GET_CR0_INTO_RDI
++ btr $X86_CR0_WP_BIT,%rdi
++ SET_RDI_INTO_CR0
++110:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ ALTERNATIVE "jmp 111f", "", X86_FEATURE_PCID
++ btr $2,%ebx
++ jnc 111f
++ GET_CR3_INTO_RDI
++ add $4097,%rdi
++ bts $63,%rdi
++ SET_RDI_INTO_CR3
++ mov $__KERNEL_DS,%edi
++ mov %edi,%ss
++111:
++#endif
++ .endm
++
++ .macro pax_erase_kstack
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++ call pax_erase_kstack
++#endif
++ .endm
++
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++ENTRY(pax_erase_kstack)
++ pushq %rdi
++ pushq %rcx
++ pushq %rax
++ pushq %r11
++
++ GET_THREAD_INFO(%r11)
++ mov TI_lowest_stack(%r11), %rdi
++ mov $-0xBEEF, %rax
++ std
++
++1: mov %edi, %ecx
++ and $THREAD_SIZE_asm - 1, %ecx
++ shr $3, %ecx
++ repne scasq
++ jecxz 2f
++
++ cmp $2*8, %ecx
++ jc 2f
++
++ mov $2*8, %ecx
++ repe scasq
++ jecxz 2f
++ jne 1b
++
++2: cld
++ or $2*8, %rdi
++ mov %esp, %ecx
++ sub %edi, %ecx
++
++ cmp $THREAD_SIZE_asm, %rcx
++ jb 3f
++ ud2
++3:
++
++ shr $3, %ecx
++ rep stosq
++
++ mov TI_task_thread_sp0(%r11), %rdi
++ sub $256, %rdi
++ mov %rdi, TI_lowest_stack(%r11)
++
++ popq %r11
++ popq %rax
++ popq %rcx
++ popq %rdi
++ pax_force_retaddr
++ ret
++ENDPROC(pax_erase_kstack)
++#endif
++
+ .macro TRACE_IRQS_IRETQ
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ bt $9, EFLAGS(%rsp) /* interrupts off? */
+@@ -88,7 +479,7 @@ ENDPROC(native_usergs_sysret64)
+ .endm
+
+ .macro TRACE_IRQS_IRETQ_DEBUG
+- bt $9, EFLAGS(%rsp) /* interrupts off? */
++ bt $X86_EFLAGS_IF_BIT, EFLAGS(%rsp) /* interrupts off? */
+ jnc 1f
+ TRACE_IRQS_ON_DEBUG
+ 1:
+@@ -175,11 +566,22 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
+ pushq %r11 /* pt_regs->r11 */
+ sub $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
+
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq %r12, R12(%rsp)
++#endif
++
++ pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
++
+ /*
+ * If we need to do entry work or if we guess we'll need to do
+ * exit work, go straight to the slow path.
+ */
+- testl $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
++ GET_THREAD_INFO(%rcx)
++ testl $_TIF_WORK_SYSCALL_ENTRY|_TIF_ALLWORK_MASK, TI_flags(%rcx)
+ jnz entry_SYSCALL64_slow_path
+
+ entry_SYSCALL_64_fastpath:
+@@ -217,9 +619,13 @@ entry_SYSCALL_64_fastpath:
+ */
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF
+- testl $_TIF_ALLWORK_MASK, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
++ GET_THREAD_INFO(%rcx)
++ testl $_TIF_ALLWORK_MASK, TI_flags(%rcx)
+ jnz 1f
+
++ pax_exit_kernel_user
++ pax_erase_kstack
++
+ LOCKDEP_SYS_EXIT
+ TRACE_IRQS_ON /* user mode is traced as IRQs on */
+ movq RIP(%rsp), %rcx
+@@ -248,6 +654,9 @@ entry_SYSCALL64_slow_path:
+ call do_syscall_64 /* returns with IRQs disabled */
+
+ return_from_SYSCALL_64:
++ pax_exit_kernel_user
++ pax_erase_kstack
++
+ RESTORE_EXTRA_REGS
+ TRACE_IRQS_IRETQ /* we're about to change IF */
+
+@@ -322,7 +731,7 @@ syscall_return_via_sysret:
+ opportunistic_sysret_failed:
+ SWAPGS
+ jmp restore_c_regs_and_iret
+-END(entry_SYSCALL_64)
++ENDPROC(entry_SYSCALL_64)
+
+ ENTRY(stub_ptregs_64)
+ /*
+@@ -349,13 +758,13 @@ ENTRY(stub_ptregs_64)
+ 1:
+ /* Called from C */
+ jmp *%rax /* called from C */
+-END(stub_ptregs_64)
++ENDPROC(stub_ptregs_64)
+
+ .macro ptregs_stub func
+ ENTRY(ptregs_\func)
+ leaq \func(%rip), %rax
+ jmp stub_ptregs_64
+-END(ptregs_\func)
++ENDPROC(ptregs_\func)
+ .endm
+
+ /* Instantiate ptregs_stub for each ptregs-using syscall */
+@@ -397,10 +806,12 @@ ENTRY(ret_from_fork)
+ 1:
+ movq %rsp, %rdi
+ call syscall_return_slowpath /* returns with IRQs disabled */
++ pax_exit_kernel_user
++ pax_erase_kstack
+ TRACE_IRQS_ON /* user mode is traced as IRQS on */
+ SWAPGS
+ jmp restore_regs_and_iret
+-END(ret_from_fork)
++ENDPROC(ret_from_fork)
+
+ /*
+ * Build the entry stubs with some assembler magic.
+@@ -415,7 +826,7 @@ ENTRY(irq_entries_start)
+ jmp common_interrupt
+ .align 8
+ .endr
+-END(irq_entries_start)
++ENDPROC(irq_entries_start)
+
+ /*
+ * Interrupt entry/exit.
+@@ -441,6 +852,12 @@ END(irq_entries_start)
+ */
+ SWAPGS
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ pax_enter_kernel_user
++#else
++ pax_enter_kernel
++#endif
++
+ /*
+ * We need to tell lockdep that IRQs are off. We can't do this until
+ * we fix gsbase, and we should do it before enter_from_user_mode
+@@ -453,7 +870,9 @@ END(irq_entries_start)
+
+ CALL_enter_from_user_mode
+
+-1:
++ jmp 2f
++1: pax_enter_kernel
++2:
+ /*
+ * Save previous stack pointer, optionally switch to interrupt stack.
+ * irq_count is used to check if a CPU is already on an interrupt stack
+@@ -465,6 +884,7 @@ END(irq_entries_start)
+ incl PER_CPU_VAR(irq_count)
+ cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
+ pushq %rdi
++
+ /* We entered an interrupt context - irqs are off: */
+ TRACE_IRQS_OFF
+
+@@ -496,6 +916,8 @@ ret_from_intr:
+ GLOBAL(retint_user)
+ mov %rsp,%rdi
+ call prepare_exit_to_usermode
++ pax_exit_kernel_user
++# pax_erase_kstack
+ TRACE_IRQS_IRETQ
+ SWAPGS
+ jmp restore_regs_and_iret
+@@ -513,6 +935,21 @@ retint_kernel:
+ jmp 0b
+ 1:
+ #endif
++
++ pax_exit_kernel
++
++#if defined(CONFIG_EFI) && defined(CONFIG_PAX_KERNEXEC_PLUGIN)
++ /* This is a quirk to allow IRQs/NMIs/MCEs during early EFI setup,
++ * namely calling EFI runtime services with a phys mapping. We're
++ * starting off with NOPs and patch in the real instrumentation
++ * (BTS/OR) before starting any userland process; even before starting
++ * up the APs.
++ */
++ ALTERNATIVE "", "pax_force_retaddr 16*8", X86_FEATURE_ALWAYS
++#else
++ pax_force_retaddr RIP
++#endif
++
+ /*
+ * The iretq could re-enable interrupts:
+ */
+@@ -556,15 +993,15 @@ native_irq_return_ldt:
+ SWAPGS
+ movq PER_CPU_VAR(espfix_waddr), %rdi
+ movq %rax, (0*8)(%rdi) /* RAX */
+- movq (2*8)(%rsp), %rax /* RIP */
++ movq (2*8 + RIP-RIP)(%rsp), %rax /* RIP */
+ movq %rax, (1*8)(%rdi)
+- movq (3*8)(%rsp), %rax /* CS */
++ movq (2*8 + CS-RIP)(%rsp), %rax /* CS */
+ movq %rax, (2*8)(%rdi)
+- movq (4*8)(%rsp), %rax /* RFLAGS */
++ movq (2*8 + EFLAGS-RIP)(%rsp), %rax /* RFLAGS */
+ movq %rax, (3*8)(%rdi)
+- movq (6*8)(%rsp), %rax /* SS */
++ movq (2*8 + SS-RIP)(%rsp), %rax /* SS */
+ movq %rax, (5*8)(%rdi)
+- movq (5*8)(%rsp), %rax /* RSP */
++ movq (2*8 + RSP-RIP)(%rsp), %rax /* RSP */
+ movq %rax, (4*8)(%rdi)
+ andl $0xffff0000, %eax
+ popq %rdi
+@@ -574,7 +1011,7 @@ native_irq_return_ldt:
+ popq %rax
+ jmp native_irq_return_iret
+ #endif
+-END(common_interrupt)
++ENDPROC(common_interrupt)
+
+ /*
+ * APIC interrupts.
+@@ -586,7 +1023,7 @@ ENTRY(\sym)
+ .Lcommon_\sym:
+ interrupt \do_sym
+ jmp ret_from_intr
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+
+ #ifdef CONFIG_TRACING
+@@ -651,7 +1088,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
+ /*
+ * Exception entry points.
+ */
+-#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss) + (TSS_ist + ((x) - 1) * 8)
++#define CPU_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r13)
+
+ .macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
+ ENTRY(\sym)
+@@ -698,6 +1135,12 @@ ENTRY(\sym)
+ .endif
+
+ .if \shift_ist != -1
++#ifdef CONFIG_SMP
++ imul $TSS_size, PER_CPU_VAR(cpu_number), %r13d
++ leaq cpu_tss(%r13), %r13
++#else
++ leaq cpu_tss(%rip), %r13
++#endif
+ subq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist)
+ .endif
+
+@@ -741,7 +1184,7 @@ ENTRY(\sym)
+
+ jmp error_exit /* %ebx: no swapgs flag */
+ .endif
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+
+ #ifdef CONFIG_TRACING
+@@ -783,8 +1226,9 @@ ENTRY(native_load_gs_index)
+ 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
+ SWAPGS
+ popfq
++ pax_force_retaddr
+ ret
+-END(native_load_gs_index)
++ENDPROC(native_load_gs_index)
+
+ _ASM_EXTABLE(.Lgs_change, bad_gs)
+ .section .fixup, "ax"
+@@ -812,8 +1256,9 @@ ENTRY(do_softirq_own_stack)
+ call __do_softirq
+ leaveq
+ decl PER_CPU_VAR(irq_count)
++ pax_force_retaddr
+ ret
+-END(do_softirq_own_stack)
++ENDPROC(do_softirq_own_stack)
+
+ #ifdef CONFIG_XEN
+ idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0
+@@ -849,7 +1294,7 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */
+ call xen_maybe_preempt_hcall
+ #endif
+ jmp error_exit
+-END(xen_do_hypervisor_callback)
++ENDPROC(xen_do_hypervisor_callback)
+
+ /*
+ * Hypervisor uses this for application faults while it executes.
+@@ -894,7 +1339,7 @@ ENTRY(xen_failsafe_callback)
+ SAVE_C_REGS
+ SAVE_EXTRA_REGS
+ jmp error_exit
+-END(xen_failsafe_callback)
++ENDPROC(xen_failsafe_callback)
+
+ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+ xen_hvm_callback_vector xen_evtchn_do_upcall
+@@ -906,7 +1351,7 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+ hyperv_callback_vector hyperv_vector_handler
+ #endif /* CONFIG_HYPERV */
+
+-idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
++idtentry int1 do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
+ idtentry int3 do_int3 has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
+ idtentry stack_segment do_stack_segment has_error_code=1
+
+@@ -943,8 +1388,34 @@ ENTRY(paranoid_entry)
+ js 1f /* negative -> in kernel */
+ SWAPGS
+ xorl %ebx, %ebx
+-1: ret
+-END(paranoid_entry)
++1:
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ testb $3, CS+8(%rsp)
++ jz 1f
++ pax_enter_kernel_user
++ jmp 2f
++#endif
++1: pax_enter_kernel
++2:
++ pax_force_retaddr
++ ret
++ENDPROC(paranoid_entry)
++
++ENTRY(paranoid_entry_nmi)
++ cld
++ SAVE_C_REGS 8
++ SAVE_EXTRA_REGS 8
++ movl $1, %ebx
++ movl $MSR_GS_BASE, %ecx
++ rdmsr
++ testl %edx, %edx
++ js 1f /* negative -> in kernel */
++ SWAPGS
++ xorl %ebx, %ebx
++1: pax_enter_kernel_nmi
++ pax_force_retaddr
++ ret
++ENDPROC(paranoid_entry_nmi)
+
+ /*
+ * "Paranoid" exit path from exception stack. This is invoked
+@@ -961,19 +1432,26 @@ END(paranoid_entry)
+ ENTRY(paranoid_exit)
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF_DEBUG
+- testl %ebx, %ebx /* swapgs needed? */
++ testl $1, %ebx /* swapgs needed? */
+ jnz paranoid_exit_no_swapgs
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ pax_exit_kernel_user
++#else
++ pax_exit_kernel
++#endif
+ TRACE_IRQS_IRETQ
+ SWAPGS_UNSAFE_STACK
+ jmp paranoid_exit_restore
+ paranoid_exit_no_swapgs:
++ pax_exit_kernel
+ TRACE_IRQS_IRETQ_DEBUG
+ paranoid_exit_restore:
+ RESTORE_EXTRA_REGS
+ RESTORE_C_REGS
+ REMOVE_PT_GPREGS_FROM_STACK 8
++ pax_force_retaddr_bts
+ INTERRUPT_RETURN
+-END(paranoid_exit)
++ENDPROC(paranoid_exit)
+
+ /*
+ * Save all registers in pt_regs, and switch gs if needed.
+@@ -987,13 +1465,18 @@ ENTRY(error_entry)
+ testb $3, CS+8(%rsp)
+ jz .Lerror_kernelspace
+
+-.Lerror_entry_from_usermode_swapgs:
+ /*
+ * We entered from user mode or we're pretending to have entered
+ * from user mode due to an IRET fault.
+ */
+ SWAPGS
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ pax_enter_kernel_user
++#else
++ pax_enter_kernel
++#endif
++
+ .Lerror_entry_from_usermode_after_swapgs:
+ /*
+ * We need to tell lockdep that IRQs are off. We can't do this until
+@@ -1002,10 +1485,12 @@ ENTRY(error_entry)
+ */
+ TRACE_IRQS_OFF
+ CALL_enter_from_user_mode
++ pax_force_retaddr
+ ret
+
+ .Lerror_entry_done:
+ TRACE_IRQS_OFF
++ pax_force_retaddr
+ ret
+
+ /*
+@@ -1023,14 +1508,16 @@ ENTRY(error_entry)
+ cmpq %rax, RIP+8(%rsp)
+ je .Lbstep_iret
+ cmpq $.Lgs_change, RIP+8(%rsp)
+- jne .Lerror_entry_done
++ jne 1f
+
+ /*
+ * hack: .Lgs_change can fail with user gsbase. If this happens, fix up
+ * gsbase and proceed. We'll fix up the exception and land in
+ * .Lgs_change's error handler with kernel gsbase.
+ */
+- jmp .Lerror_entry_from_usermode_swapgs
++ SWAPGS
++1: pax_enter_kernel
++ jmp .Lerror_entry_done
+
+ .Lbstep_iret:
+ /* Fix truncated RIP */
+@@ -1044,6 +1531,12 @@ ENTRY(error_entry)
+ */
+ SWAPGS
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ pax_enter_kernel_user
++#else
++ pax_enter_kernel
++#endif
++
+ /*
+ * Pretend that the exception came from user mode: set up pt_regs
+ * as if we faulted immediately after IRET and clear EBX so that
+@@ -1054,11 +1547,11 @@ ENTRY(error_entry)
+ mov %rax, %rsp
+ decl %ebx
+ jmp .Lerror_entry_from_usermode_after_swapgs
+-END(error_entry)
++ENDPROC(error_entry)
+
+
+ /*
+- * On entry, EBS is a "return to kernel mode" flag:
++ * On entry, EBX is a "return to kernel mode" flag:
+ * 1: already in kernel mode, don't need SWAPGS
+ * 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode
+ */
+@@ -1066,10 +1559,10 @@ ENTRY(error_exit)
+ movl %ebx, %eax
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF
+- testl %eax, %eax
++ testl $1, %eax
+ jnz retint_kernel
+ jmp retint_user
+-END(error_exit)
++ENDPROC(error_exit)
+
+ /* Runs on exception stack */
+ ENTRY(nmi)
+@@ -1123,6 +1616,8 @@ ENTRY(nmi)
+ * other IST entries.
+ */
+
++ ASM_CLAC
++
+ /* Use %rdx as our temp variable throughout */
+ pushq %rdx
+
+@@ -1166,6 +1661,12 @@ ENTRY(nmi)
+ pushq %r14 /* pt_regs->r14 */
+ pushq %r15 /* pt_regs->r15 */
+
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ xorl %ebx, %ebx
++#endif
++
++ pax_enter_kernel_nmi
++
+ /*
+ * At this point we no longer need to worry about stack damage
+ * due to nesting -- we're on the normal thread stack and we're
+@@ -1176,12 +1677,19 @@ ENTRY(nmi)
+ movq $-1, %rsi
+ call do_nmi
+
++ pax_exit_kernel_nmi
++
+ /*
+ * Return back to user mode. We must *not* do the normal exit
+ * work, because we don't want to enable interrupts. Fortunately,
+ * do_nmi doesn't modify pt_regs.
+ */
+ SWAPGS
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ movq RBX(%rsp), %rbx
++#endif
++
+ jmp restore_c_regs_and_iret
+
+ .Lnmi_from_kernel:
+@@ -1303,6 +1811,7 @@ nested_nmi_out:
+ popq %rdx
+
+ /* We are returning to kernel mode, so this cannot result in a fault. */
++# pax_force_retaddr_bts
+ INTERRUPT_RETURN
+
+ first_nmi:
+@@ -1331,7 +1840,7 @@ first_nmi:
+ pushq %rsp /* RSP (minus 8 because of the previous push) */
+ addq $8, (%rsp) /* Fix up RSP */
+ pushfq /* RFLAGS */
+- pushq $__KERNEL_CS /* CS */
++ pushq 4*8(%rsp) /* CS */
+ pushq $1f /* RIP */
+ INTERRUPT_RETURN /* continues at repeat_nmi below */
+ 1:
+@@ -1376,20 +1885,22 @@ end_repeat_nmi:
+ ALLOC_PT_GPREGS_ON_STACK
+
+ /*
+- * Use paranoid_entry to handle SWAPGS, but no need to use paranoid_exit
++ * Use paranoid_entry_nmi to handle SWAPGS, but no need to use paranoid_exit
+ * as we should not be calling schedule in NMI context.
+ * Even with normal interrupts enabled. An NMI should not be
+ * setting NEED_RESCHED or anything that normal interrupts and
+ * exceptions might do.
+ */
+- call paranoid_entry
++ call paranoid_entry_nmi
+
+ /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
+ movq %rsp, %rdi
+ movq $-1, %rsi
+ call do_nmi
+
+- testl %ebx, %ebx /* swapgs needed? */
++ pax_exit_kernel_nmi
++
++ testl $1, %ebx /* swapgs needed? */
+ jnz nmi_restore
+ nmi_swapgs:
+ SWAPGS_UNSAFE_STACK
+@@ -1400,6 +1911,8 @@ nmi_restore:
+ /* Point RSP at the "iret" frame. */
+ REMOVE_PT_GPREGS_FROM_STACK 6*8
+
++ pax_force_retaddr_bts
++
+ /*
+ * Clear "NMI executing". Set DF first so that we can easily
+ * distinguish the remaining code between here and IRET from
+@@ -1417,9 +1930,9 @@ nmi_restore:
+ * mode, so this cannot result in a fault.
+ */
+ INTERRUPT_RETURN
+-END(nmi)
++ENDPROC(nmi)
+
+ ENTRY(ignore_sysret)
+ mov $-ENOSYS, %eax
+ sysret
+-END(ignore_sysret)
++ENDPROC(ignore_sysret)
+diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
+index e1721da..83f2c49 100644
+--- a/arch/x86/entry/entry_64_compat.S
++++ b/arch/x86/entry/entry_64_compat.S
+@@ -13,11 +13,39 @@
+ #include <asm/irqflags.h>
+ #include <asm/asm.h>
+ #include <asm/smap.h>
++#include <asm/pgtable.h>
+ #include <linux/linkage.h>
+ #include <linux/err.h>
++#include <asm/alternative-asm.h>
+
+ .section .entry.text, "ax"
+
++ .macro pax_enter_kernel_user
++ pax_set_fptr_mask
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ call pax_enter_kernel_user
++#endif
++ .endm
++
++ .macro pax_exit_kernel_user
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ call pax_exit_kernel_user
++#endif
++#ifdef CONFIG_PAX_RANDKSTACK
++ pushq %rax
++ pushq %r11
++ call pax_randomize_kstack
++ popq %r11
++ popq %rax
++#endif
++ .endm
++
++ .macro pax_erase_kstack
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++ call pax_erase_kstack
++#endif
++ .endm
++
+ /*
+ * 32-bit SYSENTER entry.
+ *
+@@ -74,23 +102,34 @@ ENTRY(entry_SYSENTER_compat)
+ pushq $__USER32_CS /* pt_regs->cs */
+ pushq $0 /* pt_regs->ip = 0 (placeholder) */
+ pushq %rax /* pt_regs->orig_ax */
++ xorl %eax,%eax
+ pushq %rdi /* pt_regs->di */
+ pushq %rsi /* pt_regs->si */
+ pushq %rdx /* pt_regs->dx */
+ pushq %rcx /* pt_regs->cx */
+ pushq $-ENOSYS /* pt_regs->ax */
+- pushq $0 /* pt_regs->r8 = 0 */
+- pushq $0 /* pt_regs->r9 = 0 */
+- pushq $0 /* pt_regs->r10 = 0 */
+- pushq $0 /* pt_regs->r11 = 0 */
++ pushq %rax /* pt_regs->r8 = 0 */
++ pushq %rax /* pt_regs->r9 = 0 */
++ pushq %rax /* pt_regs->r10 = 0 */
++ pushq %rax /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp (will be overwritten) */
+- pushq $0 /* pt_regs->r12 = 0 */
+- pushq $0 /* pt_regs->r13 = 0 */
+- pushq $0 /* pt_regs->r14 = 0 */
+- pushq $0 /* pt_regs->r15 = 0 */
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ pushq %r12 /* pt_regs->r12 */
++#else
++ pushq %rax /* pt_regs->r12 = 0 */
++#endif
++ pushq %rax /* pt_regs->r13 = 0 */
++ pushq %rax /* pt_regs->r14 = 0 */
++ pushq %rax /* pt_regs->r15 = 0 */
+ cld
+
++ pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
++
+ /*
+ * SYSENTER doesn't filter flags, so we need to clear NT and AC
+ * ourselves. To save a few cycles, we can check whether
+@@ -204,16 +243,27 @@ ENTRY(entry_SYSCALL_compat)
+ pushq %rdx /* pt_regs->dx */
+ pushq %rbp /* pt_regs->cx (stashed in bp) */
+ pushq $-ENOSYS /* pt_regs->ax */
+- pushq $0 /* pt_regs->r8 = 0 */
+- pushq $0 /* pt_regs->r9 = 0 */
+- pushq $0 /* pt_regs->r10 = 0 */
+- pushq $0 /* pt_regs->r11 = 0 */
++ xorl %eax,%eax
++ pushq %rax /* pt_regs->r8 = 0 */
++ pushq %rax /* pt_regs->r9 = 0 */
++ pushq %rax /* pt_regs->r10 = 0 */
++ pushq %rax /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp (will be overwritten) */
+- pushq $0 /* pt_regs->r12 = 0 */
+- pushq $0 /* pt_regs->r13 = 0 */
+- pushq $0 /* pt_regs->r14 = 0 */
+- pushq $0 /* pt_regs->r15 = 0 */
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ pushq %r12 /* pt_regs->r12 */
++#else
++ pushq %rax /* pt_regs->r12 = 0 */
++#endif
++ pushq %rax /* pt_regs->r13 = 0 */
++ pushq %rax /* pt_regs->r14 = 0 */
++ pushq %rax /* pt_regs->r15 = 0 */
++
++ pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
+
+ /*
+ * User mode is traced as though IRQs are on, and SYSENTER
+@@ -229,11 +279,18 @@ ENTRY(entry_SYSCALL_compat)
+
+ /* Opportunistic SYSRET */
+ sysret32_from_system_call:
++ pax_exit_kernel_user
++ pax_erase_kstack
+ TRACE_IRQS_ON /* User mode traces as IRQs on. */
+ movq RBX(%rsp), %rbx /* pt_regs->rbx */
+ movq RBP(%rsp), %rbp /* pt_regs->rbp */
+ movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */
+ movq RIP(%rsp), %rcx /* pt_regs->ip (in rcx) */
++
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ movq R12(%rsp), %r12
++#endif
++
+ addq $RAX, %rsp /* Skip r8-r15 */
+ popq %rax /* pt_regs->rax */
+ popq %rdx /* Skip pt_regs->cx */
+@@ -262,7 +319,7 @@ sysret32_from_system_call:
+ movq RSP-ORIG_RAX(%rsp), %rsp
+ swapgs
+ sysretl
+-END(entry_SYSCALL_compat)
++ENDPROC(entry_SYSCALL_compat)
+
+ /*
+ * 32-bit legacy system call entry.
+@@ -314,10 +371,11 @@ ENTRY(entry_INT80_compat)
+ pushq %rdx /* pt_regs->dx */
+ pushq %rcx /* pt_regs->cx */
+ pushq $-ENOSYS /* pt_regs->ax */
+- pushq $0 /* pt_regs->r8 = 0 */
+- pushq $0 /* pt_regs->r9 = 0 */
+- pushq $0 /* pt_regs->r10 = 0 */
+- pushq $0 /* pt_regs->r11 = 0 */
++ xorl %eax,%eax
++ pushq %rax /* pt_regs->r8 = 0 */
++ pushq %rax /* pt_regs->r9 = 0 */
++ pushq %rax /* pt_regs->r10 = 0 */
++ pushq %rax /* pt_regs->r11 = 0 */
+ pushq %rbx /* pt_regs->rbx */
+ pushq %rbp /* pt_regs->rbp */
+ pushq %r12 /* pt_regs->r12 */
+@@ -326,6 +384,12 @@ ENTRY(entry_INT80_compat)
+ pushq %r15 /* pt_regs->r15 */
+ cld
+
++ pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++ pax_erase_kstack
++#endif
++
+ /*
+ * User mode is traced as though IRQs are on, and the interrupt
+ * gate turned them off.
+@@ -337,10 +401,12 @@ ENTRY(entry_INT80_compat)
+ .Lsyscall_32_done:
+
+ /* Go back to user mode. */
++ pax_exit_kernel_user
++ pax_erase_kstack
+ TRACE_IRQS_ON
+ SWAPGS
+ jmp restore_regs_and_iret
+-END(entry_INT80_compat)
++ENDPROC(entry_INT80_compat)
+
+ ALIGN
+ GLOBAL(stub32_clone)
+diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S
+index 027aec4..0e3afc9 100644
+--- a/arch/x86/entry/thunk_64.S
++++ b/arch/x86/entry/thunk_64.S
+@@ -8,6 +8,7 @@
+ #include <linux/linkage.h>
+ #include "calling.h"
+ #include <asm/asm.h>
++#include <asm/alternative-asm.h>
+
+ /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
+ .macro THUNK name, func, put_ret_addr_in_rdi=0
+@@ -65,6 +66,7 @@ restore:
+ popq %rsi
+ popq %rdi
+ popq %rbp
++ pax_force_retaddr
+ ret
+ _ASM_NOKPROBE(restore)
+ #endif
+diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
+index 253b72e..e0fb97e 100644
+--- a/arch/x86/entry/vdso/Makefile
++++ b/arch/x86/entry/vdso/Makefile
+@@ -75,7 +75,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
+ -fno-omit-frame-pointer -foptimize-sibling-calls \
+ -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
+
+-$(vobjs): KBUILD_CFLAGS += $(CFL)
++$(vobjs): KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
+
+ #
+ # vDSO code runs in userspace and -pg doesn't help with profiling anyway.
+@@ -145,6 +145,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
+ KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
+ KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
+ KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
++KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
+ KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
+ KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
+ KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
+@@ -168,7 +169,7 @@ quiet_cmd_vdso = VDSO $@
+ -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
+ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
+
+-VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=both) \
++VDSO_LDFLAGS = -fPIC -shared -Wl,--no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=both) \
+ $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS)
+ GCOV_PROFILE := n
+
+diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c
+index 2f02d23..86d61a3 100644
+--- a/arch/x86/entry/vdso/vclock_gettime.c
++++ b/arch/x86/entry/vdso/vclock_gettime.c
+@@ -315,5 +315,5 @@ notrace time_t __vdso_time(time_t *t)
+ *t = result;
+ return result;
+ }
+-int time(time_t *t)
++time_t time(time_t *t)
+ __attribute__((weak, alias("__vdso_time")));
+diff --git a/arch/x86/entry/vdso/vdso2c.h b/arch/x86/entry/vdso/vdso2c.h
+index 63a03bb..ee6bd34 100644
+--- a/arch/x86/entry/vdso/vdso2c.h
++++ b/arch/x86/entry/vdso/vdso2c.h
+@@ -12,7 +12,7 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
+ unsigned long load_size = -1; /* Work around bogus warning */
+ unsigned long mapping_size;
+ ELF(Ehdr) *hdr = (ELF(Ehdr) *)raw_addr;
+- int i;
++ unsigned int i;
+ unsigned long j;
+ ELF(Shdr) *symtab_hdr = NULL, *strtab_hdr, *secstrings_hdr,
+ *alt_sec = NULL;
+@@ -83,7 +83,7 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
+ for (i = 0;
+ i < GET_LE(&symtab_hdr->sh_size) / GET_LE(&symtab_hdr->sh_entsize);
+ i++) {
+- int k;
++ unsigned int k;
+ ELF(Sym) *sym = raw_addr + GET_LE(&symtab_hdr->sh_offset) +
+ GET_LE(&symtab_hdr->sh_entsize) * i;
+ const char *name = raw_addr + GET_LE(&strtab_hdr->sh_offset) +
+diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
+index ab220ac..a7b22cd 100644
+--- a/arch/x86/entry/vdso/vma.c
++++ b/arch/x86/entry/vdso/vma.c
+@@ -20,10 +20,7 @@
+ #include <asm/page.h>
+ #include <asm/desc.h>
+ #include <asm/cpufeature.h>
+-
+-#if defined(CONFIG_X86_64)
+-unsigned int __read_mostly vdso64_enabled = 1;
+-#endif
++#include <asm/mman.h>
+
+ void __init init_vdso_image(const struct vdso_image *image)
+ {
+@@ -89,7 +86,7 @@ static int vdso_fault(const struct vm_special_mapping *sm,
+ {
+ const struct vdso_image *image = vma->vm_mm->context.vdso_image;
+
+- if (!image || (vmf->pgoff << PAGE_SHIFT) >= image->size)
++ if (!image || vmf->pgoff >= (image->size >> PAGE_SHIFT))
+ return VM_FAULT_SIGBUS;
+
+ vmf->page = virt_to_page(image->data + (vmf->pgoff << PAGE_SHIFT));
+@@ -156,6 +153,11 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
+ .fault = vvar_fault,
+ };
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ calculate_addr = false;
++#endif
++
+ if (calculate_addr) {
+ addr = vdso_addr(current->mm->start_stack,
+ image->size - image->sym_vvar_start);
+@@ -167,15 +169,15 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
+ return -EINTR;
+
+ addr = get_unmapped_area(NULL, addr,
+- image->size - image->sym_vvar_start, 0, 0);
++ image->size - image->sym_vvar_start, 0, MAP_EXECUTABLE);
+ if (IS_ERR_VALUE(addr)) {
+ ret = addr;
+ goto up_fail;
+ }
+
+ text_start = addr - image->sym_vvar_start;
+- current->mm->context.vdso = (void __user *)text_start;
+- current->mm->context.vdso_image = image;
++ mm->context.vdso = text_start;
++ mm->context.vdso_image = image;
+
+ /*
+ * MAYWRITE to allow gdb to COW and set breakpoints
+@@ -199,14 +201,12 @@ static int map_vdso(const struct vdso_image *image, bool calculate_addr)
+ VM_PFNMAP,
+ &vvar_mapping);
+
+- if (IS_ERR(vma)) {
++ if (IS_ERR(vma))
+ ret = PTR_ERR(vma);
+- goto up_fail;
+- }
+
+ up_fail:
+ if (ret)
+- current->mm->context.vdso = NULL;
++ mm->context.vdso = 0;
+
+ up_write(&mm->mmap_sem);
+ return ret;
+@@ -225,9 +225,6 @@ static int load_vdso32(void)
+ #ifdef CONFIG_X86_64
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+- if (!vdso64_enabled)
+- return 0;
+-
+ return map_vdso(&vdso_image_64, true);
+ }
+
+@@ -236,12 +233,8 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+ int uses_interp)
+ {
+ #ifdef CONFIG_X86_X32_ABI
+- if (test_thread_flag(TIF_X32)) {
+- if (!vdso64_enabled)
+- return 0;
+-
++ if (test_thread_flag(TIF_X32))
+ return map_vdso(&vdso_image_x32, true);
+- }
+ #endif
+ #ifdef CONFIG_IA32_EMULATION
+ return load_vdso32();
+@@ -258,15 +251,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ #endif
+
+ #ifdef CONFIG_X86_64
+-static __init int vdso_setup(char *s)
+-{
+- vdso64_enabled = simple_strtoul(s, NULL, 0);
+- return 0;
+-}
+-__setup("vdso=", vdso_setup);
+-#endif
+-
+-#ifdef CONFIG_X86_64
+ static void vgetcpu_cpu_init(void *arg)
+ {
+ int cpu = smp_processor_id();
+diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c
+index 174c2549..489a8e7 100644
+--- a/arch/x86/entry/vsyscall/vsyscall_64.c
++++ b/arch/x86/entry/vsyscall/vsyscall_64.c
+@@ -38,10 +38,8 @@
+ #define CREATE_TRACE_POINTS
+ #include "vsyscall_trace.h"
+
+-static enum { EMULATE, NATIVE, NONE } vsyscall_mode =
+-#if defined(CONFIG_LEGACY_VSYSCALL_NATIVE)
+- NATIVE;
+-#elif defined(CONFIG_LEGACY_VSYSCALL_NONE)
++static enum { EMULATE, NONE } vsyscall_mode =
++#if defined(CONFIG_LEGACY_VSYSCALL_NONE)
+ NONE;
+ #else
+ EMULATE;
+@@ -52,8 +50,6 @@ static int __init vsyscall_setup(char *str)
+ if (str) {
+ if (!strcmp("emulate", str))
+ vsyscall_mode = EMULATE;
+- else if (!strcmp("native", str))
+- vsyscall_mode = NATIVE;
+ else if (!strcmp("none", str))
+ vsyscall_mode = NONE;
+ else
+@@ -271,8 +267,7 @@ do_ret:
+ return true;
+
+ sigsegv:
+- force_sig(SIGSEGV, current);
+- return true;
++ do_group_exit(SIGKILL);
+ }
+
+ /*
+@@ -290,8 +285,8 @@ static const struct vm_operations_struct gate_vma_ops = {
+ static struct vm_area_struct gate_vma = {
+ .vm_start = VSYSCALL_ADDR,
+ .vm_end = VSYSCALL_ADDR + PAGE_SIZE,
+- .vm_page_prot = PAGE_READONLY_EXEC,
+- .vm_flags = VM_READ | VM_EXEC,
++ .vm_page_prot = PAGE_READONLY,
++ .vm_flags = VM_READ,
+ .vm_ops = &gate_vma_ops,
+ };
+
+@@ -332,10 +327,7 @@ void __init map_vsyscall(void)
+ unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page);
+
+ if (vsyscall_mode != NONE)
+- __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall,
+- vsyscall_mode == NATIVE
+- ? PAGE_KERNEL_VSYSCALL
+- : PAGE_KERNEL_VVAR);
++ __set_fixmap(VSYSCALL_PAGE, physaddr_vsyscall, PAGE_KERNEL_VVAR);
+
+ BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_PAGE) !=
+ (unsigned long)VSYSCALL_ADDR);
+diff --git a/arch/x86/entry/vsyscall/vsyscall_emu_64.S b/arch/x86/entry/vsyscall/vsyscall_emu_64.S
+index c9596a9..e1f6d5d 100644
+--- a/arch/x86/entry/vsyscall/vsyscall_emu_64.S
++++ b/arch/x86/entry/vsyscall/vsyscall_emu_64.S
+@@ -7,12 +7,13 @@
+ */
+
+ #include <linux/linkage.h>
++#include <linux/init.h>
+
+ #include <asm/irq_vectors.h>
+ #include <asm/page_types.h>
+ #include <asm/unistd_64.h>
+
+-__PAGE_ALIGNED_DATA
++ __READ_ONLY
+ .globl __vsyscall_page
+ .balign PAGE_SIZE, 0xcc
+ .type __vsyscall_page, @object
+diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c
+index 6011a57..311bea0 100644
+--- a/arch/x86/events/amd/iommu.c
++++ b/arch/x86/events/amd/iommu.c
+@@ -80,12 +80,12 @@ static struct attribute_group amd_iommu_format_group = {
+ * sysfs events attributes
+ *---------------------------------------------*/
+ struct amd_iommu_event_desc {
+- struct kobj_attribute attr;
++ struct device_attribute attr;
+ const char *event;
+ };
+
+-static ssize_t _iommu_event_show(struct kobject *kobj,
+- struct kobj_attribute *attr, char *buf)
++static ssize_t _iommu_event_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct amd_iommu_event_desc *event =
+ container_of(attr, struct amd_iommu_event_desc, attr);
+@@ -407,7 +407,7 @@ static void perf_iommu_del(struct perf_event *event, int flags)
+ static __init int _init_events_attrs(struct perf_amd_iommu *perf_iommu)
+ {
+ struct attribute **attrs;
+- struct attribute_group *attr_group;
++ attribute_group_no_const *attr_group;
+ int i = 0, j;
+
+ while (amd_iommu_v2_event_descs[i].attr.attr.name)
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 91eac39..a8bc9c0 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -1541,7 +1541,7 @@ static void __init pmu_check_apic(void)
+
+ }
+
+-static struct attribute_group x86_pmu_format_group = {
++static attribute_group_no_const x86_pmu_format_group = {
+ .name = "format",
+ .attrs = NULL,
+ };
+@@ -1649,7 +1649,7 @@ static struct attribute *events_attr[] = {
+ NULL,
+ };
+
+-static struct attribute_group x86_pmu_events_group = {
++static attribute_group_no_const x86_pmu_events_group = {
+ .name = "events",
+ .attrs = events_attr,
+ };
+@@ -2257,7 +2257,7 @@ static unsigned long get_segment_base(unsigned int segment)
+ if (idx > GDT_ENTRIES)
+ return 0;
+
+- desc = raw_cpu_ptr(gdt_page.gdt) + idx;
++ desc = get_cpu_gdt_table(smp_processor_id()) + idx;
+ }
+
+ return get_desc_base(desc);
+@@ -2363,7 +2363,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
+ break;
+
+ perf_callchain_store(entry, frame.return_address);
+- fp = (void __user *)frame.next_frame;
++ fp = (void __force_user *)frame.next_frame;
+ }
+ pagefault_enable();
+ }
+diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
+index 0a6e393..aa36c3d 100644
+--- a/arch/x86/events/intel/bts.c
++++ b/arch/x86/events/intel/bts.c
+@@ -252,7 +252,7 @@ static void bts_event_start(struct perf_event *event, int flags)
+ __bts_event_start(event);
+
+ /* PMI handler: this counter is running and likely generating PMIs */
+- ACCESS_ONCE(bts->started) = 1;
++ ACCESS_ONCE_RW(bts->started) = 1;
+
+ return;
+
+@@ -274,7 +274,7 @@ static void __bts_event_stop(struct perf_event *event)
+ if (event->hw.state & PERF_HES_STOPPED)
+ return;
+
+- ACCESS_ONCE(event->hw.state) |= PERF_HES_STOPPED;
++ ACCESS_ONCE_RW(event->hw.state) |= PERF_HES_STOPPED;
+ }
+
+ static void bts_event_stop(struct perf_event *event, int flags)
+@@ -284,7 +284,7 @@ static void bts_event_stop(struct perf_event *event, int flags)
+ struct bts_buffer *buf = perf_get_aux(&bts->handle);
+
+ /* PMI handler: don't restart this counter */
+- ACCESS_ONCE(bts->started) = 0;
++ ACCESS_ONCE_RW(bts->started) = 0;
+
+ __bts_event_stop(event);
+
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index 9b4f9d3..ce64392 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -2348,6 +2348,8 @@ __intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
+ }
+
+ static void
++intel_start_scheduling(struct cpu_hw_events *cpuc) __acquires(&cpuc->excl_cntrs->lock);
++static void
+ intel_start_scheduling(struct cpu_hw_events *cpuc)
+ {
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+@@ -2357,14 +2359,18 @@ intel_start_scheduling(struct cpu_hw_events *cpuc)
+ /*
+ * nothing needed if in group validation mode
+ */
+- if (cpuc->is_fake || !is_ht_workaround_enabled())
++ if (cpuc->is_fake || !is_ht_workaround_enabled()) {
++ __acquire(&excl_cntrs->lock);
+ return;
++ }
+
+ /*
+ * no exclusion needed
+ */
+- if (WARN_ON_ONCE(!excl_cntrs))
++ if (WARN_ON_ONCE(!excl_cntrs)) {
++ __acquire(&excl_cntrs->lock);
+ return;
++ }
+
+ xl = &excl_cntrs->states[tid];
+
+@@ -2404,6 +2410,8 @@ static void intel_commit_scheduling(struct cpu_hw_events *cpuc, int idx, int cnt
+ }
+
+ static void
++intel_stop_scheduling(struct cpu_hw_events *cpuc) __releases(&cpuc->excl_cntrs->lock);
++static void
+ intel_stop_scheduling(struct cpu_hw_events *cpuc)
+ {
+ struct intel_excl_cntrs *excl_cntrs = cpuc->excl_cntrs;
+@@ -2413,13 +2421,18 @@ intel_stop_scheduling(struct cpu_hw_events *cpuc)
+ /*
+ * nothing needed if in group validation mode
+ */
+- if (cpuc->is_fake || !is_ht_workaround_enabled())
++ if (cpuc->is_fake || !is_ht_workaround_enabled()) {
++ __release(&excl_cntrs->lock);
+ return;
++ }
++
+ /*
+ * no exclusion needed
+ */
+- if (WARN_ON_ONCE(!excl_cntrs))
++ if (WARN_ON_ONCE(!excl_cntrs)) {
++ __release(&excl_cntrs->lock);
+ return;
++ }
+
+ xl = &excl_cntrs->states[tid];
+
+@@ -2602,19 +2615,22 @@ static void intel_put_excl_constraints(struct cpu_hw_events *cpuc,
+ * unused now.
+ */
+ if (hwc->idx >= 0) {
++ bool sched_started;
++
+ xl = &excl_cntrs->states[tid];
++ sched_started = xl->sched_started;
+
+ /*
+ * put_constraint may be called from x86_schedule_events()
+ * which already has the lock held so here make locking
+ * conditional.
+ */
+- if (!xl->sched_started)
++ if (!sched_started)
+ raw_spin_lock(&excl_cntrs->lock);
+
+ xl->state[hwc->idx] = INTEL_EXCL_UNUSED;
+
+- if (!xl->sched_started)
++ if (!sched_started)
+ raw_spin_unlock(&excl_cntrs->lock);
+ }
+ }
+@@ -3523,10 +3539,10 @@ __init int intel_pmu_init(void)
+ x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
+
+ if (boot_cpu_has(X86_FEATURE_PDCM)) {
+- u64 capabilities;
++ u64 capabilities = x86_pmu.intel_cap.capabilities;
+
+- rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
+- x86_pmu.intel_cap.capabilities = capabilities;
++ if (rdmsrl_safe(MSR_IA32_PERF_CAPABILITIES, &x86_pmu.intel_cap.capabilities))
++ x86_pmu.intel_cap.capabilities = capabilities;
+ }
+
+ intel_ds_init();
+diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c
+index 7b5fd81..3ca58b5 100644
+--- a/arch/x86/events/intel/cqm.c
++++ b/arch/x86/events/intel/cqm.c
+@@ -1479,7 +1479,7 @@ static struct attribute *intel_cmt_mbm_events_attr[] = {
+ NULL,
+ };
+
+-static struct attribute_group intel_cqm_events_group = {
++static attribute_group_no_const intel_cqm_events_group __read_only = {
+ .name = "events",
+ .attrs = NULL,
+ };
+@@ -1737,7 +1737,9 @@ static int __init intel_cqm_init(void)
+ goto out;
+ }
+
+- event_attr_intel_cqm_llc_scale.event_str = str;
++ pax_open_kernel();
++ const_cast(event_attr_intel_cqm_llc_scale.event_str) = str;
++ pax_close_kernel();
+
+ ret = intel_cqm_setup_rmid_cache();
+ if (ret)
+@@ -1753,12 +1755,14 @@ static int __init intel_cqm_init(void)
+ if (ret && !cqm_enabled)
+ goto out;
+
++ pax_open_kernel();
+ if (cqm_enabled && mbm_enabled)
+- intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr;
++ const_cast(intel_cqm_events_group.attrs) = intel_cmt_mbm_events_attr;
+ else if (!cqm_enabled && mbm_enabled)
+- intel_cqm_events_group.attrs = intel_mbm_events_attr;
++ const_cast(intel_cqm_events_group.attrs) = intel_mbm_events_attr;
+ else if (cqm_enabled && !mbm_enabled)
+- intel_cqm_events_group.attrs = intel_cqm_events_attr;
++ const_cast(intel_cqm_events_group.attrs) = intel_cqm_events_attr;
++ pax_close_kernel();
+
+ ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1);
+ if (ret) {
+diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
+index 9ba4e41..f931fb9 100644
+--- a/arch/x86/events/intel/cstate.c
++++ b/arch/x86/events/intel/cstate.c
+@@ -94,14 +94,14 @@
+ MODULE_LICENSE("GPL");
+
+ #define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
+-static ssize_t __cstate_##_var##_show(struct kobject *kobj, \
+- struct kobj_attribute *attr, \
++static ssize_t __cstate_##_var##_show(struct device *dev, \
++ struct device_attribute *attr, \
+ char *page) \
+ { \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+ } \
+-static struct kobj_attribute format_attr_##_var = \
++static struct device_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __cstate_##_var##_show, NULL)
+
+ static ssize_t cstate_get_attr_cpumask(struct device *dev,
+diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
+index 7ce9f3f..dc9146c 100644
+--- a/arch/x86/events/intel/ds.c
++++ b/arch/x86/events/intel/ds.c
+@@ -601,7 +601,7 @@ unlock:
+
+ static inline void intel_pmu_drain_pebs_buffer(void)
+ {
+- struct pt_regs regs;
++ struct pt_regs regs = {};
+
+ x86_pmu.drain_pebs(&regs);
+ }
+@@ -909,7 +909,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ unsigned long from = cpuc->lbr_entries[0].from;
+ unsigned long old_to, to = cpuc->lbr_entries[0].to;
+- unsigned long ip = regs->ip;
++ unsigned long ip = ktva_ktla(regs->ip);
+ int is_64bit = 0;
+ void *kaddr;
+ int size;
+@@ -961,6 +961,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+ } else {
+ kaddr = (void *)to;
+ }
++ kaddr = (void *)ktva_ktla((unsigned long)kaddr);
+
+ do {
+ struct insn insn;
+@@ -1109,7 +1110,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
+ }
+
+ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+- regs->ip = pebs->real_ip;
++ set_linear_ip(regs, pebs->real_ip);
+ regs->flags |= PERF_EFLAGS_EXACT;
+ } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
+ regs->flags |= PERF_EFLAGS_EXACT;
+diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
+index 9e2b40c..a9013c2 100644
+--- a/arch/x86/events/intel/lbr.c
++++ b/arch/x86/events/intel/lbr.c
+@@ -717,7 +717,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
+ * Ensure we don't blindy read any address by validating it is
+ * a known text address.
+ */
+- if (kernel_text_address(from)) {
++ if (kernel_text_address(ktva_ktla(from))) {
+ addr = (void *)from;
+ /*
+ * Assume we can get the maximum possible size
+@@ -739,7 +739,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
+ #ifdef CONFIG_X86_64
+ is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
+ #endif
+- insn_init(&insn, addr, bytes_read, is64);
++ insn_init(&insn, (void *)ktva_ktla((unsigned long)addr), bytes_read, is64);
+ insn_get_opcode(&insn);
+ if (!insn.opcode.got)
+ return X86_BR_ABORT;
+diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
+index 04bb5fb..69cbd32 100644
+--- a/arch/x86/events/intel/pt.c
++++ b/arch/x86/events/intel/pt.c
+@@ -172,11 +172,9 @@ static const struct attribute_group *pt_attr_groups[] = {
+
+ static int __init pt_pmu_hw_init(void)
+ {
+- struct dev_ext_attribute *de_attrs;
+- struct attribute **attrs;
+- size_t size;
++ static struct dev_ext_attribute de_attrs[ARRAY_SIZE(pt_caps)];
++ static struct attribute *attrs[ARRAY_SIZE(pt_caps)];
+ u64 reg;
+- int ret;
+ long i;
+
+ rdmsrl(MSR_PLATFORM_INFO, reg);
+@@ -207,8 +205,6 @@ static int __init pt_pmu_hw_init(void)
+ pt_pmu.vmx = true;
+ }
+
+- attrs = NULL;
+-
+ for (i = 0; i < PT_CPUID_LEAVES; i++) {
+ cpuid_count(20, i,
+ &pt_pmu.caps[CR_EAX + i*PT_CPUID_REGS_NUM],
+@@ -217,39 +213,25 @@ static int __init pt_pmu_hw_init(void)
+ &pt_pmu.caps[CR_EDX + i*PT_CPUID_REGS_NUM]);
+ }
+
+- ret = -ENOMEM;
+- size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
+- attrs = kzalloc(size, GFP_KERNEL);
+- if (!attrs)
+- goto fail;
+-
+- size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
+- de_attrs = kzalloc(size, GFP_KERNEL);
+- if (!de_attrs)
+- goto fail;
+-
++ pax_open_kernel();
+ for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
+- struct dev_ext_attribute *de_attr = de_attrs + i;
++ struct dev_ext_attribute *de_attr = &de_attrs[i];
+
+- de_attr->attr.attr.name = pt_caps[i].name;
++ const_cast(de_attr->attr.attr.name) = pt_caps[i].name;
+
+ sysfs_attr_init(&de_attr->attr.attr);
+
+- de_attr->attr.attr.mode = S_IRUGO;
+- de_attr->attr.show = pt_cap_show;
+- de_attr->var = (void *)i;
++ const_cast(de_attr->attr.attr.mode) = S_IRUGO;
++ const_cast(de_attr->attr.show) = pt_cap_show;
++ const_cast(de_attr->var) = (void *)i;
+
+ attrs[i] = &de_attr->attr.attr;
+ }
+
+- pt_cap_group.attrs = attrs;
++ const_cast(pt_cap_group.attrs) = attrs;
++ pax_close_kernel();
+
+ return 0;
+-
+-fail:
+- kfree(attrs);
+-
+- return ret;
+ }
+
+ #define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC | \
+diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
+index e30eef4..2c79b8e 100644
+--- a/arch/x86/events/intel/rapl.c
++++ b/arch/x86/events/intel/rapl.c
+@@ -116,14 +116,14 @@ static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
+ #define RAPL_EVENT_MASK 0xFFULL
+
+ #define DEFINE_RAPL_FORMAT_ATTR(_var, _name, _format) \
+-static ssize_t __rapl_##_var##_show(struct kobject *kobj, \
+- struct kobj_attribute *attr, \
++static ssize_t __rapl_##_var##_show(struct device *dev, \
++ struct device_attribute *attr, \
+ char *page) \
+ { \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+ } \
+-static struct kobj_attribute format_attr_##_var = \
++static struct device_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __rapl_##_var##_show, NULL)
+
+ #define RAPL_CNTR_WIDTH 32
+@@ -532,7 +532,7 @@ static struct attribute *rapl_events_knl_attr[] = {
+ NULL,
+ };
+
+-static struct attribute_group rapl_pmu_events_group = {
++static attribute_group_no_const rapl_pmu_events_group __read_only = {
+ .name = "events",
+ .attrs = NULL, /* patched at runtime */
+ };
+diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
+index fce7406..4187d6a 100644
+--- a/arch/x86/events/intel/uncore.c
++++ b/arch/x86/events/intel/uncore.c
+@@ -87,8 +87,8 @@ end:
+ return map;
+ }
+
+-ssize_t uncore_event_show(struct kobject *kobj,
+- struct kobj_attribute *attr, char *buf)
++ssize_t uncore_event_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+ struct uncore_event_desc *event =
+ container_of(attr, struct uncore_event_desc, attr);
+@@ -816,7 +816,7 @@ static void uncore_types_exit(struct intel_uncore_type **types)
+ static int __init uncore_type_init(struct intel_uncore_type *type, bool setid)
+ {
+ struct intel_uncore_pmu *pmus;
+- struct attribute_group *attr_group;
++ attribute_group_no_const *attr_group;
+ struct attribute **attrs;
+ size_t size;
+ int i, j;
+diff --git a/arch/x86/events/intel/uncore.h b/arch/x86/events/intel/uncore.h
+index 79766b9..8e2b3d0 100644
+--- a/arch/x86/events/intel/uncore.h
++++ b/arch/x86/events/intel/uncore.h
+@@ -119,9 +119,9 @@ struct intel_uncore_box {
+ #define UNCORE_BOX_FLAG_INITIATED 0
+
+ struct uncore_event_desc {
+- struct kobj_attribute attr;
++ struct device_attribute attr;
+ const char *config;
+-};
++} __do_const;
+
+ struct pci2phy_map {
+ struct list_head list;
+@@ -131,8 +131,8 @@ struct pci2phy_map {
+
+ struct pci2phy_map *__find_pci2phy_map(int segment);
+
+-ssize_t uncore_event_show(struct kobject *kobj,
+- struct kobj_attribute *attr, char *buf);
++ssize_t uncore_event_show(struct device *dev,
++ struct device_attribute *attr, char *buf);
+
+ #define INTEL_UNCORE_EVENT_DESC(_name, _config) \
+ { \
+@@ -141,14 +141,14 @@ ssize_t uncore_event_show(struct kobject *kobj,
+ }
+
+ #define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
+-static ssize_t __uncore_##_var##_show(struct kobject *kobj, \
+- struct kobj_attribute *attr, \
++static ssize_t __uncore_##_var##_show(struct device *dev, \
++ struct device_attribute *attr, \
+ char *page) \
+ { \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+ } \
+-static struct kobj_attribute format_attr_##_var = \
++static struct device_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
+
+ static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box)
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index 8bd764d..76a1790 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -793,7 +793,7 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
+ regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
+ if (regs->flags & X86_VM_MASK)
+ regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
+- regs->ip = ip;
++ regs->ip = kernel_ip(ip) ? ktva_ktla(ip) : ip;
+ }
+
+ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
+diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
+index cb26f18..4f43f23 100644
+--- a/arch/x86/ia32/ia32_aout.c
++++ b/arch/x86/ia32/ia32_aout.c
+@@ -153,6 +153,8 @@ static int aout_core_dump(struct coredump_params *cprm)
+ unsigned long dump_start, dump_size;
+ struct user32 dump;
+
++ memset(&dump, 0, sizeof(dump));
++
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ has_dumped = 1;
+diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
+index 2f29f4e..ac453b4 100644
+--- a/arch/x86/ia32/ia32_signal.c
++++ b/arch/x86/ia32/ia32_signal.c
+@@ -123,7 +123,7 @@ asmlinkage long sys32_sigreturn(void)
+ if (__get_user(set.sig[0], &frame->sc.oldmask)
+ || (_COMPAT_NSIG_WORDS > 1
+ && __copy_from_user((((char *) &set.sig) + 4),
+- &frame->extramask,
++ frame->extramask,
+ sizeof(frame->extramask))))
+ goto badframe;
+
+@@ -243,7 +243,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
+ sp -= frame_size;
+ /* Align the stack pointer according to the i386 ABI,
+ * i.e. so that on function entry ((sp + 4) & 15) == 0. */
+- sp = ((sp + 4) & -16ul) - 4;
++ sp = ((sp - 12) & -16ul) - 4;
+ return (void __user *) sp;
+ }
+
+@@ -288,10 +288,10 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
+ } else {
+ /* Return stub is in 32bit vsyscall page */
+ if (current->mm->context.vdso)
+- restorer = current->mm->context.vdso +
+- vdso_image_32.sym___kernel_sigreturn;
++ restorer = (void __force_user *)(current->mm->context.vdso +
++ vdso_image_32.sym___kernel_sigreturn);
+ else
+- restorer = &frame->retcode;
++ restorer = frame->retcode;
+ }
+
+ put_user_try {
+@@ -301,7 +301,7 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
+ * These are actually not used anymore, but left because some
+ * gdb versions depend on them as a marker.
+ */
+- put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
++ put_user_ex(*((const u64 *)&code), (u64 __user *)frame->retcode);
+ } put_user_catch(err);
+
+ if (err)
+@@ -343,7 +343,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
+ 0xb8,
+ __NR_ia32_rt_sigreturn,
+ 0x80cd,
+- 0,
++ 0
+ };
+
+ frame = get_sigframe(ksig, regs, sizeof(*frame), &fpstate);
+@@ -366,16 +366,19 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
+
+ if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ restorer = ksig->ka.sa.sa_restorer;
++ else if (current->mm->context.vdso)
++ /* Return stub is in 32bit vsyscall page */
++ restorer = (void __force_user *)(current->mm->context.vdso +
++ vdso_image_32.sym___kernel_rt_sigreturn);
+ else
+- restorer = current->mm->context.vdso +
+- vdso_image_32.sym___kernel_rt_sigreturn;
++ restorer = frame->retcode;
+ put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
+
+ /*
+ * Not actually used anymore, but left because some gdb
+ * versions need it.
+ */
+- put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
++ put_user_ex(*((const u64 *)&code), (u64 __user *)frame->retcode);
+ } put_user_catch(err);
+
+ err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
+index 719cd70..72af944 100644
+--- a/arch/x86/ia32/sys_ia32.c
++++ b/arch/x86/ia32/sys_ia32.c
+@@ -49,18 +49,26 @@
+
+ #define AA(__x) ((unsigned long)(__x))
+
++static inline loff_t compose_loff(unsigned int high, unsigned int low)
++{
++ loff_t retval = low;
++
++ BUILD_BUG_ON(sizeof retval != sizeof low + sizeof high);
++ __builtin_memcpy((unsigned char *)&retval + sizeof low, &high, sizeof high);
++ return retval;
++}
+
+ asmlinkage long sys32_truncate64(const char __user *filename,
+- unsigned long offset_low,
+- unsigned long offset_high)
++ unsigned int offset_low,
++ unsigned int offset_high)
+ {
+- return sys_truncate(filename, ((loff_t) offset_high << 32) | offset_low);
++ return sys_truncate(filename, compose_loff(offset_high, offset_low));
+ }
+
+-asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low,
+- unsigned long offset_high)
++asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned int offset_low,
++ unsigned int offset_high)
+ {
+- return sys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
++ return sys_ftruncate(fd, ((unsigned long) offset_high << 32) | offset_low);
+ }
+
+ /*
+@@ -69,8 +77,8 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long offset_low,
+ */
+ static int cp_stat64(struct stat64 __user *ubuf, struct kstat *stat)
+ {
+- typeof(ubuf->st_uid) uid = 0;
+- typeof(ubuf->st_gid) gid = 0;
++ typeof(((struct stat64 *)0)->st_uid) uid = 0;
++ typeof(((struct stat64 *)0)->st_gid) gid = 0;
+ SET_UID(uid, from_kuid_munged(current_user_ns(), stat->uid));
+ SET_GID(gid, from_kgid_munged(current_user_ns(), stat->gid));
+ if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
+@@ -196,29 +204,29 @@ long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high,
+ __u32 len_low, __u32 len_high, int advice)
+ {
+ return sys_fadvise64_64(fd,
+- (((u64)offset_high)<<32) | offset_low,
+- (((u64)len_high)<<32) | len_low,
++ compose_loff(offset_high, offset_low),
++ compose_loff(len_high, len_low),
+ advice);
+ }
+
+ asmlinkage ssize_t sys32_readahead(int fd, unsigned off_lo, unsigned off_hi,
+ size_t count)
+ {
+- return sys_readahead(fd, ((u64)off_hi << 32) | off_lo, count);
++ return sys_readahead(fd, compose_loff(off_hi, off_lo), count);
+ }
+
+ asmlinkage long sys32_sync_file_range(int fd, unsigned off_low, unsigned off_hi,
+ unsigned n_low, unsigned n_hi, int flags)
+ {
+ return sys_sync_file_range(fd,
+- ((u64)off_hi << 32) | off_low,
+- ((u64)n_hi << 32) | n_low, flags);
++ compose_loff(off_hi, off_low),
++ compose_loff(n_hi, n_low), flags);
+ }
+
+ asmlinkage long sys32_fadvise64(int fd, unsigned offset_lo, unsigned offset_hi,
+- size_t len, int advice)
++ int len, int advice)
+ {
+- return sys_fadvise64_64(fd, ((u64)offset_hi << 32) | offset_lo,
++ return sys_fadvise64_64(fd, compose_loff(offset_hi, offset_lo),
+ len, advice);
+ }
+
+@@ -226,6 +234,6 @@ asmlinkage long sys32_fallocate(int fd, int mode, unsigned offset_lo,
+ unsigned offset_hi, unsigned len_lo,
+ unsigned len_hi)
+ {
+- return sys_fallocate(fd, mode, ((u64)offset_hi << 32) | offset_lo,
+- ((u64)len_hi << 32) | len_lo);
++ return sys_fallocate(fd, mode, compose_loff(offset_hi, offset_lo),
++ compose_loff(len_hi, len_lo));
+ }
+diff --git a/arch/x86/include/asm/alternative-asm.h b/arch/x86/include/asm/alternative-asm.h
+index e7636ba..e1fb78a 100644
+--- a/arch/x86/include/asm/alternative-asm.h
++++ b/arch/x86/include/asm/alternative-asm.h
+@@ -18,6 +18,45 @@
+ .endm
+ #endif
+
++#ifdef KERNEXEC_PLUGIN
++ .macro pax_force_retaddr_bts rip=0
++ btsq $63,\rip(%rsp)
++ .endm
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_BTS
++ .macro pax_force_retaddr rip=0, reload=0
++ btsq $63,\rip(%rsp)
++ .endm
++ .macro pax_force_fptr ptr
++ btsq $63,\ptr
++ .endm
++ .macro pax_set_fptr_mask
++ .endm
++#endif
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR
++ .macro pax_force_retaddr rip=0, reload=0
++ .if \reload
++ pax_set_fptr_mask
++ .endif
++ orq %r12,\rip(%rsp)
++ .endm
++ .macro pax_force_fptr ptr
++ orq %r12,\ptr
++ .endm
++ .macro pax_set_fptr_mask
++ movabs $0x8000000000000000,%r12
++ .endm
++#endif
++#else
++ .macro pax_force_retaddr rip=0, reload=