[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ipfire-scm
Subject:    [git.ipfire.org] IPFire 3.x development tree branch, master, updated. 7b74d436a4643988a0ce9cbec54150
From:       git () ipfire ! org (Michael Tremer)
Date:       2013-11-30 12:13:18
Message-ID: 20131130121403.14CED21375 () argus ! ipfire ! org
[Download RAW message or body]

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "IPFire 3.x development tree".

The branch, master has been updated
       via  7b74d436a4643988a0ce9cbec541509e3c65cd12 (commit)
      from  65bc0de8386c318bad7097c46725b515fb303ba1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 7b74d436a4643988a0ce9cbec541509e3c65cd12
Author: Michael Tremer <michael.tremer at ipfire.org>
Date:   Sat Nov 30 13:12:00 2013 +0100

    kernel: Update to 3.11.6.
    
    This release drops the exynos kernel which is now added
    to the ARMv7 multiplatform kernel.

-----------------------------------------------------------------------

Summary of changes:
 kernel/patches/arm-exynos-mp.patch                 |   408 +
 ... => grsecurity-2.9.1-3.11.6-201310191259.patch} | 16211 ++++++++++---------
 .../patches/linux-3.11-omap-mpuss-lowpower.patch   |    33 +
 3 files changed, 9416 insertions(+), 7236 deletions(-)
 create mode 100644 kernel/patches/arm-exynos-mp.patch
 copy kernel/patches/{grsecurity-2.9.1-3.10.9-201308202015.patch => \
grsecurity-2.9.1-3.11.6-201310191259.patch} (90%)  create mode 100644 \
kernel/patches/linux-3.11-omap-mpuss-lowpower.patch

Difference in files:
diff --git a/kernel/patches/arm-exynos-mp.patch b/kernel/patches/arm-exynos-mp.patch
new file mode 100644
index 0000000..15667ab
--- /dev/null
+++ b/kernel/patches/arm-exynos-mp.patch
@@ -0,0 +1,408 @@
+commit 8b806e0201b97844d0eff4713eb88f0a6d0f689d
+Author: Arnd Bergmann <arnd at arndb.de>
+Date:   Fri Jun 14 17:16:30 2013 +0200
+
+    ARM: exynos multiplatform, next try
+    
+    Signed-off-by: Arnd Bergmann <arnd at arndb.de>
+    
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index e401a76..fad9324 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -422,7 +422,7 @@ choice
+ 
+ 	config DEBUG_S3C_UART0
+ 		depends on PLAT_SAMSUNG
+-		select DEBUG_EXYNOS_UART if ARCH_EXYNOS
++		select DEBUG_EXYNOS_UART if ARCH_EXYNOS_COMMON
+ 		bool "Use S3C UART 0 for low-level debug"
+ 		help
+ 		  Say Y here if you want the debug print routines to direct
+@@ -434,7 +434,7 @@ choice
+ 
+ 	config DEBUG_S3C_UART1
+ 		depends on PLAT_SAMSUNG
+-		select DEBUG_EXYNOS_UART if ARCH_EXYNOS
++		select DEBUG_EXYNOS_UART if ARCH_EXYNOS_COMMON
+ 		bool "Use S3C UART 1 for low-level debug"
+ 		help
+ 		  Say Y here if you want the debug print routines to direct
+@@ -446,7 +446,7 @@ choice
+ 
+ 	config DEBUG_S3C_UART2
+ 		depends on PLAT_SAMSUNG
+-		select DEBUG_EXYNOS_UART if ARCH_EXYNOS
++		select DEBUG_EXYNOS_UART if ARCH_EXYNOS_COMMON
+ 		bool "Use S3C UART 2 for low-level debug"
+ 		help
+ 		  Say Y here if you want the debug print routines to direct
+@@ -457,7 +457,7 @@ choice
+ 		  by CONFIG_S3C_LOWLEVEL_UART_PORT.
+ 
+ 	config DEBUG_S3C_UART3
+-		depends on PLAT_SAMSUNG && ARCH_EXYNOS
++		depends on PLAT_SAMSUNG && ARCH_EXYNOS_COMMON
+ 		select DEBUG_EXYNOS_UART
+ 		bool "Use S3C UART 3 for low-level debug"
+ 		help
+diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S
+index f3a9cff..8d8d922 100644
+--- a/arch/arm/include/debug/samsung.S
++++ b/arch/arm/include/debug/samsung.S
+@@ -9,7 +9,7 @@
+  * published by the Free Software Foundation.
+ */
+ 
+-#include <plat/regs-serial.h>
++#include <linux/serial_s3c.h>
+ 
+ /* The S5PV210/S5PC110 implementations are as belows. */
+ 
+diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
+index 855d4a7..8744890 100644
+--- a/arch/arm/mach-exynos/Kconfig
++++ b/arch/arm/mach-exynos/Kconfig
+@@ -7,13 +7,24 @@
+ 
+ # Configuration options for the EXYNOS4
+ 
+-if ARCH_EXYNOS
++config ARCH_EXYNOS_MULTI
++	bool "Samsung EXYNOS" if ARCH_MULTI_V7
++	select ARCH_HAS_CPUFREQ
++	select CPU_V7
++	select GENERIC_CLOCKEVENTS
++	select HAVE_CLK
++	select HAVE_S3C2410_I2C if I2C
++	select HAVE_S3C_RTC if RTC_CLASS
++	help
++	  Support for SAMSUNG's EXYNOS SoCs (EXYNOS4/5)
++
++if ARCH_EXYNOS || ARCH_EXYNOS_MULTI
+ 
+ menu "SAMSUNG EXYNOS SoCs Support"
+ 
+ config ARCH_EXYNOS4
+ 	bool "SAMSUNG EXYNOS4"
+-	default y
++	default ARCH_EXYNOS
+ 	select GIC_NON_BANKED
+ 	select HAVE_ARM_SCU if SMP
+ 	select HAVE_SMP
+@@ -24,12 +35,16 @@ config ARCH_EXYNOS4
+ 
+ config ARCH_EXYNOS5
+ 	bool "SAMSUNG EXYNOS5"
++	default ARCH_EXYNOS
+ 	select HAVE_ARM_SCU if SMP
+ 	select HAVE_SMP
+ 	select PINCTRL
+ 	help
+ 	  Samsung EXYNOS5 (Cortex-A15) SoC based systems
+ 
++config ARCH_EXYNOS_COMMON
++	def_bool ARCH_EXYNOS4 || ARCH_EXYNOS5
++
+ comment "EXYNOS SoCs"
+ 
+ config CPU_EXYNOS4210
+@@ -41,7 +56,7 @@ config CPU_EXYNOS4210
+ 	select PM_GENERIC_DOMAINS if PM
+ 	select S5P_PM if PM
+ 	select S5P_SLEEP if PM
+-	select SAMSUNG_DMADEV
++	select SAMSUNG_DMADEV if !ARCH_MULTIPLATFORM
+ 	help
+ 	  Enable EXYNOS4210 CPU support
+ 
+@@ -49,10 +64,11 @@ config SOC_EXYNOS4212
+ 	bool "SAMSUNG EXYNOS4212"
+ 	default y
+ 	depends on ARCH_EXYNOS4
++	select MACH_EXYNOS4_DT
+ 	select PINCTRL_EXYNOS
+ 	select S5P_PM if PM
+ 	select S5P_SLEEP if PM
+-	select SAMSUNG_DMADEV
++	select SAMSUNG_DMADEV if !ARCH_MULTIPLATFORM
+ 	help
+ 	  Enable EXYNOS4212 SoC support
+ 
+@@ -60,8 +76,9 @@ config SOC_EXYNOS4412
+ 	bool "SAMSUNG EXYNOS4412"
+ 	default y
+ 	depends on ARCH_EXYNOS4
++	select MACH_EXYNOS4_DT
+ 	select PINCTRL_EXYNOS
+-	select SAMSUNG_DMADEV
++	select SAMSUNG_DMADEV if !ARCH_MULTIPLATFORM
+ 	help
+ 	  Enable EXYNOS4412 SoC support
+ 
+@@ -70,11 +87,12 @@ config SOC_EXYNOS5250
+ 	default y
+ 	depends on ARCH_EXYNOS5
+ 	select PINCTRL_EXYNOS
++	select MACH_EXYNOS5_DT
+ 	select PM_GENERIC_DOMAINS if PM
+ 	select S5P_PM if PM
+ 	select S5P_SLEEP if PM
+ 	select S5P_DEV_MFC
+-	select SAMSUNG_DMADEV
++	select SAMSUNG_DMADEV if !ARCH_MULTIPLATFORM
+ 	help
+ 	  Enable EXYNOS5250 SoC support
+ 
+@@ -121,9 +139,7 @@ config MACH_EXYNOS4_DT
+ 	  with this machine file.
+ 
+ config MACH_EXYNOS5_DT
+-	bool "SAMSUNG EXYNOS5 Machine using device tree"
+-	default y
+-	depends on ARCH_EXYNOS5
++	bool
+ 	select ARM_AMBA
+ 	select CLKSRC_OF
+ 	select USB_ARCH_HAS_XHCI
+diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
+index e970a7a..ae397bb 100644
+--- a/arch/arm/mach-exynos/Makefile
++++ b/arch/arm/mach-exynos/Makefile
+diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
+@@ -5,14 +5,11 @@
+ #
+ # Licensed under GPLv2
+ 
+-obj-y				:=
+-obj-m				:=
+-obj-n				:=
+-obj-				:=
++ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-samsung + 
+-# Core
++ifdef CONFIG_ARCH_EXYNOS_COMMON
+ 
+-obj-$(CONFIG_ARCH_EXYNOS)	+= common.o
++obj-y                          += pmu.o
+ 
+ obj-$(CONFIG_S5P_PM)		+= pm.o
+ obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
+@@ -24,8 +21,8 @@
+ 
+ obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
+ 
+-obj-$(CONFIG_ARCH_EXYNOS)	+= exynos-smc.o
+-obj-$(CONFIG_ARCH_EXYNOS)	+= firmware.o
+++obj-y                          += exynos-smc.o
+++obj-y                          += firmware.o
+ 
+ plus_sec := $(call as-instr,.arch_extension sec,+sec)
+ AFLAGS_exynos-smc.o		:=-Wa,-march=armv7-a$(plus_sec)
+@@ -34,3 +31,5 @@
+ 
+ obj-$(CONFIG_MACH_EXYNOS4_DT)		+= mach-exynos4-dt.o
+ obj-$(CONFIG_MACH_EXYNOS5_DT)		+= mach-exynos5-dt.o
++
++endif
+index 3dc5cbe..e61abdc 100644
+--- a/arch/arm/plat-samsung/Kconfig
++++ b/arch/arm/plat-samsung/Kconfig
+@@ -6,7 +6,7 @@
+ 
+ config PLAT_SAMSUNG
+ 	bool
+-	depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P || ARCH_EXYNOS
++	depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P || ARCH_EXYNOS_COMMON
+ 	default y
+ 	select GENERIC_IRQ_CHIP
+ 	select NO_IOPORT
+@@ -176,6 +176,7 @@ config S5P_DEV_UART
+ 
+ config S3C_ADC
+ 	bool "ADC common driver support"
++	depends on !ARCH_MULTIPLATFORM
+ 	help
+ 	  Core support for the ADC block found in the Samsung SoC systems
+ 	  for drivers such as the touchscreen and hwmon to use to share
+@@ -396,6 +397,7 @@ config S5P_DEV_USB_EHCI
+ 
+ config S3C24XX_PWM
+ 	bool "PWM device support"
++	depends on !ARCH_MULTIPLATFORM
+ 	select PWM
+ 	select PWM_SAMSUNG
+ 	help
+@@ -453,7 +455,7 @@ comment "Power management"
+ config SAMSUNG_PM_DEBUG
+ 	bool "S3C2410 PM Suspend debug"
+ 	depends on PM
+-	select DEBUG_LL
++	depends on DEBUG_LL && SERIAL_SAMSUNG
+ 	help
+ 	  Say Y here if you want verbose debugging from the PM Suspend and
+ 	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
+index 98d07d8..b458e7d 100644
+--- a/arch/arm/plat-samsung/Makefile
++++ b/arch/arm/plat-samsung/Makefile
+@@ -4,6 +4,9 @@
+ #
+ # Licensed under GPLv2
+ 
++ccflags-$(CONFIG_ARCH_MULTI_V7) += -I$(srctree)/$(src)/include
++ccflags-$(CONFIG_ARCH_EXYNOS_COMMON) += -I$(srctree)/arch/arm/mach-exynos/include
++
+ obj-y				:=
+ obj-m				:=
+ obj-n				:= dummy.o
+diff --git a/arch/arm/plat-samsung/s5p-irq-pm.c b/arch/arm/plat-samsung/s5p-irq-pm.c
+index 7c1e3b7..dc66bb5 100644
+--- a/arch/arm/plat-samsung/s5p-irq-pm.c
++++ b/arch/arm/plat-samsung/s5p-irq-pm.c
+@@ -40,7 +40,7 @@ int s3c_irq_wake(struct irq_data *data, unsigned int state)
+ 	unsigned long irqbit;
+ 	unsigned int irq_rtc_tic, irq_rtc_alarm;
+ 
+-#ifdef CONFIG_ARCH_EXYNOS
++#ifdef CONFIG_ARCH_EXYNOS_COMMON
+ 	if (soc_is_exynos5250()) {
+ 		irq_rtc_tic = EXYNOS5_IRQ_RTC_TIC;
+ 		irq_rtc_alarm = EXYNOS5_IRQ_RTC_ALARM;
+diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
+index 81465c2..6bd8b5a 100644
+--- a/drivers/clocksource/Kconfig
++++ b/drivers/clocksource/Kconfig
+@@ -75,7 +75,7 @@ config CLKSRC_METAG_GENERIC
+ 	  This option enables support for the Meta per-thread timers.
+ 
+ config CLKSRC_EXYNOS_MCT
+-	def_bool y if ARCH_EXYNOS
++	def_bool y if ARCH_EXYNOS_COMMON
+ 	help
+ 	  Support for Multi Core Timer controller on Exynos SoCs.
+ 
+diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
+index 31f3adb..15454ad 100644
+--- a/drivers/devfreq/Kconfig
++++ b/drivers/devfreq/Kconfig
+@@ -68,6 +68,7 @@ comment "DEVFREQ Drivers"
+ config ARM_EXYNOS4_BUS_DEVFREQ
+ 	bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
+ 	depends on CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412
++	depends on !ARCH_MULTIPLATFORM
+ 	select ARCH_HAS_OPP
+ 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+ 	help
+diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
+index 6c6034e..d9ed7c0 100644
+--- a/drivers/iommu/Kconfig
++++ b/drivers/iommu/Kconfig
+@@ -168,7 +168,7 @@ config TEGRA_IOMMU_SMMU
+ 
+ config EXYNOS_IOMMU
+ 	bool "Exynos IOMMU Support"
+-	depends on ARCH_EXYNOS && EXYNOS_DEV_SYSMMU
++	depends on ARCH_EXYNOS_COMMON && EXYNOS_DEV_SYSMMU
+ 	select IOMMU_API
+ 	help
+ 	  Support for the IOMMU(System MMU) of Samsung Exynos application
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 5a8ad51..03688dd 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -252,7 +252,7 @@ config PINCTRL_SAMSUNG
+ 
+ config PINCTRL_EXYNOS
+ 	bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
+-	depends on OF && GPIOLIB && ARCH_EXYNOS
++	depends on OF && GPIOLIB && ARCH_EXYNOS_COMMON
+ 	select PINCTRL_SAMSUNG
+ 
+ config PINCTRL_EXYNOS5440
+diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
+index 75840b5..746a931 100644
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -140,7 +140,7 @@ config PWM_RENESAS_TPU
+ 
+ config PWM_SAMSUNG
+ 	tristate "Samsung PWM support"
+-	depends on PLAT_SAMSUNG
++	depends on PLAT_SAMSUNG && !ARCH_MULTIPLATFORM
+ 	help
+ 	  Generic PWM framework driver for Samsung.
+ 
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 89cbbab..830b8e7 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -365,7 +365,7 @@ config SPI_S3C24XX_FIQ
+ 
+ config SPI_S3C64XX
+ 	tristate "Samsung S3C64XX series type SPI"
+-	depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS)
++	depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS_COMMON)
+ 	select S3C64XX_DMA if ARCH_S3C64XX
+ 	help
+ 	  SPI driver for Samsung S3C64XX and newer SoCs.
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 4263d01..d7ad720 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -462,7 +462,7 @@ config USB_OHCI_SH
+ 
+ config USB_OHCI_EXYNOS
+ 	boolean "OHCI support for Samsung EXYNOS SoC Series"
+-	depends on ARCH_EXYNOS
++	depends on ARCH_EXYNOS_COMMON
+ 	help
+ 	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller.
+ 
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 2c301f8..0ba3e03 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -2039,7 +2039,7 @@ config FB_TMIO_ACCELL
+ config FB_S3C
+ 	tristate "Samsung S3C framebuffer support"
+ 	depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
+-		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
++		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS_COMMON)
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig
+index b8abda5..216af14 100644
+--- a/drivers/video/exynos/Kconfig
++++ b/drivers/video/exynos/Kconfig
+@@ -15,7 +15,7 @@ if EXYNOS_VIDEO
+ 
+ config EXYNOS_MIPI_DSI
+ 	bool "EXYNOS MIPI DSI driver support."
+-	depends on ARCH_S5PV210 || ARCH_EXYNOS
++	depends on ARCH_S5PV210 || ARCH_EXYNOS_COMMON
+ 	help
+ 	  This enables support for MIPI-DSI device.
+ 
+@@ -29,7 +29,7 @@ config EXYNOS_LCD_S6E8AX0
+ 
+ config EXYNOS_DP
+ 	bool "EXYNOS DP driver support"
+-	depends on ARCH_EXYNOS
++	depends on ARCH_EXYNOS_COMMON
+ 	default n
+ 	help
+ 	  This enables support for DP device.
+diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
+index 9855dfc..fcb2045 100644
+--- a/sound/soc/samsung/Kconfig
++++ b/sound/soc/samsung/Kconfig
+@@ -1,6 +1,6 @@
+ config SND_SOC_SAMSUNG
+ 	tristate "ASoC support for Samsung"
+-	depends on PLAT_SAMSUNG
++	depends on PLAT_SAMSUNG && !ARCH_MULTIPLATFORM
+ 	select S3C64XX_DMA if ARCH_S3C64XX
+ 	select S3C2410_DMA if ARCH_S3C24XX
+ 	help
diff --git a/kernel/patches/grsecurity-2.9.1-3.11.6-201310191259.patch \
b/kernel/patches/grsecurity-2.9.1-3.11.6-201310191259.patch new file mode 100644
index 0000000..46b1e15
--- /dev/null
+++ b/kernel/patches/grsecurity-2.9.1-3.11.6-201310191259.patch
@@ -0,0 +1,110845 @@
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index b89a739..79768fb 100644
+--- a/Documentation/dontdiff
++++ b/Documentation/dontdiff
+@@ -2,9 +2,11 @@
+ *.aux
+ *.bin
+ *.bz2
++*.c.[012]*.*
+ *.cis
+ *.cpio
+ *.csp
++*.dbg
+ *.dsp
+ *.dvi
+ *.elf
+@@ -14,6 +16,7 @@
+ *.gcov
+ *.gen.S
+ *.gif
++*.gmo
+ *.grep
+ *.grp
+ *.gz
+@@ -48,14 +51,17 @@
+ *.tab.h
+ *.tex
+ *.ver
++*.vim
+ *.xml
+ *.xz
+ *_MODULES
++*_reg_safe.h
+ *_vga16.c
+ *~
+ \#*#
+ *.9
+-.*
++.[^g]*
++.gen*
+ .*.d
+ .mm
+ 53c700_d.h
+@@ -69,9 +75,11 @@ Image
+ Module.markers
+ Module.symvers
+ PENDING
++PERF*
+ SCCS
+ System.map*
+ TAGS
++TRACEEVENT-CFLAGS
+ aconf
+ af_names.h
+ aic7*reg.h*
+@@ -80,6 +88,7 @@ aic7*seq.h*
+ aicasm
+ aicdb.h*
+ altivec*.c
++ashldi3.S
+ asm-offsets.h
+ asm_offsets.h
+ autoconf.h*
+@@ -92,19 +101,24 @@ 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
+@@ -115,9 +129,11 @@ 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
+@@ -125,12 +141,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
+@@ -145,14 +164,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
+@@ -162,14 +181,15 @@ mach-types.h
+ machtypes.h
+ map
+ map_hugetlb
+-media
+ mconf
++mdp
+ miboot*
+ mk_elfconfig
+ mkboot
+ mkbugboot
+ mkcpustr
+ mkdep
++mkpiggy
+ mkprep
+ mkregtable
+ mktables
+@@ -185,6 +205,8 @@ oui.c*
+ page-types
+ parse.c
+ parse.h
++parse-events*
++pasyms.h
+ patches*
+ pca200e.bin
+ pca200e_ecd.bin2
+@@ -194,6 +216,7 @@ perf-archive
+ piggyback
+ piggy.gzip
+ piggy.S
++pmu-*
+ pnmtologo
+ ppc_defs.h*
+ pss_boot.h
+@@ -203,7 +226,10 @@ r200_reg_safe.h
+ r300_reg_safe.h
+ r420_reg_safe.h
+ r600_reg_safe.h
++realmode.lds
++realmode.relocs
+ recordmcount
++regdb.c
+ relocs
+ rlim_names.h
+ rn50_reg_safe.h
+@@ -213,8 +239,12 @@ series
+ setup
+ setup.bin
+ setup.elf
++signing_key*
++size_overflow_hash.h
+ sImage
++slabinfo
+ sm_tbl*
++sortextable
+ split-include
+ syscalltab.h
+ tables.c
+@@ -224,6 +254,7 @@ tftpboot.img
+ timeconst.h
+ times.h*
+ trix_boot.h
++user_constants.h
+ utsrelease.h*
+ vdso-syms.lds
+ vdso.lds
+@@ -235,13 +266,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
+@@ -249,9 +284,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/kernel-parameters.txt \
b/Documentation/kernel-parameters.txt +index 7f9d4f5..6d1afd6 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -976,6 +976,10 @@ bytes respectively. Such letter suffixes can also be entirely \
omitted. + 			Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
+ 			Default: 1024
+ 
++	grsec_proc_gid= [GRKERNSEC_PROC_USERGROUP] Chooses GID to
++			ignore grsecurity's /proc restrictions
++
++
+ 	hashdist=	[KNL,NUMA] Large hashes allocated during boot
+ 			are distributed across NUMA nodes.  Defaults on
+ 			for 64-bit NUMA, off otherwise.
+@@ -1932,6 +1936,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.
+@@ -2199,6 +2207,25 @@ bytes respectively. Such letter suffixes can also be entirely \
omitted. + 			the specified number of seconds.  This is to be used if
+ 			your oopses keep scrolling off the screen.
+ 
++	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=
++			0/1 to disable/enable slab object sanitization (enabled by
++			default).
++
++	pax_softmode=	0/1 to disable/enable PaX softmode on boot already.
++
++	pax_extra_latent_entropy
++			Enable a very simple form of latent entropy extraction
++			from the first 4GB of memory as the bootmem allocator
++			passes the memory pages to the buddy allocator.
++
++	pax_weakuderef	[X86-64] enables the weaker but faster form of UDEREF
++			when the processor supports PCID.
++
+ 	pcbit=		[HW,ISDN]
+ 
+ 	pcd.		[PARIDE]
+diff --git a/Makefile b/Makefile
+index e87ba83..ee3c7b7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+ 
+ HOSTCC       = gcc
+ HOSTCXX      = g++
+-HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 \
-fomit-frame-pointer +-HOSTCXXFLAGS = -O2
++HOSTCFLAGS   = -Wall -W -Wmissing-prototypes -Wstrict-prototypes \
-Wno-unused-parameter -Wno-missing-field-initializers -O2 -fomit-frame-pointer \
-fno-delete-null-pointer-checks ++HOSTCFLAGS  += $(call cc-option, -Wno-empty-body)
++HOSTCXXFLAGS = -O2 -Wall -W -fno-delete-null-pointer-checks
+ 
+ # Decide whether to build built-in, modular, or both.
+ # Normally, just do built-in.
+@@ -414,8 +415,8 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper \
--exclude .svn \ + # Rules shared between *config targets and build targets
+ 
+ # Basic helpers built in scripts/
+-PHONY += scripts_basic
+-scripts_basic:
++PHONY += scripts_basic gcc-plugins
++scripts_basic: gcc-plugins
+ 	$(Q)$(MAKE) $(build)=scripts/basic
+ 	$(Q)rm -f .tmp_quiet_recordmcount
+ 
+@@ -576,6 +577,65 @@ else
+ KBUILD_CFLAGS	+= -O2
+ endif
+ 
++ifndef DISABLE_PAX_PLUGINS
++ifeq ($(call cc-ifversion, -ge, 0408, y), y)
++PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCXX)" \
"$(HOSTCXX)" "$(CC)") ++else
++PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" \
"$(HOSTCXX)" "$(CC)") ++endif
++ifneq ($(PLUGINCC),)
++ifdef CONFIG_PAX_CONSTIFY_PLUGIN
++CONSTIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/constify_plugin.so \
-DCONSTIFY_PLUGIN ++endif
++ifdef CONFIG_PAX_MEMORY_STACKLEAK
++STACKLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/stackleak_plugin.so \
-DSTACKLEAK_PLUGIN ++STACKLEAK_PLUGIN_CFLAGS += \
-fplugin-arg-stackleak_plugin-track-lowest-sp=100 ++endif
++ifdef CONFIG_KALLOCSTAT_PLUGIN
++KALLOCSTAT_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kallocstat_plugin.so
++endif
++ifdef CONFIG_PAX_KERNEXEC_PLUGIN
++KERNEXEC_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/kernexec_plugin.so
++KERNEXEC_PLUGIN_CFLAGS += \
-fplugin-arg-kernexec_plugin-method=$(CONFIG_PAX_KERNEXEC_PLUGIN_METHOD) \
-DKERNEXEC_PLUGIN ++KERNEXEC_PLUGIN_AFLAGS := -DKERNEXEC_PLUGIN
++endif
++ifdef CONFIG_CHECKER_PLUGIN
++ifeq ($(call cc-ifversion, -ge, 0406, y), y)
++CHECKER_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/checker_plugin.so \
-DCHECKER_PLUGIN ++endif
++endif
++COLORIZE_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/colorize_plugin.so
++ifdef CONFIG_PAX_SIZE_OVERFLOW
++SIZE_OVERFLOW_PLUGIN_CFLAGS := \
-fplugin=$(objtree)/tools/gcc/size_overflow_plugin.so -DSIZE_OVERFLOW_PLUGIN ++endif
++ifdef CONFIG_PAX_LATENT_ENTROPY
++LATENT_ENTROPY_PLUGIN_CFLAGS := \
-fplugin=$(objtree)/tools/gcc/latent_entropy_plugin.so -DLATENT_ENTROPY_PLUGIN \
++endif ++ifdef CONFIG_PAX_MEMORY_STRUCTLEAK
++STRUCTLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/structleak_plugin.so \
-DSTRUCTLEAK_PLUGIN ++endif
++GCC_PLUGINS_CFLAGS := $(CONSTIFY_PLUGIN_CFLAGS) $(STACKLEAK_PLUGIN_CFLAGS) \
$(KALLOCSTAT_PLUGIN_CFLAGS) ++GCC_PLUGINS_CFLAGS += $(KERNEXEC_PLUGIN_CFLAGS) \
$(CHECKER_PLUGIN_CFLAGS) $(COLORIZE_PLUGIN_CFLAGS) ++GCC_PLUGINS_CFLAGS += \
$(SIZE_OVERFLOW_PLUGIN_CFLAGS) $(LATENT_ENTROPY_PLUGIN_CFLAGS) \
$(STRUCTLEAK_PLUGIN_CFLAGS) ++GCC_PLUGINS_AFLAGS := $(KERNEXEC_PLUGIN_AFLAGS)
++export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS CONSTIFY_PLUGIN
++ifeq ($(KBUILD_EXTMOD),)
++gcc-plugins:
++	$(Q)$(MAKE) $(build)=tools/gcc
++else
++gcc-plugins: ;
++endif
++else
++gcc-plugins:
++ifeq ($(call cc-ifversion, -ge, 0405, y), y)
++	$(error Your gcc installation does not support plugins.  If the necessary headers \
for plugin support are missing, they should be installed.  On Debian, apt-get install \
gcc-<ver>-plugin-dev.  If you choose to ignore this error and lessen the improvements \
provided by this patch, re-run make with the DISABLE_PAX_PLUGINS=y argument.)) ++else
++	$(Q)echo "warning, your gcc version does not support plugins, you should upgrade \
it to gcc 4.5 at least" ++endif
++	$(Q)echo "PAX_MEMORY_STACKLEAK, constification, PAX_LATENT_ENTROPY and other \
features will be less secure.  PAX_SIZE_OVERFLOW will not be active." ++endif
++endif
++
+ include $(srctree)/arch/$(SRCARCH)/Makefile
+ 
+ ifdef CONFIG_READABLE_ASM
+@@ -733,7 +793,7 @@ export mod_sign_cmd
+ 
+ 
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
++core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
+ 
+ vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+ 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+@@ -782,6 +842,8 @@ endif
+ 
+ # The actual objects are generated when descending, 
+ # make sure no implicit rule kicks in
++$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++$(filter-out $(init-y),$(vmlinux-deps)): KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
+ 
+ # Handle descending into subdirectories listed in $(vmlinux-dirs)
+@@ -791,7 +853,7 @@ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ;
+ # Error messages still appears in the original language
+ 
+ PHONY += $(vmlinux-dirs)
+-$(vmlinux-dirs): prepare scripts
++$(vmlinux-dirs): gcc-plugins prepare scripts
+ 	$(Q)$(MAKE) $(build)=$@
+ 
+ # Store (new) KERNELRELEASE string in include/config/kernel.release
+@@ -835,6 +897,7 @@ prepare0: archprepare FORCE
+ 	$(Q)$(MAKE) $(build)=.
+ 
+ # All the preparing..
++prepare: KBUILD_CFLAGS := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS))
+ prepare: prepare0
+ 
+ # Generate some files
+@@ -942,6 +1005,8 @@ all: modules
+ #	using awk while concatenating to the final file.
+ 
+ PHONY += modules
++modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin
+ 	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > \
$(objtree)/modules.order + 	@$(kecho) '  Building modules, stage 2.';
+@@ -957,7 +1022,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin)
+ 
+ # Target to prepare building external modules
+ PHONY += modules_prepare
+-modules_prepare: prepare scripts
++modules_prepare: gcc-plugins prepare scripts
+ 
+ # Target to install modules
+ PHONY += modules_install
+@@ -1023,7 +1088,7 @@ MRPROPER_FILES += .config .config.old .version .old_version \
$(version_h) \ + 		  Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+ 		  signing_key.priv signing_key.x509 x509.genkey		\
+ 		  extra_certificates signing_key.x509.keyid		\
+-		  signing_key.x509.signer
++		  signing_key.x509.signer tools/gcc/size_overflow_hash.h
+ 
+ # clean - Delete most, but leave enough to build external modules
+ #
+@@ -1063,6 +1128,7 @@ distclean: mrproper
+ 		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+ 		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+ 		-o -name '.*.rej' \
++		-o -name '.*.rej' -o -name '*.so' \
+ 		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
+ 		-type f -print | xargs rm -f
+ 
+@@ -1224,6 +1290,8 @@ PHONY += $(module-dirs) modules
+ $(module-dirs): crmodverdir $(objtree)/Module.symvers
+ 	$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
+ 
++modules: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++modules: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
+ modules: $(module-dirs)
+ 	@$(kecho) '  Building modules, stage 2.';
+ 	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
+@@ -1363,17 +1431,21 @@ else
+         target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
+ endif
+ 
+-%.s: %.c prepare scripts FORCE
++%.s: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.s: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.s: %.c gcc-plugins prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.i: %.c prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.c prepare scripts FORCE
++%.o: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.o: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.o: %.c gcc-plugins prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.lst: %.c prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.s: %.S prepare scripts FORCE
++%.s: %.S gcc-plugins prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+-%.o: %.S prepare scripts FORCE
++%.o: %.S gcc-plugins prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+ %.symtypes: %.c prepare scripts FORCE
+ 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+@@ -1383,11 +1455,15 @@ endif
+ 	$(cmd_crmodverdir)
+ 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+ 	$(build)=$(build-dir)
+-%/: prepare scripts FORCE
++%/: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%/: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%/: gcc-plugins prepare scripts FORCE
+ 	$(cmd_crmodverdir)
+ 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+ 	$(build)=$(build-dir)
+-%.ko: prepare scripts FORCE
++%.ko: KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
++%.ko: KBUILD_AFLAGS += $(GCC_PLUGINS_AFLAGS)
++%.ko: gcc-plugins prepare scripts FORCE
+ 	$(cmd_crmodverdir)
+ 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
+ 	$(build)=$(build-dir) $(@:.ko=.o)
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 78b03ef..da28a51 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -292,6 +292,16 @@ 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))
++
+ #define smp_mb__before_atomic_dec()	smp_mb()
+ #define smp_mb__after_atomic_dec()	smp_mb()
+ #define smp_mb__before_atomic_inc()	smp_mb()
+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 bc2a0da..8ad11ee 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 d8f9b7e..f6222fa 100644
+--- a/arch/alpha/include/asm/pgtable.h
++++ b/arch/alpha/include/asm/pgtable.h
+@@ -102,6 +102,17 @@ struct vm_area_struct;
+ #define PAGE_SHARED	__pgprot(_PAGE_VALID | __ACCESS_BITS)
+ #define PAGE_COPY	__pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
+ #define PAGE_READONLY	__pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC	__pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
++# define PAGE_COPY_NOEXEC	__pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | \
_PAGE_FOE) ++# define PAGE_READONLY_NOEXEC	__pgprot(_PAGE_VALID | __ACCESS_BITS | \
_PAGE_FOW | _PAGE_FOE) ++#else
++# define PAGE_SHARED_NOEXEC	PAGE_SHARED
++# define PAGE_COPY_NOEXEC	PAGE_COPY
++# define PAGE_READONLY_NOEXEC	PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL	__pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
+ 
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
+diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
+index 2fd00b7..cfd5069 100644
+--- a/arch/alpha/kernel/module.c
++++ b/arch/alpha/kernel/module.c
+@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
+ 
+ 	/* The small sections were sorted to the end of the segment.
+ 	   The following should definitely cover them.  */
+-	gp = (u64)me->module_core + me->core_size - 0x8000;
++	gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
+ 	got = sechdrs[me->arch.gotsecindex].sh_addr;
+ 
+ 	for (i = 0; i < n; i++) {
+diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
+index 1402fcc..0b1abd2 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -1298,10 +1298,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;
+@@ -1309,6 +1310,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);
+ }
+ 
+@@ -1341,20 +1343,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 0c4132d..88f0d53 100644
+--- a/arch/alpha/mm/fault.c
++++ b/arch/alpha/mm/fault.c
+@@ -53,6 +53,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,
+@@ -133,8 +251,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/arm/Kconfig b/arch/arm/Kconfig
+index 43594d5..da71e62 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1791,7 +1791,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
+diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
+index da1c77d..2ee6056 100644
+--- a/arch/arm/include/asm/atomic.h
++++ b/arch/arm/include/asm/atomic.h
+@@ -17,17 +17,35 @@
+ #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__
+ 
++#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)	(*(volatile int *)&(v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return v->counter;
++}
+ #define atomic_set(v,i)	(((v)->counter) = (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
+ 
+ #if __LINUX_ARM_ARCH__ >= 6
+ 
+@@ -42,6 +60,35 @@ static inline void atomic_add(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_add\n"
++"1:	ldrex	%1, [%3]\n"
++"	adds	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_add_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	add	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -60,6 +107,42 @@ static inline int atomic_add_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_add_return\n"
++"1:	ldrex	%1, [%3]\n"
++"	adds	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++
++	smp_mb();
++
++	return result;
++}
++
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	smp_mb();
++
++	__asm__ __volatile__("@ atomic_add_return_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	add	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -80,6 +163,35 @@ static inline void atomic_sub(int i, atomic_t *v)
+ 	int result;
+ 
+ 	__asm__ __volatile__("@ atomic_sub\n"
++"1:	ldrex	%1, [%3]\n"
++"	subs	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strex	%1, %0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "Ir" (i)
++	: "cc");
++}
++
++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
++{
++	unsigned long tmp;
++	int result;
++
++	__asm__ __volatile__("@ atomic_sub_unchecked\n"
+ "1:	ldrex	%0, [%3]\n"
+ "	sub	%0, %0, %4\n"
+ "	strex	%1, %0, [%3]\n"
+@@ -98,11 +210,25 @@ static inline int atomic_sub_return(int i, atomic_t *v)
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic_sub_return\n"
+-"1:	ldrex	%0, [%3]\n"
+-"	sub	%0, %0, %4\n"
++"1:	ldrex	%1, [%3]\n"
++"	subs	%0, %1, %4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strex	%1, %0, [%3]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter), "Ir" (i)
+ 	: "cc");
+@@ -134,6 +260,28 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int \
new) + 	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;
++}
++
+ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ {
+ 	unsigned long tmp, tmp2;
+@@ -167,7 +315,17 @@ static inline int atomic_add_return(int i, atomic_t *v)
+ 
+ 	return val;
+ }
++
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
++	return atomic_add_return(i, v);
++}
++
+ #define atomic_add(i, v)	(void) atomic_add_return(i, v)
++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
++{
++	(void) atomic_add_return(i, v);
++}
+ 
+ static inline int atomic_sub_return(int i, atomic_t *v)
+ {
+@@ -182,6 +340,10 @@ static inline int atomic_sub_return(int i, atomic_t *v)
+ 	return val;
+ }
+ #define atomic_sub(i, v)	(void) atomic_sub_return(i, v)
++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
++{
++	(void) atomic_sub_return(i, v);
++}
+ 
+ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+ {
+@@ -197,6 +359,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(v, old, new);
++}
++
+ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+ {
+ 	unsigned long flags;
+@@ -209,6 +376,10 @@ static inline void atomic_clear_mask(unsigned long mask, \
unsigned long *addr) + #endif /* __LINUX_ARM_ARCH__ */
+ 
+ #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)
+ {
+@@ -221,11 +392,27 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int \
u) + }
+ 
+ #define atomic_inc(v)		atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++	atomic_add_unchecked(1, v);
++}
+ #define atomic_dec(v)		atomic_sub(1, v)
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++	atomic_sub_unchecked(1, v);
++}
+ 
+ #define atomic_inc_and_test(v)	(atomic_add_return(1, v) == 0)
++static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v) == 0;
++}
+ #define atomic_dec_and_test(v)	(atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return(v)    (atomic_add_return(1, v))
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_return_unchecked(1, v);
++}
+ #define atomic_dec_return(v)    (atomic_sub_return(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+ 
+@@ -241,6 +428,14 @@ typedef struct {
+ 	u64 __aligned(8) counter;
+ } atomic64_t;
+ 
++#ifdef CONFIG_PAX_REFCOUNT
++typedef struct {
++	u64 __aligned(8) counter;
++} atomic64_unchecked_t;
++#else
++typedef atomic64_t atomic64_unchecked_t;
++#endif
++
+ #define ATOMIC64_INIT(i) { (i) }
+ 
+ #ifdef CONFIG_ARM_LPAE
+@@ -257,6 +452,19 @@ static inline u64 atomic64_read(const atomic64_t *v)
+ 	return result;
+ }
+ 
++static inline u64 atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++	u64 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, u64 i)
+ {
+ 	__asm__ __volatile__("@ atomic64_set\n"
+@@ -265,6 +473,15 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
+ 	: "r" (&v->counter), "r" (i)
+ 	);
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, u64 i)
++{
++	__asm__ __volatile__("@ atomic64_set_unchecked\n"
++"	strd	%2, %H2, [%1]"
++	: "=Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	);
++}
+ #else
+ static inline u64 atomic64_read(const atomic64_t *v)
+ {
+@@ -279,6 +496,19 @@ static inline u64 atomic64_read(const atomic64_t *v)
+ 	return result;
+ }
+ 
++static inline u64 atomic64_read_unchecked(atomic64_unchecked_t *v)
++{
++	u64 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, u64 i)
+ {
+ 	u64 tmp;
+@@ -292,6 +522,21 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
+ 	: "r" (&v->counter), "r" (i)
+ 	: "cc");
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, u64 i)
++{
++	u64 tmp;
++
++	__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
+ 
+ static inline void atomic64_add(u64 i, atomic64_t *v)
+@@ -302,6 +547,36 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
+ 	__asm__ __volatile__("@ atomic64_add\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	adds	%0, %0, %4\n"
++"	adcs	%H0, %H0, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++}
++
++static inline void atomic64_add_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	__asm__ __volatile__("@ atomic64_add_unchecked\n"
++"1:	ldrexd	%0, %H0, [%3]\n"
++"	adds	%0, %0, %4\n"
+ "	adc	%H0, %H0, %H4\n"
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+@@ -313,12 +588,49 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
+ 
+ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_add_return\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	adds	%0, %1, %4\n"
++"	adcs	%H0, %H1, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++
++	smp_mb();
++
++	return result;
++}
++
++static inline u64 atomic64_add_return_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	smp_mb();
++
++	__asm__ __volatile__("@ atomic64_add_return_unchecked\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	adds	%0, %0, %4\n"
+ "	adc	%H0, %H0, %H4\n"
+@@ -342,6 +654,36 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
+ 	__asm__ __volatile__("@ atomic64_sub\n"
+ "1:	ldrexd	%0, %H0, [%3]\n"
+ "	subs	%0, %0, %4\n"
++"	sbcs	%H0, %H0, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
++"	strexd	%1, %0, %H0, [%3]\n"
++"	teq	%1, #0\n"
++"	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
++	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++	: "r" (&v->counter), "r" (i)
++	: "cc");
++}
++
++static inline void atomic64_sub_unchecked(u64 i, atomic64_unchecked_t *v)
++{
++	u64 result;
++	unsigned long tmp;
++
++	__asm__ __volatile__("@ atomic64_sub_unchecked\n"
++"1:	ldrexd	%0, %H0, [%3]\n"
++"	subs	%0, %0, %4\n"
+ "	sbc	%H0, %H0, %H4\n"
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+@@ -353,18 +695,32 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
+ 
+ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_sub_return\n"
+-"1:	ldrexd	%0, %H0, [%3]\n"
+-"	subs	%0, %0, %4\n"
+-"	sbc	%H0, %H0, %H4\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	subs	%0, %1, %4\n"
++"	sbcs	%H0, %H1, %H4\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	strexd	%1, %0, %H0, [%3]\n"
+ "	teq	%1, #0\n"
+ "	bne	1b"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"\n4:\n"
++	_ASM_EXTABLE(2b, 4b)
++#endif
++
+ 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ 	: "r" (&v->counter), "r" (i)
+ 	: "cc");
+@@ -398,6 +754,30 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, \
u64 new) + 	return oldval;
+ }
+ 
++static inline u64 atomic64_cmpxchg_unchecked(atomic64_unchecked_t *ptr, u64 old, \
u64 new) ++{
++	u64 oldval;
++	unsigned long res;
++
++	smp_mb();
++
++	do {
++		__asm__ __volatile__("@ atomic64_cmpxchg_unchecked\n"
++		"ldrexd		%1, %H1, [%3]\n"
++		"mov		%0, #0\n"
++		"teq		%1, %4\n"
++		"teqeq		%H1, %H4\n"
++		"strexdeq	%0, %5, %H5, [%3]"
++		: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++		: "r" (&ptr->counter), "r" (old), "r" (new)
++		: "cc");
++	} while (res);
++
++	smp_mb();
++
++	return oldval;
++}
++
+ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+ {
+ 	u64 result;
+@@ -421,21 +801,34 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+ 
+ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+ {
+-	u64 result;
+-	unsigned long tmp;
++	u64 result, tmp;
+ 
+ 	smp_mb();
+ 
+ 	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
+-"1:	ldrexd	%0, %H0, [%3]\n"
+-"	subs	%0, %0, #1\n"
+-"	sbc	%H0, %H0, #0\n"
++"1:	ldrexd	%1, %H1, [%3]\n"
++"	subs	%0, %1, #1\n"
++"	sbcs	%H0, %H1, #0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"	mov	%0, %1\n"
++"	mov	%H0, %H1\n"
++"2:	bkpt	0xf103\n"
++"3:\n"
++#endif
++
+ "	teq	%H0, #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");
+@@ -458,13 +851,25 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, \
u64 u) + "	teq	%0, %5\n"
+ "	teqeq	%H0, %H5\n"
+ "	moveq	%1, #0\n"
+-"	beq	2f\n"
++"	beq	4f\n"
+ "	adds	%0, %0, %6\n"
+-"	adc	%H0, %H0, %H6\n"
++"	adcs	%H0, %H0, %H6\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++"	bvc	3f\n"
++"2:	bkpt	0xf103\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");
+@@ -477,10 +882,13 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, \
u64 u) + 
+ #define atomic64_add_negative(a, v)	(atomic64_add_return((a), (v)) < 0)
+ #define atomic64_inc(v)			atomic64_add(1LL, (v))
++#define atomic64_inc_unchecked(v)	atomic64_add_unchecked(1LL, (v))
+ #define atomic64_inc_return(v)		atomic64_add_return(1LL, (v))
++#define atomic64_inc_return_unchecked(v)	atomic64_add_return_unchecked(1LL, (v))
+ #define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+ #define atomic64_sub_and_test(a, v)	(atomic64_sub_return((a), (v)) == 0)
+ #define atomic64_dec(v)			atomic64_sub(1LL, (v))
++#define atomic64_dec_unchecked(v)	atomic64_sub_unchecked(1LL, (v))
+ #define atomic64_dec_return(v)		atomic64_sub_return(1LL, (v))
+ #define atomic64_dec_and_test(v)	(atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1LL, 0LL)
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+index 75fe66b..ba3dee4 100644
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -4,8 +4,10 @@
+ #ifndef __ASMARM_CACHE_H
+ #define __ASMARM_CACHE_H
+ 
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT		CONFIG_ARM_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES		(_AC(1,UL) << L1_CACHE_SHIFT)
+ 
+ /*
+  * Memory returned by kmalloc() may be used for DMA, so we must make
+@@ -24,5 +26,6 @@
+ #endif
+ 
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
++#define __read_only __attribute__ ((__section__(".data..read_only")))
+ 
+ #endif
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index 17d0ae8..014e350 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 6dcc164..b14d917 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 4f009c1..466c59b 100644
+--- a/arch/arm/include/asm/cmpxchg.h
++++ b/arch/arm/include/asm/cmpxchg.h
+@@ -102,6 +102,8 @@ static inline unsigned long __xchg(unsigned long x, volatile \
void *ptr, int size + 
+ #define xchg(ptr,x) \
+ 	((__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/domain.h b/arch/arm/include/asm/domain.h
+index 6ddbe44..b5e38b1 100644
+--- a/arch/arm/include/asm/domain.h
++++ b/arch/arm/include/asm/domain.h
+@@ -48,18 +48,37 @@
+  * Domain types
+  */
+ #define DOMAIN_NOACCESS	0
+-#define DOMAIN_CLIENT	1
+ #ifdef CONFIG_CPU_USE_DOMAINS
++#define DOMAIN_USERCLIENT	1
++#define DOMAIN_KERNELCLIENT	1
+ #define DOMAIN_MANAGER	3
++#define DOMAIN_VECTORS		DOMAIN_USER
+ #else
++
++#ifdef CONFIG_PAX_KERNEXEC
+ #define DOMAIN_MANAGER	1
++#define DOMAIN_KERNEXEC	3
++#else
++#define DOMAIN_MANAGER	1
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++#define DOMAIN_USERCLIENT	0
++#define DOMAIN_UDEREF		1
++#define DOMAIN_VECTORS		DOMAIN_KERNEL
++#else
++#define DOMAIN_USERCLIENT	1
++#define DOMAIN_VECTORS		DOMAIN_USER
++#endif
++#define DOMAIN_KERNELCLIENT	1
++
+ #endif
+ 
+ #define domain_val(dom,type)	((type) << (2*(dom)))
+ 
+ #ifndef __ASSEMBLY__
+ 
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || \
defined(CONFIG_PAX_MEMORY_UDEREF) + static inline void set_domain(unsigned val)
+ {
+ 	asm volatile(
+@@ -68,15 +87,7 @@ static inline void set_domain(unsigned val)
+ 	isb();
+ }
+ 
+-#define modify_domain(dom,type)					\
+-	do {							\
+-	struct thread_info *thread = current_thread_info();	\
+-	unsigned int domain = thread->cpu_domain;		\
+-	domain &= ~domain_val(dom, DOMAIN_MANAGER);		\
+-	thread->cpu_domain = domain | domain_val(dom, type);	\
+-	set_domain(thread->cpu_domain);				\
+-	} while (0)
+-
++extern void modify_domain(unsigned int dom, unsigned int type);
+ #else
+ static inline void set_domain(unsigned val) { }
+ static inline void modify_domain(unsigned dom, unsigned type)	{ }
+diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
+index 56211f2..17e8a25 100644
+--- a/arch/arm/include/asm/elf.h
++++ b/arch/arm/include/asm/elf.h
+@@ -116,7 +116,14 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t \
*elfregs); +    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	(2 * TASK_SIZE / 3)
++#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 
+@@ -126,10 +133,6 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t \
*elfregs); + extern void elf_set_personality(const struct elf32_hdr *);
+ #define SET_PERSONALITY(ex)	elf_set_personality(&(ex))
+ 
+-struct mm_struct;
+-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+-#define arch_randomize_brk arch_randomize_brk
+-
+ #ifdef CONFIG_MMU
+ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+ struct linux_binprm;
+diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
+index de53547..52b9a28 100644
+--- a/arch/arm/include/asm/fncpy.h
++++ 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 e42cf59..7b94b8f 100644
+--- a/arch/arm/include/asm/futex.h
++++ b/arch/arm/include/asm/futex.h
+@@ -50,6 +50,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ 		return -EFAULT;
+ 
++	pax_open_userland();
++
+ 	smp_mb();
+ 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ 	"1:	ldrex	%1, [%4]\n"
+@@ -65,6 +67,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 	: "cc", "memory");
+ 	smp_mb();
+ 
++	pax_close_userland();
++
+ 	*uval = val;
+ 	return ret;
+ }
+@@ -95,6 +99,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ 		return -EFAULT;
+ 
++	pax_open_userland();
++
+ 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ 	"1:	" TUSER(ldr) "	%1, [%4]\n"
+ 	"	teq	%1, %2\n"
+@@ -105,6 +111,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+ 	: "cc", "memory");
+ 
++	pax_close_userland();
++
+ 	*uval = val;
+ 	return ret;
+ }
+@@ -127,6 +135,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+ 		return -EFAULT;
+ 
+ 	pagefault_disable();	/* implies preempt_disable() */
++	pax_open_userland();
+ 
+ 	switch (op) {
+ 	case FUTEX_OP_SET:
+@@ -148,6 +157,7 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+ 		ret = -ENOSYS;
+ 	}
+ 
++	pax_close_userland();
+ 	pagefault_enable();	/* subsumes preempt_enable() */
+ 
+ 	if (!ret) {
+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 2fe141f..192dc01 100644
+--- a/arch/arm/include/asm/mach/map.h
++++ b/arch/arm/include/asm/mach/map.h
+@@ -27,13 +27,16 @@ struct map_desc {
+ #define MT_MINICLEAN		6
+ #define MT_LOW_VECTORS		7
+ #define MT_HIGH_VECTORS		8
+-#define MT_MEMORY		9
++#define MT_MEMORY_RWX		9
+ #define MT_ROM			10
+-#define MT_MEMORY_NONCACHED	11
++#define MT_MEMORY_NONCACHED_RX	11
+ #define MT_MEMORY_DTCM		12
+ #define MT_MEMORY_ITCM		13
+ #define MT_MEMORY_SO		14
+ #define MT_MEMORY_DMA_READY	15
++#define MT_MEMORY_RW		16
++#define MT_MEMORY_RX		17
++#define MT_MEMORY_NONCACHED_RW	18
+ 
+ #ifdef CONFIG_MMU
+ extern void iotable_init(struct map_desc *, int);
+diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
+index 12f71a1..04e063c 100644
+--- a/arch/arm/include/asm/outercache.h
++++ b/arch/arm/include/asm/outercache.h
+@@ -35,7 +35,7 @@ struct outer_cache_fns {
+ #endif
+ 	void (*set_debug)(unsigned long);
+ 	void (*resume)(void);
+-};
++} __no_const;
+ 
+ #ifdef CONFIG_OUTER_CACHE
+ 
+diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
+index 4355f0e..c229913 100644
+--- a/arch/arm/include/asm/page.h
++++ b/arch/arm/include/asm/page.h
+@@ -114,7 +114,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 943504f..c37a730 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 */
+ 
+@@ -126,6 +133,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)
+ {
+@@ -155,7 +175,7 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t \
*ptep) + static inline void
+ pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
+ {
+-	__pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
++	__pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE | __supported_pmd_mask);
+ }
+ #define pmd_pgtable(pmd) pmd_page(pmd)
+ 
+diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h \
b/arch/arm/include/asm/pgtable-2level-hwdef.h +index 5cfba15..f415e1a 100644
+--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
++++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
+@@ -20,12 +20,15 @@
+ #define PMD_TYPE_FAULT		(_AT(pmdval_t, 0) << 0)
+ #define PMD_TYPE_TABLE		(_AT(pmdval_t, 1) << 0)
+ #define PMD_TYPE_SECT		(_AT(pmdval_t, 2) << 0)
++#define PMD_PXNTABLE		(_AT(pmdval_t, 1) << 2)		/* v7 */
+ #define PMD_BIT4		(_AT(pmdval_t, 1) << 4)
+ #define PMD_DOMAIN(x)		(_AT(pmdval_t, (x)) << 5)
+ #define PMD_PROTECTION		(_AT(pmdval_t, 1) << 9)		/* v5 */
++
+ /*
+  *   - section
+  */
++#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 */
+@@ -37,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)
+@@ -66,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 f97ee02..cc9fe9e 100644
+--- a/arch/arm/include/asm/pgtable-2level.h
++++ b/arch/arm/include/asm/pgtable-2level.h
+@@ -126,6 +126,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:   XXCB
+diff --git a/arch/arm/include/asm/pgtable-3level-hwdef.h \
b/arch/arm/include/asm/pgtable-3level-hwdef.h +index 626989f..9d67a33 100644
+--- a/arch/arm/include/asm/pgtable-3level-hwdef.h
++++ b/arch/arm/include/asm/pgtable-3level-hwdef.h
+@@ -75,6 +75,7 @@
+ #define PTE_EXT_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
+ #define PTE_EXT_AF		(_AT(pteval_t, 1) << 10)	/* Access Flag */
+ #define PTE_EXT_NG		(_AT(pteval_t, 1) << 11)	/* nG */
++#define PTE_EXT_PXN		(_AT(pteval_t, 1) << 53)	/* PXN */
+ #define PTE_EXT_XN		(_AT(pteval_t, 1) << 54)	/* XN */
+ 
+ /*
+diff --git a/arch/arm/include/asm/pgtable-3level.h \
b/arch/arm/include/asm/pgtable-3level.h +index 5689c18..eea12f9 100644
+--- a/arch/arm/include/asm/pgtable-3level.h
++++ b/arch/arm/include/asm/pgtable-3level.h
+@@ -82,6 +82,7 @@
+ #define L_PTE_RDONLY		(_AT(pteval_t, 1) << 7)		/* AP[2] */
+ #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)	/* unused */
+ #define L_PTE_SPECIAL		(_AT(pteval_t, 1) << 56)	/* unused */
+@@ -95,6 +96,7 @@
+ /*
+  * 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 04aeb02..73b70dd 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
+ 
+@@ -260,7 +308,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return 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/proc-fns.h b/arch/arm/include/asm/proc-fns.h
+index 5324c11..bcae5f0 100644
+--- a/arch/arm/include/asm/proc-fns.h
++++ b/arch/arm/include/asm/proc-fns.h
+@@ -75,7 +75,7 @@ extern struct processor {
+ 	unsigned int suspend_size;
+ 	void (*do_suspend)(void *);
+ 	void (*do_resume)(void *);
+-} processor;
++} __do_const processor;
+ 
+ #ifndef MULTI_CPU
+ extern void cpu_proc_init(void);
+diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h
+index c4ae171..ea0c0c2 100644
+--- a/arch/arm/include/asm/psci.h
++++ b/arch/arm/include/asm/psci.h
+@@ -29,7 +29,7 @@ struct psci_operations {
+ 	int (*cpu_off)(struct psci_power_state state);
+ 	int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
+ 	int (*migrate)(unsigned long cpuid);
+-};
++} __no_const;
+ 
+ extern struct psci_operations psci_ops;
+ extern struct smp_operations psci_smp_ops;
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index a8cae71c..65dd797 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -110,7 +110,7 @@ struct smp_operations {
+ 	int  (*cpu_disable)(unsigned int cpu);
+ #endif
+ #endif
+-};
++} __no_const;
+ 
+ /*
+  * set platform specific SMP operations
+diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h
+index f1d96d4..73ddd72 100644
+--- a/arch/arm/include/asm/syscall.h
++++ b/arch/arm/include/asm/syscall.h
+@@ -57,6 +57,9 @@ static inline void syscall_get_arguments(struct task_struct *task,
+ 					 unsigned int i, unsigned int n,
+ 					 unsigned long *args)
+ {
++	if (n == 0)
++		return;
++
+ 	if (i + n > SYSCALL_MAX_ARGS) {
+ 		unsigned long *args_bad = args + SYSCALL_MAX_ARGS - i;
+ 		unsigned int n_bad = n + i - SYSCALL_MAX_ARGS;
+@@ -81,6 +84,9 @@ static inline void syscall_set_arguments(struct task_struct *task,
+ 					 unsigned int i, unsigned int n,
+ 					 const unsigned long *args)
+ {
++	if (n == 0)
++		return;
++
+ 	if (i + n > SYSCALL_MAX_ARGS) {
+ 		pr_warning("%s called with max args %d, handling only %d\n",
+ 			   __func__, i + n, SYSCALL_MAX_ARGS);
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index 2b8114f..8fe9bcf 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -77,9 +77,9 @@ struct thread_info {
+ 	.flags		= 0,						\
+ 	.preempt_count	= INIT_PREEMPT_COUNT,				\
+ 	.addr_limit	= KERNEL_DS,					\
+-	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_MANAGER) |	\
+-			  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |	\
+-			  domain_val(DOMAIN_IO, DOMAIN_CLIENT),		\
++	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) |	\
++			  domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT) |	\
++			  domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT),	\
+ 	.restart_block	= {						\
+ 		.fn	= do_no_restart_syscall,			\
+ 	},								\
+@@ -152,7 +152,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define TIF_SYSCALL_AUDIT	9
+ #define TIF_SYSCALL_TRACEPOINT	10
+ #define TIF_SECCOMP		11	/* seccomp syscall filtering active */
+-#define TIF_NOHZ		12	/* in adaptive nohz mode */
++/* within 8 bits of TIF_SYSCALL_TRACE
++ *  to meet flexible second operand requirements
++ */
++#define TIF_GRSEC_SETXID	12
++#define TIF_NOHZ		13	/* in adaptive nohz mode */
+ #define TIF_USING_IWMMXT	17
+ #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
+ #define TIF_RESTORE_SIGMASK	20
+@@ -165,10 +169,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
+ #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
++#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/uaccess.h b/arch/arm/include/asm/uaccess.h
+index 7e1f760..de33b13 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>
+ 
+ #define VERIFY_READ 0
+ #define VERIFY_WRITE 1
+@@ -63,11 +64,38 @@ extern int __put_user_bad(void);
+ static inline void set_fs(mm_segment_t fs)
+ {
+ 	current_thread_info()->addr_limit = fs;
+-	modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
++	modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_KERNELCLIENT : DOMAIN_MANAGER);
+ }
+ 
+ #define segment_eq(a,b)	((a) == (b))
+ 
++#define __HAVE_ARCH_PAX_OPEN_USERLAND
++#define __HAVE_ARCH_PAX_CLOSE_USERLAND
++
++static inline void pax_open_userland(void)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (segment_eq(get_fs(), USER_DS)) {
++		BUG_ON(test_domain(DOMAIN_USER, DOMAIN_UDEREF));
++		modify_domain(DOMAIN_USER, DOMAIN_UDEREF);
++	}
++#endif
++
++}
++
++static inline void pax_close_userland(void)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (segment_eq(get_fs(), USER_DS)) {
++		BUG_ON(test_domain(DOMAIN_USER, DOMAIN_NOACCESS));
++		modify_domain(DOMAIN_USER, DOMAIN_NOACCESS);
++	}
++#endif
++
++}
++
+ #define __addr_ok(addr) ({ \
+ 	unsigned long flag; \
+ 	__asm__("cmp %2, %0; movlo %0, #0" \
+@@ -143,8 +171,12 @@ extern int __get_user_4(void *);
+ 
+ #define get_user(x,p)							\
+ 	({								\
++		int __e;						\
+ 		might_fault();						\
+-		__get_user_check(x,p);					\
++		pax_open_userland();					\
++		__e = __get_user_check(x,p);				\
++		pax_close_userland();					\
++		__e;							\
+ 	 })
+ 
+ extern int __put_user_1(void *, unsigned int);
+@@ -188,8 +220,12 @@ extern int __put_user_8(void *, unsigned long long);
+ 
+ #define put_user(x,p)							\
+ 	({								\
++		int __e;						\
+ 		might_fault();						\
+-		__put_user_check(x,p);					\
++		pax_open_userland();					\
++		__e = __put_user_check(x,p);				\
++		pax_close_userland();					\
++		__e;							\
+ 	 })
+ 
+ #else /* CONFIG_MMU */
+@@ -230,13 +266,17 @@ static inline void set_fs(mm_segment_t fs)
+ #define __get_user(x,ptr)						\
+ ({									\
+ 	long __gu_err = 0;						\
++	pax_open_userland();						\
+ 	__get_user_err((x),(ptr),__gu_err);				\
++	pax_close_userland();						\
+ 	__gu_err;							\
+ })
+ 
+ #define __get_user_error(x,ptr,err)					\
+ ({									\
++	pax_open_userland();						\
+ 	__get_user_err((x),(ptr),err);					\
++	pax_close_userland();						\
+ 	(void) 0;							\
+ })
+ 
+@@ -312,13 +352,17 @@ do {									\
+ #define __put_user(x,ptr)						\
+ ({									\
+ 	long __pu_err = 0;						\
++	pax_open_userland();						\
+ 	__put_user_err((x),(ptr),__pu_err);				\
++	pax_close_userland();						\
+ 	__pu_err;							\
+ })
+ 
+ #define __put_user_error(x,ptr,err)					\
+ ({									\
++	pax_open_userland();						\
+ 	__put_user_err((x),(ptr),err);					\
++	pax_close_userland();						\
+ 	(void) 0;							\
+ })
+ 
+@@ -418,11 +462,44 @@ do {									\
+ 
+ 
+ #ifdef CONFIG_MMU
+-extern unsigned long __must_check __copy_from_user(void *to, const void __user \
*from, unsigned long n); +-extern unsigned long __must_check __copy_to_user(void \
__user *to, const void *from, unsigned long n); ++extern unsigned long __must_check \
___copy_from_user(void *to, const void __user *from, unsigned long n); ++extern \
unsigned long __must_check ___copy_to_user(void __user *to, const void *from, \
unsigned long n); ++
++static inline unsigned long __must_check __copy_from_user(void *to, const void \
__user *from, unsigned long n) ++{
++	unsigned long ret;
++
++	check_object_size(to, n, false);
++	pax_open_userland();
++	ret = ___copy_from_user(to, from, n);
++	pax_close_userland();
++	return ret;
++}
++
++static inline unsigned long __must_check __copy_to_user(void __user *to, const void \
*from, unsigned long n) ++{
++	unsigned long ret;
++
++	check_object_size(from, n, true);
++	pax_open_userland();
++	ret = ___copy_to_user(to, from, n);
++	pax_close_userland();
++	return ret;
++}
++
+ extern unsigned long __must_check __copy_to_user_std(void __user *to, const void \
*from, unsigned long n); +-extern unsigned long __must_check __clear_user(void __user \
*addr, unsigned long n); ++extern unsigned long __must_check ___clear_user(void \
__user *addr, unsigned long n); + extern unsigned long __must_check \
__clear_user_std(void __user *addr, unsigned long n); ++
++static inline unsigned long __must_check __clear_user(void __user *addr, unsigned \
long n) ++{
++	unsigned long ret;
++	pax_open_userland();
++	ret = ___clear_user(addr, n);
++	pax_close_userland();
++	return ret;
++}
++
+ #else
+ #define __copy_from_user(to,from,n)	(memcpy(to, (void __force *)from, n), 0)
+ #define __copy_to_user(to,from,n)	(memcpy((void __force *)to, from, n), 0)
+@@ -431,6 +508,9 @@ extern unsigned long __must_check __clear_user_std(void __user \
*addr, unsigned l + 
+ static inline unsigned long __must_check copy_from_user(void *to, const void __user \
*from, unsigned long n) + {
++	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 */
+@@ -440,6 +520,9 @@ static inline unsigned long __must_check copy_from_user(void \
*to, const void __u + 
+ static inline unsigned long __must_check copy_to_user(void __user *to, const void \
*from, unsigned long n) + {
++	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 60d3b73..e5a0f22 100644
+--- a/arch/arm/kernel/armksyms.c
++++ b/arch/arm/kernel/armksyms.c
+@@ -53,7 +53,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);
+ 
+@@ -89,9 +89,9 @@ EXPORT_SYMBOL(__memzero);
+ #ifdef CONFIG_MMU
+ EXPORT_SYMBOL(copy_page);
+ 
+-EXPORT_SYMBOL(__copy_from_user);
+-EXPORT_SYMBOL(__copy_to_user);
+-EXPORT_SYMBOL(__clear_user);
++EXPORT_SYMBOL(___copy_from_user);
++EXPORT_SYMBOL(___copy_to_user);
++EXPORT_SYMBOL(___clear_user);
+ 
+ EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+index 9cbe70c..a7b5e34 100644
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -47,6 +47,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
+@@ -89,11 +170,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
+ 
+@@ -149,7 +234,11 @@ ENDPROC(__und_invalid)
+ 	.macro	svc_entry, stack_hole=0
+  UNWIND(.fnstart		)
+  UNWIND(.save {r0 - pc}		)
++
++	pax_enter_kernel
++
+ 	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++
+ #ifdef CONFIG_THUMB2_KERNEL
+  SPFIX(	str	r0, [sp]	)	@ temporarily saved
+  SPFIX(	mov	r0, sp		)
+@@ -164,7 +253,12 @@ ENDPROC(__und_invalid)
+ 	ldmia	r0, {r3 - r5}
+ 	add	r7, sp, #S_SP - 4	@ here for interlock avoidance
+ 	mov	r6, #-1			@  ""  ""      ""       ""
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	@ offset sp by 8 as done in pax_enter_kernel
++	add	r2, sp, #(S_FRAME_SIZE + \stack_hole + 4)
++#else
+ 	add	r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
++#endif
+  SPFIX(	addeq	r2, r2, #4	)
+ 	str	r3, [sp, #-4]!		@ save the "real" r0 copied
+ 					@ from the exception stack
+@@ -316,6 +410,9 @@ ENDPROC(__pabt_svc)
+ 	.macro	usr_entry
+  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}	)
+@@ -415,7 +512,9 @@ __und_usr:
+ 	tst	r3, #PSR_T_BIT			@ Thumb mode?
+ 	bne	__und_usr_thumb
+ 	sub	r4, r2, #4			@ ARM instr at LR - 4
++	pax_open_userland
+ 1:	ldrt	r0, [r4]
++	pax_close_userland
+ #ifdef CONFIG_CPU_ENDIAN_BE8
+ 	rev	r0, r0				@ little endian instruction
+ #endif
+@@ -450,10 +549,14 @@ __und_usr_thumb:
+  */
+ 	.arch	armv6t2
+ #endif
++	pax_open_userland
+ 2:	ldrht	r5, [r4]
++	pax_close_userland
+ 	cmp	r5, #0xe800			@ 32bit instruction if xx != 0
+ 	blo	__und_usr_fault_16		@ 16bit undefined instruction
++	pax_open_userland
+ 3:	ldrht	r0, [r2]
++	pax_close_userland
+ 	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
+ 	str	r2, [sp, #S_PC]			@ it's a 2x16bit instr, update
+ 	orr	r0, r0, r5, lsl #16
+@@ -482,7 +585,8 @@ ENDPROC(__und_usr)
+  */
+ 	.pushsection .fixup, "ax"
+ 	.align	2
+-4:	mov	pc, r9
++4:	pax_close_userland
++	mov	pc, r9
+ 	.popsection
+ 	.pushsection __ex_table,"a"
+ 	.long	1b, 4b
+@@ -692,7 +796,7 @@ ENTRY(__switch_to)
+  THUMB(	str	lr, [ip], #4		   )
+ 	ldr	r4, [r2, #TI_TP_VALUE]
+ 	ldr	r5, [r2, #TI_TP_VALUE + 4]
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || \
defined(CONFIG_PAX_MEMORY_UDEREF) + 	ldr	r6, [r2, #TI_CPU_DOMAIN]
+ #endif
+ 	switch_tls r1, r4, r5, r3, r7
+@@ -701,7 +805,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 94104bf..e425391 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -10,18 +10,46 @@
+ 
+ #include <asm/unistd.h>
+ #include <asm/ftrace.h>
++#include <asm/domain.h>
+ #include <asm/unwind.h>
+ 
++#include "entry-header.S"
++
+ #ifdef CONFIG_NEED_RET_TO_USER
+ #include <mach/entry-macro.S>
+ #else
+ 	.macro  arch_ret_to_user, tmp1, tmp2
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	@ save regs
++	stmdb	sp!, {r1, r2}
++        @ read DACR from cpu_domain into r1
++        mov     r2, sp
++        @ assume 8K pages, since we have to split the immediate in two
++        bic     r2, r2, #(0x1fc0)
++        bic     r2, r2, #(0x3f)
++        ldr     r1, [r2, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_KERNEXEC
++        @ set type of DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++        bic     r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++        orr     r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++        @ set current DOMAIN_USER to DOMAIN_UDEREF
++        bic     r1, r1, #(domain_val(DOMAIN_USER, 3))
++        orr     r1, r1, #(domain_val(DOMAIN_USER, DOMAIN_UDEREF))
++#endif
++        @ write r1 to current_thread_info()->cpu_domain
++        str     r1, [r2, #TI_CPU_DOMAIN]
++        @ write r1 to DACR
++        mcr     p15, 0, r1, c3, c0, 0
++        @ instruction sync
++        instr_sync
++	@ restore regs
++	ldmia	sp!, {r1, r2}
++#endif
+ 	.endm
+ #endif
+ 
+-#include "entry-header.S"
+-
+-
+ 	.align	5
+ /*
+  * This is the fast syscall return path.  We do as little as
+@@ -413,6 +441,12 @@ ENTRY(vector_swi)
+  USER(	ldr	scno, [lr, #-4]		)	@ get SWI instruction
+ #endif
+ 
++	/*
++	 * do this here to avoid a performance hit of wrapping the code above
++	 * that directly dereferences userland to parse the SWI instruction
++	 */
++	pax_enter_kernel_user
++
+ 	adr	tbl, sys_call_table		@ load syscall table pointer
+ 
+ #if defined(CONFIG_OABI_COMPAT)
+diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
+index de23a9b..94c37c4 100644
+--- a/arch/arm/kernel/entry-header.S
++++ b/arch/arm/kernel/entry-header.S
+@@ -184,6 +184,60 @@
+ 	msr	cpsr_c, \rtemp			@ switch back to the SVC mode
+ 	.endm
+ 
++	.macro	pax_enter_kernel_user
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	@ save regs
++	stmdb	sp!, {r0, r1}
++	@ read DACR from cpu_domain into r1
++	mov	r0, sp
++	@ assume 8K pages, since we have to split the immediate in two
++	bic	r0, r0, #(0x1fc0)
++	bic	r0, r0, #(0x3f)
++	ldr	r1, [r0, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	@ set current DOMAIN_USER to DOMAIN_NOACCESS
++	bic	r1, r1, #(domain_val(DOMAIN_USER, 3))
++#endif
++#ifdef CONFIG_PAX_KERNEXEC
++	@ set current DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++	bic	r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++	orr	r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++	@ write r1 to current_thread_info()->cpu_domain
++	str	r1, [r0, #TI_CPU_DOMAIN]
++	@ write r1 to DACR
++	mcr	p15, 0, r1, c3, c0, 0
++	@ instruction sync
++	instr_sync
++	@ restore regs
++	ldmia	sp!, {r0, r1}
++#endif
++	.endm
++
++	.macro  pax_exit_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	@ save regs
++	stmdb	sp!, {r0, r1}
++	@ read old DACR from stack into r1
++	ldr	r1, [sp, #(8 + S_SP)]
++	sub	r1, r1, #8
++	ldr	r1, [r1]
++
++	@ write r1 to current_thread_info()->cpu_domain
++	mov	r0, sp
++	@ assume 8K pages, since we have to split the immediate in two
++	bic	r0, r0, #(0x1fc0)
++	bic	r0, r0, #(0x3f)
++	str	r1, [r0, #TI_CPU_DOMAIN]
++	@ write r1 to DACR
++	mcr	p15, 0, r1, c3, c0, 0
++	@ instruction sync
++	instr_sync
++	@ restore regs
++	ldmia	sp!, {r0, r1}
++#endif
++	.endm
++
+ #ifndef CONFIG_THUMB2_KERNEL
+ 	.macro	svc_exit, rpsr, irq = 0
+ 	.if	\irq != 0
+@@ -203,6 +257,9 @@
+ 	blne	trace_hardirqs_off
+ #endif
+ 	.endif
++
++	pax_exit_kernel
++
+ 	msr	spsr_cxsf, \rpsr
+ #if defined(CONFIG_CPU_V6)
+ 	ldr	r0, [sp]
+@@ -266,6 +323,9 @@
+ 	blne	trace_hardirqs_off
+ #endif
+ 	.endif
++
++	pax_exit_kernel
++
+ 	ldr	lr, [sp, #S_SP]			@ top of the stack
+ 	ldrd	r0, r1, [sp, #S_LR]		@ calling lr and pc
+ 	clrex					@ clear the exclusive monitor
+diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
+index 918875d..cd5fa27 100644
+--- a/arch/arm/kernel/fiq.c
++++ b/arch/arm/kernel/fiq.c
+@@ -87,7 +87,10 @@ void set_fiq_handler(void *start, unsigned int length)
+ 	void *base = vectors_page;
+ 	unsigned offset = FIQ_OFFSET;
+ 
++	pax_open_kernel();
+ 	memcpy(base + offset, start, length);
++	pax_close_kernel();
++
+ 	if (!cache_is_vipt_nonaliasing())
+ 		flush_icache_range((unsigned long)base + offset, offset +
+ 				   length);
+diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
+index 2c7cc1e..ab2e911 100644
+--- a/arch/arm/kernel/head.S
++++ b/arch/arm/kernel/head.S
+@@ -52,7 +52,9 @@
+ 	.equ	swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
+ 
+ 	.macro	pgtbl, rd, phys
+-	add	\rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE
++	mov	\rd, #TEXT_OFFSET
++	sub	\rd, #PG_DIR_SIZE
++	add	\rd, \rd, \phys
+ 	.endm
+ 
+ /*
+@@ -432,7 +434,7 @@ __enable_mmu:
+ 	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+ 		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+ 		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+-		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
++		      domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT))
+ 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
+ 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
+ #endif
+diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
+index 85c3fb6..054c2dc 100644
+--- a/arch/arm/kernel/module.c
++++ b/arch/arm/kernel/module.c
+@@ -37,12 +37,39 @@
+ #endif
+ 
+ #ifdef CONFIG_MMU
+-void *module_alloc(unsigned long size)
++static inline void *__module_alloc(unsigned long size, pgprot_t prot)
+ {
++	if (!size || PAGE_ALIGN(size) > MODULES_END - MODULES_VADDR)
++		return NULL;
+ 	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+-				GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
++				GFP_KERNEL, prot, -1,
+ 				__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_free_exec(struct module *mod, void *module_region)
++{
++	module_free(mod, module_region);
++}
++EXPORT_SYMBOL(module_free_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 07314af..c46655c 100644
+--- a/arch/arm/kernel/patch.c
++++ b/arch/arm/kernel/patch.c
+@@ -18,6 +18,7 @@ void __kprobes __patch_text(void *addr, unsigned int insn)
+ 	bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
+ 	int size;
+ 
++	pax_open_kernel();
+ 	if (thumb2 && __opcode_is_thumb16(insn)) {
+ 		*(u16 *)addr = __opcode_to_mem_thumb16(insn);
+ 		size = sizeof(u16);
+@@ -39,6 +40,7 @@ void __kprobes __patch_text(void *addr, unsigned int insn)
+ 		*(u32 *)addr = insn;
+ 		size = sizeof(u32);
+ 	}
++	pax_close_kernel();
+ 
+ 	flush_icache_range((uintptr_t)(addr),
+ 			   (uintptr_t)(addr) + size);
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index 94f6b05..efd7312 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -217,6 +217,7 @@ void machine_power_off(void)
+ 
+ 	if (pm_power_off)
+ 		pm_power_off();
++	BUG();
+ }
+ 
+ /*
+@@ -230,7 +231,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)
++__noreturn void machine_restart(char *cmd)
+ {
+ 	local_irq_disable();
+ 	smp_send_stop();
+@@ -253,8 +254,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,
+@@ -422,12 +423,6 @@ unsigned long get_wchan(struct task_struct *p)
+ 	return 0;
+ }
+ 
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-	unsigned long range_end = mm->brk + 0x02000000;
+-	return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+-}
+-
+ #ifdef CONFIG_MMU
+ #ifdef CONFIG_KUSER_HELPERS
+ /*
+@@ -443,7 +438,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);
+@@ -469,41 +464,16 @@ int in_gate_area_no_mm(unsigned long addr)
+ 
+ const char *arch_vma_name(struct vm_area_struct *vma)
+ {
+-	return is_gate_vma(vma) ? "[vectors]" :
+-		(vma->vm_mm && vma->vm_start == vma->vm_mm->context.sigpage) ?
+-		 "[sigpage]" : NULL;
++	return is_gate_vma(vma) ? "[vectors]" : NULL;
+ }
+ 
+-static struct page *signal_page;
+-extern struct page *get_signal_page(void);
+-
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+ 	struct mm_struct *mm = current->mm;
+-	unsigned long addr;
+-	int ret;
+-
+-	if (!signal_page)
+-		signal_page = get_signal_page();
+-	if (!signal_page)
+-		return -ENOMEM;
+ 
+ 	down_write(&mm->mmap_sem);
+-	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+-	if (IS_ERR_VALUE(addr)) {
+-		ret = addr;
+-		goto up_fail;
+-	}
+-
+-	ret = install_special_mapping(mm, addr, PAGE_SIZE,
+-		VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+-		&signal_page);
+-
+-	if (ret == 0)
+-		mm->context.sigpage = addr;
+-
+- up_fail:
++	mm->context.sigpage = (PAGE_OFFSET + (get_random_int() % 0x3FFEFFE0)) & \
0xFFFFFFFC; + 	up_write(&mm->mmap_sem);
+-	return ret;
++	return 0;
+ }
+ #endif
+diff --git a/arch/arm/kernel/psci.c b/arch/arm/kernel/psci.c
+index 4693188..4596c5e 100644
+--- a/arch/arm/kernel/psci.c
++++ b/arch/arm/kernel/psci.c
+@@ -24,7 +24,7 @@
+ #include <asm/opcodes-virt.h>
+ #include <asm/psci.h>
+ 
+-struct psci_operations psci_ops;
++struct psci_operations psci_ops __read_only;
+ 
+ static int (*invoke_psci_fn)(u32, u32, u32, u32);
+ 
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index 0dd3b79..e018f64 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -929,10 +929,19 @@ static int tracehook_report_syscall(struct pt_regs *regs,
+ 	return current_thread_info()->syscall;
+ }
+ 
++#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. */
+ 	if (secure_computing(scno) == -1)
+ 		return -1;
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index afc2489..6372bc8 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -98,21 +98,23 @@ EXPORT_SYMBOL(system_serial_high);
+ unsigned int elf_hwcap __read_mostly;
+ EXPORT_SYMBOL(elf_hwcap);
+ 
++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;
+ #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
+ 
+@@ -245,9 +247,13 @@ static int __get_cpu_architecture(void)
+ 		asm("mrc	p15, 0, %0, c0, c1, 4"
+ 		    : "=r" (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
+@@ -571,7 +577,7 @@ static void __init setup_processor(void)
+ 	__cpu_architecture = __get_cpu_architecture();
+ 
+ #ifdef MULTI_CPU
+-	processor = *list->proc;
++	memcpy((void *)&processor, list->proc, sizeof processor);
+ #endif
+ #ifdef MULTI_TLB
+ 	cpu_tlb = *list->tlb;
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+index ab33042..11248a8 100644
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -45,8 +45,6 @@ static const unsigned long sigreturn_codes[7] = {
+ 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
+ };
+ 
+-static unsigned long signal_return_offset;
+-
+ #ifdef CONFIG_CRUNCH
+ static int preserve_crunch_context(struct crunch_sigframe __user *frame)
+ {
+@@ -411,8 +409,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
+ 		{
+@@ -616,33 +613,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 2dc1934..ecf0e21 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -71,7 +71,7 @@ enum ipi_msg_type {
+ 
+ static DECLARE_COMPLETION(cpu_running);
+ 
+-static struct smp_operations smp_ops;
++static struct smp_operations smp_ops __read_only;
+ 
+ void __init smp_set_ops(struct smp_operations *ops)
+ {
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index ab517fc..9adf2fa 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -55,7 +55,7 @@ static void dump_mem(const char *, const char *, unsigned long, \
unsigned long); + void dump_backtrace_entry(unsigned long where, unsigned long from, \
unsigned long frame) + {
+ #ifdef CONFIG_KALLSYMS
+-	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
+@@ -257,6 +257,8 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+ static int die_owner = -1;
+ static unsigned int die_nest_count;
+ 
++extern void gr_handle_kernel_exploit(void);
++
+ static unsigned long oops_begin(void)
+ {
+ 	int cpu;
+@@ -299,6 +301,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, \
int signr) + 		panic("Fatal exception in interrupt");
+ 	if (panic_on_oops)
+ 		panic("Fatal exception");
++
++	gr_handle_kernel_exploit();
++
+ 	if (signr)
+ 		do_exit(signr);
+ }
+@@ -592,7 +597,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
+ 			 * The user helper at 0xffff0fe0 must be used instead.
+ 			 * (see entry-armv.S for details)
+ 			 */
++			pax_open_kernel();
+ 			*((unsigned int *)0xffff0ff0) = regs->ARM_r0;
++			pax_close_kernel();
+ 		}
+ 		return 0;
+ 
+@@ -849,7 +856,11 @@ void __init early_trap_init(void *vectors_base)
+ 	kuser_init(vectors_base);
+ 
+ 	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
+-	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
++
++#ifndef CONFIG_PAX_MEMORY_UDEREF
++	modify_domain(DOMAIN_USER, DOMAIN_USERCLIENT);
++#endif
++
+ #else /* ifndef CONFIG_CPU_V7M */
+ 	/*
+ 	 * on V7-M there is no need to copy the vector table to a dedicated
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index 7bcee5c..e2f3249 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -8,7 +8,11 @@
+ #include <asm/thread_info.h>
+ #include <asm/memory.h>
+ #include <asm/page.h>
+-	
++
++#ifdef CONFIG_PAX_KERNEXEC
++#include <asm/pgtable.h>
++#endif
++
+ #define PROC_INFO							\
+ 	. = ALIGN(4);							\
+ 	VMLINUX_SYMBOL(__proc_info_begin) = .;				\
+@@ -34,7 +38,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
+@@ -90,6 +94,11 @@ SECTIONS
+ 		_text = .;
+ 		HEAD_TEXT
+ 	}
++
++#ifdef CONFIG_PAX_KERNEXEC
++	. = ALIGN(1<<SECTION_SHIFT);
++#endif
++
+ 	.text : {			/* Real text segment		*/
+ 		_stext = .;		/* Text and read-only data	*/
+ 			__exception_text_start = .;
+@@ -112,6 +121,8 @@ SECTIONS
+ 			ARM_CPU_KEEP(PROC_INFO)
+ 	}
+ 
++	_etext = .;			/* End of text section */
++
+ 	RO_DATA(PAGE_SIZE)
+ 
+ 	. = ALIGN(4);
+@@ -142,7 +153,9 @@ SECTIONS
+ 
+ 	NOTES
+ 
+-	_etext = .;			/* End of text and rodata section */
++#ifdef CONFIG_PAX_KERNEXEC
++	. = ALIGN(1<<SECTION_SHIFT);
++#endif
+ 
+ #ifndef CONFIG_XIP_KERNEL
+ 	. = ALIGN(PAGE_SIZE);
+@@ -220,6 +233,11 @@ SECTIONS
+ 	. = PAGE_OFFSET + TEXT_OFFSET;
+ #else
+ 	__init_end = .;
++
++#ifdef CONFIG_PAX_KERNEXEC
++	. = ALIGN(1<<SECTION_SHIFT);
++#endif
++
+ 	. = ALIGN(THREAD_SIZE);
+ 	__data_loc = .;
+ #endif
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index 741f66a..8a5615c 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -56,7 +56,7 @@ static unsigned long hyp_default_vectors;
+ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
+ 
+ /* The VMID used in the VTTBR */
+-static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
++static atomic64_unchecked_t kvm_vmid_gen = ATOMIC64_INIT(1);
+ static u8 kvm_next_vmid;
+ static DEFINE_SPINLOCK(kvm_vmid_lock);
+ 
+@@ -392,7 +392,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));
+ }
+ 
+ /**
+@@ -425,7 +425,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;
+ 
+ 		/*
+@@ -442,7 +442,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++;
+ 
+diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
+index 14a0d98..7771a7d 100644
+--- a/arch/arm/lib/clear_user.S
++++ b/arch/arm/lib/clear_user.S
+@@ -12,14 +12,14 @@
+ 
+ 		.text
+ 
+-/* Prototype: int __clear_user(void *addr, size_t sz)
++/* Prototype: int ___clear_user(void *addr, size_t sz)
+  * Purpose  : clear some user memory
+  * Params   : addr - user memory address to clear
+  *          : sz   - number of bytes to clear
+  * Returns  : number of bytes NOT cleared
+  */
+ ENTRY(__clear_user_std)
+-WEAK(__clear_user)
++WEAK(___clear_user)
+ 		stmfd	sp!, {r1, lr}
+ 		mov	r2, #0
+ 		cmp	r1, #4
+@@ -44,7 +44,7 @@ WEAK(__clear_user)
+ USER(		strnebt	r2, [r0])
+ 		mov	r0, #0
+ 		ldmfd	sp!, {r1, pc}
+-ENDPROC(__clear_user)
++ENDPROC(___clear_user)
+ ENDPROC(__clear_user_std)
+ 
+ 		.pushsection .fixup,"ax"
+diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
+index 66a477a..bee61d3 100644
+--- a/arch/arm/lib/copy_from_user.S
++++ b/arch/arm/lib/copy_from_user.S
+@@ -16,7 +16,7 @@
+ /*
+  * Prototype:
+  *
+- *	size_t __copy_from_user(void *to, const void *from, size_t n)
++ *	size_t ___copy_from_user(void *to, const void *from, size_t n)
+  *
+  * Purpose:
+  *
+@@ -84,11 +84,11 @@
+ 
+ 	.text
+ 
+-ENTRY(__copy_from_user)
++ENTRY(___copy_from_user)
+ 
+ #include "copy_template.S"
+ 
+-ENDPROC(__copy_from_user)
++ENDPROC(___copy_from_user)
+ 
+ 	.pushsection .fixup,"ax"
+ 	.align 0
+diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
+index 6ee2f67..d1cce76 100644
+--- a/arch/arm/lib/copy_page.S
++++ b/arch/arm/lib/copy_page.S
+@@ -10,6 +10,7 @@
+  *  ASM optimised string functions
+  */
+ #include <linux/linkage.h>
++#include <linux/const.h>
+ #include <asm/assembler.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
+diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
+index d066df6..df28194 100644
+--- a/arch/arm/lib/copy_to_user.S
++++ b/arch/arm/lib/copy_to_user.S
+@@ -16,7 +16,7 @@
+ /*
+  * Prototype:
+  *
+- *	size_t __copy_to_user(void *to, const void *from, size_t n)
++ *	size_t ___copy_to_user(void *to, const void *from, size_t n)
+  *
+  * Purpose:
+  *
+@@ -88,11 +88,11 @@
+ 	.text
+ 
+ ENTRY(__copy_to_user_std)
+-WEAK(__copy_to_user)
++WEAK(___copy_to_user)
+ 
+ #include "copy_template.S"
+ 
+-ENDPROC(__copy_to_user)
++ENDPROC(___copy_to_user)
+ ENDPROC(__copy_to_user_std)
+ 
+ 	.pushsection .fixup,"ax"
+diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
+index 7d08b43..f7ca7ea 100644
+--- a/arch/arm/lib/csumpartialcopyuser.S
++++ b/arch/arm/lib/csumpartialcopyuser.S
+@@ -57,8 +57,8 @@
+  *  Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+  */
+ 
+-#define FN_ENTRY	ENTRY(csum_partial_copy_from_user)
+-#define FN_EXIT		ENDPROC(csum_partial_copy_from_user)
++#define FN_ENTRY	ENTRY(__csum_partial_copy_from_user)
++#define FN_EXIT		ENDPROC(__csum_partial_copy_from_user)
+ 
+ #include "csumpartialcopygeneric.S"
+ 
+diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c
+index 5306de3..aed6d03 100644
+--- a/arch/arm/lib/delay.c
++++ b/arch/arm/lib/delay.c
+@@ -28,7 +28,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 025f742..a9e5b3b 100644
+--- a/arch/arm/lib/uaccess_with_memcpy.c
++++ b/arch/arm/lib/uaccess_with_memcpy.c
+@@ -104,7 +104,7 @@ out:
+ }
+ 
+ unsigned long
+-__copy_to_user(void __user *to, const void *from, unsigned long n)
++___copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ 	/*
+ 	 * This test is stubbed out of the main function above to keep
+@@ -155,7 +155,7 @@ out:
+ 	return n;
+ }
+ 
+-unsigned long __clear_user(void __user *addr, unsigned long n)
++unsigned long ___clear_user(void __user *addr, unsigned long n)
+ {
+ 	/* See rational for this in __copy_to_user() above. */
+ 	if (n < 64)
+diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
+index e9238b5..6ed904a 100644
+--- a/arch/arm/mach-kirkwood/common.c
++++ b/arch/arm/mach-kirkwood/common.c
+@@ -150,7 +150,16 @@ static void clk_gate_fn_disable(struct clk_hw *hw)
+ 	clk_gate_ops.disable(hw);
+ }
+ 
+-static struct clk_ops clk_gate_fn_ops;
++static int clk_gate_fn_is_enabled(struct clk_hw *hw)
++{
++	return clk_gate_ops.is_enabled(hw);
++}
++
++static struct clk_ops clk_gate_fn_ops = {
++	.enable = clk_gate_fn_enable,
++	.disable = clk_gate_fn_disable,
++	.is_enabled = clk_gate_fn_is_enabled,
++};
+ 
+ static struct clk __init *clk_register_gate_fn(struct device *dev,
+ 		const char *name,
+@@ -184,14 +193,6 @@ static struct clk __init *clk_register_gate_fn(struct device \
*dev, + 	gate_fn->fn_en = fn_en;
+ 	gate_fn->fn_dis = fn_dis;
+ 
+-	/* ops is the gate ops, but with our enable/disable functions */
+-	if (clk_gate_fn_ops.enable != clk_gate_fn_enable ||
+-	    clk_gate_fn_ops.disable != clk_gate_fn_disable) {
+-		clk_gate_fn_ops = clk_gate_ops;
+-		clk_gate_fn_ops.enable = clk_gate_fn_enable;
+-		clk_gate_fn_ops.disable = clk_gate_fn_disable;
+-	}
+-
+ 	clk = clk_register(dev, &gate_fn->gate.hw);
+ 
+ 	if (IS_ERR(clk))
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index 827d1500..2885dc6 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -627,7 +627,7 @@ static int n8x0_menelaus_late_init(struct device *dev)
+ }
+ #endif
+ 
+-static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
++static struct menelaus_platform_data n8x0_menelaus_platform_data __initconst = {
+ 	.late_init = n8x0_menelaus_late_init,
+ };
+ 
+diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
+index f3fdd6a..3564800 100644
+--- a/arch/arm/mach-omap2/gpmc.c
++++ b/arch/arm/mach-omap2/gpmc.c
+@@ -148,7 +148,6 @@ struct omap3_gpmc_regs {
+ };
+ 
+ static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
+-static struct irq_chip gpmc_irq_chip;
+ static unsigned gpmc_irq_start;
+ 
+ static struct resource	gpmc_mem_root;
+@@ -716,6 +715,18 @@ static void gpmc_irq_noop(struct irq_data *data) { }
+ 
+ static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+ 
++static struct irq_chip gpmc_irq_chip = {
++	.name = "gpmc",
++	.irq_startup = gpmc_irq_noop_ret,
++	.irq_enable = gpmc_irq_enable,
++	.irq_disable = gpmc_irq_disable,
++	.irq_shutdown = gpmc_irq_noop,
++	.irq_ack = gpmc_irq_noop,
++	.irq_mask = gpmc_irq_noop,
++	.irq_unmask = gpmc_irq_noop,
++
++};
++
+ static int gpmc_setup_irq(void)
+ {
+ 	int i;
+@@ -730,15 +741,6 @@ static int gpmc_setup_irq(void)
+ 		return gpmc_irq_start;
+ 	}
+ 
+-	gpmc_irq_chip.name = "gpmc";
+-	gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
+-	gpmc_irq_chip.irq_enable = gpmc_irq_enable;
+-	gpmc_irq_chip.irq_disable = gpmc_irq_disable;
+-	gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
+-	gpmc_irq_chip.irq_ack = gpmc_irq_noop;
+-	gpmc_irq_chip.irq_mask = gpmc_irq_noop;
+-	gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
+-
+ 	gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
+ 	gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
+ 
+diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c \
b/arch/arm/mach-omap2/omap-mpuss-lowpower.c +index f991016..145ebeb 100644
+--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
++++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+@@ -84,7 +84,7 @@ struct cpu_pm_ops {
+ 	int (*finish_suspend)(unsigned long cpu_state);
+ 	void (*resume)(void);
+ 	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+-};
++} __no_const;
+ 
+ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+ static struct powerdomain *mpuss_pd;
+@@ -102,7 +102,7 @@ static void dummy_cpu_resume(void)
+ static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+ {}
+ 
+-struct cpu_pm_ops omap_pm_ops = {
++static struct cpu_pm_ops omap_pm_ops __read_only = {
+ 	.finish_suspend		= default_finish_suspend,
+ 	.resume			= dummy_cpu_resume,
+ 	.scu_prepare		= dummy_scu_prepare,
+diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c \
b/arch/arm/mach-omap2/omap-wakeupgen.c +index 813c615..ce467c6 100644
+--- a/arch/arm/mach-omap2/omap-wakeupgen.c
++++ b/arch/arm/mach-omap2/omap-wakeupgen.c
+@@ -339,7 +339,7 @@ static int irq_cpu_hotplug_notify(struct notifier_block *self,
+ 	return NOTIFY_OK;
+ }
+ 
+-static struct notifier_block __refdata irq_hotplug_notifier = {
++static struct notifier_block irq_hotplug_notifier = {
+ 	.notifier_call = irq_cpu_hotplug_notify,
+ };
+ 
+diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
+index f99f68e..e573e20 100644
+--- a/arch/arm/mach-omap2/omap_device.c
++++ b/arch/arm/mach-omap2/omap_device.c
+@@ -504,7 +504,7 @@ void omap_device_delete(struct omap_device *od)
+ struct platform_device __init *omap_device_build(const char *pdev_name,
+ 						 int pdev_id,
+ 						 struct omap_hwmod *oh,
+-						 void *pdata, int pdata_len)
++						 const void *pdata, int pdata_len)
+ {
+ 	struct omap_hwmod *ohs[] = { oh };
+ 
+@@ -532,7 +532,7 @@ struct platform_device __init *omap_device_build(const char \
*pdev_name, + struct platform_device __init *omap_device_build_ss(const char \
*pdev_name, + 						    int pdev_id,
+ 						    struct omap_hwmod **ohs,
+-						    int oh_cnt, void *pdata,
++						    int oh_cnt, const void *pdata,
+ 						    int pdata_len)
+ {
+ 	int ret = -ENOMEM;
+diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h
+index 17ca1ae..beba869 100644
+--- a/arch/arm/mach-omap2/omap_device.h
++++ b/arch/arm/mach-omap2/omap_device.h
+@@ -71,12 +71,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 7f4db12..0243012 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -194,10 +194,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/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
+index d15c7bb..b2d1f0c 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-tegra/cpuidle-tegra20.c \
b/arch/arm/mach-tegra/cpuidle-tegra20.c +index 706aa42..f85e9131 100644
+--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
++++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
+@@ -180,7 +180,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-ux500/setup.h b/arch/arm/mach-ux500/setup.h
+index cad3ca86..1d79e0f 100644
+--- a/arch/arm/mach-ux500/setup.h
++++ b/arch/arm/mach-ux500/setup.h
+@@ -37,13 +37,6 @@ extern void ux500_timer_init(void);
+ 	.type		= MT_DEVICE,		\
+ }
+ 
+-#define __MEM_DEV_DESC(x, sz)	{		\
+-	.virtual	= IO_ADDRESS(x),	\
+-	.pfn		= __phys_to_pfn(x),	\
+-	.length		= sz,			\
+-	.type		= MT_MEMORY,		\
+-}
+-
+ extern struct smp_operations ux500_smp_ops;
+ extern void ux500_cpu_die(unsigned int cpu);
+ 
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index cd2c88e..7430282 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -446,7 +446,7 @@ config CPU_32v5
+ 
+ config CPU_32v6
+ 	bool
+-	select CPU_USE_DOMAINS if CPU_V6 && MMU
++	select CPU_USE_DOMAINS if CPU_V6 && MMU && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ 	select TLS_REG_EMUL if !CPU_32v6K && !MMU
+ 
+ config CPU_32v6K
+@@ -601,6 +601,7 @@ config CPU_CP15_MPU
+ 
+ config CPU_USE_DOMAINS
+ 	bool
++	depends on !ARM_LPAE && !PAX_KERNEXEC
+ 	help
+ 	  This option enables or disables the use of domain switching
+ 	  via the set_fs() function.
+@@ -800,6 +801,7 @@ config NEED_KUSER_HELPERS
+ config KUSER_HELPERS
+ 	bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+ 	default y
++	depends on !(CPU_V6 || CPU_V6K || CPU_V7)
+ 	help
+ 	  Warning: disabling this option may break user programs.
+ 
+@@ -812,7 +814,7 @@ config KUSER_HELPERS
+ 	  See Documentation/arm/kernel_user_helpers.txt for details.
+ 
+ 	  However, the fixed address nature of these helpers can be used
+-	  by ROP (return orientated programming) authors when creating
++	  by ROP (Return Oriented Programming) authors when creating
+ 	  exploits.
+ 
+ 	  If all of the binaries and libraries which run on your platform
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index 6f4585b..7b6f52b 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -211,10 +211,12 @@ union offset_union {
+ #define __get16_unaligned_check(ins,val,addr)			\
+ 	do {							\
+ 		unsigned int err = 0, v, a = addr;		\
++		pax_open_userland();				\
+ 		__get8_unaligned_check(ins,v,a,err);		\
+ 		val =  v << ((BE) ? 8 : 0);			\
+ 		__get8_unaligned_check(ins,v,a,err);		\
+ 		val |= v << ((BE) ? 0 : 8);			\
++		pax_close_userland();				\
+ 		if (err)					\
+ 			goto fault;				\
+ 	} while (0)
+@@ -228,6 +230,7 @@ union offset_union {
+ #define __get32_unaligned_check(ins,val,addr)			\
+ 	do {							\
+ 		unsigned int err = 0, v, a = addr;		\
++		pax_open_userland();				\
+ 		__get8_unaligned_check(ins,v,a,err);		\
+ 		val =  v << ((BE) ? 24 :  0);			\
+ 		__get8_unaligned_check(ins,v,a,err);		\
+@@ -236,6 +239,7 @@ union offset_union {
+ 		val |= v << ((BE) ?  8 : 16);			\
+ 		__get8_unaligned_check(ins,v,a,err);		\
+ 		val |= v << ((BE) ?  0 : 24);			\
++		pax_close_userland();				\
+ 		if (err)					\
+ 			goto fault;				\
+ 	} while (0)
+@@ -249,6 +253,7 @@ union offset_union {
+ #define __put16_unaligned_check(ins,val,addr)			\
+ 	do {							\
+ 		unsigned int err = 0, v = val, a = addr;	\
++		pax_open_userland();				\
+ 		__asm__( FIRST_BYTE_16				\
+ 	 ARM(	"1:	"ins"	%1, [%2], #1\n"	)		\
+ 	 THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
+@@ -268,6 +273,7 @@ union offset_union {
+ 		"	.popsection\n"				\
+ 		: "=r" (err), "=&r" (v), "=&r" (a)		\
+ 		: "0" (err), "1" (v), "2" (a));			\
++		pax_close_userland();				\
+ 		if (err)					\
+ 			goto fault;				\
+ 	} while (0)
+@@ -281,6 +287,7 @@ union offset_union {
+ #define __put32_unaligned_check(ins,val,addr)			\
+ 	do {							\
+ 		unsigned int err = 0, v = val, a = addr;	\
++		pax_open_userland();				\
+ 		__asm__( FIRST_BYTE_32				\
+ 	 ARM(	"1:	"ins"	%1, [%2], #1\n"	)		\
+ 	 THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
+@@ -310,6 +317,7 @@ union offset_union {
+ 		"	.popsection\n"				\
+ 		: "=r" (err), "=&r" (v), "=&r" (a)		\
+ 		: "0" (err), "1" (v), "2" (a));			\
++		pax_close_userland();				\
+ 		if (err)					\
+ 			goto fault;				\
+ 	} while (0)
+diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
+index 4a05444..d21968c 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);
+@@ -183,7 +183,7 @@ static int is_reserved_asid(u64 asid)
+ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ {
+ 	u64 asid = atomic64_read(&mm->context.id);
+-	u64 generation = atomic64_read(&asid_generation);
++	u64 generation = atomic64_read_unchecked(&asid_generation);
+ 
+ 	if (asid != 0 && is_reserved_asid(asid)) {
+ 		/*
+@@ -201,7 +201,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ 		 */
+ 		asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
+ 		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);
+@@ -230,14 +230,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 c97f794..6461880 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,20 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, \
unsigned int fsr, + 	if (fixup_exception(regs))
+ 		return;
+ 
++#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_ERR "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_ERR "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.
+ 	 */
+@@ -174,6 +189,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
+ 	}
+ #endif
+ 
++#ifdef CONFIG_PAX_PAGEEXEC
++	if (fsr & FSR_LNX_PF) {
++		pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
++		do_group_exit(SIGKILL);
++	}
++#endif
++
+ 	tsk->thread.address = addr;
+ 	tsk->thread.error_code = fsr;
+ 	tsk->thread.trap_no = 14;
+@@ -398,6 +420,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
+  *
+@@ -545,9 +594,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_ERR "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_ERR "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:
+ 	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
+ 		inf->name, fsr, addr);
+ 
+@@ -571,15 +633,92 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned \
int, struct pt_regs * + 	ifsr_info[nr].name = name;
+ }
+ 
++asmlinkage int sys_sigreturn(struct pt_regs *regs);
++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
++
+ asmlinkage void __exception
+ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+ {
+ 	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ 	struct siginfo info;
++	unsigned long pc = instruction_pointer(regs);
++
++	if (user_mode(regs)) {
++		unsigned long sigpage = current->mm->context.sigpage;
++
++		if (sigpage <= pc && pc < sigpage + 7*4) {
++			if (pc < sigpage + 3*4)
++				sys_sigreturn(regs);
++			else
++				sys_rt_sigreturn(regs);
++			return;
++		}
++		if (pc == 0xffff0f60UL) {
++			/*
++			 * PaX: __kuser_cmpxchg64 emulation
++			 */
++			// TODO
++			//regs->ARM_pc = regs->ARM_lr;
++			//return;
++		}
++		if (pc == 0xffff0fa0UL) {
++			/*
++			 * PaX: __kuser_memory_barrier emulation
++			 */
++			// dmb(); implied by the exception
++			regs->ARM_pc = regs->ARM_lr;
++			return;
++		}
++		if (pc == 0xffff0fc0UL) {
++			/*
++			 * PaX: __kuser_cmpxchg emulation
++			 */
++			// TODO
++			//regs->ARM_pc = regs->ARM_lr;
++			//return;
++		}
++		if (pc == 0xffff0fe0UL) {
++			/*
++			 * PaX: __kuser_get_tls emulation
++			 */
++			regs->ARM_r0 = current_thread_info()->tp_value[0];
++			regs->ARM_pc = regs->ARM_lr;
++			return;
++		}
++	}
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	else if (is_domain_fault(ifsr) || is_xn_fault(ifsr)) {
++		if (current->signal->curr_ip)
++			printk(KERN_ERR "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_ERR "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) {
++		unsigned int bkpt;
++
++		if (!probe_kernel_address(pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) {
++			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:
+ 	printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+ 		inf->name, ifsr, addr);
+ 
+diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
+index cf08bdf..772656c 100644
+--- a/arch/arm/mm/fault.h
++++ b/arch/arm/mm/fault.h
+@@ -3,6 +3,7 @@
+ 
+ /*
+  * Fault status register encodings.  We steal bit 31 for our own purposes.
++ * Set when the FSR value is from an instruction fault.
+  */
+ #define FSR_LNX_PF		(1 << 31)
+ #define FSR_WRITE		(1 << 11)
+@@ -22,6 +23,17 @@ static inline int fsr_fs(unsigned int fsr)
+ }
+ #endif
+ 
++/* valid for LPAE and !LPAE */
++static inline int is_xn_fault(unsigned int fsr)
++{
++	return ((fsr_fs(fsr) & 0x3c) == 0xc);
++}
++
++static inline int is_domain_fault(unsigned int fsr)
++{
++	return ((fsr_fs(fsr) & 0xD) == 0x9);
++}
++
+ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+ unsigned long search_exception_table(unsigned long addr);
+ 
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index 15225d8..25e2e3c 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -30,6 +30,8 @@
+ #include <asm/setup.h>
+ #include <asm/tlb.h>
+ #include <asm/fixmap.h>
++#include <asm/system_info.h>
++#include <asm/cp15.h>
+ 
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+@@ -683,7 +685,46 @@ void free_initmem(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 f123d6e..04bf569 100644
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -392,9 +392,9 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool \
cached) + 	unsigned int mtype;
+ 
+ 	if (cached)
+-		mtype = MT_MEMORY;
++		mtype = MT_MEMORY_RX;
+ 	else
+-		mtype = MT_MEMORY_NONCACHED;
++		mtype = MT_MEMORY_NONCACHED_RX;
+ 
+ 	return __arm_ioremap_caller(phys_addr, size, mtype,
+ 			__builtin_return_address(0));
+diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
+index 0c63562..7128a90 100644
+--- a/arch/arm/mm/mmap.c
++++ b/arch/arm/mm/mmap.c
+@@ -59,6 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 	struct vm_area_struct *vma;
+ 	int do_align = 0;
+ 	int aliasing = cache_is_vipt_aliasing();
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ 	struct vm_unmapped_area_info info;
+ 
+ 	/*
+@@ -81,6 +82,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 	if (len > TASK_SIZE)
+ 		return -ENOMEM;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ 	if (addr) {
+ 		if (do_align)
+ 			addr = COLOUR_ALIGN(addr, pgoff);
+@@ -88,8 +93,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 			addr = PAGE_ALIGN(addr);
+ 
+ 		vma = find_vma(mm, addr);
+-		if (TASK_SIZE - len >= addr &&
+-		    (!vma || addr + len <= vma->vm_start))
++		if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ 			return addr;
+ 	}
+ 
+@@ -99,6 +103,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 	info.high_limit = TASK_SIZE;
+ 	info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ 	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
+ 	return vm_unmapped_area(&info);
+ }
+ 
+@@ -112,6 +117,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	unsigned long addr = addr0;
+ 	int do_align = 0;
+ 	int aliasing = cache_is_vipt_aliasing();
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ 	struct vm_unmapped_area_info info;
+ 
+ 	/*
+@@ -132,6 +138,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const \
unsigned long addr0, + 		return addr;
+ 	}
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ 	/* requesting a specific address */
+ 	if (addr) {
+ 		if (do_align)
+@@ -139,8 +149,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 		else
+ 			addr = PAGE_ALIGN(addr);
+ 		vma = find_vma(mm, addr);
+-		if (TASK_SIZE - len >= addr &&
+-				(!vma || addr + len <= vma->vm_start))
++		if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ 			return addr;
+ 	}
+ 
+@@ -150,6 +159,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	info.high_limit = mm->mmap_base;
+ 	info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ 	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
+ 	addr = vm_unmapped_area(&info);
+ 
+ 	/*
+@@ -173,6 +183,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
++
+ 	/* 8 bits of randomness in 20 address space bits */
+ 	if ((current->flags & PF_RANDOMIZE) &&
+ 	    !(current->personality & ADDR_NO_RANDOMIZE))
+@@ -180,9 +194,21 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ 
+ 	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 53cdbd3..670f177 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -36,6 +36,22 @@
+ #include "mm.h"
+ #include "tcm.h"
+ 
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || \
defined(CONFIG_PAX_MEMORY_UDEREF) ++void modify_domain(unsigned int dom, unsigned int \
type) ++{
++	struct thread_info *thread = current_thread_info();
++	unsigned int domain = thread->cpu_domain;
++	/*
++	 * DOMAIN_MANAGER might be defined to some other value,
++	 * use the arch-defined constant
++	 */
++	domain &= ~domain_val(dom, 3);
++	thread->cpu_domain = domain | domain_val(dom, type);
++	set_domain(thread->cpu_domain);
++}
++EXPORT_SYMBOL(modify_domain);
++#endif
++
+ /*
+  * empty_zero_page is a special page that is used for
+  * zero-initialized data and COW.
+@@ -228,10 +244,18 @@ __setup("noalign", noalign_setup);
+ 
+ #endif /* ifdef CONFIG_CPU_CP15 / else */
+ 
+-#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
++#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY
+ #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,
+@@ -260,16 +284,16 @@ static struct mem_type mem_types[] = {
+ 	[MT_UNCACHED] = {
+ 		.prot_pte	= PROT_PTE_DEVICE,
+ 		.prot_l1	= PMD_TYPE_TABLE,
+-		.prot_sect	= PMD_TYPE_SECT | PMD_SECT_XN,
++		.prot_sect	= PROT_SECT_DEVICE,
+ 		.domain		= DOMAIN_IO,
+ 	},
+ 	[MT_CACHECLEAN] = {
+-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
++		.prot_sect = PMD_TYPE_SECT | PMD_SECT_RDONLY,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+ #ifndef CONFIG_ARM_LPAE
+ 	[MT_MINICLEAN] = {
+-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
++		.prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE | PMD_SECT_RDONLY,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+ #endif
+@@ -277,36 +301,54 @@ static struct mem_type mem_types[] = {
+ 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ 				L_PTE_RDONLY,
+ 		.prot_l1   = PMD_TYPE_TABLE,
+-		.domain    = DOMAIN_USER,
++		.domain    = DOMAIN_VECTORS,
+ 	},
+ 	[MT_HIGH_VECTORS] = {
+ 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ 				L_PTE_USER | L_PTE_RDONLY,
+ 		.prot_l1   = PMD_TYPE_TABLE,
+-		.domain    = DOMAIN_USER,
++		.domain    = DOMAIN_VECTORS,
+ 	},
+-	[MT_MEMORY] = {
++	[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,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
++	[MT_MEMORY_RW] = {
++		.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,
++		.domain	   = DOMAIN_KERNEL,
++	},
++	[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] = {
+-		.prot_sect = PMD_TYPE_SECT,
++		.prot_sect = PMD_TYPE_SECT | PMD_SECT_RDONLY,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+-	[MT_MEMORY_NONCACHED] = {
++	[MT_MEMORY_NONCACHED_RW] = {
+ 		.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_NONCACHED_RX] = {
++		.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_DTCM] = {
+-		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+-				L_PTE_XN,
++		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ 		.prot_l1   = PMD_TYPE_TABLE,
+-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
++		.prot_sect = PMD_TYPE_SECT | PMD_SECT_RDONLY,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+ 	[MT_MEMORY_ITCM] = {
+@@ -316,10 +358,10 @@ static struct mem_type mem_types[] = {
+ 	},
+ 	[MT_MEMORY_SO] = {
+ 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+-				L_PTE_MT_UNCACHED | L_PTE_XN,
++				L_PTE_MT_UNCACHED,
+ 		.prot_l1   = PMD_TYPE_TABLE,
+ 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S |
+-				PMD_SECT_UNCACHED | PMD_SECT_XN,
++				PMD_SECT_UNCACHED,
+ 		.domain    = DOMAIN_KERNEL,
+ 	},
+ 	[MT_MEMORY_DMA_READY] = {
+@@ -405,9 +447,35 @@ static void __init build_mem_type_table(void)
+ 			 * to prevent speculative instruction fetches.
+ 			 */
+ 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_DEVICE].prot_pte |= L_PTE_XN;
+ 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_DEVICE_NONSHARED].prot_pte |= L_PTE_XN;
+ 			mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_XN;
+ 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_XN;
++
++			/* Mark other regions on ARMv6+ as execute-never */
++
++#ifdef CONFIG_PAX_KERNEXEC
++			mem_types[MT_UNCACHED].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_UNCACHED].prot_pte |= L_PTE_XN;
++			mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_CACHECLEAN].prot_pte |= L_PTE_XN;
++#ifndef CONFIG_ARM_LPAE
++			mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_MINICLEAN].prot_pte |= L_PTE_XN;
++#endif
++			mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_XN;
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_pte |= PMD_SECT_XN;
++			mem_types[MT_MEMORY_DTCM].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_MEMORY_DTCM].prot_pte |= L_PTE_XN;
++#endif
++
++			mem_types[MT_MEMORY_SO].prot_sect |= PMD_SECT_XN;
++			mem_types[MT_MEMORY_SO].prot_pte |= L_PTE_XN;
+ 		}
+ 		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ 			/*
+@@ -468,6 +536,9 @@ static void __init build_mem_type_table(void)
+ 		 * from SVC mode and no access from userspace.
+ 		 */
+ 		mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#ifdef CONFIG_PAX_KERNEXEC
++		mem_types[MT_MEMORY_RX].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#endif
+ 		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ #endif
+@@ -485,11 +556,17 @@ static void __init build_mem_type_table(void)
+ 			mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+ 			mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+ 			mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
+-			mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+-			mem_types[MT_MEMORY].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_NONCACHED].prot_sect |= PMD_SECT_S;
+-			mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |= PMD_SECT_S;
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_pte |= L_PTE_SHARED;
++			mem_types[MT_MEMORY_NONCACHED_RX].prot_sect |= PMD_SECT_S;
++			mem_types[MT_MEMORY_NONCACHED_RX].prot_pte |= L_PTE_SHARED;
+ 		}
+ 	}
+ 
+@@ -500,15 +577,20 @@ static void __init build_mem_type_table(void)
+ 	if (cpu_arch >= CPU_ARCH_ARMv6) {
+ 		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ 			/* Non-cacheable Normal is XCB = 001 */
+-			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |=
++				PMD_SECT_BUFFERED;
++			mem_types[MT_MEMORY_NONCACHED_RX].prot_sect |=
+ 				PMD_SECT_BUFFERED;
+ 		} else {
+ 			/* For both ARMv6 and non-TEX-remapping ARMv7 */
+-			mem_types[MT_MEMORY_NONCACHED].prot_sect |=
++			mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |=
++				PMD_SECT_TEX(1);
++			mem_types[MT_MEMORY_NONCACHED_RX].prot_sect |=
+ 				PMD_SECT_TEX(1);
+ 		}
+ 	} else {
+-		mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
++		mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |= PMD_SECT_BUFFERABLE;
++		mem_types[MT_MEMORY_NONCACHED_RX].prot_sect |= PMD_SECT_BUFFERABLE;
+ 	}
+ 
+ #ifdef CONFIG_ARM_LPAE
+@@ -524,6 +606,8 @@ static void __init build_mem_type_table(void)
+ 	vecs_pgprot |= PTE_EXT_AF;
+ #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);
+@@ -541,10 +625,15 @@ static void __init build_mem_type_table(void)
+ 
+ 	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
+ 	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
+-	mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+-	mem_types[MT_MEMORY].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_NONCACHED].prot_sect |= ecc_mask;
++	mem_types[MT_MEMORY_NONCACHED_RW].prot_sect |= ecc_mask;
++	mem_types[MT_MEMORY_NONCACHED_RX].prot_sect |= ecc_mask;
+ 	mem_types[MT_ROM].prot_sect |= cp->pmd;
+ 
+ 	switch (cp->pmd) {
+@@ -1186,18 +1275,15 @@ void __init arm_mm_memblock_reserve(void)
+  * called function.  This means you can't use any function or debugging
+  * method which may touch any device, otherwise the kernel _will_ crash.
+  */
++
++static char vectors[PAGE_SIZE * 2] __read_only __aligned(PAGE_SIZE);
++
+ static void __init devicemaps_init(struct machine_desc *mdesc)
+ {
+ 	struct map_desc map;
+ 	unsigned long addr;
+-	void *vectors;
+ 
+-	/*
+-	 * Allocate the vector page early.
+-	 */
+-	vectors = early_alloc(PAGE_SIZE * 2);
+-
+-	early_trap_init(vectors);
++	early_trap_init(&vectors);
+ 
+ 	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
+ 		pmd_clear(pmd_off_k(addr));
+@@ -1237,7 +1323,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
+ 	 * location (0xffff0000).  If we aren't using high-vectors, also
+ 	 * create a mapping at the low-vectors virtual address.
+ 	 */
+-	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
+@@ -1309,8 +1395,39 @@ static void __init map_lowmem(void)
+ 		map.pfn = __phys_to_pfn(start);
+ 		map.virtual = __phys_to_virt(start);
+ 		map.length = end - start;
+-		map.type = MT_MEMORY;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++		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);
++		}
++#endif
++
++		map.type = MT_MEMORY_RW;
+ 		create_mapping(&map);
+ 	}
+ }
+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/arm/plat-samsung/include/plat/dma-ops.h \
b/arch/arm/plat-samsung/include/plat/dma-ops.h +index ce6d763..cfea917 100644
+--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
++++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
+@@ -47,7 +47,7 @@ struct samsung_dma_ops {
+ 	int (*started)(unsigned ch);
+ 	int (*flush)(unsigned ch);
+ 	int (*stop)(unsigned ch);
+-};
++} __no_const;
+ 
+ extern void *samsung_dmadev_get_ops(void);
+ extern void *s3c_dma_get_ops(void);
+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 d232888..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         (2 * TASK_SIZE / 3)
++#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 b2f2d2d..d1c85cb 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.
+@@ -174,6 +191,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/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 b86329d..6709906 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -186,6 +186,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..c2a401d 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 f4ca594..adc72fd6 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 __cacheline_aligned	__aligned(L1_CACHE_BYTES)
+ #define ____cacheline_aligned	__aligned(L1_CACHE_BYTES)
+diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
+index 6e6fe18..a6ae668 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -208,6 +208,16 @@ 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))
++
+ /* Atomic operations are already serializing */
+ #define smp_mb__before_atomic_dec()	barrier()
+ #define smp_mb__after_atomic_dec()	barrier()
+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 96a8d92..617a1cf 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 7935115..c0eca6a 100644
+--- a/arch/ia64/include/asm/pgtable.h
++++ b/arch/ia64/include/asm/pgtable.h
+@@ -12,7 +12,7 @@
+  *	David Mosberger-Tang <davidm at hpl.hp.com>
+  */
+ 
+-
++#include <linux/const.h>
+ #include <asm/mman.h>
+ #include <asm/page.h>
+ #include <asm/processor.h>
+@@ -142,6 +142,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 54ff557..70c88b7 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 449c8c0..18965fb 100644
+--- a/arch/ia64/include/asm/uaccess.h
++++ b/arch/ia64/include/asm/uaccess.h
+@@ -240,12 +240,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);
+ }
+ 
+@@ -255,10 +267,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;									\
+ })
+ 
+@@ -266,11 +281,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 24603be..948052d 100644
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -307,8 +307,7 @@ plt_target (struct plt_entry *plt)
+ void
+ module_free (struct module *mod, void *module_region)
+ {
+-	if (mod && mod->arch.init_unw_table &&
+-	    module_region == mod->module_init) {
++	if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
+ 		unw_remove_unwind_table(mod->arch.init_unw_table);
+ 		mod->arch.init_unw_table = NULL;
+ 	}
+@@ -494,15 +493,39 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, \
char *secstrings, + }
+ 
+ static inline int
++in_init_rx (const struct module *mod, uint64_t addr)
++{
++	return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
++}
++
++static inline int
++in_init_rw (const struct module *mod, uint64_t addr)
++{
++	return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
++}
++
++static inline int
+ in_init (const struct module *mod, uint64_t addr)
+ {
+-	return addr - (uint64_t) mod->module_init < mod->init_size;
++	return in_init_rx(mod, addr) || in_init_rw(mod, addr);
++}
++
++static inline int
++in_core_rx (const struct module *mod, uint64_t addr)
++{
++	return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
++}
++
++static inline int
++in_core_rw (const struct module *mod, uint64_t addr)
++{
++	return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
+ }
+ 
+ static inline int
+ in_core (const struct module *mod, uint64_t addr)
+ {
+-	return addr - (uint64_t) mod->module_core < mod->core_size;
++	return in_core_rx(mod, addr) || in_core_rw(mod, addr);
+ }
+ 
+ static inline int
+@@ -685,7 +708,14 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, \
uint64_t addend, + 		break;
+ 
+ 	      case RV_BDREL:
+-		val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
++		if (in_init_rx(mod, val))
++			val -= (uint64_t) mod->module_init_rx;
++		else if (in_init_rw(mod, val))
++			val -= (uint64_t) mod->module_init_rw;
++		else if (in_core_rx(mod, val))
++			val -= (uint64_t) mod->module_core_rx;
++		else if (in_core_rw(mod, val))
++			val -= (uint64_t) mod->module_core_rw;
+ 		break;
+ 
+ 	      case RV_LTV:
+@@ -820,15 +850,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, \
unsigned int symind + 		 *     addresses have been selected...
+ 		 */
+ 		uint64_t gp;
+-		if (mod->core_size > MAX_LTOFF)
++		if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
+ 			/*
+ 			 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
+ 			 * at the end of the module.
+ 			 */
+-			gp = mod->core_size - MAX_LTOFF / 2;
++			gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
+ 		else
+-			gp = mod->core_size / 2;
+-		gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
++			gp = (mod->core_size_rx + mod->core_size_rw) / 2;
++		gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
+ 		mod->arch.gp = gp;
+ 		DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
+ 	}
+diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
+index ab33328..f39506c 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..65180b2 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 0ccb28f..8992469 100644
+--- a/arch/ia64/kernel/vmlinux.lds.S
++++ b/arch/ia64/kernel/vmlinux.lds.S
+@@ -198,7 +198,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 6cf0341..d352594 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
+@@ -149,8 +166,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 76069c1..c2aa816 100644
+--- a/arch/ia64/mm/hugetlbpage.c
++++ b/arch/ia64/mm/hugetlbpage.c
+@@ -149,6 +149,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;
+@@ -172,6 +173,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 b6f7f43..c04320d 100644
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -120,6 +120,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)) {
+diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h
+index 40b3ee9..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 3c52fa6..11b2ad8 100644
+--- a/arch/metag/mm/hugetlbpage.c
++++ b/arch/metag/mm/hugetlbpage.c
+@@ -200,6 +200,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/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
+index 08b6079..8b554d2 100644
+--- a/arch/mips/include/asm/atomic.h
++++ b/arch/mips/include/asm/atomic.h
+@@ -21,15 +21,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)		(*(volatile int *)&(v)->counter)
++static inline int atomic_read(const atomic_t *v)
++{
++	return (*(volatile const int *) &v->counter);
++}
++
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return (*(volatile const int *) &v->counter);
++}
+ 
+ /*
+  * atomic_set - set atomic variable
+@@ -38,7 +62,15 @@
+  *
+  * Atomically sets the value of @v to @i.
+  */
+-#define atomic_set(v, i)		((v)->counter = (i))
++static inline void atomic_set(atomic_t *v, int i)
++{
++	v->counter = i;
++}
++
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
+ 
+ /*
+  * atomic_add - add integer to atomic variable
+@@ -47,7 +79,67 @@
+  *
+  * Atomically adds @i to @v.
+  */
+-static __inline__ void atomic_add(int i, atomic_t * v)
++static __inline__ void atomic_add(int i, atomic_t *v)
++{
++	int temp;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%0, %1		# atomic_add		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"2:	add	%0, %2					\n"
++#else
++		"	addu	%0, %2					\n"
++#endif
++		"	sc	%0, %1					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%0, %1		# atomic_add		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Exception on overflow. */
++		"2:	add	%0, %2					\n"
++#else
++		"	addu	%0, %2					\n"
++#endif
++		"	sc	%0, %1					\n"
++		"	beqz	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	add	%0, %1					\n"
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#else
++		"	addu	%0, %1					\n"
++#endif
++		: "+r" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++}
++
++static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t *v)
+ {
+ 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ 		int temp;
+@@ -90,7 +182,67 @@ static __inline__ void atomic_add(int i, atomic_t * v)
+  *
+  * Atomically subtracts @i from @v.
+  */
+-static __inline__ void atomic_sub(int i, atomic_t * v)
++static __inline__ void atomic_sub(int i, atomic_t *v)
++{
++	int temp;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%0, %1		# atomic64_sub		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Exception on overflow. */
++		"2:	sub	%0, %2					\n"
++#else
++		"	subu	%0, %2					\n"
++#endif
++		"	sc	%0, %1					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%0, %1		# atomic64_sub		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Exception on overflow. */
++		"2:	sub	%0, %2					\n"
++#else
++		"	subu	%0, %2					\n"
++#endif
++		"	sc	%0, %1					\n"
++		"	beqz	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	sub	%0, %1					\n"
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#else
++		"	subu	%0, %1					\n"
++#endif
++		: "+r" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++}
++
++static __inline__ void atomic_sub_unchecked(long i, atomic_unchecked_t *v)
+ {
+ 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ 		int temp;
+@@ -129,7 +281,93 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
+ /*
+  * Same as above, but return the result value
+  */
+-static __inline__ int atomic_add_return(int i, atomic_t * v)
++static __inline__ int atomic_add_return(int i, atomic_t *v)
++{
++	int result;
++	int temp;
++
++	smp_mb__before_llsc();
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%1, %2		# atomic_add_return	\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	add	%0, %1, %3				\n"
++#else
++		"	addu	%0, %1, %3				\n"
++#endif
++		"	sc	%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	b	4f					\n"
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	addu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%1, %2	# atomic_add_return		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	add	%0, %1, %3				\n"
++#else
++		"	addu	%0, %1, %3				\n"
++#endif
++		"	sc	%0, %2					\n"
++		"	bnez	%0, 4f					\n"
++		"	b	1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	addu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++		"	lw	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	add	%0, %2					\n"
++#else
++		"	addu	%0, %2					\n"
++#endif
++		"	sw	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Note: Dest reg is not modified on overflow */
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#endif
++		: "=&r" (result), "+m" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++
++	smp_llsc_mb();
++
++	return result;
++}
++
++static __inline__ int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
+ {
+ 	int result;
+ 
+@@ -178,7 +416,93 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
+ 	return result;
+ }
+ 
+-static __inline__ int atomic_sub_return(int i, atomic_t * v)
++static __inline__ int atomic_sub_return(int i, atomic_t *v)
++{
++	int result;
++	int temp;
++
++	smp_mb__before_llsc();
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%1, %2		# atomic_sub_return	\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	sub	%0, %1, %3				\n"
++#else
++		"	subu	%0, %1, %3				\n"
++#endif
++		"	sc	%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	b	4f					\n"
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	subu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
++		: "Ir" (i), "m" (v->counter)
++		: "memory");
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	ll	%1, %2	# atomic_sub_return		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	sub	%0, %1, %3				\n"
++#else
++		"	subu	%0, %1, %3				\n"
++#endif
++		"	sc	%0, %2					\n"
++		"	bnez	%0, 4f					\n"
++		"	b	1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	subu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++		"	lw	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	sub	%0, %2					\n"
++#else
++		"	subu	%0, %2					\n"
++#endif
++		"	sw	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Note: Dest reg is not modified on overflow */
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#endif
++		: "=&r" (result), "+m" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++
++	smp_llsc_mb();
++
++	return result;
++}
++static __inline__ int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v)
+ {
+ 	int result;
+ 
+@@ -238,7 +562,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
+  * 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;
+ 
+@@ -295,8 +619,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
+@@ -324,6 +666,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
+@@ -345,6 +691,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
+@@ -369,6 +719,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
+@@ -377,6 +731,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
+@@ -398,14 +756,30 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, \
int u) +  * @v: pointer of type atomic64_t
+  *
+  */
+-#define atomic64_read(v)	(*(volatile long *)&(v)->counter)
++static inline long atomic64_read(const atomic64_t *v)
++{
++	return (*(volatile const long *) &v->counter);
++}
++
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++	return (*(volatile const long *) &v->counter);
++}
+ 
+ /*
+  * atomic64_set - set atomic variable
+  * @v: pointer of type atomic64_t
+  * @i: required value
+  */
+-#define atomic64_set(v, i)	((v)->counter = (i))
++static inline void atomic64_set(atomic64_t *v, long i)
++{
++	v->counter = i;
++}
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++	v->counter = i;
++}
+ 
+ /*
+  * atomic64_add - add integer to atomic variable
+@@ -414,7 +788,66 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, \
int u) +  *
+  * Atomically adds @i to @v.
+  */
+-static __inline__ void atomic64_add(long i, atomic64_t * v)
++static __inline__ void atomic64_add(long i, atomic64_t *v)
++{
++	long temp;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%0, %1		# atomic64_add		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"2:	dadd	%0, %2					\n"
++#else
++		"	daddu	%0, %2					\n"
++#endif
++		"	scd	%0, %1					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%0, %1		# atomic64_add		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"2:	dadd	%0, %2					\n"
++#else
++		"	daddu	%0, %2					\n"
++#endif
++		"	scd	%0, %1					\n"
++		"	beqz	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	dadd	%0, %1					\n"
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#else
++		"	daddu	%0, %1					\n"
++#endif
++		: "+r" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++}
++static __inline__ void atomic64_add_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ 		long temp;
+@@ -457,7 +890,67 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
+  *
+  * Atomically subtracts @i from @v.
+  */
+-static __inline__ void atomic64_sub(long i, atomic64_t * v)
++static __inline__ void atomic64_sub(long i, atomic64_t *v)
++{
++	long temp;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%0, %1		# atomic64_sub		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Exception on overflow. */
++		"2:	dsub	%0, %2					\n"
++#else
++		"	dsubu	%0, %2					\n"
++#endif
++		"	scd	%0, %1					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%0, %1		# atomic64_sub		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Exception on overflow. */
++		"2:	dsub	%0, %2					\n"
++#else
++		"	dsubu	%0, %2					\n"
++#endif
++		"	scd	%0, %1					\n"
++		"	beqz	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"3:							\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	dsub	%0, %1					\n"
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#else
++		"	dsubu	%0, %1					\n"
++#endif
++		: "+r" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++}
++
++static __inline__ void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ 	if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ 		long temp;
+@@ -496,7 +989,93 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
+ /*
+  * Same as above, but return the result value
+  */
+-static __inline__ long atomic64_add_return(long i, atomic64_t * v)
++static __inline__ long atomic64_add_return(long i, atomic64_t *v)
++{
++	long result;
++	long temp;
++
++	smp_mb__before_llsc();
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%1, %2		# atomic64_add_return	\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	dadd	%0, %1, %3				\n"
++#else
++		"	daddu	%0, %1, %3				\n"
++#endif
++		"	scd	%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	b	4f					\n"
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	daddu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "+m" (v->counter)
++		: "Ir" (i));
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%1, %2	# atomic64_add_return		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	dadd	%0, %1, %3				\n"
++#else
++		"	daddu	%0, %1, %3				\n"
++#endif
++		"	scd	%0, %2					\n"
++		"	bnez	%0, 4f					\n"
++		"	b	1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	daddu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
++		: "Ir" (i), "m" (v->counter)
++		: "memory");
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++		"	ld	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	dadd	%0, %2					\n"
++#else
++		"	daddu	%0, %2					\n"
++#endif
++		"	sd	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Note: Dest reg is not modified on overflow */
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#endif
++		: "=&r" (result), "+m" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++
++	smp_llsc_mb();
++
++	return result;
++}
++static __inline__ long atomic64_add_return_unchecked(long i, atomic64_unchecked_t \
*v) + {
+ 	long result;
+ 
+@@ -546,7 +1125,97 @@ static __inline__ long atomic64_add_return(long i, atomic64_t \
* v) + 	return result;
+ }
+ 
+-static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
++static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
++{
++	long result;
++	long temp;
++
++	smp_mb__before_llsc();
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		long temp;
++
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%1, %2		# atomic64_sub_return	\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	dsub	%0, %1, %3				\n"
++#else
++		"	dsubu	%0, %1, %3				\n"
++#endif
++		"	scd	%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	b	4f					\n"
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	dsubu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
++		: "Ir" (i), "m" (v->counter)
++		: "memory");
++	} else if (kernel_uses_llsc) {
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:	lld	%1, %2	# atomic64_sub_return		\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"2:	dsub	%0, %1, %3				\n"
++#else
++		"	dsubu	%0, %1, %3				\n"
++#endif
++		"	scd	%0, %2					\n"
++		"	bnez	%0, 4f					\n"
++		"	b	1b					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"	.set	noreorder				\n"
++		"3:	b	5f					\n"
++		"	move	%0, %1					\n"
++		"	.set	reorder					\n"
++		_ASM_EXTABLE(2b, 3b)
++#endif
++		"4:	dsubu	%0, %1, %3				\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		"5:							\n"
++#endif
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
++		: "Ir" (i), "m" (v->counter)
++		: "memory");
++	} else {
++		unsigned long flags;
++
++		raw_local_irq_save(flags);
++		__asm__ __volatile__(
++		"	ld	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++			/* Exception on overflow. */
++		"1:	dsub	%0, %2					\n"
++#else
++		"	dsubu	%0, %2					\n"
++#endif
++		"	sd	%0, %1					\n"
++#ifdef CONFIG_PAX_REFCOUNT
++		/* Note: Dest reg is not modified on overflow */
++		"2:							\n"
++		_ASM_EXTABLE(1b, 2b)
++#endif
++		: "=&r" (result), "+m" (v->counter) : "Ir" (i));
++		raw_local_irq_restore(flags);
++	}
++
++	smp_llsc_mb();
++
++	return result;
++}
++
++static __inline__ long atomic64_sub_return_unchecked(long i, atomic64_unchecked_t \
*v) + {
+ 	long result;
+ 
+@@ -605,7 +1274,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * \
v) +  * 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;
+ 
+@@ -662,9 +1331,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
+@@ -694,6 +1380,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
+@@ -715,6 +1402,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
+@@ -739,6 +1427,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
+@@ -747,6 +1436,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 cf3ae24..238d22f 100644
+--- a/arch/mips/include/asm/elf.h
++++ b/arch/mips/include/asm/elf.h
+@@ -372,13 +372,16 @@ extern const char *__elf_platform;
+ #define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+ #endif
+ 
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE	(TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN	(TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN	(TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+ struct linux_binprm;
+ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ 				       int uses_interp);
+ 
+-struct mm_struct;
+-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+-#define arch_randomize_brk arch_randomize_brk
+-
+ #endif /* _ASM_ELF_H */
+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/local.h b/arch/mips/include/asm/local.h
+index d44622c..64990d2 100644
+--- a/arch/mips/include/asm/local.h
++++ b/arch/mips/include/asm/local.h
+@@ -12,15 +12,25 @@ typedef struct
+ 	atomic_long_t a;
+ } local_t;
+ 
++typedef struct {
++	atomic_long_unchecked_t a;
++} local_unchecked_t;
++
+ #define LOCAL_INIT(i)	{ ATOMIC_LONG_INIT(i) }
+ 
+ #define local_read(l)	atomic_long_read(&(l)->a)
++#define local_read_unchecked(l)	atomic_long_read_unchecked(&(l)->a)
+ #define local_set(l, i) atomic_long_set(&(l)->a, (i))
++#define local_set_unchecked(l, i)	atomic_long_set_unchecked(&(l)->a, (i))
+ 
+ #define local_add(i, l) atomic_long_add((i), (&(l)->a))
++#define local_add_unchecked(i, l) atomic_long_add_unchecked((i), (&(l)->a))
+ #define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
++#define local_sub_unchecked(i, l) atomic_long_sub_unchecked((i), (&(l)->a))
+ #define local_inc(l)	atomic_long_inc(&(l)->a)
++#define local_inc_unchecked(l)	atomic_long_inc_unchecked(&(l)->a)
+ #define local_dec(l)	atomic_long_dec(&(l)->a)
++#define local_dec_unchecked(l)	atomic_long_dec_unchecked(&(l)->a)
+ 
+ /*
+  * Same as above, but return the result value
+@@ -70,6 +80,51 @@ static __inline__ long local_add_return(long i, local_t * l)
+ 	return result;
+ }
+ 
++static __inline__ long local_add_return_unchecked(long i, local_unchecked_t * l)
++{
++	unsigned long result;
++
++	if (kernel_uses_llsc && R10000_LLSC_WAR) {
++		unsigned long temp;
++
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:"	__LL	"%1, %2		# local_add_return	\n"
++		"	addu	%0, %1, %3				\n"
++			__SC	"%0, %2					\n"
++		"	beqzl	%0, 1b					\n"
++		"	addu	%0, %1, %3				\n"
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++		: "Ir" (i), "m" (l->a.counter)
++		: "memory");
++	} else if (kernel_uses_llsc) {
++		unsigned long temp;
++
++		__asm__ __volatile__(
++		"	.set	mips3					\n"
++		"1:"	__LL	"%1, %2		# local_add_return	\n"
++		"	addu	%0, %1, %3				\n"
++			__SC	"%0, %2					\n"
++		"	beqz	%0, 1b					\n"
++		"	addu	%0, %1, %3				\n"
++		"	.set	mips0					\n"
++		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++		: "Ir" (i), "m" (l->a.counter)
++		: "memory");
++	} else {
++		unsigned long flags;
++
++		local_irq_save(flags);
++		result = l->a.counter;
++		result += i;
++		l->a.counter = result;
++		local_irq_restore(flags);
++	}
++
++	return result;
++}
++
+ static __inline__ long local_sub_return(long i, local_t * l)
+ {
+ 	unsigned long result;
+@@ -117,6 +172,8 @@ static __inline__ long local_sub_return(long i, local_t * l)
+ 
+ #define local_cmpxchg(l, o, n) \
+ 	((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
++#define local_cmpxchg_unchecked(l, o, n) \
++	((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+ #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+ 
+ /**
+diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
+index f6be474..12ad554 100644
+--- a/arch/mips/include/asm/page.h
++++ b/arch/mips/include/asm/page.h
+@@ -95,7 +95,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 881d18b..cea38bc 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/smtc_proc.h b/arch/mips/include/asm/smtc_proc.h
+index 25da651..ae2a259 100644
+--- a/arch/mips/include/asm/smtc_proc.h
++++ b/arch/mips/include/asm/smtc_proc.h
+@@ -18,6 +18,6 @@ extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
+ 
+ /* Count of number of recoveries of "stolen" FPU access rights on 34K */
+ 
+-extern atomic_t smtc_fpu_recoveries;
++extern atomic_unchecked_t smtc_fpu_recoveries;
+ 
+ #endif /* __ASM_SMTC_PROC_H */
+diff --git a/arch/mips/include/asm/thread_info.h \
b/arch/mips/include/asm/thread_info.h +index 61215a3..213ee0e 100644
+--- a/arch/mips/include/asm/thread_info.h
++++ b/arch/mips/include/asm/thread_info.h
+@@ -116,6 +116,8 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_32BIT_ADDR		23	/* 32-bit address space (o32/n32) */
+ #define TIF_FPUBOUND		24	/* thread bound to FPU-full CPU set */
+ #define TIF_LOAD_WATCH		25	/* If set, load watch registers */
++/* li takes a 32bit immediate */
++#define TIF_GRSEC_SETXID	29	/* update credentials on syscall entry/exit */
+ #define TIF_SYSCALL_TRACE	31	/* syscall trace active */
+ 
+ #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+@@ -132,20 +134,18 @@ static inline struct thread_info *current_thread_info(void)
+ #define _TIF_32BIT_ADDR		(1<<TIF_32BIT_ADDR)
+ #define _TIF_FPUBOUND		(1<<TIF_FPUBOUND)
+ #define _TIF_LOAD_WATCH		(1<<TIF_LOAD_WATCH)
++#define _TIF_GRSEC_SETXID	(1<<TIF_GRSEC_SETXID)
+ 
+-#define _TIF_WORK_SYSCALL_ENTRY	(_TIF_NOHZ | _TIF_SYSCALL_TRACE |	\
+-				 _TIF_SYSCALL_AUDIT)
++#define _TIF_WORK_SYSCALL_ENTRY	(_TIF_NOHZ | _TIF_SYSCALL_TRACE | \
_TIF_SYSCALL_AUDIT | _TIF_GRSEC_SETXID) + 
+ /* work to do in syscall_trace_leave() */
+-#define _TIF_WORK_SYSCALL_EXIT	(_TIF_NOHZ | _TIF_SYSCALL_TRACE |	\
+-				 _TIF_SYSCALL_AUDIT)
++#define _TIF_WORK_SYSCALL_EXIT	(_TIF_NOHZ | _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT \
| _TIF_GRSEC_SETXID) + 
+ /* work to do on interrupt/exception return */
+ #define _TIF_WORK_MASK		\
+ 	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
+ /* work to do on any return to u-space */
+-#define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK |		\
+-				 _TIF_WORK_SYSCALL_EXIT)
++#define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT | \
_TIF_GRSEC_SETXID) + 
+ #endif /* __KERNEL__ */
+ 
+diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
+index 1188e00..41cf144 100644
+--- a/arch/mips/kernel/binfmt_elfn32.c
++++ b/arch/mips/kernel/binfmt_elfn32.c
+@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #undef ELF_ET_DYN_BASE
+ #define ELF_ET_DYN_BASE		(TASK32_SIZE / 3 * 2)
+ 
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE	(TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN	(TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN	(TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #include <asm/processor.h>
+ #include <linux/module.h>
+ #include <linux/elfcore.h>
+diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
+index 202e581..689ca79 100644
+--- a/arch/mips/kernel/binfmt_elfo32.c
++++ b/arch/mips/kernel/binfmt_elfo32.c
+@@ -56,6 +56,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>
+ 
+ /*
+diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
+index d1fea7a..45602ea 100644
+--- a/arch/mips/kernel/irq.c
++++ b/arch/mips/kernel/irq.c
+@@ -77,17 +77,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)
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index ddc7610..8c58f17 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -566,15 +566,3 @@ unsigned long get_wchan(struct task_struct *task)
+ 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;
+-}
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+index 8ae1ebe..1bcbf47 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -529,6 +529,10 @@ static inline int audit_arch(void)
+ 	return arch;
+ }
+ 
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /*
+  * Notification of system call entry/exit
+  * - triggered by current->work.syscall_trace
+@@ -540,6 +544,11 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
+ 	/* do the secure computing check first */
+ 	secure_computing_strict(regs->regs[2]);
+ 
++#ifdef CONFIG_GRKERNSEC_SETXID
++	if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++		gr_delayed_cred_worker();
++#endif
++
+ 	if (!(current->ptrace & PT_PTRACED))
+ 		goto out;
+ 
+diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
+index c10aa84..9ec2e60 100644
+--- a/arch/mips/kernel/smtc-proc.c
++++ b/arch/mips/kernel/smtc-proc.c
+@@ -31,7 +31,7 @@ unsigned long selfipis[NR_CPUS];
+ 
+ struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
+ 
+-atomic_t smtc_fpu_recoveries;
++atomic_unchecked_t smtc_fpu_recoveries;
+ 
+ static int smtc_proc_show(struct seq_file *m, void *v)
+ {
+@@ -48,7 +48,7 @@ static int smtc_proc_show(struct seq_file *m, void *v)
+ 	for(i = 0; i < NR_CPUS; i++)
+ 		seq_printf(m, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
+ 	seq_printf(m, "%d Recoveries of \"stolen\" FPU\n",
+-		   atomic_read(&smtc_fpu_recoveries));
++		   atomic_read_unchecked(&smtc_fpu_recoveries));
+ 	return 0;
+ }
+ 
+@@ -73,7 +73,7 @@ void init_smtc_stats(void)
+ 		smtc_cpu_stats[i].selfipis = 0;
+ 	}
+ 
+-	atomic_set(&smtc_fpu_recoveries, 0);
++	atomic_set_unchecked(&smtc_fpu_recoveries, 0);
+ 
+ 	proc_create("smtc", 0444, NULL, &smtc_proc_fops);
+ }
+diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
+index dfc1b91..11a2c07 100644
+--- a/arch/mips/kernel/smtc.c
++++ b/arch/mips/kernel/smtc.c
+@@ -1359,7 +1359,7 @@ void smtc_soft_dump(void)
+ 	}
+ 	smtc_ipi_qdump();
+ 	printk("%d Recoveries of \"stolen\" FPU\n",
+-	       atomic_read(&smtc_fpu_recoveries));
++	       atomic_read_unchecked(&smtc_fpu_recoveries));
+ }
+ 
+ 
+diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
+index 84536bf..79caa4d 100644
+--- a/arch/mips/kernel/sync-r4k.c
++++ b/arch/mips/kernel/sync-r4k.c
+@@ -21,8 +21,8 @@
+ #include <asm/mipsregs.h>
+ 
+ static atomic_t count_start_flag = ATOMIC_INIT(0);
+-static atomic_t count_count_start = ATOMIC_INIT(0);
+-static atomic_t count_count_stop = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_start = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_stop = ATOMIC_INIT(0);
+ static atomic_t count_reference = ATOMIC_INIT(0);
+ 
+ #define COUNTON 100
+@@ -69,13 +69,13 @@ void synchronise_count_master(int cpu)
+ 
+ 	for (i = 0; i < NR_LOOPS; i++) {
+ 		/* slaves loop on '!= 2' */
+-		while (atomic_read(&count_count_start) != 1)
++		while (atomic_read_unchecked(&count_count_start) != 1)
+ 			mb();
+-		atomic_set(&count_count_stop, 0);
++		atomic_set_unchecked(&count_count_stop, 0);
+ 		smp_wmb();
+ 
+ 		/* this lets the slaves write their count register */
+-		atomic_inc(&count_count_start);
++		atomic_inc_unchecked(&count_count_start);
+ 
+ 		/*
+ 		 * Everyone initialises count in the last loop:
+@@ -86,11 +86,11 @@ void synchronise_count_master(int cpu)
+ 		/*
+ 		 * Wait for all slaves to leave the synchronization point:
+ 		 */
+-		while (atomic_read(&count_count_stop) != 1)
++		while (atomic_read_unchecked(&count_count_stop) != 1)
+ 			mb();
+-		atomic_set(&count_count_start, 0);
++		atomic_set_unchecked(&count_count_start, 0);
+ 		smp_wmb();
+-		atomic_inc(&count_count_stop);
++		atomic_inc_unchecked(&count_count_stop);
+ 	}
+ 	/* Arrange for an interrupt in a short while */
+ 	write_c0_compare(read_c0_count() + COUNTON);
+@@ -131,8 +131,8 @@ void synchronise_count_slave(int cpu)
+ 	initcount = atomic_read(&count_reference);
+ 
+ 	for (i = 0; i < NR_LOOPS; i++) {
+-		atomic_inc(&count_count_start);
+-		while (atomic_read(&count_count_start) != 2)
++		atomic_inc_unchecked(&count_count_start);
++		while (atomic_read_unchecked(&count_count_start) != 2)
+ 			mb();
+ 
+ 		/*
+@@ -141,8 +141,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 aec3408..74d79d3 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -683,7 +683,18 @@ asmlinkage void do_ov(struct pt_regs *regs)
+ 	siginfo_t info;
+ 
+ 	prev_state = exception_enter();
+-	die_if_kernel("Integer overflow", regs);
++	if (unlikely(!user_mode(regs))) {
++
++#ifdef CONFIG_PAX_REFCOUNT
++		if (fixup_exception(regs)) {
++			pax_report_refcount_overflow(regs);
++			exception_exit(prev_state);
++			return;
++		}
++#endif
++
++		die("Integer overflow", regs);
++	}
+ 
+ 	info.si_code = FPE_INTOVF;
+ 	info.si_signo = SIGFPE;
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+index 85df1cd..4f0a4de 100644
+--- a/arch/mips/mm/fault.c
++++ b/arch/mips/mm/fault.c
+@@ -28,6 +28,23 @@
+ #include <asm/highmem.h>		/* For VMALLOC_END */
+ #include <linux/kdebug.h>
+ 
++#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
+@@ -197,6 +214,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 0
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index f1baadd..8537544 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(vmm, 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;
+@@ -146,6 +152,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 = get_random_int();
+ 		random_factor = random_factor << PAGE_SHIFT;
+@@ -157,40 +167,25 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ 
+ 	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;
+ 	}
+ }
+ 
+-static inline unsigned long brk_rnd(void)
+-{
+-	unsigned long rnd = get_random_int();
+-
+-	rnd = rnd << PAGE_SHIFT;
+-	/* 8MB for 32bit, 256MB for 64bit */
+-	if (TASK_IS_32BIT_ADDR)
+-		rnd = rnd & 0x7ffffful;
+-	else
+-		rnd = rnd & 0xffffffful;
+-
+-	return rnd;
+-}
+-
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-	unsigned long base = mm->brk;
+-	unsigned long ret;
+-
+-	ret = PAGE_ALIGN(base + brk_rnd());
+-
+-	if (ret < mm->brk)
+-		return mm->brk;
+-
+-	return ret;
+-}
+-
+ int __virt_addr_valid(const volatile void *kaddr)
+ {
+ 	return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
+diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
+index a2358b4..7cead4f 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/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 472886c..00e7df9 100644
+--- a/arch/parisc/include/asm/atomic.h
++++ b/arch/parisc/include/asm/atomic.h
+@@ -252,6 +252,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 47f11c7..3420df2 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-byte cachelines; PA 1.1 processors have
+@@ -15,13 +16,13 @@
+  * just ruin performance.
+  */
+ #ifdef CONFIG_PA20
+-#define L1_CACHE_BYTES 64
+ #define L1_CACHE_SHIFT 6
+ #else
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
+ #endif
+ 
++#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 ad2b503..bdf1651 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 fc987a1..6e068ef 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|__GFP_REPEAT,
+@@ -93,6 +98,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 34899b5..02dd060 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -223,6 +223,17 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned \
long); + #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 e0a8235..ce2f1e1 100644
+--- a/arch/parisc/include/asm/uaccess.h
++++ b/arch/parisc/include/asm/uaccess.h
+@@ -245,10 +245,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 2a625fb..9908930 100644
+--- a/arch/parisc/kernel/module.c
++++ b/arch/parisc/kernel/module.c
+@@ -98,16 +98,38 @@
+ 
+ /* three functions to determine where in the module core
+  * or init pieces the location is */
++static inline int in_init_rx(struct module *me, void *loc)
++{
++	return (loc >= me->module_init_rx &&
++		loc < (me->module_init_rx + me->init_size_rx));
++}
++
++static inline int in_init_rw(struct module *me, void *loc)
++{
++	return (loc >= me->module_init_rw &&
++		loc < (me->module_init_rw + me->init_size_rw));
++}
++
+ static inline int in_init(struct module *me, void *loc)
+ {
+-	return (loc >= me->module_init &&
+-		loc <= (me->module_init + me->init_size));
++	return in_init_rx(me, loc) || in_init_rw(me, loc);
++}
++
++static inline int in_core_rx(struct module *me, void *loc)
++{
++	return (loc >= me->module_core_rx &&
++		loc < (me->module_core_rx + me->core_size_rx));
++}
++
++static inline int in_core_rw(struct module *me, void *loc)
++{
++	return (loc >= me->module_core_rw &&
++		loc < (me->module_core_rw + me->core_size_rw));
+ }
+ 
+ static inline int in_core(struct module *me, void *loc)
+ {
+-	return (loc >= me->module_core &&
+-		loc <= (me->module_core + me->core_size));
++	return in_core_rx(me, loc) || in_core_rw(me, loc);
+ }
+ 
+ static inline int in_local(struct module *me, void *loc)
+@@ -371,13 +393,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
+ 	}
+ 
+ 	/* align things a bit */
+-	me->core_size = ALIGN(me->core_size, 16);
+-	me->arch.got_offset = me->core_size;
+-	me->core_size += gots * sizeof(struct got_entry);
++	me->core_size_rw = ALIGN(me->core_size_rw, 16);
++	me->arch.got_offset = me->core_size_rw;
++	me->core_size_rw += gots * sizeof(struct got_entry);
+ 
+-	me->core_size = ALIGN(me->core_size, 16);
+-	me->arch.fdesc_offset = me->core_size;
+-	me->core_size += fdescs * sizeof(Elf_Fdesc);
++	me->core_size_rw = ALIGN(me->core_size_rw, 16);
++	me->arch.fdesc_offset = me->core_size_rw;
++	me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
+ 
+ 	me->arch.got_max = gots;
+ 	me->arch.fdesc_max = fdescs;
+@@ -395,7 +417,7 @@ static Elf64_Word get_got(struct module *me, unsigned long \
value, long addend) + 
+ 	BUG_ON(value == 0);
+ 
+-	got = me->module_core + me->arch.got_offset;
++	got = me->module_core_rw + me->arch.got_offset;
+ 	for (i = 0; got[i].addr; i++)
+ 		if (got[i].addr == value)
+ 			goto out;
+@@ -413,7 +435,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->module_core + me->arch.fdesc_offset;
++	Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
+ 
+ 	if (!value) {
+ 		printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+@@ -431,7 +453,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long \
value) + 
+ 	/* Create new one */
+ 	fdesc->addr = value;
+-	fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
++	fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
+ 	return (Elf_Addr)fdesc;
+ }
+ #endif /* CONFIG_64BIT */
+@@ -843,7 +865,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->module_core + me->arch.got_offset;
++	gp = (Elf_Addr)me->module_core_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 5dfd248..64914ac 100644
+--- a/arch/parisc/kernel/sys_parisc.c
++++ b/arch/parisc/kernel/sys_parisc.c
+@@ -33,9 +33,11 @@
+ #include <linux/utsname.h>
+ #include <linux/personality.h>
+ 
+-static unsigned long get_unshared_area(unsigned long addr, unsigned long len)
++static unsigned long get_unshared_area(struct file *filp, unsigned long addr, \
unsigned long len, ++					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;
+@@ -43,6 +45,7 @@ static unsigned long get_unshared_area(unsigned long addr, \
unsigned long len) + 	info.high_limit = TASK_SIZE;
+ 	info.align_mask = 0;
+ 	info.align_offset = 0;
++	info.threadstack_offset = offset;
+ 	return vm_unmapped_area(&info);
+ }
+ 
+@@ -61,10 +64,11 @@ static int get_offset(struct address_space *mapping)
+ 	return (unsigned long) mapping >> 8;
+ }
+ 
+-static unsigned long get_shared_area(struct address_space *mapping,
+-		unsigned long addr, unsigned long len, unsigned long pgoff)
++static unsigned long get_shared_area(struct file *filp, struct address_space \
*mapping, ++		unsigned long addr, unsigned long len, unsigned long pgoff, unsigned \
long flags) + {
+ 	struct vm_unmapped_area_info info;
++	unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+ 
+ 	info.flags = 0;
+ 	info.length = len;
+@@ -72,6 +76,7 @@ static unsigned long get_shared_area(struct address_space \
*mapping, + 	info.high_limit = TASK_SIZE;
+ 	info.align_mask = PAGE_MASK & (SHMLBA - 1);
+ 	info.align_offset = (get_offset(mapping) + pgoff) << PAGE_SHIFT;
++	info.threadstack_offset = offset;
+ 	return vm_unmapped_area(&info);
+ }
+ 
+@@ -86,15 +91,22 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned \
long addr, + 			return -EINVAL;
+ 		return addr;
+ 	}
+-	if (!addr)
++	if (!addr) {
+ 		addr = TASK_UNMAPPED_BASE;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++		if (current->mm->pax_flags & MF_PAX_RANDMMAP)
++			addr += current->mm->delta_mmap;
++#endif
++
++	}
++
+ 	if (filp) {
+-		addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
++		addr = get_shared_area(filp, filp->f_mapping, addr, len, pgoff, flags);
+ 	} else if(flags & MAP_SHARED) {
+-		addr = get_shared_area(NULL, addr, len, pgoff);
++		addr = get_shared_area(filp, NULL, addr, len, pgoff, flags);
+ 	} else {
+-		addr = get_unshared_area(addr, len);
++		addr = get_unshared_area(filp, addr, len, flags);
+ 	}
+ 	return addr;
+ }
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
+index b3f87a3..5d5d03d 100644
+--- a/arch/parisc/kernel/traps.c
++++ b/arch/parisc/kernel/traps.c
+@@ -727,9 +727,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 f247a34..dc0f219 100644
+--- a/arch/parisc/mm/fault.c
++++ b/arch/parisc/mm/fault.c
+@@ -15,6 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/module.h>
++#include <linux/unistd.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/traps.h>
+@@ -52,7 +53,7 @@ DEFINE_PER_CPU(struct exception_data, exception_data);
+ 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) {
+@@ -138,6 +139,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;
+@@ -194,8 +305,33 @@ good_area:
+ 
+ 	acc_type = parisc_acctyp(code,regs->iir);
+ 
+-	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/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
+index e3b1d41..8e81edf 100644
+--- a/arch/powerpc/include/asm/atomic.h
++++ b/arch/powerpc/include/asm/atomic.h
+@@ -523,6 +523,16 @@ static __inline__ long atomic64_inc_not_zero(atomic64_t *v)
+ 	return t1;
+ }
+ 
++#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 /* __powerpc64__ */
+ 
+ #endif /* __KERNEL__ */
+diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
+index 9e495c9..b6878e5 100644
+--- a/arch/powerpc/include/asm/cache.h
++++ b/arch/powerpc/include/asm/cache.h
+@@ -3,6 +3,7 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ 
+ /* bytes per L1 cache line */
+ #if defined(CONFIG_8xx) || defined(CONFIG_403GCX)
+@@ -22,7 +23,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 cc0655a..13eac2e 100644
+--- a/arch/powerpc/include/asm/elf.h
++++ b/arch/powerpc/include/asm/elf.h
+@@ -28,8 +28,19 @@
+    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.  */
+ 
+-extern unsigned long randomize_et_dyn(unsigned long base);
+-#define ELF_ET_DYN_BASE		(randomize_et_dyn(0x20000000))
++#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
+ 
+ /*
+  * Our registers are always unsigned longs, whether we're a 32 bit
+@@ -123,10 +134,6 @@ extern int arch_setup_additional_pages(struct linux_binprm \
*bprm, + 	(0x7ff >> (PAGE_SHIFT - 12)) : \
+ 	(0x3ffff >> (PAGE_SHIFT - 12)))
+ 
+-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+-#define arch_randomize_brk arch_randomize_brk
+-
+-
+ #ifdef CONFIG_SPU_BASE
+ /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
+ #define NT_SPU		1
+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/mman.h b/arch/powerpc/include/asm/mman.h
+index 8565c25..2865190 100644
+--- a/arch/powerpc/include/asm/mman.h
++++ b/arch/powerpc/include/asm/mman.h
+@@ -24,7 +24,7 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long \
prot) + }
+ #define arch_calc_vm_prot_bits(prot) arch_calc_vm_prot_bits(prot)
+ 
+-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/page.h b/arch/powerpc/include/asm/page.h
+index b9f4262..dcf04f7 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 88693ce..ac6f9ab 100644
+--- a/arch/powerpc/include/asm/page_64.h
++++ b/arch/powerpc/include/asm/page_64.h
+@@ -153,15 +153,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/pgalloc-64.h \
b/arch/powerpc/include/asm/pgalloc-64.h +index f65e27b..23ffb5b 100644
+--- a/arch/powerpc/include/asm/pgalloc-64.h
++++ b/arch/powerpc/include/asm/pgalloc-64.h
+@@ -53,6 +53,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, 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);
++}
++
+ #define pmd_populate(mm, pmd, pte_page) \
+ 	pmd_populate_kernel(mm, pmd, page_address(pte_page))
+ #define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
+@@ -171,6 +177,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/pgtable.h b/arch/powerpc/include/asm/pgtable.h
+index 7d6eacf..14c0240 100644
+--- a/arch/powerpc/include/asm/pgtable.h
++++ b/arch/powerpc/include/asm/pgtable.h
+@@ -2,6 +2,7 @@
+ #define _ASM_POWERPC_PGTABLE_H
+ #ifdef __KERNEL__
+ 
++#include <linux/const.h>
+ #ifndef __ASSEMBLY__
+ #include <asm/processor.h>		/* For TASK_SIZE */
+ #include <asm/mmu.h>
+diff --git a/arch/powerpc/include/asm/pte-hash32.h \
b/arch/powerpc/include/asm/pte-hash32.h +index 4aad413..85d86bf 100644
+--- a/arch/powerpc/include/asm/pte-hash32.h
++++ b/arch/powerpc/include/asm/pte-hash32.h
+@@ -21,6 +21,7 @@
+ #define _PAGE_FILE	0x004	/* when !present: nonlinear file mapping */
+ #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/reg.h b/arch/powerpc/include/asm/reg.h
+index 99222e2..f629aef 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -234,6 +234,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 48cfc85..891382f 100644
+--- a/arch/powerpc/include/asm/smp.h
++++ b/arch/powerpc/include/asm/smp.h
+@@ -50,7 +50,7 @@ struct smp_ops_t {
+ 	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/thread_info.h \
b/arch/powerpc/include/asm/thread_info.h +index ba7b197..d292e26 100644
+--- a/arch/powerpc/include/asm/thread_info.h
++++ b/arch/powerpc/include/asm/thread_info.h
+@@ -93,7 +93,6 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_POLLING_NRFLAG	3	/* true if poll_idle() is polling
+ 					   TIF_NEED_RESCHED */
+ #define TIF_32BIT		4	/* 32 bit binary */
+-#define TIF_PERFMON_WORK	5	/* work for pfm_handle_work() */
+ #define TIF_PERFMON_CTXSW	6	/* perfmon needs ctxsw calls */
+ #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
+ #define TIF_SINGLESTEP		8	/* singlestepping active */
+@@ -107,6 +106,9 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_EMULATE_STACK_STORE	16	/* Is an instruction emulation
+ 						for stack store? */
+ #define TIF_MEMDIE		17	/* is terminating due to OOM killer */
++#define TIF_PERFMON_WORK	18	/* work for pfm_handle_work() */
++/* mask must be expressable within 16 bits to satisfy 'andi' instruction reqs */
++#define TIF_GRSEC_SETXID	5	/* update credentials on syscall entry/exit */
+ 
+ /* as above, but as bit values */
+ #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+@@ -126,9 +128,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_T_OR_A	(_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 9485b43..4718d50 100644
+--- a/arch/powerpc/include/asm/uaccess.h
++++ b/arch/powerpc/include/asm/uaccess.h
+@@ -318,52 +318,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)
+ {
+@@ -387,6 +341,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);
+ }
+ 
+@@ -413,6 +371,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);
+ }
+ 
+@@ -430,6 +392,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/exceptions-64e.S \
b/arch/powerpc/kernel/exceptions-64e.S +index 645170a..6cf0271 100644
+--- a/arch/powerpc/kernel/exceptions-64e.S
++++ b/arch/powerpc/kernel/exceptions-64e.S
+@@ -757,6 +757,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)
+@@ -765,8 +766,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 902ca3c..e942155 100644
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -1357,10 +1357,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/module_32.c b/arch/powerpc/kernel/module_32.c
+index 2e3200c..72095ce 100644
+--- a/arch/powerpc/kernel/module_32.c
++++ b/arch/powerpc/kernel/module_32.c
+@@ -162,7 +162,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) {
+-		printk("Module doesn't contain .plt or .init.plt sections.\n");
++		printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
+ 		return -ENOEXEC;
+ 	}
+ 
+@@ -192,11 +192,16 @@ static uint32_t do_plt_call(void *location,
+ 
+ 	DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
+ 	/* Init, or core PLT? */
+-	if (location >= mod->module_core
+-	    && location < mod->module_core + mod->core_size)
++	if ((location >= mod->module_core_rx && location < mod->module_core_rx + \
mod->core_size_rx) || ++	    (location >= mod->module_core_rw && location < \
mod->module_core_rw + mod->core_size_rw)) + 		entry = (void \
*)sechdrs[mod->arch.core_plt_section].sh_addr; +-	else
++	else if ((location >= mod->module_init_rx && location < mod->module_init_rx + \
mod->init_size_rx) || ++		 (location >= mod->module_init_rw && location < \
mod->module_init_rw + mod->init_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]) {
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 8083be2..10aa352 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -884,8 +884,8 @@ void show_regs(struct pt_regs * regs)
+ 	 * Lookup NIP late so we have the best change of getting the
+ 	 * above info out without failing
+ 	 */
+-	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
+ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ 	printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch);
+@@ -1349,10 +1349,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 || ip == mrth) && curr_frame >= 0) {
+-				printk(" (%pS)",
++				printk(" (%pA)",
+ 				       (void *)current->ret_stack[curr_frame].ret);
+ 				curr_frame--;
+ 			}
+@@ -1372,7 +1372,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("--- Exception: %lx at %pS\n    LR = %pS\n",
++			printk("--- Exception: %lx at %pA\n    LR = %pA\n",
+ 			       regs->trap, (void *)regs->nip, (void *)lr);
+ 			firstframe = 1;
+ 		}
+@@ -1408,58 +1408,3 @@ void notrace __ppc64_runlatch_off(void)
+ 	mtspr(SPRN_CTRLT, ctrl);
+ }
+ #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;
+-
+-	/* 8MB for 32bit, 1GB for 64bit */
+-	if (is_32bit_task())
+-		rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+-	else
+-		rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+-
+-	return rnd << PAGE_SHIFT;
+-}
+-
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-	unsigned long base = mm->brk;
+-	unsigned long ret;
+-
+-#ifdef CONFIG_PPC_STD_MMU_64
+-	/*
+-	 * If we are using 1TB segments and we are allowed to randomise
+-	 * the heap, we can put it above 1TB so it is backed by a 1TB
+-	 * segment. Otherwise the heap will be in the bottom 1TB
+-	 * which always uses 256MB segments and this may result in a
+-	 * performance penalty.
+-	 */
+-	if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
+-		base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
+-#endif
+-
+-	ret = PAGE_ALIGN(base + brk_rnd());
+-
+-	if (ret < mm->brk)
+-		return mm->brk;
+-
+-	return ret;
+-}
+-
+-unsigned long randomize_et_dyn(unsigned long base)
+-{
+-	unsigned long ret = PAGE_ALIGN(base + brk_rnd());
+-
+-	if (ret < base)
+-		return base;
+-
+-	return ret;
+-}
+diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
+index 9a0d24c..e7fbedf 100644
+--- a/arch/powerpc/kernel/ptrace.c
++++ b/arch/powerpc/kernel/ptrace.c
+@@ -1761,6 +1761,10 @@ long arch_ptrace(struct task_struct *child, long request,
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /*
+  * We must return the syscall number to actually look up in the table.
+  * This can be -1L to skip running any syscall at all.
+@@ -1773,6 +1777,11 @@ long do_syscall_trace_enter(struct pt_regs *regs)
+ 
+ 	secure_computing_strict(regs->gpr[0]);
+ 
++#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) &&
+ 	    tracehook_report_syscall_entry(regs))
+ 		/*
+@@ -1807,6 +1816,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 0f83122..c0aca6a 100644
+--- a/arch/powerpc/kernel/signal_32.c
++++ b/arch/powerpc/kernel/signal_32.c
+@@ -987,7 +987,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction \
*ka, + 	/* 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 887e99d..310bc11 100644
+--- a/arch/powerpc/kernel/signal_64.c
++++ b/arch/powerpc/kernel/signal_64.c
+@@ -751,7 +751,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, \
siginfo_t *info, + #endif
+ 
+ 	/* 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 e435bc0..41c2964 100644
+--- a/arch/powerpc/kernel/traps.c
++++ b/arch/powerpc/kernel/traps.c
+@@ -141,6 +141,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)
+ {
+@@ -190,6 +192,9 @@ static void __kprobes oops_end(unsigned long flags, struct \
pt_regs *regs, + 		panic("Fatal exception in interrupt");
+ 	if (panic_on_oops)
+ 		panic("Fatal exception");
++
++	gr_handle_kernel_exploit();
++
+ 	do_exit(signr);
+ }
+ 
+diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
+index 1d9c926..25f4741 100644
+--- a/arch/powerpc/kernel/vdso.c
++++ b/arch/powerpc/kernel/vdso.c
+@@ -34,6 +34,7 @@
+ #include <asm/firmware.h>
+ #include <asm/vdso.h>
+ #include <asm/vdso_datapage.h>
++#include <asm/mman.h>
+ 
+ #include "setup.h"
+ 
+@@ -222,7 +223,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
+@@ -242,7 +243,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 8726779..a33c512 100644
+--- a/arch/powerpc/mm/fault.c
++++ b/arch/powerpc/mm/fault.c
+@@ -33,6 +33,10 @@
+ #include <linux/magic.h>
+ #include <linux/ratelimit.h>
+ #include <linux/context_tracking.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>
+@@ -69,6 +73,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.
+@@ -216,7 +247,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
+@@ -371,7 +402,7 @@ 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 */
+@@ -386,7 +417,7 @@ good_area:
+ 		 * processors use the same I/D cache coherency mechanism
+ 		 * as embedded.
+ 		 */
+-		if (error_code & DSISR_PROTFAULT)
++		if (error_code & (DSISR_PROTFAULT | DSISR_GUARDED))
+ 			goto bad_area;
+ #endif /* CONFIG_PPC_STD_MMU */
+ 
+@@ -471,6 +502,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 cb8bdbe..d770680 100644
+--- a/arch/powerpc/mm/mmap.c
++++ b/arch/powerpc/mm/mmap.c
+@@ -57,6 +57,10 @@ static unsigned long mmap_rnd(void)
+ {
+ 	unsigned long rnd = 0;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ 	if (current->flags & PF_RANDOMIZE) {
+ 		/* 8MB for 32bit, 1GB for 64bit */
+ 		if (is_32bit_task())
+@@ -91,9 +95,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();
++
++#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 3e99c14..f00953c 100644
+--- a/arch/powerpc/mm/slice.c
++++ b/arch/powerpc/mm/slice.c
+@@ -103,7 +103,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)
+@@ -277,6 +277,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 -EINVAL;
+ 
++#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);
+diff --git a/arch/powerpc/platforms/cell/spufs/file.c \
b/arch/powerpc/platforms/cell/spufs/file.c +index 9098692..3d54cd1 100644
+--- a/arch/powerpc/platforms/cell/spufs/file.c
++++ b/arch/powerpc/platforms/cell/spufs/file.c
+@@ -280,9 +280,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/include/asm/atomic.h b/arch/s390/include/asm/atomic.h
+index c797832..ce575c8 100644
+--- a/arch/s390/include/asm/atomic.h
++++ b/arch/s390/include/asm/atomic.h
+@@ -326,6 +326,16 @@ 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))
++
+ #define smp_mb__before_atomic_dec()	smp_mb()
+ #define smp_mb__after_atomic_dec()	smp_mb()
+ #define smp_mb__before_atomic_inc()	smp_mb()
+diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h
+index 4d7ccac..d03d0ad 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 78f4f87..598ce39 100644
+--- a/arch/s390/include/asm/elf.h
++++ b/arch/s390/include/asm/elf.h
+@@ -162,8 +162,14 @@ extern unsigned int vdso_enabled;
+    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.  */
+ 
+-extern unsigned long randomize_et_dyn(unsigned long base);
+-#define ELF_ET_DYN_BASE		(randomize_et_dyn(STACK_TOP / 3 * 2))
++#define ELF_ET_DYN_BASE		(STACK_TOP / 3 * 2)
++
++#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. */
+@@ -222,9 +228,6 @@ struct linux_binprm;
+ #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+ int arch_setup_additional_pages(struct linux_binprm *, int);
+ 
+-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+-#define arch_randomize_brk arch_randomize_brk
+-
+ void *fill_cpu_elf_notes(void *ptr, struct save_area *sa);
+ 
+ #endif
+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 9c33ed4..e40cbef 100644
+--- a/arch/s390/include/asm/uaccess.h
++++ b/arch/s390/include/asm/uaccess.h
+@@ -252,6 +252,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);
+ }
+ 
+@@ -275,6 +279,9 @@ copy_to_user(void __user *to, const void *from, 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 (__builtin_constant_p(n) && (n <= 256))
+ 		return uaccess.copy_from_user_small(n, from, to);
+ 	else
+@@ -306,10 +313,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 7845e15..59c4353 100644
+--- a/arch/s390/kernel/module.c
++++ b/arch/s390/kernel/module.c
+@@ -169,11 +169,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_size = ALIGN(me->core_size, 4);
+-	me->arch.got_offset = me->core_size;
+-	me->core_size += me->arch.got_size;
+-	me->arch.plt_offset = me->core_size;
+-	me->core_size += me->arch.plt_size;
++	me->core_size_rw = ALIGN(me->core_size_rw, 4);
++	me->arch.got_offset = me->core_size_rw;
++	me->core_size_rw += me->arch.got_size;
++	me->arch.plt_offset = me->core_size_rx;
++	me->core_size_rx += me->arch.plt_size;
+ 	return 0;
+ }
+ 
+@@ -289,7 +289,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym \
*symtab, + 		if (info->got_initialized == 0) {
+ 			Elf_Addr *gotent;
+ 
+-			gotent = me->module_core + me->arch.got_offset +
++			gotent = me->module_core_rw + me->arch.got_offset +
+ 				info->got_offset;
+ 			*gotent = val;
+ 			info->got_initialized = 1;
+@@ -312,7 +312,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->module_core - loc;
++			val += (Elf_Addr) me->module_core_rw - loc;
+ 			rc = apply_rela_bits(loc, val, 1, 32, 1);
+ 		}
+ 		break;
+@@ -325,7 +325,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->module_core + me->arch.plt_offset +
++			ip = me->module_core_rx + me->arch.plt_offset +
+ 				info->plt_offset;
+ #ifndef CONFIG_64BIT
+ 			ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
+@@ -350,7 +350,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->module_core +
++				val = (Elf_Addr) me->module_core_rx +
+ 					me->arch.plt_offset +
+ 					info->plt_offset;
+ 			val += rela->r_addend - loc;
+@@ -372,7 +372,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->module_core + me->arch.got_offset);
++			((Elf_Addr) me->module_core_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)
+@@ -382,7 +382,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->module_core + me->arch.got_offset +
++		val = (Elf_Addr) me->module_core_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 2bc3edd..ab9d598 100644
+--- a/arch/s390/kernel/process.c
++++ b/arch/s390/kernel/process.c
+@@ -236,39 +236,3 @@ 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)
+-{
+-	/* 8MB for 32bit, 1GB for 64bit */
+-	if (is_32bit_task())
+-		return (get_random_int() & 0x7ffUL) << PAGE_SHIFT;
+-	else
+-		return (get_random_int() & 0x3ffffUL) << PAGE_SHIFT;
+-}
+-
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-	unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+-
+-	if (ret < mm->brk)
+-		return mm->brk;
+-	return ret;
+-}
+-
+-unsigned long randomize_et_dyn(unsigned long base)
+-{
+-	unsigned long ret = PAGE_ALIGN(base + brk_rnd());
+-
+-	if (!(current->flags & PF_RANDOMIZE))
+-		return base;
+-	if (ret < base)
+-		return base;
+-	return ret;
+-}
+diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
+index 4002329..99b67cb 100644
+--- a/arch/s390/mm/mmap.c
++++ b/arch/s390/mm/mmap.c
+@@ -90,9 +90,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();
++
++#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;
+ 	}
+ }
+@@ -173,9 +185,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 = s390_get_unmapped_area;
+ 	} else {
+ 		mm->mmap_base = mmap_base();
++
++#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 f4c6d02..e9355c3 100644
+--- a/arch/score/kernel/process.c
++++ b/arch/score/kernel/process.c
+@@ -116,8 +116,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..cb5e44f 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;
+@@ -85,6 +89,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	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/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h
+index be56a24..443328f 100644
+--- a/arch/sparc/include/asm/atomic_64.h
++++ b/arch/sparc/include/asm/atomic_64.h
+@@ -14,18 +14,40 @@
+ #define ATOMIC64_INIT(i)	{ (i) }
+ 
+ #define atomic_read(v)		(*(volatile int *)&(v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return v->counter;
++}
+ #define atomic64_read(v)	(*(volatile long *)&(v)->counter)
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++	return v->counter;
++}
+ 
+ #define atomic_set(v, i)	(((v)->counter) = i)
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
+ #define atomic64_set(v, i)	(((v)->counter) = i)
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++	v->counter = i;
++}
+ 
+ extern void atomic_add(int, atomic_t *);
++extern void atomic_add_unchecked(int, atomic_unchecked_t *);
+ extern void atomic64_add(long, atomic64_t *);
++extern void atomic64_add_unchecked(long, atomic64_unchecked_t *);
+ extern void atomic_sub(int, atomic_t *);
++extern void atomic_sub_unchecked(int, atomic_unchecked_t *);
+ extern void atomic64_sub(long, atomic64_t *);
++extern void atomic64_sub_unchecked(long, atomic64_unchecked_t *);
+ 
+ extern int atomic_add_ret(int, atomic_t *);
++extern int atomic_add_ret_unchecked(int, atomic_unchecked_t *);
+ extern long atomic64_add_ret(long, atomic64_t *);
++extern long atomic64_add_ret_unchecked(long, atomic64_unchecked_t *);
+ extern int atomic_sub_ret(int, atomic_t *);
+ extern long atomic64_sub_ret(long, atomic64_t *);
+ 
+@@ -33,13 +55,29 @@ extern long atomic64_sub_ret(long, atomic64_t *);
+ #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
+ 
+ #define atomic_inc_return(v) atomic_add_ret(1, v)
++static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++	return atomic_add_ret_unchecked(1, v);
++}
+ #define atomic64_inc_return(v) atomic64_add_ret(1, v)
++static inline long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
++{
++	return atomic64_add_ret_unchecked(1, v);
++}
+ 
+ #define atomic_sub_return(i, v) atomic_sub_ret(i, v)
+ #define atomic64_sub_return(i, v) atomic64_sub_ret(i, v)
+ 
+ #define atomic_add_return(i, v) atomic_add_ret(i, v)
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
++	return atomic_add_ret_unchecked(i, v);
++}
+ #define atomic64_add_return(i, v) atomic64_add_ret(i, v)
++static inline long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v)
++{
++	return atomic64_add_ret_unchecked(i, v);
++}
+ 
+ /*
+  * atomic_inc_and_test - increment and test
+@@ -50,6 +88,10 @@ extern long atomic64_sub_ret(long, atomic64_t *);
+  * 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_ret(i, v) == 0)
+@@ -59,25 +101,60 @@ extern long atomic64_sub_ret(long, atomic64_t *);
+ #define atomic64_dec_and_test(v) (atomic64_sub_ret(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_ret(i, v) < 0)
+ #define atomic64_add_negative(i, v) (atomic64_add_ret(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;
+@@ -88,20 +165,35 @@ 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)))
+ #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 370ca1e..d4f4a98 100644
+--- a/arch/sparc/include/asm/elf_64.h
++++ b/arch/sparc/include/asm/elf_64.h
+@@ -189,6 +189,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 9b1c36d..209298b 100644
+--- a/arch/sparc/include/asm/pgalloc_32.h
++++ b/arch/sparc/include/asm/pgalloc_32.h
+@@ -33,6 +33,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 bcfe063..b333142 100644
+--- a/arch/sparc/include/asm/pgalloc_64.h
++++ b/arch/sparc/include/asm/pgalloc_64.h
+@@ -26,6 +26,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+ }
+ 
+ #define pud_populate(MM, PUD, PMD)	pud_set(PUD, PMD)
++#define pud_populate_kernel(MM, PUD, PMD)	pud_populate((MM), (PUD), (PMD))
+ 
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+diff --git a/arch/sparc/include/asm/pgtable_32.h \
b/arch/sparc/include/asm/pgtable_32.h +index 502f632..da1917f 100644
+--- a/arch/sparc/include/asm/pgtable_32.h
++++ b/arch/sparc/include/asm/pgtable_32.h
+@@ -50,6 +50,9 @@ extern unsigned long calc_highpages(void);
+ #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.
+@@ -62,18 +65,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 79da178..c2eede8 100644
+--- a/arch/sparc/include/asm/pgtsrmmu.h
++++ b/arch/sparc/include/asm/pgtsrmmu.h
+@@ -115,6 +115,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/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 dd38075..e7cac83 100644
+--- a/arch/sparc/include/asm/thread_info_32.h
++++ b/arch/sparc/include/asm/thread_info_32.h
+@@ -49,6 +49,8 @@ struct thread_info {
+ 	unsigned long		w_saved;
+ 
+ 	struct restart_block	restart_block;
++
++	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 d5e5042..9bfee76 100644
+--- a/arch/sparc/include/asm/thread_info_64.h
++++ b/arch/sparc/include/asm/thread_info_64.h
+@@ -63,6 +63,8 @@ struct thread_info {
+ 	struct pt_regs		*kern_una_regs;
+ 	unsigned int		kern_una_insn;
+ 
++	unsigned long		lowest_stack;
++
+ 	unsigned long		fpregs[0] __attribute__ ((aligned(64)));
+ };
+ 
+@@ -192,10 +194,11 @@ register struct thread_info *current_thread_info_reg \
asm("g6"); + #define TIF_UNALIGNED		5	/* allowed to do unaligned accesses */
+ /* flag bit 6 is available */
+ #define TIF_32BIT		7	/* 32-bit binary */
+-/* flag bit 8 is available */
++#define TIF_GRSEC_SETXID	8	/* update credentials on syscall entry/exit */
+ #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.
+@@ -214,12 +217,18 @@ 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_GRSEC_SETXID)
++
++
+ /*
+  * Thread-synchronous status.
+  *
+diff --git a/arch/sparc/include/asm/uaccess.h b/arch/sparc/include/asm/uaccess.h
+index 0167d26..767bb0c 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 53a28dd..50c38c3 100644
+--- a/arch/sparc/include/asm/uaccess_32.h
++++ b/arch/sparc/include/asm/uaccess_32.h
+@@ -250,27 +250,46 @@ extern unsigned long __copy_user(void __user *to, const void \
__user *from, unsig + 
+ 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 e562d3c..191f176 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>
+@@ -214,8 +215,15 @@ extern 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);
+ 
+@@ -231,8 +239,15 @@ extern 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 d432fb2..6056af1 100644
+--- a/arch/sparc/kernel/Makefile
++++ b/arch/sparc/kernel/Makefile
+@@ -3,7 +3,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 fdd819d..5af08c8 100644
+--- a/arch/sparc/kernel/process_32.c
++++ b/arch/sparc/kernel/process_32.c
+@@ -116,14 +116,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],
+@@ -160,7 +160,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 baebab2..9cd13b1 100644
+--- a/arch/sparc/kernel/process_64.c
++++ b/arch/sparc/kernel/process_64.c
+@@ -158,7 +158,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)
+@@ -167,7 +167,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]);
+@@ -180,7 +180,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]);
+ }
+@@ -269,7 +269,7 @@ void arch_trigger_all_cpu_backtrace(void)
+ 		       ((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..ec62734 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 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 7ff45e4..a58f271 100644
+--- a/arch/sparc/kernel/ptrace_64.c
++++ b/arch/sparc/kernel/ptrace_64.c
+@@ -1057,6 +1057,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;
+@@ -1064,6 +1068,11 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
+ 	/* do the secure computing check first */
+ 	secure_computing_strict(regs->u_regs[UREG_G1]);
+ 
++#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);
+ 
+@@ -1084,6 +1093,11 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
+ 
+ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+ {
++#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 e142545..fd29654 100644
+--- a/arch/sparc/kernel/smp_64.c
++++ b/arch/sparc/kernel/smp_64.c
+@@ -869,8 +869,8 @@ extern unsigned long xcall_flush_dcache_page_cheetah;
+ extern unsigned long xcall_flush_dcache_page_spitfire;
+ 
+ #ifdef CONFIG_DEBUG_DCFLUSH
+-extern atomic_t dcpage_flushes;
+-extern atomic_t dcpage_flushes_xcall;
++extern atomic_unchecked_t dcpage_flushes;
++extern atomic_unchecked_t dcpage_flushes_xcall;
+ #endif
+ 
+ static inline void __local_flush_dcache_page(struct page *page)
+@@ -894,7 +894,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();
+@@ -918,7 +918,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
+ 		}
+ 	}
+@@ -937,7 +937,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);
+@@ -954,7 +954,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 3a8d184..49498a8 100644
+--- a/arch/sparc/kernel/sys_sparc_32.c
++++ b/arch/sparc/kernel/sys_sparc_32.c
+@@ -52,7 +52,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 51561b8..8256764 100644
+--- a/arch/sparc/kernel/sys_sparc_64.c
++++ b/arch/sparc/kernel/sys_sparc_64.c
+@@ -90,13 +90,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;
+@@ -111,6 +112,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);
+@@ -118,22 +123,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);
+ 	}
+@@ -151,6 +162,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	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.  */
+@@ -160,7 +172,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;
+@@ -173,6 +185,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)
+@@ -181,8 +197,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;
+ 	}
+ 
+@@ -192,6 +207,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);
+ 
+ 	/*
+@@ -204,6 +220,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);
+ 	}
+@@ -260,10 +282,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_int();
+ 		if (test_thread_flag(TIF_32BIT))
+@@ -276,7 +302,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;
+ 
+ 	/*
+@@ -289,6 +315,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 */
+@@ -300,6 +332,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 73ec8a7..4611979 100644
+--- a/arch/sparc/kernel/syscalls.S
++++ b/arch/sparc/kernel/syscalls.S
+@@ -52,7 +52,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), \
%g0 ++	andcc	%l5, _TIF_WORK_SYSCALL, %g0
+ 	be,pt	%icc, rtrap
+ 	 nop
+ 	call	syscall_trace_leave
+@@ -184,7 +184,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), \
%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
+@@ -207,7 +207,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), \
%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
+@@ -223,7 +223,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), \
%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 6629829..036032d 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 die_if_kernel(char *str, struct pt_regs *regs)
+ {
+ 	static int die_counter;
+@@ -76,15 +78,17 @@ void 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 b3f833a..f485f80 100644
+--- a/arch/sparc/kernel/traps_64.c
++++ b/arch/sparc/kernel/traps_64.c
+@@ -76,7 +76,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);
+ 	}
+ }
+ 
+@@ -96,6 +96,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);
+ 	}
+@@ -114,11 +120,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);
+@@ -1142,7 +1153,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,
+@@ -1749,7 +1760,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.");
+ 	}
+ 
+@@ -1757,7 +1768,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 {
+@@ -1830,8 +1841,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)
+ {
+@@ -1923,7 +1934,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;
+@@ -1981,8 +1992,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);
+@@ -2036,7 +2047,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long \
offset) +  */
+ 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.
+@@ -2089,7 +2100,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);
+ }
+ 
+ unsigned long sun4v_err_itlb_vaddr;
+@@ -2104,9 +2115,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",
+@@ -2128,9 +2139,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",
+@@ -2336,13 +2347,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++;
+ 			}
+ 		}
+@@ -2360,6 +2371,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 die_if_kernel(char *str, struct pt_regs *regs)
+ {
+ 	static int die_counter;
+@@ -2388,7 +2401,7 @@ void 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);
+@@ -2401,8 +2414,10 @@ void die_if_kernel(char *str, struct pt_regs *regs)
+ 		}
+ 		user_instruction_dump ((unsigned int __user *) regs->tpc);
+ 	}
+-	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 8201c25e..072a2a7 100644
+--- a/arch/sparc/kernel/unaligned_64.c
++++ b/arch/sparc/kernel/unaligned_64.c
+@@ -286,7 +286,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 dbe119b..089c7c1 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 85c233d..68500e0 100644
+--- a/arch/sparc/lib/atomic_64.S
++++ b/arch/sparc/lib/atomic_64.S
+@@ -17,7 +17,12 @@
+ ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	lduw	[%o1], %g1
+-	add	%g1, %o0, %g7
++	addcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%icc, 6
++#endif
++
+ 	cas	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%icc, BACKOFF_LABEL(2f, 1b)
+@@ -27,10 +32,28 @@ ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */
+ 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic_add)
+ 
++ENTRY(atomic_add_unchecked) /* %o0 = increment, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	lduw	[%o1], %g1
++	add	%g1, %o0, %g7
++	cas	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%icc, 2f
++	 nop
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic_add_unchecked)
++
+ ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	lduw	[%o1], %g1
+-	sub	%g1, %o0, %g7
++	subcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%icc, 6
++#endif
++
+ 	cas	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%icc, BACKOFF_LABEL(2f, 1b)
+@@ -40,10 +63,28 @@ ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */
+ 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic_sub)
+ 
++ENTRY(atomic_sub_unchecked) /* %o0 = decrement, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	lduw	[%o1], %g1
++	sub	%g1, %o0, %g7
++	cas	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%icc, 2f
++	 nop
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic_sub_unchecked)
++
+ ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	lduw	[%o1], %g1
+-	add	%g1, %o0, %g7
++	addcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%icc, 6
++#endif
++
+ 	cas	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%icc, BACKOFF_LABEL(2f, 1b)
+@@ -53,10 +94,29 @@ ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */
+ 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic_add_ret)
+ 
++ENTRY(atomic_add_ret_unchecked) /* %o0 = increment, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	lduw	[%o1], %g1
++	addcc	%g1, %o0, %g7
++	cas	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%icc, 2f
++	 add	%g7, %o0, %g7
++	sra	%g7, 0, %o0
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic_add_ret_unchecked)
++
+ ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	lduw	[%o1], %g1
+-	sub	%g1, %o0, %g7
++	subcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%icc, 6
++#endif
++
+ 	cas	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%icc, BACKOFF_LABEL(2f, 1b)
+@@ -69,7 +129,12 @@ ENDPROC(atomic_sub_ret)
+ ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	ldx	[%o1], %g1
+-	add	%g1, %o0, %g7
++	addcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%xcc, 6
++#endif
++
+ 	casx	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
+@@ -79,10 +144,28 @@ ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */
+ 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic64_add)
+ 
++ENTRY(atomic64_add_unchecked) /* %o0 = increment, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	ldx	[%o1], %g1
++	addcc	%g1, %o0, %g7
++	casx	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%xcc, 2f
++	 nop
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic64_add_unchecked)
++
+ ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	ldx	[%o1], %g1
+-	sub	%g1, %o0, %g7
++	subcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%xcc, 6
++#endif
++
+ 	casx	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
+@@ -92,10 +175,28 @@ ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */
+ 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic64_sub)
+ 
++ENTRY(atomic64_sub_unchecked) /* %o0 = decrement, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	ldx	[%o1], %g1
++	subcc	%g1, %o0, %g7
++	casx	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%xcc, 2f
++	 nop
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic64_sub_unchecked)
++
+ ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	ldx	[%o1], %g1
+-	add	%g1, %o0, %g7
++	addcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%xcc, 6
++#endif
++
+ 	casx	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
+@@ -105,10 +206,29 @@ ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr \
*/ + 2:	BACKOFF_SPIN(%o2, %o3, 1b)
+ ENDPROC(atomic64_add_ret)
+ 
++ENTRY(atomic64_add_ret_unchecked) /* %o0 = increment, %o1 = atomic_ptr */
++	BACKOFF_SETUP(%o2)
++1:	ldx	[%o1], %g1
++	addcc	%g1, %o0, %g7
++	casx	[%o1], %g1, %g7
++	cmp	%g1, %g7
++	bne,pn	%xcc, 2f
++	 add	%g7, %o0, %g7
++	mov	%g7, %o0
++	retl
++	 nop
++2:	BACKOFF_SPIN(%o2, %o3, 1b)
++ENDPROC(atomic64_add_ret_unchecked)
++
+ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */
+ 	BACKOFF_SETUP(%o2)
+ 1:	ldx	[%o1], %g1
+-	sub	%g1, %o0, %g7
++	subcc	%g1, %o0, %g7
++
++#ifdef CONFIG_PAX_REFCOUNT
++	tvs	%xcc, 6
++#endif
++
+ 	casx	[%o1], %g1, %g7
+ 	cmp	%g1, %g7
+ 	bne,pn	%xcc, BACKOFF_LABEL(2f, 1b)
+diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
+index 323335b..ed85ea2 100644
+--- a/arch/sparc/lib/ksyms.c
++++ b/arch/sparc/lib/ksyms.c
+@@ -100,12 +100,18 @@ EXPORT_SYMBOL(__clear_user);
+ 
+ /* Atomic counter implementation. */
+ EXPORT_SYMBOL(atomic_add);
++EXPORT_SYMBOL(atomic_add_unchecked);
+ EXPORT_SYMBOL(atomic_add_ret);
++EXPORT_SYMBOL(atomic_add_ret_unchecked);
+ EXPORT_SYMBOL(atomic_sub);
++EXPORT_SYMBOL(atomic_sub_unchecked);
+ EXPORT_SYMBOL(atomic_sub_ret);
+ EXPORT_SYMBOL(atomic64_add);
++EXPORT_SYMBOL(atomic64_add_unchecked);
+ EXPORT_SYMBOL(atomic64_add_ret);
++EXPORT_SYMBOL(atomic64_add_ret_unchecked);
+ EXPORT_SYMBOL(atomic64_sub);
++EXPORT_SYMBOL(atomic64_sub_unchecked);
+ EXPORT_SYMBOL(atomic64_sub_ret);
+ EXPORT_SYMBOL(atomic64_dec_if_positive);
+ 
+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 e98bfda..ea8d221 100644
+--- a/arch/sparc/mm/fault_32.c
++++ b/arch/sparc/mm/fault_32.c
+@@ -21,6 +21,9 @@
+ #include <linux/perf_event.h>
+ #include <linux/interrupt.h>
+ #include <linux/kdebug.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+ 
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -159,6 +162,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)
+ {
+@@ -230,6 +504,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 5062ff3..e0b75f3 100644
+--- a/arch/sparc/mm/fault_64.c
++++ b/arch/sparc/mm/fault_64.c
+@@ -21,6 +21,9 @@
+ #include <linux/kprobes.h>
+ #include <linux/kdebug.h>
+ #include <linux/percpu.h>
++#include <linux/slab.h>
++#include <linux/pagemap.h>
++#include <linux/compiler.h>
+ 
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+@@ -74,7 +77,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);
+@@ -270,6 +273,466 @@ static void noinline __kprobes \
bogus_32bit_fault_address(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)
+ {
+ 	struct mm_struct *mm = current->mm;
+@@ -341,6 +804,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 d2b5944..d878f3c 100644
+--- a/arch/sparc/mm/hugetlbpage.c
++++ b/arch/sparc/mm/hugetlbpage.c
+@@ -28,7 +28,8 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct \
file *filp, + 							unsigned long addr,
+ 							unsigned long len,
+ 							unsigned long pgoff,
+-							unsigned long flags)
++							unsigned long flags,
++							unsigned long offset)
+ {
+ 	unsigned long task_size = TASK_SIZE;
+ 	struct vm_unmapped_area_info info;
+@@ -38,15 +39,22 @@ static unsigned long hugetlb_get_unmapped_area_bottomup(struct \
file *filp, + 
+ 	info.flags = 0;
+ 	info.length = len;
+-	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);
+ 	}
+@@ -58,7 +66,8 @@ static unsigned long
+ hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ 				  const unsigned long len,
+ 				  const unsigned long pgoff,
+-				  const unsigned long flags)
++				  const unsigned long flags,
++				  const unsigned long offset)
+ {
+ 	struct mm_struct *mm = current->mm;
+ 	unsigned long addr = addr0;
+@@ -73,6 +82,7 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const \
unsigned long addr0, + 	info.high_limit = mm->mmap_base;
+ 	info.align_mask = PAGE_MASK & ~HPAGE_MASK;
+ 	info.align_offset = 0;
++	info.threadstack_offset = offset;
+ 	addr = vm_unmapped_area(&info);
+ 
+ 	/*
+@@ -85,6 +95,12 @@ hugetlb_get_unmapped_area_topdown(struct file *filp, const \
unsigned long addr0, + 		VM_BUG_ON(addr != -ENOMEM);
+ 		info.flags = 0;
+ 		info.low_limit = TASK_UNMAPPED_BASE;
++
++#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);
+ 	}
+@@ -99,6 +115,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ 	struct mm_struct *mm = current->mm;
+ 	struct vm_area_struct *vma;
+ 	unsigned long task_size = TASK_SIZE;
++	unsigned long offset = gr_rand_threadstack_offset(mm, file, flags);
+ 
+ 	if (test_thread_flag(TIF_32BIT))
+ 		task_size = STACK_TOP32;
+@@ -114,19 +131,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 ed82eda..0d80e77 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -188,9 +188,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
+ 
+@@ -198,7 +198,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
+@@ -466,10 +466,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/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
+index f4500c6..889656c 100644
+--- a/arch/tile/include/asm/atomic_64.h
++++ b/arch/tile/include/asm/atomic_64.h
+@@ -143,6 +143,16 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, \
long u) + 
+ #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))
++
+ /* Atomic dec and inc don't implement barrier, so provide them if needed. */
+ #define smp_mb__before_atomic_dec()	smp_mb()
+ #define smp_mb__after_atomic_dec()	smp_mb()
+diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
+index a9a5299..0fce79e 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 e4d44bd..99927a3 100644
+--- a/arch/tile/include/asm/uaccess.h
++++ b/arch/tile/include/asm/uaccess.h
+@@ -408,9 +408,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 650ccff..45fe2d6 100644
+--- a/arch/tile/mm/hugetlbpage.c
++++ b/arch/tile/mm/hugetlbpage.c
+@@ -239,6 +239,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);
+ }
+ 
+@@ -256,6 +257,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 133f7de..1d6f2f1 100644
+--- a/arch/um/Makefile
++++ b/arch/um/Makefile
+@@ -62,6 +62,10 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst \
-D__KERNEL__,,\ + 	$(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) \
$(MODE_INCLUDE) \ + 	$(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter \
include + 
++ifdef CONSTIFY_PLUGIN
++USER_CFLAGS	+= -fplugin-arg-constify_plugin-no-constify
++endif
++
+ #This will adjust *FLAGS accordingly to the platform.
+ include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
+ 
+diff --git a/arch/um/defconfig b/arch/um/defconfig
+index 08107a7..ab22afe 100644
+--- a/arch/um/defconfig
++++ b/arch/um/defconfig
+@@ -51,7 +51,6 @@ CONFIG_X86_CMPXCHG=y
+ CONFIG_X86_L1_CACHE_SHIFT=5
+ CONFIG_X86_XADD=y
+ CONFIG_X86_PPRO_FENCE=y
+-CONFIG_X86_WP_WORKS_OK=y
+ CONFIG_X86_INVLPG=y
+ CONFIG_X86_BSWAP=y
+ CONFIG_X86_POPAD_OK=y
+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 5ff53d9..5850cdf 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 0032f92..cd151e0 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 bbcef52..6a2a483 100644
+--- a/arch/um/kernel/process.c
++++ b/arch/um/kernel/process.c
+@@ -367,22 +367,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/system.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 b32ebf9..5704f98 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -248,7 +248,7 @@ config X86_HT
+ 
+ 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
+@@ -1088,6 +1088,7 @@ config MICROCODE_EARLY
+ 
+ config X86_MSR
+ 	tristate "/dev/cpu/*/msr - Model-specific register support"
++	depends on !GRKERNSEC_KMEM
+ 	---help---
+ 	  This device gives privileged processes access to the x86
+ 	  Model-Specific Registers (MSRs).  It is a character device with
+@@ -1111,7 +1112,7 @@ choice
+ 
+ config NOHIGHMEM
+ 	bool "off"
+-	depends on !X86_NUMAQ
++	depends on !X86_NUMAQ && !(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
+@@ -1148,7 +1149,7 @@ config NOHIGHMEM
+ 
+ config HIGHMEM4G
+ 	bool "4GB"
+-	depends on !X86_NUMAQ
++	depends on !X86_NUMAQ && !(PAX_PAGEEXEC && PAX_ENABLE_PAE)
+ 	---help---
+ 	  Select this if you have a 32-bit processor and between 1 and 4
+ 	  gigabytes of physical RAM.
+@@ -1201,7 +1202,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
+@@ -1599,6 +1600,7 @@ config SECCOMP
+ 
+ config CC_STACKPROTECTOR
+ 	bool "Enable -fstack-protector buffer overflow detection"
++	depends on X86_64 || !PAX_MEMORY_UDEREF
+ 	---help---
+ 	  This option turns on the -fstack-protector GCC feature. This
+ 	  feature puts, at the beginning of functions, a canary value on
+@@ -1718,6 +1720,8 @@ config X86_NEED_RELOCS
+ config PHYSICAL_ALIGN
+ 	hex "Alignment value to which kernel should be aligned" if X86_32
+ 	default "0x1000000"
++	range 0x200000 0x1000000 if PAX_KERNEXEC && X86_PAE
++	range 0x400000 0x1000000 if PAX_KERNEXEC && !X86_PAE
+ 	range 0x2000 0x1000000
+ 	---help---
+ 	  This value puts the alignment restrictions on physical address
+@@ -1793,9 +1797,10 @@ config DEBUG_HOTPLUG_CPU0
+ 	  If unsure, say N.
+ 
+ config COMPAT_VDSO
+-	def_bool y
++	def_bool n
+ 	prompt "Compat VDSO support"
+ 	depends on X86_32 || IA32_EMULATION
++	depends on !PAX_PAGEEXEC && !PAX_SEGMEXEC && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ 	---help---
+ 	  Map the 32-bit VDSO to the predictable old-style address too.
+ 
+diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+index c026cca..14657ae 100644
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -319,7 +319,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
+@@ -327,7 +327,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
+@@ -373,7 +373,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 78d91af..8ceb94b 100644
+--- a/arch/x86/Kconfig.debug
++++ b/arch/x86/Kconfig.debug
+@@ -74,7 +74,7 @@ config X86_PTDUMP
+ config DEBUG_RODATA
+ 	bool "Write protect kernel read-only data structures"
+ 	default y
+-	depends on DEBUG_KERNEL
++	depends on DEBUG_KERNEL && BROKEN
+ 	---help---
+ 	  Mark the kernel read-only data as write-protected in the pagetables,
+ 	  in order to catch accidental (and incorrect) writes to such const
+@@ -92,7 +92,7 @@ config DEBUG_RODATA_TEST
+ 
+ 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
+diff --git a/arch/x86/Makefile b/arch/x86/Makefile
+index 07639c6..6f2c901 100644
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -54,6 +54,7 @@ else
+         UTS_MACHINE := x86_64
+         CHECKFLAGS += -D__x86_64__ -m64
+ 
++        biarch := $(call cc-option,-m64)
+         KBUILD_AFLAGS += -m64
+         KBUILD_CFLAGS += -m64
+ 
+@@ -241,3 +242,12 @@ define archhelp
+   echo  '                  FDINITRD=file initrd for the booted kernel'
+   echo  '  kvmconfig	- Enable additional options for guest kernel support'
+ 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
++
++archprepare:
++	$(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
+diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
+index 379814b..add62ce 100644
+--- a/arch/x86/boot/Makefile
++++ b/arch/x86/boot/Makefile
+@@ -65,6 +65,9 @@ KBUILD_CFLAGS	:= $(USERINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+ 		   $(call cc-option, -fno-stack-protector) \
+ 		   $(call cc-option, -mpreferred-stack-boundary=2)
+ KBUILD_CFLAGS	+= $(call cc-option, -m32)
++ifdef CONSTIFY_PLUGIN
++KBUILD_CFLAGS	+= -fplugin-arg-constify_plugin-no-constify
++endif
+ KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
+ GCOV_PROFILE := n
+ 
+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 5b75319..331a4ca 100644
+--- a/arch/x86/boot/boot.h
++++ b/arch/x86/boot/boot.h
+@@ -85,7 +85,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;
+ }
+ 
+@@ -181,7 +181,7 @@ static inline void wrgs32(u32 v, addr_t addr)
+ static inline int memcmp(const void *s1, const void *s2, size_t len)
+ {
+ 	u8 diff;
+-	asm("repe; cmpsb; setnz %0"
++	asm volatile("repe; cmpsb; setnz %0"
+ 	    : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+ 	return diff;
+ }
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
+index dcd90df..c830d7d 100644
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -15,6 +15,9 @@ cflags-$(CONFIG_X86_64) := -mcmodel=small
+ KBUILD_CFLAGS += $(cflags-y)
+ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
+ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
++ifdef CONSTIFY_PLUGIN
++KBUILD_CFLAGS += -fplugin-arg-constify_plugin-no-constify
++endif
+ 
+ KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
+ GCOV_PROFILE := n
+diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
+index b7388a4..03844ec 100644
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -150,7 +150,6 @@ again:
+ 		*addr = max_addr;
+ 	}
+ 
+-free_pool:
+ 	efi_call_phys1(sys_table->boottime->free_pool, map);
+ 
+ fail:
+@@ -214,7 +213,6 @@ static efi_status_t low_alloc(unsigned long size, unsigned long \
align, + 	if (i == map_size / desc_size)
+ 		status = EFI_NOT_FOUND;
+ 
+-free_pool:
+ 	efi_call_phys1(sys_table->boottime->free_pool, map);
+ fail:
+ 	return status;
+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/head_32.S b/arch/x86/boot/compressed/head_32.S
+index 1e3184f..0d11e2e 100644
+--- a/arch/x86/boot/compressed/head_32.S
++++ b/arch/x86/boot/compressed/head_32.S
+@@ -118,7 +118,7 @@ preferred_addr:
+ 	notl	%eax
+ 	andl    %eax, %ebx
+ #else
+-	movl	$LOAD_PHYSICAL_ADDR, %ebx
++	movl	$____LOAD_PHYSICAL_ADDR, %ebx
+ #endif
+ 
+ 	/* Target address to relocate to for decompression */
+@@ -204,7 +204,7 @@ relocated:
+  * and where it was actually loaded.
+  */
+ 	movl	%ebp, %ebx
+-	subl	$LOAD_PHYSICAL_ADDR, %ebx
++	subl	$____LOAD_PHYSICAL_ADDR, %ebx
+ 	jz	2f	/* Nothing to be done if loaded at compiled addr. */
+ /*
+  * Process relocations.
+@@ -212,8 +212,7 @@ relocated:
+ 
+ 1:	subl	$4, %edi
+ 	movl	(%edi), %ecx
+-	testl	%ecx, %ecx
+-	jz	2f
++	jecxz	2f
+ 	addl	%ebx, -__PAGE_OFFSET(%ebx, %ecx)
+ 	jmp	1b
+ 2:
+diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
+index 06e71c2..88a98264 100644
+--- a/arch/x86/boot/compressed/head_64.S
++++ b/arch/x86/boot/compressed/head_64.S
+@@ -95,7 +95,7 @@ ENTRY(startup_32)
+ 	notl	%eax
+ 	andl	%eax, %ebx
+ #else
+-	movl	$LOAD_PHYSICAL_ADDR, %ebx
++	movl	$____LOAD_PHYSICAL_ADDR, %ebx
+ #endif
+ 
+ 	/* Target address to relocate to for decompression */
+@@ -270,7 +270,7 @@ preferred_addr:
+ 	notq	%rax
+ 	andq	%rax, %rbp
+ #else
+-	movq	$LOAD_PHYSICAL_ADDR, %rbp
++	movq	$____LOAD_PHYSICAL_ADDR, %rbp
+ #endif
+ 
+ 	/* Target address to relocate to for decompression */
+@@ -361,8 +361,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 0319c88..7c1931f 100644
+--- a/arch/x86/boot/compressed/misc.c
++++ b/arch/x86/boot/compressed/misc.c
+@@ -307,7 +307,7 @@ 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
+@@ -358,7 +358,7 @@ asmlinkage void decompress_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/cpucheck.c b/arch/x86/boot/cpucheck.c
+index 4d3ff03..e4972ff 100644
+--- a/arch/x86/boot/cpucheck.c
++++ b/arch/x86/boot/cpucheck.c
+@@ -74,7 +74,7 @@ static int has_fpu(void)
+ 	u16 fcw = -1, fsw = -1;
+ 	u32 cr0;
+ 
+-	asm("movl %%cr0,%0" : "=r" (cr0));
++	asm volatile("movl %%cr0,%0" : "=r" (cr0));
+ 	if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
+ 		cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
+ 		asm volatile("movl %0,%%cr0" : : "r" (cr0));
+@@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
+ {
+ 	u32 f0, f1;
+ 
+-	asm("pushfl ; "
++	asm volatile("pushfl ; "
+ 	    "pushfl ; "
+ 	    "popl %0 ; "
+ 	    "movl %0,%1 ; "
+@@ -115,7 +115,7 @@ static void get_flags(void)
+ 		set_bit(X86_FEATURE_FPU, cpu.flags);
+ 
+ 	if (has_eflag(X86_EFLAGS_ID)) {
+-		asm("cpuid"
++		asm volatile("cpuid"
+ 		    : "=a" (max_intel_level),
+ 		      "=b" (cpu_vendor[0]),
+ 		      "=d" (cpu_vendor[1]),
+@@ -124,7 +124,7 @@ static void get_flags(void)
+ 
+ 		if (max_intel_level >= 0x00000001 &&
+ 		    max_intel_level <= 0x0000ffff) {
+-			asm("cpuid"
++			asm volatile("cpuid"
+ 			    : "=a" (tfms),
+ 			      "=c" (cpu.flags[4]),
+ 			      "=d" (cpu.flags[0])
+@@ -136,7 +136,7 @@ static void get_flags(void)
+ 				cpu.model += ((tfms >> 16) & 0xf) << 4;
+ 		}
+ 
+-		asm("cpuid"
++		asm volatile("cpuid"
+ 		    : "=a" (max_amd_level)
+ 		    : "a" (0x80000000)
+ 		    : "ebx", "ecx", "edx");
+@@ -144,7 +144,7 @@ static void get_flags(void)
+ 		if (max_amd_level >= 0x80000001 &&
+ 		    max_amd_level <= 0x8000ffff) {
+ 			u32 eax = 0x80000001;
+-			asm("cpuid"
++			asm volatile("cpuid"
+ 			    : "+a" (eax),
+ 			      "=c" (cpu.flags[6]),
+ 			      "=d" (cpu.flags[1])
+@@ -203,9 +203,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_flags();	/* Make sure it really did something */
+ 		err = check_flags();
+@@ -218,9 +218,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_flags();
+@@ -231,12 +231,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_flags();
+ 	}
+diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
+index 9ec06a1..2c25e79 100644
+--- a/arch/x86/boot/header.S
++++ b/arch/x86/boot/header.S
+@@ -409,10 +409,14 @@ 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
+ 
+ #define ZO_INIT_SIZE	(ZO__end - ZO_startup_32 + ZO_z_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 11e8c6e..fdbb1ed 100644
+--- a/arch/x86/boot/video-vesa.c
++++ b/arch/x86/boot/video-vesa.c
+@@ -200,6 +200,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 43eda28..5ab5fdb 100644
+--- a/arch/x86/boot/video.c
++++ b/arch/x86/boot/video.c
+@@ -96,7 +96,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..5e37f27 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 0, 1; ret
++
+ #define epilogue(FUNC,r1,r2,r3,r4,r5,r6,r7,r8,r9) \
+ 	movq	r1,r2;			\
+ 	movq	r3,r4;			\
+diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
+index 477e9d7..3ab339f 100644
+--- a/arch/x86/crypto/aesni-intel_asm.S
++++ b/arch/x86/crypto/aesni-intel_asm.S
+@@ -31,6 +31,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
++#include <asm/alternative-asm.h>
+ 
+ #ifdef __x86_64__
+ .data
+@@ -1441,6 +1442,7 @@ _return_T_done_decrypt:
+ 	pop	%r14
+ 	pop	%r13
+ 	pop	%r12
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_gcm_dec)
+ 
+@@ -1705,6 +1707,7 @@ _return_T_done_encrypt:
+ 	pop	%r14
+ 	pop	%r13
+ 	pop	%r12
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_gcm_enc)
+ 
+@@ -1722,6 +1725,7 @@ _key_expansion_256a:
+ 	pxor %xmm1, %xmm0
+ 	movaps %xmm0, (TKEYP)
+ 	add $0x10, TKEYP
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_key_expansion_128)
+ ENDPROC(_key_expansion_256a)
+@@ -1748,6 +1752,7 @@ _key_expansion_192a:
+ 	shufps $0b01001110, %xmm2, %xmm1
+ 	movaps %xmm1, 0x10(TKEYP)
+ 	add $0x20, TKEYP
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_key_expansion_192a)
+ 
+@@ -1768,6 +1773,7 @@ _key_expansion_192b:
+ 
+ 	movaps %xmm0, (TKEYP)
+ 	add $0x10, TKEYP
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_key_expansion_192b)
+ 
+@@ -1781,6 +1787,7 @@ _key_expansion_256b:
+ 	pxor %xmm1, %xmm2
+ 	movaps %xmm2, (TKEYP)
+ 	add $0x10, TKEYP
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_key_expansion_256b)
+ 
+@@ -1894,6 +1901,7 @@ ENTRY(aesni_set_key)
+ #ifndef __x86_64__
+ 	popl KEYP
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_set_key)
+ 
+@@ -1916,6 +1924,7 @@ ENTRY(aesni_enc)
+ 	popl KLEN
+ 	popl KEYP
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_enc)
+ 
+@@ -1974,6 +1983,7 @@ _aesni_enc1:
+ 	AESENC KEY STATE
+ 	movaps 0x70(TKEYP), KEY
+ 	AESENCLAST KEY STATE
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_enc1)
+ 
+@@ -2083,6 +2093,7 @@ _aesni_enc4:
+ 	AESENCLAST KEY STATE2
+ 	AESENCLAST KEY STATE3
+ 	AESENCLAST KEY STATE4
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_enc4)
+ 
+@@ -2106,6 +2117,7 @@ ENTRY(aesni_dec)
+ 	popl KLEN
+ 	popl KEYP
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_dec)
+ 
+@@ -2164,6 +2176,7 @@ _aesni_dec1:
+ 	AESDEC KEY STATE
+ 	movaps 0x70(TKEYP), KEY
+ 	AESDECLAST KEY STATE
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_dec1)
+ 
+@@ -2273,6 +2286,7 @@ _aesni_dec4:
+ 	AESDECLAST KEY STATE2
+ 	AESDECLAST KEY STATE3
+ 	AESDECLAST KEY STATE4
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_dec4)
+ 
+@@ -2331,6 +2345,7 @@ ENTRY(aesni_ecb_enc)
+ 	popl KEYP
+ 	popl LEN
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_ecb_enc)
+ 
+@@ -2390,6 +2405,7 @@ ENTRY(aesni_ecb_dec)
+ 	popl KEYP
+ 	popl LEN
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_ecb_dec)
+ 
+@@ -2432,6 +2448,7 @@ ENTRY(aesni_cbc_enc)
+ 	popl LEN
+ 	popl IVP
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_cbc_enc)
+ 
+@@ -2523,6 +2540,7 @@ ENTRY(aesni_cbc_dec)
+ 	popl LEN
+ 	popl IVP
+ #endif
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_cbc_dec)
+ 
+@@ -2550,6 +2568,7 @@ _aesni_inc_init:
+ 	mov $1, TCTR_LOW
+ 	MOVQ_R64_XMM TCTR_LOW INC
+ 	MOVQ_R64_XMM CTR TCTR_LOW
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_inc_init)
+ 
+@@ -2579,6 +2598,7 @@ _aesni_inc:
+ .Linc_low:
+ 	movaps CTR, IV
+ 	PSHUFB_XMM BSWAP_MASK IV
++	pax_force_retaddr_bts
+ 	ret
+ ENDPROC(_aesni_inc)
+ 
+@@ -2640,6 +2660,7 @@ ENTRY(aesni_ctr_enc)
+ .Lctr_enc_ret:
+ 	movups IV, (IVP)
+ .Lctr_enc_just_ret:
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_ctr_enc)
+ 
+@@ -2766,6 +2787,7 @@ ENTRY(aesni_xts_crypt8)
+ 	pxor INC, STATE4
+ 	movdqu STATE4, 0x70(OUTP)
+ 
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(aesni_xts_crypt8)
+ 
+diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S \
b/arch/x86/crypto/blowfish-x86_64-asm_64.S +index 246c670..4d1ed00 100644
+--- 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,9 +150,11 @@ ENTRY(__blowfish_enc_blk)
+ 	jnz .L__enc_xor;
+ 
+ 	write_block();
++	pax_force_retaddr 0, 1
+ 	ret;
+ .L__enc_xor:
+ 	xor_block();
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__blowfish_enc_blk)
+ 
+@@ -183,6 +186,7 @@ ENTRY(blowfish_dec_blk)
+ 
+ 	movq %r11, %rbp;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_dec_blk)
+ 
+@@ -334,6 +338,7 @@ ENTRY(__blowfish_enc_blk_4way)
+ 
+ 	popq %rbx;
+ 	popq %rbp;
++	pax_force_retaddr 0, 1
+ 	ret;
+ 
+ .L__enc_xor4:
+@@ -341,6 +346,7 @@ ENTRY(__blowfish_enc_blk_4way)
+ 
+ 	popq %rbx;
+ 	popq %rbp;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__blowfish_enc_blk_4way)
+ 
+@@ -375,5 +381,6 @@ ENTRY(blowfish_dec_blk_4way)
+ 	popq %rbx;
+ 	popq %rbp;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(blowfish_dec_blk_4way)
+diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S \
b/arch/x86/crypto/camellia-aesni-avx-asm_64.S +index ce71f92..2dd5b1e 100644
+--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+@@ -16,6 +16,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+ 
+@@ -191,6 +192,7 @@ roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ 	roundsm16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+ 		  %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15,
+ 		  %rcx, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm16_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ 
+@@ -199,6 +201,7 @@ roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ 	roundsm16(%xmm4, %xmm5, %xmm6, %xmm7, %xmm0, %xmm1, %xmm2, %xmm3,
+ 		  %xmm12, %xmm13, %xmm14, %xmm15, %xmm8, %xmm9, %xmm10, %xmm11,
+ 		  %rax, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm16_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ 
+@@ -780,6 +783,7 @@ __camellia_enc_blk16:
+ 		    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ 		    %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -865,6 +869,7 @@ __camellia_dec_blk16:
+ 		    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+ 		    %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -904,6 +909,7 @@ ENTRY(camellia_ecb_enc_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_enc_16way)
+ 
+@@ -932,6 +938,7 @@ ENTRY(camellia_ecb_dec_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_dec_16way)
+ 
+@@ -981,6 +988,7 @@ ENTRY(camellia_cbc_dec_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_cbc_dec_16way)
+ 
+@@ -1092,6 +1100,7 @@ ENTRY(camellia_ctr_16way)
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ctr_16way)
+ 
+@@ -1234,6 +1243,7 @@ camellia_xts_crypt_16way:
+ 		     %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+ 		     %xmm8, %rsi);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_xts_crypt_16way)
+ 
+diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S \
b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +index 0e0b886..8fc756a 100644
+--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+@@ -11,6 +11,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+ 
+@@ -230,6 +231,7 @@ roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd:
+ 	roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+ 		  %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15,
+ 		  %rcx, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd)
+ 
+@@ -238,6 +240,7 @@ roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab:
+ 	roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3,
+ 		  %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11,
+ 		  %rax, (%r9));
++	pax_force_retaddr_bts
+ 	ret;
+ ENDPROC(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab)
+ 
+@@ -820,6 +823,7 @@ __camellia_enc_blk32:
+ 		    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ 		    %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -905,6 +909,7 @@ __camellia_dec_blk32:
+ 		    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+ 		    %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
+ 
++	pax_force_retaddr_bts
+ 	ret;
+ 
+ .align 8
+@@ -948,6 +953,7 @@ ENTRY(camellia_ecb_enc_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_enc_32way)
+ 
+@@ -980,6 +986,7 @@ ENTRY(camellia_ecb_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ecb_dec_32way)
+ 
+@@ -1046,6 +1053,7 @@ ENTRY(camellia_cbc_dec_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_cbc_dec_32way)
+ 
+@@ -1184,6 +1192,7 @@ ENTRY(camellia_ctr_32way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_ctr_32way)
+ 
+@@ -1349,6 +1358,7 @@ camellia_xts_crypt_32way:
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_xts_crypt_32way)
+ 
+diff --git a/arch/x86/crypto/camellia-x86_64-asm_64.S \
b/arch/x86/crypto/camellia-x86_64-asm_64.S +index 310319c..ce174a4 100644
+--- a/arch/x86/crypto/camellia-x86_64-asm_64.S
++++ 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,12 +229,14 @@ ENTRY(__camellia_enc_blk)
+ 	enc_outunpack(mov, RT1);
+ 
+ 	movq RRBP, %rbp;
++	pax_force_retaddr 0, 1
+ 	ret;
+ 
+ .L__enc_xor:
+ 	enc_outunpack(xor, RT1);
+ 
+ 	movq RRBP, %rbp;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__camellia_enc_blk)
+ 
+@@ -272,6 +275,7 @@ ENTRY(camellia_dec_blk)
+ 	dec_outunpack();
+ 
+ 	movq RRBP, %rbp;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_dec_blk)
+ 
+@@ -463,6 +467,7 @@ ENTRY(__camellia_enc_blk_2way)
+ 
+ 	movq RRBP, %rbp;
+ 	popq %rbx;
++	pax_force_retaddr 0, 1
+ 	ret;
+ 
+ .L__enc2_xor:
+@@ -470,6 +475,7 @@ ENTRY(__camellia_enc_blk_2way)
+ 
+ 	movq RRBP, %rbp;
+ 	popq %rbx;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__camellia_enc_blk_2way)
+ 
+@@ -510,5 +516,6 @@ ENTRY(camellia_dec_blk_2way)
+ 
+ 	movq RRBP, %rbp;
+ 	movq RXOR, %rbx;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(camellia_dec_blk_2way)
+diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S \
b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +index c35fd5d..c1ee236 100644
+--- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
+@@ -24,6 +24,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .file "cast5-avx-x86_64-asm_64.S"
+ 
+@@ -281,6 +282,7 @@ __cast5_enc_blk16:
+ 	outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
+ 	outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__cast5_enc_blk16)
+ 
+@@ -352,6 +354,7 @@ __cast5_dec_blk16:
+ 	outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
+ 	outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ 
+ .L__skip_dec:
+@@ -388,6 +391,7 @@ ENTRY(cast5_ecb_enc_16way)
+ 	vmovdqu RR4, (6*4*4)(%r11);
+ 	vmovdqu RL4, (7*4*4)(%r11);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast5_ecb_enc_16way)
+ 
+@@ -420,6 +424,7 @@ ENTRY(cast5_ecb_dec_16way)
+ 	vmovdqu RR4, (6*4*4)(%r11);
+ 	vmovdqu RL4, (7*4*4)(%r11);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast5_ecb_dec_16way)
+ 
+@@ -469,6 +474,7 @@ ENTRY(cast5_cbc_dec_16way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast5_cbc_dec_16way)
+ 
+@@ -542,5 +548,6 @@ ENTRY(cast5_ctr_16way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast5_ctr_16way)
+diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S \
b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +index e3531f8..18ded3a 100644
+--- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
+@@ -24,6 +24,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+ 
+ .file "cast6-avx-x86_64-asm_64.S"
+@@ -295,6 +296,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 0, 1
+ 	ret;
+ ENDPROC(__cast6_enc_blk8)
+ 
+@@ -340,6 +342,7 @@ __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 0, 1
+ 	ret;
+ ENDPROC(__cast6_dec_blk8)
+ 
+@@ -358,6 +361,7 @@ ENTRY(cast6_ecb_enc_8way)
+ 
+ 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_ecb_enc_8way)
+ 
+@@ -376,6 +380,7 @@ ENTRY(cast6_ecb_dec_8way)
+ 
+ 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_ecb_dec_8way)
+ 
+@@ -399,6 +404,7 @@ ENTRY(cast6_cbc_dec_8way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_cbc_dec_8way)
+ 
+@@ -424,6 +430,7 @@ ENTRY(cast6_ctr_8way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_ctr_8way)
+ 
+@@ -446,6 +453,7 @@ ENTRY(cast6_xts_enc_8way)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_xts_enc_8way)
+ 
+@@ -468,5 +476,6 @@ ENTRY(cast6_xts_dec_8way)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(cast6_xts_dec_8way)
+diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S \
b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S +index dbc4339..3d868c5 100644
+--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
++++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+@@ -45,6 +45,7 @@
+ 
+ #include <asm/inst.h>
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
+ 
+@@ -312,6 +313,7 @@ do_return:
+ 	popq    %rsi
+ 	popq    %rdi
+ 	popq    %rbx
++	pax_force_retaddr 0, 1
+         ret
+ 
+         ################################################################
+diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S \
b/arch/x86/crypto/ghash-clmulni-intel_asm.S +index 586f41a..d02851e 100644
+--- a/arch/x86/crypto/ghash-clmulni-intel_asm.S
++++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S
+@@ -18,6 +18,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
++#include <asm/alternative-asm.h>
+ 
+ .data
+ 
+@@ -93,6 +94,7 @@ __clmul_gf128mul_ble:
+ 	psrlq $1, T2
+ 	pxor T2, T1
+ 	pxor T1, DATA
++	pax_force_retaddr
+ 	ret
+ ENDPROC(__clmul_gf128mul_ble)
+ 
+@@ -105,6 +107,7 @@ ENTRY(clmul_ghash_mul)
+ 	call __clmul_gf128mul_ble
+ 	PSHUFB_XMM BSWAP DATA
+ 	movups DATA, (%rdi)
++	pax_force_retaddr
+ 	ret
+ ENDPROC(clmul_ghash_mul)
+ 
+@@ -132,6 +135,7 @@ ENTRY(clmul_ghash_update)
+ 	PSHUFB_XMM BSWAP DATA
+ 	movups DATA, (%rdi)
+ .Lupdate_just_ret:
++	pax_force_retaddr
+ 	ret
+ ENDPROC(clmul_ghash_update)
+ 
+@@ -157,5 +161,6 @@ ENTRY(clmul_ghash_setkey)
+ 	pand .Lpoly, %xmm1
+ 	pxor %xmm1, %xmm0
+ 	movups %xmm0, (%rdi)
++	pax_force_retaddr
+ 	ret
+ ENDPROC(clmul_ghash_setkey)
+diff --git a/arch/x86/crypto/salsa20-x86_64-asm_64.S \
b/arch/x86/crypto/salsa20-x86_64-asm_64.S +index 9279e0b..9270820 100644
+--- a/arch/x86/crypto/salsa20-x86_64-asm_64.S
++++ 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 0, 1
+ 	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 2f202f4..d9164d6 100644
+--- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
+@@ -24,6 +24,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+ 
+ .file "serpent-avx-x86_64-asm_64.S"
+@@ -618,6 +619,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)
+ 
+@@ -672,6 +674,7 @@ __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)
+ 
+@@ -688,6 +691,7 @@ ENTRY(serpent_ecb_enc_8way_avx)
+ 
+ 	store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_enc_8way_avx)
+ 
+@@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_8way_avx)
+ 
+ 	store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_dec_8way_avx)
+ 
+@@ -720,6 +725,7 @@ ENTRY(serpent_cbc_dec_8way_avx)
+ 
+ 	store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_cbc_dec_8way_avx)
+ 
+@@ -738,6 +744,7 @@ ENTRY(serpent_ctr_8way_avx)
+ 
+ 	store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ctr_8way_avx)
+ 
+@@ -758,6 +765,7 @@ ENTRY(serpent_xts_enc_8way_avx)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_enc_8way_avx)
+ 
+@@ -778,5 +786,6 @@ ENTRY(serpent_xts_dec_8way_avx)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_dec_8way_avx)
+diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S \
b/arch/x86/crypto/serpent-avx2-asm_64.S +index b222085..abd483c 100644
+--- a/arch/x86/crypto/serpent-avx2-asm_64.S
++++ b/arch/x86/crypto/serpent-avx2-asm_64.S
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx2.S"
+ 
+ .file "serpent-avx2-asm_64.S"
+@@ -610,6 +611,7 @@ __serpent_enc_blk16:
+ 	write_blocks(RA1, RB1, RC1, RD1, RK0, RK1, RK2);
+ 	write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(__serpent_enc_blk16)
+ 
+@@ -664,6 +666,7 @@ __serpent_dec_blk16:
+ 	write_blocks(RC1, RD1, RB1, RE1, RK0, RK1, RK2);
+ 	write_blocks(RC2, RD2, RB2, RE2, RK0, RK1, RK2);
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(__serpent_dec_blk16)
+ 
+@@ -684,6 +687,7 @@ ENTRY(serpent_ecb_enc_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_enc_16way)
+ 
+@@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ecb_dec_16way)
+ 
+@@ -725,6 +730,7 @@ ENTRY(serpent_cbc_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_cbc_dec_16way)
+ 
+@@ -748,6 +754,7 @@ ENTRY(serpent_ctr_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_ctr_16way)
+ 
+@@ -772,6 +779,7 @@ ENTRY(serpent_xts_enc_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_enc_16way)
+ 
+@@ -796,5 +804,6 @@ ENTRY(serpent_xts_dec_16way)
+ 
+ 	vzeroupper;
+ 
++	pax_force_retaddr
+ 	ret;
+ ENDPROC(serpent_xts_dec_16way)
+diff --git a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S \
b/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S +index acc066c..1559cc4 100644
+--- a/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
++++ 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/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S
+index a410950..3356d42 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
+@@ -104,6 +105,7 @@
+ 	pop	%r12
+ 	pop	%rbp
+ 	pop	%rbx
++	pax_force_retaddr 0, 1
+ 	ret
+ 
+ 	ENDPROC(\name)
+diff --git a/arch/x86/crypto/sha256-avx-asm.S b/arch/x86/crypto/sha256-avx-asm.S
+index 642f156..4ab07b9 100644
+--- a/arch/x86/crypto/sha256-avx-asm.S
++++ b/arch/x86/crypto/sha256-avx-asm.S
+@@ -49,6 +49,7 @@
+ 
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define    VMOVDQ vmovdqu
+@@ -460,6 +461,7 @@ done_hash:
+ 	popq    %r13
+ 	popq    %rbp
+ 	popq    %rbx
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha256_transform_avx)
+ 
+diff --git a/arch/x86/crypto/sha256-avx2-asm.S b/arch/x86/crypto/sha256-avx2-asm.S
+index 9e86944..2e7f95a 100644
+--- a/arch/x86/crypto/sha256-avx2-asm.S
++++ b/arch/x86/crypto/sha256-avx2-asm.S
+@@ -50,6 +50,7 @@
+ 
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define	VMOVDQ vmovdqu
+@@ -720,6 +721,7 @@ done_hash:
+ 	popq	%r12
+ 	popq	%rbp
+ 	popq	%rbx
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha256_transform_rorx)
+ 
+diff --git a/arch/x86/crypto/sha256-ssse3-asm.S b/arch/x86/crypto/sha256-ssse3-asm.S
+index f833b74..c36ed14 100644
+--- a/arch/x86/crypto/sha256-ssse3-asm.S
++++ b/arch/x86/crypto/sha256-ssse3-asm.S
+@@ -47,6 +47,7 @@
+ ########################################################################
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ ## assume buffers not aligned
+ #define    MOVDQ movdqu
+@@ -471,6 +472,7 @@ done_hash:
+ 	popq    %rbp
+ 	popq    %rbx
+ 
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha256_transform_ssse3)
+ 
+diff --git a/arch/x86/crypto/sha512-avx-asm.S b/arch/x86/crypto/sha512-avx-asm.S
+index 974dde9..4533d34 100644
+--- a/arch/x86/crypto/sha512-avx-asm.S
++++ b/arch/x86/crypto/sha512-avx-asm.S
+@@ -49,6 +49,7 @@
+ 
+ #ifdef CONFIG_AS_AVX
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -364,6 +365,7 @@ updateblock:
+ 	mov	frame_RSPSAVE(%rsp), %rsp
+ 
+ nowork:
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha512_transform_avx)
+ 
+diff --git a/arch/x86/crypto/sha512-avx2-asm.S b/arch/x86/crypto/sha512-avx2-asm.S
+index 568b961..061ef1d 100644
+--- a/arch/x86/crypto/sha512-avx2-asm.S
++++ b/arch/x86/crypto/sha512-avx2-asm.S
+@@ -51,6 +51,7 @@
+ 
+ #ifdef CONFIG_AS_AVX2
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -678,6 +679,7 @@ done_hash:
+ 
+ 	# Restore Stack Pointer
+ 	mov	frame_RSPSAVE(%rsp), %rsp
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha512_transform_rorx)
+ 
+diff --git a/arch/x86/crypto/sha512-ssse3-asm.S b/arch/x86/crypto/sha512-ssse3-asm.S
+index fb56855..e23914f 100644
+--- a/arch/x86/crypto/sha512-ssse3-asm.S
++++ b/arch/x86/crypto/sha512-ssse3-asm.S
+@@ -48,6 +48,7 @@
+ ########################################################################
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ 
+ .text
+ 
+@@ -363,6 +364,7 @@ updateblock:
+ 	mov	frame_RSPSAVE(%rsp), %rsp
+ 
+ nowork:
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(sha512_transform_ssse3)
+ 
+diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S \
b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +index 0505813..63b1d00 100644
+--- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
++++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
+@@ -24,6 +24,7 @@
+  */
+ 
+ #include <linux/linkage.h>
++#include <asm/alternative-asm.h>
+ #include "glue_helper-asm-avx.S"
+ 
+ .file "twofish-avx-x86_64-asm_64.S"
+@@ -284,6 +285,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 0, 1
+ 	ret;
+ ENDPROC(__twofish_enc_blk8)
+ 
+@@ -324,6 +326,7 @@ __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 0, 1
+ 	ret;
+ ENDPROC(__twofish_dec_blk8)
+ 
+@@ -342,6 +345,7 @@ ENTRY(twofish_ecb_enc_8way)
+ 
+ 	store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ecb_enc_8way)
+ 
+@@ -360,6 +364,7 @@ ENTRY(twofish_ecb_dec_8way)
+ 
+ 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ecb_dec_8way)
+ 
+@@ -383,6 +388,7 @@ ENTRY(twofish_cbc_dec_8way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_cbc_dec_8way)
+ 
+@@ -408,6 +414,7 @@ ENTRY(twofish_ctr_8way)
+ 
+ 	popq %r12;
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_ctr_8way)
+ 
+@@ -430,6 +437,7 @@ ENTRY(twofish_xts_enc_8way)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_xts_enc_8way)
+ 
+@@ -452,5 +460,6 @@ ENTRY(twofish_xts_dec_8way)
+ 	/* dst <= regs xor IVs(in dst) */
+ 	store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
+ 
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_xts_dec_8way)
+diff --git a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S \
b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S +index 1c3b7ce..b365c5e 100644
+--- 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 0, 1
+ 	ret;
+ 
+ .L__enc_xor3:
+@@ -269,6 +271,7 @@ ENTRY(__twofish_enc_blk_3way)
+ 	popq %r13;
+ 	popq %r14;
+ 	popq %r15;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(__twofish_enc_blk_3way)
+ 
+@@ -308,5 +311,6 @@ ENTRY(twofish_dec_blk_3way)
+ 	popq %r13;
+ 	popq %r14;
+ 	popq %r15;
++	pax_force_retaddr 0, 1
+ 	ret;
+ ENDPROC(twofish_dec_blk_3way)
+diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S \
b/arch/x86/crypto/twofish-x86_64-asm_64.S +index a039d21..29e7615 100644
+--- 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
+@@ -265,6 +266,7 @@ ENTRY(twofish_enc_blk)
+ 
+ 	popq	R1
+ 	movq	$1,%rax
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(twofish_enc_blk)
+ 
+@@ -317,5 +319,6 @@ ENTRY(twofish_dec_blk)
+ 
+ 	popq	R1
+ 	movq	$1,%rax
++	pax_force_retaddr 0, 1
+ 	ret
+ ENDPROC(twofish_dec_blk)
+diff --git a/arch/x86/ia32/ia32_aout.c b/arch/x86/ia32/ia32_aout.c
+index bae3aba..c1788c1 100644
+--- a/arch/x86/ia32/ia32_aout.c
++++ b/arch/x86/ia32/ia32_aout.c
+@@ -159,6 +159,8 @@ static int aout_core_dump(long signr, struct pt_regs *regs, \
struct file *file, + 	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 665a730..8e7a67a 100644
+--- a/arch/x86/ia32/ia32_signal.c
++++ b/arch/x86/ia32/ia32_signal.c
+@@ -338,7 +338,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;
+ }
+ 
+@@ -396,7 +396,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)
+@@ -438,7 +438,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);
+@@ -461,16 +461,18 @@ 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 = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
+ 		else
+-			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
+-						 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/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 474dc1b..9297c58 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -15,8 +15,10 @@
+ #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>
+ 
+ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this.  */
+ #include <linux/elf-em.h>
+@@ -96,6 +98,32 @@ ENTRY(native_irq_enable_sysexit)
+ ENDPROC(native_irq_enable_sysexit)
+ #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
++
++	.macro pax_erase_kstack
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++	call pax_erase_kstack
++#endif
++	.endm
++
+ /*
+  * 32bit SYSENTER instruction entry.
+  *
+@@ -122,12 +150,6 @@ ENTRY(ia32_sysenter_target)
+ 	CFI_REGISTER	rsp,rbp
+ 	SWAPGS_UNSAFE_STACK
+ 	movq	PER_CPU_VAR(kernel_stack), %rsp
+-	addq	$(KERNEL_STACK_OFFSET),%rsp
+-	/*
+-	 * No need to follow this irqs on/off section: the syscall
+-	 * disabled irqs, here we enable it straight after entry:
+-	 */
+-	ENABLE_INTERRUPTS(CLBR_NONE)
+  	movl	%ebp,%ebp		/* zero extension */
+ 	pushq_cfi $__USER32_DS
+ 	/*CFI_REL_OFFSET ss,0*/
+@@ -135,24 +157,49 @@ ENTRY(ia32_sysenter_target)
+ 	CFI_REL_OFFSET rsp,0
+ 	pushfq_cfi
+ 	/*CFI_REL_OFFSET rflags,0*/
+-	movl	TI_sysenter_return+THREAD_INFO(%rsp,3*8-KERNEL_STACK_OFFSET),%r10d
+-	CFI_REGISTER rip,r10
++	orl	$X86_EFLAGS_IF,(%rsp)
++	GET_THREAD_INFO(%r11)
++	movl	TI_sysenter_return(%r11), %r11d
++	CFI_REGISTER rip,r11
+ 	pushq_cfi $__USER32_CS
+ 	/*CFI_REL_OFFSET cs,0*/
+ 	movl	%eax, %eax
+-	pushq_cfi %r10
++	pushq_cfi %r11
+ 	CFI_REL_OFFSET rip,0
+ 	pushq_cfi %rax
+ 	cld
+ 	SAVE_ARGS 0,1,0
++	pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs, here we enable it straight after entry:
++	 */
++	ENABLE_INTERRUPTS(CLBR_NONE)
+  	/* no need to do an access_ok check here because rbp has been
+  	   32bit zero extended */ 
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	addq	pax_user_shadow_base,%rbp
++	ASM_PAX_OPEN_USERLAND
++#endif
++
+ 	ASM_STAC
+ 1:	movl	(%rbp),%ebp
+ 	_ASM_EXTABLE(1b,ia32_badarg)
+ 	ASM_CLAC
+-	orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+-	testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
++	GET_THREAD_INFO(%r11)
++	orl    $TS_COMPAT,TI_status(%r11)
++	testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
+ 	CFI_REMEMBER_STATE
+ 	jnz  sysenter_tracesys
+ 	cmpq	$(IA32_NR_syscalls-1),%rax
+@@ -162,12 +209,15 @@ sysenter_do_call:
+ sysenter_dispatch:
+ 	call	*ia32_sys_call_table(,%rax,8)
+ 	movq	%rax,RAX-ARGOFFSET(%rsp)
++	GET_THREAD_INFO(%r11)
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF
+-	testl	$_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	testl	$_TIF_ALLWORK_MASK,TI_flags(%r11)
+ 	jnz	sysexit_audit
+ sysexit_from_sys_call:
+-	andl    $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	pax_exit_kernel_user
++	pax_erase_kstack
++	andl    $~TS_COMPAT,TI_status(%r11)
+ 	/* clear IF, that popfq doesn't enable interrupts early */
+ 	andl  $~0x200,EFLAGS-R11(%rsp) 
+ 	movl	RIP-R11(%rsp),%edx		/* User %eip */
+@@ -193,6 +243,9 @@ sysexit_from_sys_call:
+ 	movl %eax,%esi			/* 2nd arg: syscall number */
+ 	movl $AUDIT_ARCH_I386,%edi	/* 1st arg: audit arch */
+ 	call __audit_syscall_entry
++
++	pax_erase_kstack
++
+ 	movl RAX-ARGOFFSET(%rsp),%eax	/* reload syscall number */
+ 	cmpq $(IA32_NR_syscalls-1),%rax
+ 	ja ia32_badsys
+@@ -204,7 +257,7 @@ sysexit_from_sys_call:
+ 	.endm
+ 
+ 	.macro auditsys_exit exit
+-	testl $(_TIF_ALLWORK_MASK & \
~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) ++	testl \
$(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r11) + 	jnz \
ia32_ret_from_sys_call + 	TRACE_IRQS_ON
+ 	ENABLE_INTERRUPTS(CLBR_NONE)
+@@ -215,11 +268,12 @@ sysexit_from_sys_call:
+ 1:	setbe %al		/* 1 if error, 0 if not */
+ 	movzbl %al,%edi		/* zero-extend that into %edi */
+ 	call __audit_syscall_exit
++	GET_THREAD_INFO(%r11)
+ 	movq RAX-ARGOFFSET(%rsp),%rax	/* reload syscall return value */
+ 	movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),%edi
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF
+-	testl %edi,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	testl %edi,TI_flags(%r11)
+ 	jz \exit
+ 	CLEAR_RREGS -ARGOFFSET
+ 	jmp int_with_check
+@@ -237,7 +291,7 @@ sysexit_audit:
+ 
+ sysenter_tracesys:
+ #ifdef CONFIG_AUDITSYSCALL
+-	testl	$(_TIF_WORK_SYSCALL_ENTRY & \
~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) \
++	testl	$(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r11) + \
jz	sysenter_auditsys + #endif
+ 	SAVE_REST
+@@ -249,6 +303,9 @@ sysenter_tracesys:
+ 	RESTORE_REST
+ 	cmpq	$(IA32_NR_syscalls-1),%rax
+ 	ja	int_ret_from_sys_call /* sysenter_tracesys has set RAX(%rsp) */
++
++	pax_erase_kstack
++
+ 	jmp	sysenter_do_call
+ 	CFI_ENDPROC
+ ENDPROC(ia32_sysenter_target)
+@@ -276,19 +333,25 @@ ENDPROC(ia32_sysenter_target)
+ ENTRY(ia32_cstar_target)
+ 	CFI_STARTPROC32	simple
+ 	CFI_SIGNAL_FRAME
+-	CFI_DEF_CFA	rsp,KERNEL_STACK_OFFSET
++	CFI_DEF_CFA	rsp,0
+ 	CFI_REGISTER	rip,rcx
+ 	/*CFI_REGISTER	rflags,r11*/
+ 	SWAPGS_UNSAFE_STACK
+ 	movl	%esp,%r8d
+ 	CFI_REGISTER	rsp,r8
+ 	movq	PER_CPU_VAR(kernel_stack),%rsp
++	SAVE_ARGS 8*6,0,0
++	pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
+ 	/*
+ 	 * No need to follow this irqs on/off section: the syscall
+ 	 * disabled irqs and here we enable it straight after entry:
+ 	 */
+ 	ENABLE_INTERRUPTS(CLBR_NONE)
+-	SAVE_ARGS 8,0,0
+ 	movl 	%eax,%eax	/* zero extension */
+ 	movq	%rax,ORIG_RAX-ARGOFFSET(%rsp)
+ 	movq	%rcx,RIP-ARGOFFSET(%rsp)
+@@ -304,12 +367,25 @@ ENTRY(ia32_cstar_target)
+ 	/* no need to do an access_ok check here because r8 has been
+ 	   32bit zero extended */ 
+ 	/* hardware stack frame is complete now */	
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_OPEN_USERLAND
++	movq	pax_user_shadow_base,%r8
++	addq	RSP-ARGOFFSET(%rsp),%r8
++#endif
++
+ 	ASM_STAC
+ 1:	movl	(%r8),%r9d
+ 	_ASM_EXTABLE(1b,ia32_badarg)
+ 	ASM_CLAC
+-	orl     $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+-	testl   $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
++	GET_THREAD_INFO(%r11)
++	orl   $TS_COMPAT,TI_status(%r11)
++	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
+ 	CFI_REMEMBER_STATE
+ 	jnz   cstar_tracesys
+ 	cmpq $IA32_NR_syscalls-1,%rax
+@@ -319,12 +395,15 @@ cstar_do_call:
+ cstar_dispatch:
+ 	call *ia32_sys_call_table(,%rax,8)
+ 	movq %rax,RAX-ARGOFFSET(%rsp)
++	GET_THREAD_INFO(%r11)
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF
+-	testl $_TIF_ALLWORK_MASK,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	testl $_TIF_ALLWORK_MASK,TI_flags(%r11)
+ 	jnz sysretl_audit
+ sysretl_from_sys_call:
+-	andl $~TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	pax_exit_kernel_user
++	pax_erase_kstack
++	andl $~TS_COMPAT,TI_status(%r11)
+ 	RESTORE_ARGS 0,-ARG_SKIP,0,0,0
+ 	movl RIP-ARGOFFSET(%rsp),%ecx
+ 	CFI_REGISTER rip,rcx
+@@ -352,7 +431,7 @@ sysretl_audit:
+ 
+ cstar_tracesys:
+ #ifdef CONFIG_AUDITSYSCALL
+-	testl $(_TIF_WORK_SYSCALL_ENTRY & \
~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) ++	testl \
$(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%r11) + 	jz cstar_auditsys
+ #endif
+ 	xchgl %r9d,%ebp
+@@ -366,11 +445,19 @@ cstar_tracesys:
+ 	xchgl %ebp,%r9d
+ 	cmpq $(IA32_NR_syscalls-1),%rax
+ 	ja int_ret_from_sys_call /* cstar_tracesys has set RAX(%rsp) */
++
++	pax_erase_kstack
++
+ 	jmp cstar_do_call
+ END(ia32_cstar_target)
+ 				
+ ia32_badarg:
+ 	ASM_CLAC
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	ASM_PAX_CLOSE_USERLAND
++#endif
++
+ 	movq $-EFAULT,%rax
+ 	jmp ia32_sysret
+ 	CFI_ENDPROC
+@@ -407,19 +494,26 @@ ENTRY(ia32_syscall)
+ 	CFI_REL_OFFSET	rip,RIP-RIP
+ 	PARAVIRT_ADJUST_EXCEPTION_FRAME
+ 	SWAPGS
+-	/*
+-	 * No need to follow this irqs on/off section: the syscall
+-	 * disabled irqs and here we enable it straight after entry:
+-	 */
+-	ENABLE_INTERRUPTS(CLBR_NONE)
+ 	movl %eax,%eax
+ 	pushq_cfi %rax
+ 	cld
+ 	/* note the registers are not zero extended to the sf.
+ 	   this could be a problem. */
+ 	SAVE_ARGS 0,1,0
+-	orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
+-	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
++	/*
++	 * No need to follow this irqs on/off section: the syscall
++	 * disabled irqs and here we enable it straight after entry:
++	 */
++	ENABLE_INTERRUPTS(CLBR_NONE)
++	GET_THREAD_INFO(%r11)
++	orl   $TS_COMPAT,TI_status(%r11)
++	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
+ 	jnz ia32_tracesys
+ 	cmpq $(IA32_NR_syscalls-1),%rax
+ 	ja ia32_badsys
+@@ -442,6 +536,9 @@ ia32_tracesys:
+ 	RESTORE_REST
+ 	cmpq $(IA32_NR_syscalls-1),%rax
+ 	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
++
++	pax_erase_kstack
++
+ 	jmp ia32_do_call
+ END(ia32_syscall)
+ 
+diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
+index 8e0ceec..af13504 100644
+--- a/arch/x86/ia32/sys_ia32.c
++++ b/arch/x86/ia32/sys_ia32.c
+@@ -69,8 +69,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)) ||
+diff --git a/arch/x86/include/asm/alternative-asm.h \
b/arch/x86/include/asm/alternative-asm.h +index 372231c..a5aa1a1 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 %r10,\rip(%rsp)
++	.endm
++	.macro pax_force_fptr ptr
++	orq %r10,\ptr
++	.endm
++	.macro pax_set_fptr_mask
++	movabs $0x8000000000000000,%r10
++	.endm
++#endif
++#else
++	.macro pax_force_retaddr rip=0, reload=0
++	.endm
++	.macro pax_force_fptr ptr
++	.endm
++	.macro pax_force_retaddr_bts rip=0
++	.endm
++	.macro pax_set_fptr_mask
++	.endm
++#endif
++
+ .macro altinstruction_entry orig alt feature orig_len alt_len
+ 	.long \orig - .
+ 	.long \alt - .
+diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
+index 58ed6d9..f1cbe58 100644
+--- a/arch/x86/include/asm/alternative.h
++++ b/arch/x86/include/asm/alternative.h
+@@ -105,7 +105,7 @@ static inline int alternatives_text_reserved(void *start, void \
*end) + 	".pushsection .discard,\"aw\", at progbits\n"			\
+ 	DISCARD_ENTRY(1)						\
+ 	".popsection\n"							\
+-	".pushsection .altinstr_replacement, \"ax\"\n"			\
++	".pushsection .altinstr_replacement, \"a\"\n"			\
+ 	ALTINSTR_REPLACEMENT(newinstr, feature, 1)			\
+ 	".popsection"
+ 
+@@ -119,7 +119,7 @@ static inline int alternatives_text_reserved(void *start, void \
*end) + 	DISCARD_ENTRY(1)						\
+ 	DISCARD_ENTRY(2)						\
+ 	".popsection\n"							\
+-	".pushsection .altinstr_replacement, \"ax\"\n"			\
++	".pushsection .altinstr_replacement, \"a\"\n"			\
+ 	ALTINSTR_REPLACEMENT(newinstr1, feature1, 1)			\
+ 	ALTINSTR_REPLACEMENT(newinstr2, feature2, 2)			\
+ 	".popsection"
+diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
+index f8119b5..7209d5b 100644
+--- a/arch/x86/include/asm/apic.h
++++ b/arch/x86/include/asm/apic.h
+@@ -45,7 +45,7 @@ static inline void generic_apic_probe(void)
+ 
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 
+-extern unsigned int apic_verbosity;
++extern int apic_verbosity;
+ extern int local_apic_timer_c2_ok;
+ 
+ extern int disable_apic;
+diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h
+index 20370c6..a2eb9b0 100644
+--- a/arch/x86/include/asm/apm.h
++++ b/arch/x86/include/asm/apm.h
+@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 \
ecx_in, + 	__asm__ __volatile__(APM_DO_ZERO_SEGS
+ 		"pushl %%edi\n\t"
+ 		"pushl %%ebp\n\t"
+-		"lcall *%%cs:apm_bios_entry\n\t"
++		"lcall *%%ss:apm_bios_entry\n\t"
+ 		"setc %%al\n\t"
+ 		"popl %%ebp\n\t"
+ 		"popl %%edi\n\t"
+@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in,
+ 	__asm__ __volatile__(APM_DO_ZERO_SEGS
+ 		"pushl %%edi\n\t"
+ 		"pushl %%ebp\n\t"
+-		"lcall *%%cs:apm_bios_entry\n\t"
++		"lcall *%%ss:apm_bios_entry\n\t"
+ 		"setc %%bl\n\t"
+ 		"popl %%ebp\n\t"
+ 		"popl %%edi\n\t"
+diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
+index 722aa3b..3a0bb27 100644
+--- a/arch/x86/include/asm/atomic.h
++++ b/arch/x86/include/asm/atomic.h
+@@ -22,7 +22,18 @@
+  */
+ static inline int atomic_read(const atomic_t *v)
+ {
+-	return (*(volatile int *)&(v)->counter);
++	return (*(volatile const int *)&(v)->counter);
++}
++
++/**
++ * atomic_read_unchecked - read atomic variable
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically reads the value of @v.
++ */
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++	return (*(volatile const int *)&(v)->counter);
+ }
+ 
+ /**
+@@ -38,6 +49,18 @@ static inline void atomic_set(atomic_t *v, int i)
+ }
+ 
+ /**
++ * atomic_set_unchecked - set atomic variable
++ * @v: pointer of type atomic_unchecked_t
++ * @i: required value
++ *
++ * Atomically sets the value of @v to @i.
++ */
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++	v->counter = i;
++}
++
++/**
+  * atomic_add - add integer to atomic variable
+  * @i: integer value to add
+  * @v: pointer of type atomic_t
+@@ -46,7 +69,29 @@ static inline void atomic_set(atomic_t *v, int i)
+  */
+ static inline void atomic_add(int i, atomic_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "addl %1,%0"
++	asm volatile(LOCK_PREFIX "addl %1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "subl %1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (v->counter)
++		     : "ir" (i));
++}
++
++/**
++ * atomic_add_unchecked - add integer to atomic variable
++ * @i: integer value to add
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically adds @i to @v.
++ */
++static inline void atomic_add_unchecked(int i, atomic_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "addl %1,%0\n"
+ 		     : "+m" (v->counter)
+ 		     : "ir" (i));
+ }
+@@ -60,7 +105,29 @@ static inline void atomic_add(int i, atomic_t *v)
+  */
+ static inline void atomic_sub(int i, atomic_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "subl %1,%0"
++	asm volatile(LOCK_PREFIX "subl %1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "addl %1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (v->counter)
++		     : "ir" (i));
++}
++
++/**
++ * atomic_sub_unchecked - subtract integer from atomic variable
++ * @i: integer value to subtract
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically subtracts @i from @v.
++ */
++static inline void atomic_sub_unchecked(int i, atomic_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "subl %1,%0\n"
+ 		     : "+m" (v->counter)
+ 		     : "ir" (i));
+ }
+@@ -78,7 +145,16 @@ static inline int atomic_sub_and_test(int i, atomic_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
++	asm volatile(LOCK_PREFIX "subl %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "addl %2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "+m" (v->counter), "=qm" (c)
+ 		     : "ir" (i) : "memory");
+ 	return c;
+@@ -92,7 +168,27 @@ static inline int atomic_sub_and_test(int i, atomic_t *v)
+  */
+ static inline void atomic_inc(atomic_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "incl %0"
++	asm volatile(LOCK_PREFIX "incl %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "decl %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (v->counter));
++}
++
++/**
++ * atomic_inc_unchecked - increment atomic variable
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically increments @v by 1.
++ */
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "incl %0\n"
+ 		     : "+m" (v->counter));
+ }
+ 
+@@ -104,7 +200,27 @@ static inline void atomic_inc(atomic_t *v)
+  */
+ static inline void atomic_dec(atomic_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "decl %0"
++	asm volatile(LOCK_PREFIX "decl %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "incl %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (v->counter));
++}
++
++/**
++ * atomic_dec_unchecked - decrement atomic variable
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically decrements @v by 1.
++ */
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "decl %0\n"
+ 		     : "+m" (v->counter));
+ }
+ 
+@@ -120,7 +236,16 @@ static inline int atomic_dec_and_test(atomic_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "decl %0; sete %1"
++	asm volatile(LOCK_PREFIX "decl %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "incl %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "+m" (v->counter), "=qm" (c)
+ 		     : : "memory");
+ 	return c != 0;
+@@ -138,7 +263,35 @@ static inline int atomic_inc_and_test(atomic_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "incl %0; sete %1"
++	asm volatile(LOCK_PREFIX "incl %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "decl %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
++		     : "+m" (v->counter), "=qm" (c)
++		     : : "memory");
++	return c != 0;
++}
++
++/**
++ * atomic_inc_and_test_unchecked - increment and test
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically increments @v by 1
++ * and returns true if the result is zero, or false for all
++ * other cases.
++ */
++static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++	unsigned char c;
++
++	asm volatile(LOCK_PREFIX "incl %0\n"
++		     "sete %1\n"
+ 		     : "+m" (v->counter), "=qm" (c)
+ 		     : : "memory");
+ 	return c != 0;
+@@ -157,7 +310,16 @@ static inline int atomic_add_negative(int i, atomic_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
++	asm volatile(LOCK_PREFIX "addl %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "subl %2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sets %1\n"
+ 		     : "+m" (v->counter), "=qm" (c)
+ 		     : "ir" (i) : "memory");
+ 	return c;
+@@ -172,6 +334,18 @@ static inline int atomic_add_negative(int i, atomic_t *v)
+  */
+ static inline int atomic_add_return(int i, atomic_t *v)
+ {
++	return i + xadd_check_overflow(&v->counter, i);
++}
++
++/**
++ * atomic_add_return_unchecked - add integer and return
++ * @i: integer value to add
++ * @v: pointer of type atomic_unchecked_t
++ *
++ * Atomically adds @i to @v and returns @i + @v
++ */
++static inline int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
++{
+ 	return i + xadd(&v->counter, i);
+ }
+ 
+@@ -188,6 +362,10 @@ static inline int atomic_sub_return(int i, atomic_t *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 atomic_dec_return(v)  (atomic_sub_return(1, v))
+ 
+ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+@@ -195,11 +373,21 @@ 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 already a given value
+  * @v: pointer of type atomic_t
+@@ -211,12 +399,25 @@ static inline int atomic_xchg(atomic_t *v, int 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("addl %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++			     "jno 0f\n"
++			     "subl %2,%0\n"
++			     "int $4\n0:\n"
++			     _ASM_EXTABLE(0b, 0b)
++#endif
++
++			     : "=r" (new)
++			     : "0" (c), "ir" (a));
++
++		old = atomic_cmpxchg(v, c, new);
+ 		if (likely(old == c))
+ 			break;
+ 		c = old;
+@@ -225,6 +426,49 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int \
u) + }
+ 
+ /**
++ * atomic_inc_not_zero_hint - increment if not null
++ * @v: pointer of type atomic_t
++ * @hint: probable value of the atomic before the increment
++ *
++ * This version of atomic_inc_not_zero() gives a hint of probable
++ * value of the atomic. This helps processor to not read the memory
++ * before doing the atomic read/modify/write cycle, lowering
++ * number of bus transactions on some arches.
++ *
++ * Returns: 0 if increment was not done, 1 otherwise.
++ */
++#define atomic_inc_not_zero_hint atomic_inc_not_zero_hint
++static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint)
++{
++	int val, c = hint, new;
++
++	/* sanity test, should be removed by compiler if hint is a constant */
++	if (!hint)
++		return __atomic_add_unless(v, 1, 0);
++
++	do {
++		asm volatile("incl %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++			     "jno 0f\n"
++			     "decl %0\n"
++			     "int $4\n0:\n"
++			     _ASM_EXTABLE(0b, 0b)
++#endif
++
++			     : "=r" (new)
++			     : "0" (c));
++
++		val = atomic_cmpxchg(v, c, new);
++		if (val == c)
++			return 1;
++		c = val;
++	} while (c);
++
++	return 0;
++}
++
++/**
+  * atomic_inc_short - increment of a short integer
+  * @v: pointer to type int
+  *
+@@ -253,14 +497,37 @@ static inline void atomic_or_long(unsigned long *v1, unsigned \
long v2) + #endif
+ 
+ /* These are x86-specific, used by some header files */
+-#define atomic_clear_mask(mask, addr)				\
+-	asm volatile(LOCK_PREFIX "andl %0,%1"			\
+-		     : : "r" (~(mask)), "m" (*(addr)) : "memory")
++static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
++{
++	asm volatile(LOCK_PREFIX "andl %1,%0"
++		     : "+m" (v->counter)
++		     : "r" (~(mask))
++		     : "memory");
++}
+ 
+-#define atomic_set_mask(mask, addr)				\
+-	asm volatile(LOCK_PREFIX "orl %0,%1"			\
+-		     : : "r" ((unsigned)(mask)), "m" (*(addr))	\
+-		     : "memory")
++static inline void atomic_clear_mask_unchecked(unsigned int mask, \
atomic_unchecked_t *v) ++{
++	asm volatile(LOCK_PREFIX "andl %1,%0"
++		     : "+m" (v->counter)
++		     : "r" (~(mask))
++		     : "memory");
++}
++
++static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
++{
++	asm volatile(LOCK_PREFIX "orl %1,%0"
++		     : "+m" (v->counter)
++		     : "r" (mask)
++		     : "memory");
++}
++
++static inline void atomic_set_mask_unchecked(unsigned int mask, atomic_unchecked_t \
*v) ++{
++	asm volatile(LOCK_PREFIX "orl %1,%0"
++		     : "+m" (v->counter)
++		     : "r" (mask)
++		     : "memory");
++}
+ 
+ /* Atomic operations are already serializing on x86 */
+ #define smp_mb__before_atomic_dec()	barrier()
+diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
+index b154de7..aadebd8 100644
+--- a/arch/x86/include/asm/atomic64_32.h
++++ b/arch/x86/include/asm/atomic64_32.h
+@@ -12,6 +12,14 @@ typedef struct {
+ 	u64 __aligned(8) counter;
+ } atomic64_t;
+ 
++#ifdef CONFIG_PAX_REFCOUNT
++typedef struct {
++	u64 __aligned(8) counter;
++} atomic64_unchecked_t;
++#else
++typedef atomic64_t atomic64_unchecked_t;
++#endif
++
+ #define ATOMIC64_INIT(val)	{ (val) }
+ 
+ #define __ATOMIC64_DECL(sym) void atomic64_##sym(atomic64_t *, ...)
+@@ -37,21 +45,31 @@ typedef struct {
+ 	ATOMIC64_DECL_ONE(sym##_386)
+ 
+ ATOMIC64_DECL_ONE(add_386);
++ATOMIC64_DECL_ONE(add_unchecked_386);
+ ATOMIC64_DECL_ONE(sub_386);
++ATOMIC64_DECL_ONE(sub_unchecked_386);
+ ATOMIC64_DECL_ONE(inc_386);
++ATOMIC64_DECL_ONE(inc_unchecked_386);
+ ATOMIC64_DECL_ONE(dec_386);
++ATOMIC64_DECL_ONE(dec_unchecked_386);
+ #endif
+ 
+ #define alternative_atomic64(f, out, in...) \
+ 	__alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in)
+ 
+ ATOMIC64_DECL(read);
++ATOMIC64_DECL(read_unchecked);
+ ATOMIC64_DECL(set);
++ATOMIC64_DECL(set_unchecked);
+ ATOMIC64_DECL(xchg);
+ ATOMIC64_DECL(add_return);
++ATOMIC64_DECL(add_return_unchecked);
+ ATOMIC64_DECL(sub_return);
++ATOMIC64_DECL(sub_return_unchecked);
+ ATOMIC64_DECL(inc_return);
++ATOMIC64_DECL(inc_return_unchecked);
+ ATOMIC64_DECL(dec_return);
++ATOMIC64_DECL(dec_return_unchecked);
+ ATOMIC64_DECL(dec_if_positive);
+ ATOMIC64_DECL(inc_not_zero);
+ ATOMIC64_DECL(add_unless);
+@@ -77,6 +95,21 @@ static inline long long atomic64_cmpxchg(atomic64_t *v, long long \
o, long long n + }
+ 
+ /**
++ * atomic64_cmpxchg_unchecked - cmpxchg atomic64 variable
++ * @p: pointer to type atomic64_unchecked_t
++ * @o: expected value
++ * @n: new value
++ *
++ * Atomically sets @v to @n if it was equal to @o and returns
++ * the old value.
++ */
++
++static inline long long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long \
long o, long long n) ++{
++	return cmpxchg64(&v->counter, o, n);
++}
++
++/**
+  * atomic64_xchg - xchg atomic64 variable
+  * @v: pointer to type atomic64_t
+  * @n: value to assign
+@@ -112,6 +145,22 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+ }
+ 
+ /**
++ * atomic64_set_unchecked - set atomic64 variable
++ * @v: pointer to type atomic64_unchecked_t
++ * @n: value to assign
++ *
++ * Atomically sets the value of @v to @n.
++ */
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long long i)
++{
++	unsigned high = (unsigned)(i >> 32);
++	unsigned low = (unsigned)i;
++	alternative_atomic64(set, /* no output */,
++			     "S" (v), "b" (low), "c" (high)
++			     : "eax", "edx", "memory");
++}
++
++/**
+  * atomic64_read - read atomic64 variable
+  * @v: pointer to type atomic64_t
+  *
+@@ -125,6 +174,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+  }
+ 
+ /**
++ * atomic64_read_unchecked - read atomic64 variable
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically reads the value of @v and returns it.
++ */
++static inline long long atomic64_read_unchecked(atomic64_unchecked_t *v)
++{
++	long long r;
++	alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
++	return r;
++ }
++
++/**
+  * atomic64_add_return - add and return
+  * @i: integer value to add
+  * @v: pointer to type atomic64_t
+@@ -139,6 +201,21 @@ static inline long long atomic64_add_return(long long i, \
atomic64_t *v) + 	return i;
+ }
+ 
++/**
++ * atomic64_add_return_unchecked - add and return
++ * @i: integer value to add
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically adds @i to @v and returns @i + *@v
++ */
++static inline long long atomic64_add_return_unchecked(long long i, \
atomic64_unchecked_t *v) ++{
++	alternative_atomic64(add_return_unchecked,
++			     ASM_OUTPUT2("+A" (i), "+c" (v)),
++			     ASM_NO_INPUT_CLOBBER("memory"));
++	return i;
++}
++
+ /*
+  * Other variants with different arithmetic operators:
+  */
+@@ -158,6 +235,14 @@ static inline long long atomic64_inc_return(atomic64_t *v)
+ 	return a;
+ }
+ 
++static inline long long atomic64_inc_return_unchecked(atomic64_unchecked_t *v)
++{
++	long long a;
++	alternative_atomic64(inc_return_unchecked, "=&A" (a),
++			     "S" (v) : "memory", "ecx");
++	return a;
++}
++
+ static inline long long atomic64_dec_return(atomic64_t *v)
+ {
+ 	long long a;
+@@ -182,6 +267,21 @@ static inline long long atomic64_add(long long i, atomic64_t \
*v) + }
+ 
+ /**
++ * atomic64_add_unchecked - add integer to atomic64 variable
++ * @i: integer value to add
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically adds @i to @v.
++ */
++static inline long long atomic64_add_unchecked(long long i, atomic64_unchecked_t \
*v) ++{
++	__alternative_atomic64(add_unchecked, add_return_unchecked,
++			       ASM_OUTPUT2("+A" (i), "+c" (v)),
++			       ASM_NO_INPUT_CLOBBER("memory"));
++	return i;
++}
++
++/**
+  * atomic64_sub - subtract the atomic64 variable
+  * @i: integer value to subtract
+  * @v: pointer to type atomic64_t
+diff --git a/arch/x86/include/asm/atomic64_64.h b/arch/x86/include/asm/atomic64_64.h
+index 0e1cbfc..5623683 100644
+--- a/arch/x86/include/asm/atomic64_64.h
++++ b/arch/x86/include/asm/atomic64_64.h
+@@ -18,7 +18,19 @@
+  */
+ static inline long atomic64_read(const atomic64_t *v)
+ {
+-	return (*(volatile long *)&(v)->counter);
++	return (*(volatile const long *)&(v)->counter);
++}
++
++/**
++ * atomic64_read_unchecked - read atomic64 variable
++ * @v: pointer of type atomic64_unchecked_t
++ *
++ * Atomically reads the value of @v.
++ * Doesn't imply a read memory barrier.
++ */
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++	return (*(volatile const long *)&(v)->counter);
+ }
+ 
+ /**
+@@ -34,6 +46,18 @@ static inline void atomic64_set(atomic64_t *v, long i)
+ }
+ 
+ /**
++ * atomic64_set_unchecked - set atomic64 variable
++ * @v: pointer to type atomic64_unchecked_t
++ * @i: required value
++ *
++ * Atomically sets the value of @v to @i.
++ */
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++	v->counter = i;
++}
++
++/**
+  * atomic64_add - add integer to atomic64 variable
+  * @i: integer value to add
+  * @v: pointer to type atomic64_t
+@@ -42,6 +66,28 @@ static inline void atomic64_set(atomic64_t *v, long i)
+  */
+ static inline void atomic64_add(long i, atomic64_t *v)
+ {
++	asm volatile(LOCK_PREFIX "addq %1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "subq %1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "=m" (v->counter)
++		     : "er" (i), "m" (v->counter));
++}
++
++/**
++ * atomic64_add_unchecked - add integer to atomic64 variable
++ * @i: integer value to add
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically adds @i to @v.
++ */
++static inline void atomic64_add_unchecked(long i, atomic64_unchecked_t *v)
++{
+ 	asm volatile(LOCK_PREFIX "addq %1,%0"
+ 		     : "=m" (v->counter)
+ 		     : "er" (i), "m" (v->counter));
+@@ -56,7 +102,29 @@ static inline void atomic64_add(long i, atomic64_t *v)
+  */
+ static inline void atomic64_sub(long i, atomic64_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "subq %1,%0"
++	asm volatile(LOCK_PREFIX "subq %1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "addq %1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "=m" (v->counter)
++		     : "er" (i), "m" (v->counter));
++}
++
++/**
++ * atomic64_sub_unchecked - subtract the atomic64 variable
++ * @i: integer value to subtract
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically subtracts @i from @v.
++ */
++static inline void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "subq %1,%0\n"
+ 		     : "=m" (v->counter)
+ 		     : "er" (i), "m" (v->counter));
+ }
+@@ -74,7 +142,16 @@ static inline int atomic64_sub_and_test(long i, atomic64_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
++	asm volatile(LOCK_PREFIX "subq %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "addq %2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "=m" (v->counter), "=qm" (c)
+ 		     : "er" (i), "m" (v->counter) : "memory");
+ 	return c;
+@@ -88,6 +165,27 @@ static inline int atomic64_sub_and_test(long i, atomic64_t *v)
+  */
+ static inline void atomic64_inc(atomic64_t *v)
+ {
++	asm volatile(LOCK_PREFIX "incq %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "decq %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "=m" (v->counter)
++		     : "m" (v->counter));
++}
++
++/**
++ * atomic64_inc_unchecked - increment atomic64 variable
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically increments @v by 1.
++ */
++static inline void atomic64_inc_unchecked(atomic64_unchecked_t *v)
++{
+ 	asm volatile(LOCK_PREFIX "incq %0"
+ 		     : "=m" (v->counter)
+ 		     : "m" (v->counter));
+@@ -101,7 +199,28 @@ static inline void atomic64_inc(atomic64_t *v)
+  */
+ static inline void atomic64_dec(atomic64_t *v)
+ {
+-	asm volatile(LOCK_PREFIX "decq %0"
++	asm volatile(LOCK_PREFIX "decq %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "incq %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "=m" (v->counter)
++		     : "m" (v->counter));
++}
++
++/**
++ * atomic64_dec_unchecked - decrement atomic64 variable
++ * @v: pointer to type atomic64_t
++ *
++ * Atomically decrements @v by 1.
++ */
++static inline void atomic64_dec_unchecked(atomic64_unchecked_t *v)
++{
++	asm volatile(LOCK_PREFIX "decq %0\n"
+ 		     : "=m" (v->counter)
+ 		     : "m" (v->counter));
+ }
+@@ -118,7 +237,16 @@ static inline int atomic64_dec_and_test(atomic64_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "decq %0; sete %1"
++	asm volatile(LOCK_PREFIX "decq %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "incq %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "=m" (v->counter), "=qm" (c)
+ 		     : "m" (v->counter) : "memory");
+ 	return c != 0;
+@@ -136,7 +264,16 @@ static inline int atomic64_inc_and_test(atomic64_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "incq %0; sete %1"
++	asm volatile(LOCK_PREFIX "incq %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "decq %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "=m" (v->counter), "=qm" (c)
+ 		     : "m" (v->counter) : "memory");
+ 	return c != 0;
+@@ -155,7 +292,16 @@ static inline int atomic64_add_negative(long i, atomic64_t *v)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
++	asm volatile(LOCK_PREFIX "addq %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX "subq %2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sets %1\n"
+ 		     : "=m" (v->counter), "=qm" (c)
+ 		     : "er" (i), "m" (v->counter) : "memory");
+ 	return c;
+@@ -170,6 +316,18 @@ static inline int atomic64_add_negative(long i, atomic64_t *v)
+  */
+ static inline long atomic64_add_return(long i, atomic64_t *v)
+ {
++	return i + xadd_check_overflow(&v->counter, i);
++}
++
++/**
++ * atomic64_add_return_unchecked - add and return
++ * @i: integer value to add
++ * @v: pointer to type atomic64_unchecked_t
++ *
++ * Atomically adds @i to @v and returns @i + @v
++ */
++static inline long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v)
++{
+ 	return i + xadd(&v->counter, i);
+ }
+ 
+@@ -179,6 +337,10 @@ static inline long atomic64_sub_return(long i, atomic64_t *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);
++}
+ #define atomic64_dec_return(v)  (atomic64_sub_return(1, (v)))
+ 
+ static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
+@@ -186,6 +348,11 @@ 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);
+@@ -202,17 +369,30 @@ static inline long atomic64_xchg(atomic64_t *v, long new)
+  */
+ static inline int 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("add %2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++			     "jno 0f\n"
++			     "sub %2,%0\n"
++			     "int $4\n0:\n"
++			     _ASM_EXTABLE(0b, 0b)
++#endif
++
++			     : "=r" (new)
++			     : "0" (c), "ir" (a));
++
++		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/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
+index 6dfd019..28e188d 100644
+--- a/arch/x86/include/asm/bitops.h
++++ b/arch/x86/include/asm/bitops.h
+@@ -40,7 +40,7 @@
+  * a mask operation on a byte.
+  */
+ #define IS_IMMEDIATE(nr)		(__builtin_constant_p(nr))
+-#define CONST_MASK_ADDR(nr, addr)	BITOP_ADDR((void *)(addr) + ((nr)>>3))
++#define CONST_MASK_ADDR(nr, addr)	BITOP_ADDR((volatile void *)(addr) + ((nr)>>3))
+ #define CONST_MASK(nr)			(1 << ((nr) & 7))
+ 
+ /**
+@@ -486,7 +486,7 @@ static inline int fls(int x)
+  * at position 64.
+  */
+ #ifdef CONFIG_X86_64
+-static __always_inline int fls64(__u64 x)
++static __always_inline long fls64(__u64 x)
+ {
+ 	int bitpos = -1;
+ 	/*
+diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
+index 4fa687a..60f2d39 100644
+--- a/arch/x86/include/asm/boot.h
++++ b/arch/x86/include/asm/boot.h
+@@ -6,10 +6,15 @@
+ #include <uapi/asm/boot.h>
+ 
+ /* Physical address where kernel should be loaded. */
+-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
+ 				+ (CONFIG_PHYSICAL_ALIGN - 1)) \
+ 				& ~(CONFIG_PHYSICAL_ALIGN - 1))
+ 
++#ifndef __ASSEMBLY__
++extern unsigned char __LOAD_PHYSICAL_ADDR[];
++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
++#endif
++
+ /* Minimum kernel alignment, as a power of two */
+ #ifdef CONFIG_X86_64
+ #define MIN_KERNEL_ALIGN_LG2	PMD_SHIFT
+diff --git a/arch/x86/include/asm/cache.h b/arch/x86/include/asm/cache.h
+index 48f99f1..d78ebf9 100644
+--- a/arch/x86/include/asm/cache.h
++++ b/arch/x86/include/asm/cache.h
+@@ -5,12 +5,13 @@
+ 
+ /* L1 cache line size */
+ #define L1_CACHE_SHIFT	(CONFIG_X86_L1_CACHE_SHIFT)
+-#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")))
++#define __read_only __attribute__((__section__(".data..read_only")))
+ 
+ #define INTERNODE_CACHE_SHIFT CONFIG_X86_INTERNODE_CACHE_SHIFT
+-#define INTERNODE_CACHE_BYTES (1 << INTERNODE_CACHE_SHIFT)
++#define INTERNODE_CACHE_BYTES (_AC(1,UL) << INTERNODE_CACHE_SHIFT)
+ 
+ #ifdef CONFIG_X86_VSMP
+ #ifdef CONFIG_SMP
+diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
+index 9863ee3..4a1f8e1 100644
+--- a/arch/x86/include/asm/cacheflush.h
++++ b/arch/x86/include/asm/cacheflush.h
+@@ -27,7 +27,7 @@ static inline unsigned long get_page_memtype(struct page *pg)
+ 	unsigned long pg_flags = pg->flags & _PGMT_MASK;
+ 
+ 	if (pg_flags == _PGMT_DEFAULT)
+-		return -1;
++		return ~0UL;
+ 	else if (pg_flags == _PGMT_WC)
+ 		return _PAGE_CACHE_WC;
+ 	else if (pg_flags == _PGMT_UC_MINUS)
+diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
+index f50de69..2b0a458 100644
+--- a/arch/x86/include/asm/checksum_32.h
++++ b/arch/x86/include/asm/checksum_32.h
+@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_generic(const void *src, void \
*dst, + 					    int len, __wsum sum,
+ 					    int *src_err_ptr, int *dst_err_ptr);
+ 
++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
++						  int len, __wsum sum,
++						  int *src_err_ptr, int *dst_err_ptr);
++
++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
++						  int len, __wsum sum,
++						  int *src_err_ptr, int *dst_err_ptr);
++
+ /*
+  *	Note: when you get a NULL pointer exception here this means someone
+  *	passed in an incorrect kernel address to one of these functions.
+@@ -53,7 +61,7 @@ static inline __wsum csum_partial_copy_from_user(const void __user \
*src, + 
+ 	might_sleep();
+ 	stac();
+-	ret = csum_partial_copy_generic((__force void *)src, dst,
++	ret = csum_partial_copy_generic_from_user((__force void *)src, dst,
+ 					len, sum, err_ptr, NULL);
+ 	clac();
+ 
+@@ -187,7 +195,7 @@ static inline __wsum csum_and_copy_to_user(const void *src,
+ 	might_sleep();
+ 	if (access_ok(VERIFY_WRITE, dst, len)) {
+ 		stac();
+-		ret = csum_partial_copy_generic(src, (__force void *)dst,
++		ret = csum_partial_copy_generic_to_user(src, (__force void *)dst,
+ 						len, sum, NULL, err_ptr);
+ 		clac();
+ 		return ret;
+diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h
+index d47786a..ce1b05d 100644
+--- a/arch/x86/include/asm/cmpxchg.h
++++ b/arch/x86/include/asm/cmpxchg.h
+@@ -14,8 +14,12 @@ extern void __cmpxchg_wrong_size(void)
+ 	__compiletime_error("Bad argument size for cmpxchg");
+ extern void __xadd_wrong_size(void)
+ 	__compiletime_error("Bad argument size for xadd");
++extern void __xadd_check_overflow_wrong_size(void)
++	__compiletime_error("Bad argument size for xadd_check_overflow");
+ extern void __add_wrong_size(void)
+ 	__compiletime_error("Bad argument size for add");
++extern void __add_check_overflow_wrong_size(void)
++	__compiletime_error("Bad argument size for add_check_overflow");
+ 
+ /*
+  * Constants for operation sizes. On 32-bit, the 64-bit size it set to
+@@ -67,6 +71,34 @@ extern void __add_wrong_size(void)
+ 		__ret;							\
+ 	})
+ 
++#define __xchg_op_check_overflow(ptr, arg, op, lock)			\
++	({								\
++	        __typeof__ (*(ptr)) __ret = (arg);			\
++		switch (sizeof(*(ptr))) {				\
++		case __X86_CASE_L:					\
++			asm volatile (lock #op "l %0, %1\n"		\
++				      "jno 0f\n"			\
++				      "mov %0,%1\n"			\
++				      "int $4\n0:\n"			\
++				      _ASM_EXTABLE(0b, 0b)		\
++				      : "+r" (__ret), "+m" (*(ptr))	\
++				      : : "memory", "cc");		\
++			break;						\
++		case __X86_CASE_Q:					\
++			asm volatile (lock #op "q %q0, %1\n"		\
++				      "jno 0f\n"			\
++				      "mov %0,%1\n"			\
++				      "int $4\n0:\n"			\
++				      _ASM_EXTABLE(0b, 0b)		\
++				      : "+r" (__ret), "+m" (*(ptr))	\
++				      : : "memory", "cc");		\
++			break;						\
++		default:						\
++			__ ## op ## _check_overflow_wrong_size();	\
++		}							\
++		__ret;							\
++	})
++
+ /*
+  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
+  * Since this is generally used to protect other memory information, we
+@@ -167,6 +199,9 @@ extern void __add_wrong_size(void)
+ #define xadd_sync(ptr, inc)	__xadd((ptr), (inc), "lock; ")
+ #define xadd_local(ptr, inc)	__xadd((ptr), (inc), "")
+ 
++#define __xadd_check_overflow(ptr, inc, lock)	__xchg_op_check_overflow((ptr), \
(inc), xadd, lock) ++#define xadd_check_overflow(ptr, \
inc)		__xadd_check_overflow((ptr), (inc), LOCK_PREFIX) ++
+ #define __add(ptr, inc, lock)						\
+ 	({								\
+ 	        __typeof__ (*(ptr)) __ret = (inc);			\
+diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
+index 59c6c40..5e0b22c 100644
+--- a/arch/x86/include/asm/compat.h
++++ b/arch/x86/include/asm/compat.h
+@@ -41,7 +41,7 @@ typedef s64 __attribute__((aligned(4))) compat_s64;
+ typedef u32		compat_uint_t;
+ typedef u32		compat_ulong_t;
+ typedef u64 __attribute__((aligned(4))) compat_u64;
+-typedef u32		compat_uptr_t;
++typedef u32		__user compat_uptr_t;
+ 
+ struct compat_timespec {
+ 	compat_time_t	tv_sec;
+diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
+index 7290585..717e89e 100644
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -203,7 +203,7 @@
+ #define X86_FEATURE_DECODEASSISTS (8*32+12) /* AMD Decode Assists support */
+ #define X86_FEATURE_PAUSEFILTER (8*32+13) /* AMD filtered pause intercept */
+ #define X86_FEATURE_PFTHRESHOLD (8*32+14) /* AMD pause filter threshold */
+-
++#define X86_FEATURE_STRONGUDEREF (8*32+31) /* PaX PCID based strong UDEREF */
+ 
+ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
+ #define X86_FEATURE_FSGSBASE	(9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
+@@ -211,7 +211,7 @@
+ #define X86_FEATURE_BMI1	(9*32+ 3) /* 1st group bit manipulation extensions */
+ #define X86_FEATURE_HLE		(9*32+ 4) /* Hardware Lock Elision */
+ #define X86_FEATURE_AVX2	(9*32+ 5) /* AVX2 instructions */
+-#define X86_FEATURE_SMEP	(9*32+ 7) /* Supervisor Mode Execution Protection */
++#define X86_FEATURE_SMEP	(9*32+ 7) /* Supervisor Mode Execution Prevention */
+ #define X86_FEATURE_BMI2	(9*32+ 8) /* 2nd group bit manipulation extensions */
+ #define X86_FEATURE_ERMS	(9*32+ 9) /* Enhanced REP MOVSB/STOSB */
+ #define X86_FEATURE_INVPCID	(9*32+10) /* Invalidate Processor Context ID */
+@@ -353,6 +353,7 @@ extern const char * const x86_power_flags[32];
+ #undef  cpu_has_centaur_mcr
+ #define cpu_has_centaur_mcr	0
+ 
++#define cpu_has_pcid		boot_cpu_has(X86_FEATURE_PCID)
+ #endif /* CONFIG_X86_64 */
+ 
+ #if __GNUC__ >= 4
+@@ -403,7 +404,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
+ 
+ #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS
+ 	t_warn:
+-		warn_pre_alternatives();
++		if (bit != X86_FEATURE_PCID && bit != X86_FEATURE_INVPCID)
++			warn_pre_alternatives();
+ 		return false;
+ #endif
+ #else /* GCC_VERSION >= 40500 */
+@@ -421,7 +423,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit)
+ 			     ".section .discard,\"aw\", at progbits\n"
+ 			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
+ 			     ".previous\n"
+-			     ".section .altinstr_replacement,\"ax\"\n"
++			     ".section .altinstr_replacement,\"a\"\n"
+ 			     "3: movb $1,%0\n"
+ 			     "4:\n"
+ 			     ".previous\n"
+@@ -457,7 +459,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+ 			 " .byte 2b - 1b\n"		/* src len */
+ 			 " .byte 4f - 3f\n"		/* repl len */
+ 			 ".previous\n"
+-			 ".section .altinstr_replacement,\"ax\"\n"
++			 ".section .altinstr_replacement,\"a\"\n"
+ 			 "3: .byte 0xe9\n .long %l[t_no] - 2b\n"
+ 			 "4:\n"
+ 			 ".previous\n"
+@@ -490,7 +492,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+ 			     ".section .discard,\"aw\", at progbits\n"
+ 			     " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */
+ 			     ".previous\n"
+-			     ".section .altinstr_replacement,\"ax\"\n"
++			     ".section .altinstr_replacement,\"a\"\n"
+ 			     "3: movb $0,%0\n"
+ 			     "4:\n"
+ 			     ".previous\n"
+@@ -504,7 +506,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit)
+ 			     ".section .discard,\"aw\", at progbits\n"
+ 			     " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */
+ 			     ".previous\n"
+-			     ".section .altinstr_replacement,\"ax\"\n"
++			     ".section .altinstr_replacement,\"a\"\n"
+ 			     "5: movb $1,%0\n"
+ 			     "6:\n"
+ 			     ".previous\n"
+diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
+index b90e5df..b462c91 100644
+--- a/arch/x86/include/asm/desc.h
++++ b/arch/x86/include/asm/desc.h
+@@ -4,6 +4,7 @@
+ #include <asm/desc_defs.h>
+ #include <asm/ldt.h>
+ #include <asm/mmu.h>
++#include <asm/pgtable.h>
+ 
+ #include <linux/smp.h>
+ #include <linux/percpu.h>
+@@ -17,6 +18,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct \
user_desc *in + 
+ 	desc->type		= (info->read_exec_only ^ 1) << 1;
+ 	desc->type	       |= info->contents << 2;
++	desc->type	       |= info->seg_not_present ^ 1;
+ 
+ 	desc->s			= 1;
+ 	desc->dpl		= 0x3;
+@@ -35,19 +37,14 @@ static inline void fill_ldt(struct desc_struct *desc, const \
struct user_desc *in + }
+ 
+ extern struct desc_ptr idt_descr;
+-extern gate_desc idt_table[];
+-extern struct desc_ptr debug_idt_descr;
+-extern gate_desc debug_idt_table[];
+-
+-struct gdt_page {
+-	struct desc_struct gdt[GDT_ENTRIES];
+-} __attribute__((aligned(PAGE_SIZE)));
+-
+-DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
++extern gate_desc idt_table[IDT_ENTRIES];
++extern const struct desc_ptr debug_idt_descr;
++extern gate_desc debug_idt_table[IDT_ENTRIES];
+ 
++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct \
desc_struct)]; + static inline struct desc_struct *get_cpu_gdt_table(unsigned int \
cpu) + {
+-	return per_cpu(gdt_page, cpu).gdt;
++	return cpu_gdt_table[cpu];
+ }
+ 
+ #ifdef CONFIG_X86_64
+@@ -72,8 +69,14 @@ static inline void pack_gate(gate_desc *gate, unsigned char type,
+ 			     unsigned long base, unsigned dpl, unsigned flags,
+ 			     unsigned short seg)
+ {
+-	gate->a = (seg << 16) | (base & 0xffff);
+-	gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8);
++	gate->gate.offset_low	= base;
++	gate->gate.seg		= seg;
++	gate->gate.reserved	= 0;
++	gate->gate.type		= type;
++	gate->gate.s		= 0;
++	gate->gate.dpl		= dpl;
++	gate->gate.p		= 1;
++	gate->gate.offset_high	= base >> 16;
+ }
+ 
+ #endif
+@@ -118,12 +121,16 @@ static inline void paravirt_free_ldt(struct desc_struct *ldt, \
unsigned entries) + 
+ static inline void native_write_idt_entry(gate_desc *idt, int entry, const \
gate_desc *gate) + {
++	pax_open_kernel();
+ 	memcpy(&idt[entry], gate, sizeof(*gate));
++	pax_close_kernel();
+ }
+ 
+ static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, const \
void *desc) + {
++	pax_open_kernel();
+ 	memcpy(&ldt[entry], desc, 8);
++	pax_close_kernel();
+ }
+ 
+ static inline void
+@@ -137,7 +144,9 @@ native_write_gdt_entry(struct desc_struct *gdt, int entry, const \
void *desc, int + 	default:	size = sizeof(*gdt);		break;
+ 	}
+ 
++	pax_open_kernel();
+ 	memcpy(&gdt[entry], desc, size);
++	pax_close_kernel();
+ }
+ 
+ static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
+@@ -210,7 +219,9 @@ static inline void native_set_ldt(const void *addr, unsigned int \
entries) + 
+ static inline void native_load_tr_desc(void)
+ {
++	pax_open_kernel();
+ 	asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
++	pax_close_kernel();
+ }
+ 
+ static inline void native_load_gdt(const struct desc_ptr *dtr)
+@@ -247,8 +258,10 @@ static inline void native_load_tls(struct thread_struct *t, \
unsigned int cpu) + 	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+ 	unsigned int i;
+ 
++	pax_open_kernel();
+ 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
+ 		gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
++	pax_close_kernel();
+ }
+ 
+ #define _LDT_empty(info)				\
+@@ -287,7 +300,7 @@ static inline void load_LDT(mm_context_t *pc)
+ 	preempt_enable();
+ }
+ 
+-static inline unsigned long get_desc_base(const struct desc_struct *desc)
++static inline unsigned long __intentional_overflow(-1) get_desc_base(const struct \
desc_struct *desc) + {
+ 	return (unsigned)(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));
+ }
+@@ -311,7 +324,7 @@ static inline void set_desc_limit(struct desc_struct *desc, \
unsigned long limit) + }
+ 
+ #ifdef CONFIG_X86_64
+-static inline void set_nmi_gate(int gate, void *addr)
++static inline void set_nmi_gate(int gate, const void *addr)
+ {
+ 	gate_desc s;
+ 
+@@ -321,8 +334,8 @@ static inline void set_nmi_gate(int gate, void *addr)
+ #endif
+ 
+ #ifdef CONFIG_TRACING
+-extern struct desc_ptr trace_idt_descr;
+-extern gate_desc trace_idt_table[];
++extern const struct desc_ptr trace_idt_descr;
++extern gate_desc trace_idt_table[IDT_ENTRIES];
+ static inline void write_trace_idt_entry(int entry, const gate_desc *gate)
+ {
+ 	write_idt_entry(trace_idt_table, entry, gate);
+@@ -333,7 +346,7 @@ static inline void write_trace_idt_entry(int entry, const \
gate_desc *gate) + }
+ #endif
+ 
+-static inline void _set_gate(int gate, unsigned type, void *addr,
++static inline void _set_gate(int gate, unsigned type, const void *addr,
+ 			     unsigned dpl, unsigned ist, unsigned seg)
+ {
+ 	gate_desc s;
+@@ -353,7 +366,7 @@ static inline void _set_gate(int gate, unsigned type, void \
*addr, +  * Pentium F0 0F bugfix can have resulted in the mapped
+  * IDT being write-protected.
+  */
+-static inline void set_intr_gate(unsigned int n, void *addr)
++static inline void set_intr_gate(unsigned int n, const void *addr)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
+@@ -410,19 +423,19 @@ static inline void __alloc_intr_gate(unsigned int n, void \
*addr) + /*
+  * This routine sets up an interrupt gate at directory privilege level 3.
+  */
+-static inline void set_system_intr_gate(unsigned int n, void *addr)
++static inline void set_system_intr_gate(unsigned int n, const void *addr)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_INTERRUPT, addr, 0x3, 0, __KERNEL_CS);
+ }
+ 
+-static inline void set_system_trap_gate(unsigned int n, void *addr)
++static inline void set_system_trap_gate(unsigned int n, const void *addr)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_TRAP, addr, 0x3, 0, __KERNEL_CS);
+ }
+ 
+-static inline void set_trap_gate(unsigned int n, void *addr)
++static inline void set_trap_gate(unsigned int n, const void *addr)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_TRAP, addr, 0, 0, __KERNEL_CS);
+@@ -431,16 +444,16 @@ static inline void set_trap_gate(unsigned int n, void *addr)
+ static inline void set_task_gate(unsigned int n, unsigned int gdt_entry)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+-	_set_gate(n, GATE_TASK, (void *)0, 0, 0, (gdt_entry<<3));
++	_set_gate(n, GATE_TASK, (const void *)0, 0, 0, (gdt_entry<<3));
+ }
+ 
+-static inline void set_intr_gate_ist(int n, void *addr, unsigned ist)
++static inline void set_intr_gate_ist(int n, const void *addr, unsigned ist)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_INTERRUPT, addr, 0, ist, __KERNEL_CS);
+ }
+ 
+-static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
++static inline void set_system_intr_gate_ist(int n, const void *addr, unsigned ist)
+ {
+ 	BUG_ON((unsigned)n > 0xFF);
+ 	_set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
+@@ -512,4 +525,17 @@ static inline void load_current_idt(void)
+ 	else
+ 		load_idt((const struct desc_ptr *)&idt_descr);
+ }
++
++#ifdef CONFIG_X86_32
++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
++{
++	struct desc_struct d;
++
++	if (likely(limit))
++		limit = (limit - 1UL) >> PAGE_SHIFT;
++	pack_descriptor(&d, base, limit, 0xFB, 0xC);
++	write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, \
DESCTYPE_S); ++}
++#endif
++
+ #endif /* _ASM_X86_DESC_H */
+diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
+index 278441f..b95a174 100644
+--- a/arch/x86/include/asm/desc_defs.h
++++ b/arch/x86/include/asm/desc_defs.h
+@@ -31,6 +31,12 @@ struct desc_struct {
+ 			unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
+ 			unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
+ 		};
++		struct {
++			u16 offset_low;
++			u16 seg;
++			unsigned reserved: 8, type: 4, s: 1, dpl: 2, p: 1;
++			unsigned offset_high: 16;
++		} gate;
+ 	};
+ } __attribute__((packed));
+ 
+diff --git a/arch/x86/include/asm/div64.h b/arch/x86/include/asm/div64.h
+index ced283a..ffe04cc 100644
+--- a/arch/x86/include/asm/div64.h
++++ b/arch/x86/include/asm/div64.h
+@@ -39,7 +39,7 @@
+ 	__mod;							\
+ })
+ 
+-static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
++static inline u64 __intentional_overflow(-1) div_u64_rem(u64 dividend, u32 divisor, \
u32 *remainder) + {
+ 	union {
+ 		u64 v64;
+diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
+index 9c999c1..3860cb8 100644
+--- a/arch/x86/include/asm/elf.h
++++ b/arch/x86/include/asm/elf.h
+@@ -243,7 +243,25 @@ extern int force_personality32;
+    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.  */
+ 
++#ifdef CONFIG_PAX_SEGMEXEC
++#define ELF_ET_DYN_BASE		((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? \
SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2) ++#else
+ #define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
++#endif
++
++#ifdef CONFIG_PAX_ASLR
++#ifdef CONFIG_X86_32
++#define PAX_ELF_ET_DYN_BASE	0x10000000UL
++
++#define PAX_DELTA_MMAP_LEN	(current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
++#define PAX_DELTA_STACK_LEN	(current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
++#else
++#define PAX_ELF_ET_DYN_BASE	0x400000UL
++
++#define PAX_DELTA_MMAP_LEN	((test_thread_flag(TIF_ADDR32)) ? 16 : \
TASK_SIZE_MAX_SHIFT - PAGE_SHIFT - 3) ++#define \
PAX_DELTA_STACK_LEN	((test_thread_flag(TIF_ADDR32)) ? 16 : TASK_SIZE_MAX_SHIFT - \
PAGE_SHIFT - 3) ++#endif
++#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,
+@@ -296,16 +314,12 @@ do {									\
+ 
+ #define ARCH_DLINFO							\
+ do {									\
+-	if (vdso_enabled)						\
+-		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
+-			    (unsigned long)current->mm->context.vdso);	\
++	NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);	\
+ } while (0)
+ 
+ #define ARCH_DLINFO_X32							\
+ do {									\
+-	if (vdso_enabled)						\
+-		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
+-			    (unsigned long)current->mm->context.vdso);	\
++	NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);	\
+ } while (0)
+ 
+ #define AT_SYSINFO		32
+@@ -320,7 +334,7 @@ else									\
+ 
+ #endif /* !CONFIG_X86_32 */
+ 
+-#define VDSO_CURRENT_BASE	((unsigned long)current->mm->context.vdso)
++#define VDSO_CURRENT_BASE	(current->mm->context.vdso)
+ 
+ #define VDSO_ENTRY							\
+ 	((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
+@@ -336,9 +350,6 @@ extern int x32_setup_additional_pages(struct linux_binprm *bprm,
+ extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
+ #define compat_arch_setup_additional_pages	syscall32_setup_pages
+ 
+-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+-#define arch_randomize_brk arch_randomize_brk
+-
+ /*
+  * True on X86_32 or when emulating IA32 on X86_64
+  */
+diff --git a/arch/x86/include/asm/emergency-restart.h \
b/arch/x86/include/asm/emergency-restart.h +index 77a99ac..39ff7f5 100644
+--- a/arch/x86/include/asm/emergency-restart.h
++++ b/arch/x86/include/asm/emergency-restart.h
+@@ -1,6 +1,6 @@
+ #ifndef _ASM_X86_EMERGENCY_RESTART_H
+ #define _ASM_X86_EMERGENCY_RESTART_H
+ 
+-extern void machine_emergency_restart(void);
++extern void machine_emergency_restart(void) __noreturn;
+ 
+ #endif /* _ASM_X86_EMERGENCY_RESTART_H */
+diff --git a/arch/x86/include/asm/fpu-internal.h \
b/arch/x86/include/asm/fpu-internal.h +index 4d0bda7..221da4d 100644
+--- a/arch/x86/include/asm/fpu-internal.h
++++ b/arch/x86/include/asm/fpu-internal.h
+@@ -124,8 +124,11 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
+ #define user_insn(insn, output, input...)				\
+ ({									\
+ 	int err;							\
++	pax_open_userland();						\
+ 	asm volatile(ASM_STAC "\n"					\
+-		     "1:" #insn "\n\t"					\
++		     "1:"						\
++		     __copyuser_seg					\
++		     #insn "\n\t"					\
+ 		     "2: " ASM_CLAC "\n"				\
+ 		     ".section .fixup,\"ax\"\n"				\
+ 		     "3:  movl $-1,%[err]\n"				\
+@@ -134,6 +137,7 @@ static inline void sanitize_i387_state(struct task_struct *tsk)
+ 		     _ASM_EXTABLE(1b, 3b)				\
+ 		     : [err] "=r" (err), output				\
+ 		     : "0"(0), input);					\
++	pax_close_userland();						\
+ 	err;								\
+ })
+ 
+@@ -298,7 +302,7 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
+ 		"emms\n\t"		/* clear stack tags */
+ 		"fildl %P[addr]",	/* set F?P to defined value */
+ 		X86_FEATURE_FXSAVE_LEAK,
+-		[addr] "m" (tsk->thread.fpu.has_fpu));
++		[addr] "m" (init_tss[raw_smp_processor_id()].x86_tss.sp0));
+ 
+ 	return fpu_restore_checking(&tsk->thread.fpu);
+ }
+diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h
+index be27ba1..04a8801 100644
+--- a/arch/x86/include/asm/futex.h
++++ b/arch/x86/include/asm/futex.h
+@@ -12,6 +12,7 @@
+ #include <asm/smap.h>
+ 
+ #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg)	\
++	typecheck(u32 __user *, uaddr);				\
+ 	asm volatile("\t" ASM_STAC "\n"				\
+ 		     "1:\t" insn "\n"				\
+ 		     "2:\t" ASM_CLAC "\n"			\
+@@ -20,15 +21,16 @@
+ 		     "\tjmp\t2b\n"				\
+ 		     "\t.previous\n"				\
+ 		     _ASM_EXTABLE(1b, 3b)			\
+-		     : "=r" (oldval), "=r" (ret), "+m" (*uaddr)	\
++		     : "=r" (oldval), "=r" (ret), "+m" (*(u32 __user *)____m(uaddr))	\
+ 		     : "i" (-EFAULT), "0" (oparg), "1" (0))
+ 
+ #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg)	\
++	typecheck(u32 __user *, uaddr);				\
+ 	asm volatile("\t" ASM_STAC "\n"				\
+ 		     "1:\tmovl	%2, %0\n"			\
+ 		     "\tmovl\t%0, %3\n"				\
+ 		     "\t" insn "\n"				\
+-		     "2:\t" LOCK_PREFIX "cmpxchgl %3, %2\n"	\
++		     "2:\t" LOCK_PREFIX __copyuser_seg"cmpxchgl %3, %2\n"	\
+ 		     "\tjnz\t1b\n"				\
+ 		     "3:\t" ASM_CLAC "\n"			\
+ 		     "\t.section .fixup,\"ax\"\n"		\
+@@ -38,7 +40,7 @@
+ 		     _ASM_EXTABLE(1b, 4b)			\
+ 		     _ASM_EXTABLE(2b, 4b)			\
+ 		     : "=&a" (oldval), "=&r" (ret),		\
+-		       "+m" (*uaddr), "=&r" (tem)		\
++		       "+m" (*(u32 __user *)____m(uaddr)), "=&r" (tem)	\
+ 		     : "r" (oparg), "i" (-EFAULT), "1" (0))
+ 
+ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
+@@ -57,12 +59,13 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 \
__user *uaddr) + 
+ 	pagefault_disable();
+ 
++	pax_open_userland();
+ 	switch (op) {
+ 	case FUTEX_OP_SET:
+-		__futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
++		__futex_atomic_op1(__copyuser_seg"xchgl %0, %2", ret, oldval, uaddr, oparg);
+ 		break;
+ 	case FUTEX_OP_ADD:
+-		__futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, oldval,
++		__futex_atomic_op1(LOCK_PREFIX __copyuser_seg"xaddl %0, %2", ret, oldval,
+ 				   uaddr, oparg);
+ 		break;
+ 	case FUTEX_OP_OR:
+@@ -77,6 +80,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 \
__user *uaddr) + 	default:
+ 		ret = -ENOSYS;
+ 	}
++	pax_close_userland();
+ 
+ 	pagefault_enable();
+ 
+@@ -115,18 +119,20 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 \
__user *uaddr, + 	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ 		return -EFAULT;
+ 
++	pax_open_userland();
+ 	asm volatile("\t" ASM_STAC "\n"
+-		     "1:\t" LOCK_PREFIX "cmpxchgl %4, %2\n"
++		     "1:\t" LOCK_PREFIX __copyuser_seg"cmpxchgl %4, %2\n"
+ 		     "2:\t" ASM_CLAC "\n"
+ 		     "\t.section .fixup, \"ax\"\n"
+ 		     "3:\tmov     %3, %0\n"
+ 		     "\tjmp     2b\n"
+ 		     "\t.previous\n"
+ 		     _ASM_EXTABLE(1b, 3b)
+-		     : "+r" (ret), "=a" (oldval), "+m" (*uaddr)
++		     : "+r" (ret), "=a" (oldval), "+m" (*(u32 __user *)____m(uaddr))
+ 		     : "i" (-EFAULT), "r" (newval), "1" (oldval)
+ 		     : "memory"
+ 	);
++	pax_close_userland();
+ 
+ 	*uval = oldval;
+ 	return ret;
+diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
+index e4ac559..c1c0c87 100644
+--- a/arch/x86/include/asm/hw_irq.h
++++ b/arch/x86/include/asm/hw_irq.h
+@@ -165,8 +165,8 @@ extern void setup_ioapic_dest(void);
+ extern void enable_IO_APIC(void);
+ 
+ /* Statistics */
+-extern atomic_t irq_err_count;
+-extern atomic_t irq_mis_count;
++extern atomic_unchecked_t irq_err_count;
++extern atomic_unchecked_t irq_mis_count;
+ 
+ /* EISA */
+ extern void eisa_set_level_irq(unsigned int irq);
+diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
+index a203659..9889f1c 100644
+--- a/arch/x86/include/asm/i8259.h
++++ b/arch/x86/include/asm/i8259.h
+@@ -62,7 +62,7 @@ struct legacy_pic {
+ 	void (*init)(int auto_eoi);
+ 	int (*irq_pending)(unsigned int irq);
+ 	void (*make_irq)(unsigned int irq);
+-};
++} __do_const;
+ 
+ extern struct legacy_pic *legacy_pic;
+ extern struct legacy_pic null_legacy_pic;
+diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
+index 34f69cb..6d95446 100644
+--- a/arch/x86/include/asm/io.h
++++ b/arch/x86/include/asm/io.h
+@@ -51,12 +51,12 @@ static inline void name(type val, volatile void __iomem *addr) \
+ "m" (*(volatile type __force *)addr) barrier); }
+ 
+ build_mmio_read(readb, "b", unsigned char, "=q", :"memory")
+-build_mmio_read(readw, "w", unsigned short, "=r", :"memory")
+-build_mmio_read(readl, "l", unsigned int, "=r", :"memory")
++build_mmio_read(__intentional_overflow(-1) readw, "w", unsigned short, "=r", \
:"memory") ++build_mmio_read(__intentional_overflow(-1) readl, "l", unsigned int, \
"=r", :"memory") + 
+ build_mmio_read(__readb, "b", unsigned char, "=q", )
+-build_mmio_read(__readw, "w", unsigned short, "=r", )
+-build_mmio_read(__readl, "l", unsigned int, "=r", )
++build_mmio_read(__intentional_overflow(-1) __readw, "w", unsigned short, "=r", )
++build_mmio_read(__intentional_overflow(-1) __readl, "l", unsigned int, "=r", )
+ 
+ build_mmio_write(writeb, "b", unsigned char, "q", :"memory")
+ build_mmio_write(writew, "w", unsigned short, "r", :"memory")
+@@ -184,7 +184,7 @@ static inline void __iomem *ioremap(resource_size_t offset, \
unsigned long size) + 	return ioremap_nocache(offset, size);
+ }
+ 
+-extern void iounmap(volatile void __iomem *addr);
++extern void iounmap(const volatile void __iomem *addr);
+ 
+ extern void set_iounmap_nonlazy(void);
+ 
+@@ -194,6 +194,17 @@ extern void set_iounmap_nonlazy(void);
+ 
+ #include <linux/vmalloc.h>
+ 
++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
++static inline int valid_phys_addr_range(unsigned long addr, size_t count)
++{
++	return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1ULL << \
(boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0; ++}
++
++static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
++{
++	return (pfn + (count >> PAGE_SHIFT)) < (1ULL << (boot_cpu_data.x86_phys_bits - \
PAGE_SHIFT)) ? 1 : 0; ++}
++
+ /*
+  * Convert a virtual cached pointer to an uncached pointer
+  */
+diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
+index bba3cf8..06bc8da 100644
+--- a/arch/x86/include/asm/irqflags.h
++++ b/arch/x86/include/asm/irqflags.h
+@@ -141,6 +141,11 @@ static inline notrace unsigned long arch_local_irq_save(void)
+ 	sti;					\
+ 	sysexit
+ 
++#define GET_CR0_INTO_RDI		mov %cr0, %rdi
++#define SET_RDI_INTO_CR0		mov %rdi, %cr0
++#define GET_CR3_INTO_RDI		mov %cr3, %rdi
++#define SET_RDI_INTO_CR3		mov %rdi, %cr3
++
+ #else
+ #define INTERRUPT_RETURN		iret
+ #define ENABLE_INTERRUPTS_SYSEXIT	sti; sysexit
+diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
+index 5a6d287..f815789 100644
+--- a/arch/x86/include/asm/kprobes.h
++++ b/arch/x86/include/asm/kprobes.h
+@@ -38,13 +38,8 @@ typedef u8 kprobe_opcode_t;
+ #define RELATIVEJUMP_SIZE 5
+ #define RELATIVECALL_OPCODE 0xe8
+ #define RELATIVE_ADDR_SIZE 4
+-#define MAX_STACK_SIZE 64
+-#define MIN_STACK_SIZE(ADDR)					       \
+-	(((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
+-			      THREAD_SIZE - (unsigned long)(ADDR)))    \
+-	 ? (MAX_STACK_SIZE)					       \
+-	 : (((unsigned long)current_thread_info()) +		       \
+-	    THREAD_SIZE - (unsigned long)(ADDR)))
++#define MAX_STACK_SIZE 64UL
++#define MIN_STACK_SIZE(ADDR)	min(MAX_STACK_SIZE, current->thread.sp0 - (unsigned \
long)(ADDR)) + 
+ #define flush_insn_slot(p)	do { } while (0)
+ 
+diff --git a/arch/x86/include/asm/local.h b/arch/x86/include/asm/local.h
+index 2d89e39..baee879 100644
+--- a/arch/x86/include/asm/local.h
++++ b/arch/x86/include/asm/local.h
+@@ -10,33 +10,97 @@ 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))
+ 
+ static inline void local_inc(local_t *l)
+ {
+-	asm volatile(_ASM_INC "%0"
++	asm volatile(_ASM_INC "%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_DEC "%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (l->a.counter));
++}
++
++static inline void local_inc_unchecked(local_unchecked_t *l)
++{
++	asm volatile(_ASM_INC "%0\n"
+ 		     : "+m" (l->a.counter));
+ }
+ 
+ static inline void local_dec(local_t *l)
+ {
+-	asm volatile(_ASM_DEC "%0"
++	asm volatile(_ASM_DEC "%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_INC "%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (l->a.counter));
++}
++
++static inline void local_dec_unchecked(local_unchecked_t *l)
++{
++	asm volatile(_ASM_DEC "%0\n"
+ 		     : "+m" (l->a.counter));
+ }
+ 
+ static inline void local_add(long i, local_t *l)
+ {
+-	asm volatile(_ASM_ADD "%1,%0"
++	asm volatile(_ASM_ADD "%1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_SUB "%1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (l->a.counter)
++		     : "ir" (i));
++}
++
++static inline void local_add_unchecked(long i, local_unchecked_t *l)
++{
++	asm volatile(_ASM_ADD "%1,%0\n"
+ 		     : "+m" (l->a.counter)
+ 		     : "ir" (i));
+ }
+ 
+ static inline void local_sub(long i, local_t *l)
+ {
+-	asm volatile(_ASM_SUB "%1,%0"
++	asm volatile(_ASM_SUB "%1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_ADD "%1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+m" (l->a.counter)
++		     : "ir" (i));
++}
++
++static inline void local_sub_unchecked(long i, local_unchecked_t *l)
++{
++	asm volatile(_ASM_SUB "%1,%0\n"
+ 		     : "+m" (l->a.counter)
+ 		     : "ir" (i));
+ }
+@@ -54,7 +118,16 @@ static inline int local_sub_and_test(long i, local_t *l)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(_ASM_SUB "%2,%0; sete %1"
++	asm volatile(_ASM_SUB "%2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_ADD "%2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "+m" (l->a.counter), "=qm" (c)
+ 		     : "ir" (i) : "memory");
+ 	return c;
+@@ -72,7 +145,16 @@ static inline int local_dec_and_test(local_t *l)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(_ASM_DEC "%0; sete %1"
++	asm volatile(_ASM_DEC "%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_INC "%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "+m" (l->a.counter), "=qm" (c)
+ 		     : : "memory");
+ 	return c != 0;
+@@ -90,7 +172,16 @@ static inline int local_inc_and_test(local_t *l)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(_ASM_INC "%0; sete %1"
++	asm volatile(_ASM_INC "%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_DEC "%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sete %1\n"
+ 		     : "+m" (l->a.counter), "=qm" (c)
+ 		     : : "memory");
+ 	return c != 0;
+@@ -109,7 +200,16 @@ static inline int local_add_negative(long i, local_t *l)
+ {
+ 	unsigned char c;
+ 
+-	asm volatile(_ASM_ADD "%2,%0; sets %1"
++	asm volatile(_ASM_ADD "%2,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_SUB "%2,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     "sets %1\n"
+ 		     : "+m" (l->a.counter), "=qm" (c)
+ 		     : "ir" (i) : "memory");
+ 	return c;
+@@ -125,6 +225,30 @@ static inline int local_add_negative(long i, local_t *l)
+ static inline long local_add_return(long i, local_t *l)
+ {
+ 	long __i = i;
++	asm volatile(_ASM_XADD "%0, %1\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     _ASM_MOV "%0,%1\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
++		     : "+r" (i), "+m" (l->a.counter)
++		     : : "memory");
++	return i + __i;
++}
++
++/**
++ * local_add_return_unchecked - add and return
++ * @i: integer value to add
++ * @l: pointer to type local_unchecked_t
++ *
++ * Atomically adds @i to @l and returns @i + @l
++ */
++static inline long local_add_return_unchecked(long i, local_unchecked_t *l)
++{
++	long __i = i;
+ 	asm volatile(_ASM_XADD "%0, %1;"
+ 		     : "+r" (i), "+m" (l->a.counter)
+ 		     : : "memory");
+@@ -141,6 +265,8 @@ static inline long local_sub_return(long i, 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)))
+ /* Always has a lock prefix */
+ #define local_xchg(l, n) (xchg(&((l)->a.counter), (n)))
+ 
+diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h
+new file mode 100644
+index 0000000..2bfd3ba
+--- /dev/null
++++ b/arch/x86/include/asm/mman.h
+@@ -0,0 +1,15 @@
++#ifndef _X86_MMAN_H
++#define _X86_MMAN_H
++
++#include <uapi/asm/mman.h>
++
++#ifdef __KERNEL__
++#ifndef __ASSEMBLY__
++#ifdef CONFIG_X86_32
++#define arch_mmap_check	i386_mmap_check
++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags);
++#endif
++#endif
++#endif
++
++#endif /* X86_MMAN_H */
+diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h
+index 5f55e69..e20bfb1 100644
+--- a/arch/x86/include/asm/mmu.h
++++ b/arch/x86/include/asm/mmu.h
+@@ -9,7 +9,7 @@
+  * we put the segment information here.
+  */
+ typedef struct {
+-	void *ldt;
++	struct desc_struct *ldt;
+ 	int size;
+ 
+ #ifdef CONFIG_X86_64
+@@ -18,7 +18,19 @@ typedef struct {
+ #endif
+ 
+ 	struct mutex lock;
+-	void *vdso;
++	unsigned long vdso;
++
++#ifdef CONFIG_X86_32
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++	unsigned long user_cs_base;
++	unsigned long user_cs_limit;
++
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
++	cpumask_t cpu_user_cs_mask;
++#endif
++
++#endif
++#endif
+ } mm_context_t;
+ 
+ #ifdef CONFIG_SMP
+diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
+index be12c53..2124e35 100644
+--- a/arch/x86/include/asm/mmu_context.h
++++ b/arch/x86/include/asm/mmu_context.h
+@@ -24,6 +24,20 @@ void destroy_context(struct mm_struct *mm);
+ 
+ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+ {
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (!(static_cpu_has(X86_FEATURE_PCID))) {
++		unsigned int i;
++		pgd_t *pgd;
++
++		pax_open_kernel();
++		pgd = get_cpu_pgd(smp_processor_id(), kernel);
++		for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
++			set_pgd_batched(pgd+i, native_make_pgd(0));
++		pax_close_kernel();
++	}
++#endif
++
+ #ifdef CONFIG_SMP
+ 	if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+ 		this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
+@@ -34,16 +48,55 @@ static inline void switch_mm(struct mm_struct *prev, struct \
mm_struct *next, + 			     struct task_struct *tsk)
+ {
+ 	unsigned cpu = smp_processor_id();
++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) && (defined(CONFIG_PAX_PAGEEXEC) \
|| defined(CONFIG_PAX_SEGMEXEC)) ++	int tlbstate = TLBSTATE_OK;
++#endif
+ 
+ 	if (likely(prev != next)) {
+ #ifdef CONFIG_SMP
++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || \
defined(CONFIG_PAX_SEGMEXEC)) ++		tlbstate = this_cpu_read(cpu_tlbstate.state);
++#endif
+ 		this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ 		this_cpu_write(cpu_tlbstate.active_mm, next);
+ #endif
+ 		cpumask_set_cpu(cpu, mm_cpumask(next));
+ 
+ 		/* Re-load page tables */
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		pax_open_kernel();
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID))
++			__clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd);
++		else
++#endif
++
++		__clone_user_pgds(get_cpu_pgd(cpu, kernel), next->pgd);
++		__shadow_user_pgds(get_cpu_pgd(cpu, kernel) + USER_PGD_PTRS, next->pgd);
++		pax_close_kernel();
++		BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & \
__PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & \
__PHYSICAL_MASK)); ++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID)) {
++			if (static_cpu_has(X86_FEATURE_INVPCID)) {
++				u64 descriptor[2];
++				descriptor[0] = PCID_USER;
++				asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_CONTEXT) : \
"memory"); ++			} else {
++				write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++				if (static_cpu_has(X86_FEATURE_STRONGUDEREF))
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++				else
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++			}
++		} else
++#endif
++
++			load_cr3(get_cpu_pgd(cpu, kernel));
++#else
+ 		load_cr3(next->pgd);
++#endif
+ 
+ 		/* Stop flush ipis for the previous mm */
+ 		cpumask_clear_cpu(cpu, mm_cpumask(prev));
+@@ -51,9 +104,63 @@ static inline void switch_mm(struct mm_struct *prev, struct \
mm_struct *next, + 		/* Load the LDT, if the LDT is different: */
+ 		if (unlikely(prev->context.ldt != next->context.ldt))
+ 			load_LDT_nolock(&next->context);
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
++		if (!(__supported_pte_mask & _PAGE_NX)) {
++			smp_mb__before_clear_bit();
++			cpu_clear(cpu, prev->context.cpu_user_cs_mask);
++			smp_mb__after_clear_bit();
++			cpu_set(cpu, next->context.cpu_user_cs_mask);
++		}
++#endif
++
++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || \
defined(CONFIG_PAX_SEGMEXEC)) ++		if (unlikely(prev->context.user_cs_base != \
next->context.user_cs_base || ++			     prev->context.user_cs_limit != \
next->context.user_cs_limit)) ++			set_user_cs(next->context.user_cs_base, \
next->context.user_cs_limit, cpu); ++#ifdef CONFIG_SMP
++		else if (unlikely(tlbstate != TLBSTATE_OK))
++			set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
++#endif
++#endif
++
+ 	}
++	else {
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		pax_open_kernel();
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID))
++			__clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd);
++		else
++#endif
++
++		__clone_user_pgds(get_cpu_pgd(cpu, kernel), next->pgd);
++		__shadow_user_pgds(get_cpu_pgd(cpu, kernel) + USER_PGD_PTRS, next->pgd);
++		pax_close_kernel();
++		BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & \
__PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & \
__PHYSICAL_MASK)); ++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (static_cpu_has(X86_FEATURE_PCID)) {
++			if (static_cpu_has(X86_FEATURE_INVPCID)) {
++				u64 descriptor[2];
++				descriptor[0] = PCID_USER;
++				asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_CONTEXT) : \
"memory"); ++			} else {
++				write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++				if (static_cpu_has(X86_FEATURE_STRONGUDEREF))
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++				else
++					write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++			}
++		} else
++#endif
++
++			load_cr3(get_cpu_pgd(cpu, kernel));
++#endif
++
+ #ifdef CONFIG_SMP
+-	  else {
+ 		this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ 		BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
+ 
+@@ -70,11 +177,28 @@ static inline void switch_mm(struct mm_struct *prev, struct \
mm_struct *next, + 			 * tlb flush IPI delivery. We must reload CR3
+ 			 * to make sure to use no freed page tables.
+ 			 */
++
++#ifndef CONFIG_PAX_PER_CPU_PGD
+ 			load_cr3(next->pgd);
++#endif
++
+ 			load_LDT_nolock(&next->context);
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
++			if (!(__supported_pte_mask & _PAGE_NX))
++				cpu_set(cpu, next->context.cpu_user_cs_mask);
++#endif
++
++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_PAGEEXEC) || \
defined(CONFIG_PAX_SEGMEXEC)) ++#ifdef CONFIG_PAX_PAGEEXEC
++			if (!((next->pax_flags & MF_PAX_PAGEEXEC) && (__supported_pte_mask & _PAGE_NX)))
++#endif
++				set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
++#endif
++
+ 		}
++#endif
+ 	}
+-#endif
+ }
+ 
+ #define activate_mm(prev, next)			\
+diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
+index e3b7819..b257c64 100644
+--- a/arch/x86/include/asm/module.h
++++ b/arch/x86/include/asm/module.h
+@@ -5,6 +5,7 @@
+ 
+ #ifdef CONFIG_X86_64
+ /* X86_64 does not define MODULE_PROC_FAMILY */
++#define MODULE_PROC_FAMILY ""
+ #elif defined CONFIG_M486
+ #define MODULE_PROC_FAMILY "486 "
+ #elif defined CONFIG_M586
+@@ -57,8 +58,20 @@
+ #error unknown processor family
+ #endif
+ 
+-#ifdef CONFIG_X86_32
+-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
++#ifdef CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_BTS
++#define MODULE_PAX_KERNEXEC "KERNEXEC_BTS "
++#elif defined(CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR)
++#define MODULE_PAX_KERNEXEC "KERNEXEC_OR "
++#else
++#define MODULE_PAX_KERNEXEC ""
+ #endif
+ 
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++#define MODULE_PAX_UDEREF "UDEREF "
++#else
++#define MODULE_PAX_UDEREF ""
++#endif
++
++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_PAX_KERNEXEC \
MODULE_PAX_UDEREF ++
+ #endif /* _ASM_X86_MODULE_H */
+diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h
+index 86f9301..b365cda 100644
+--- a/arch/x86/include/asm/nmi.h
++++ b/arch/x86/include/asm/nmi.h
+@@ -40,11 +40,11 @@ struct nmiaction {
+ 	nmi_handler_t		handler;
+ 	unsigned long		flags;
+ 	const char		*name;
+-};
++} __do_const;
+ 
+ #define register_nmi_handler(t, fn, fg, n, init...)	\
+ ({							\
+-	static struct nmiaction init fn##_na = {	\
++	static const struct nmiaction init fn##_na = {	\
+ 		.handler = (fn),			\
+ 		.name = (n),				\
+ 		.flags = (fg),				\
+@@ -52,7 +52,7 @@ struct nmiaction {
+ 	__register_nmi_handler((t), &fn##_na);		\
+ })
+ 
+-int __register_nmi_handler(unsigned int, struct nmiaction *);
++int __register_nmi_handler(unsigned int, const struct nmiaction *);
+ 
+ void unregister_nmi_handler(unsigned int, const char *);
+ 
+diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h
+index c878924..21f4889 100644
+--- a/arch/x86/include/asm/page.h
++++ b/arch/x86/include/asm/page.h
+@@ -52,6 +52,7 @@ static inline void copy_user_page(void *to, void *from, unsigned \
long vaddr, + 	__phys_addr_symbol(__phys_reloc_hide((unsigned long)(x)))
+ 
+ #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
++#define __early_va(x)		((void *)((unsigned long)(x)+__START_KERNEL_map - \
phys_base)) + 
+ #define __boot_va(x)		__va(x)
+ #define __boot_pa(x)		__pa(x)
+diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
+index 0f1ddee..e2fc3d1 100644
+--- a/arch/x86/include/asm/page_64.h
++++ b/arch/x86/include/asm/page_64.h
+@@ -7,9 +7,9 @@
+ 
+ /* duplicated to the one in bootmem.h */
+ extern unsigned long max_pfn;
+-extern unsigned long phys_base;
++extern const unsigned long phys_base;
+ 
+-static inline unsigned long __phys_addr_nodebug(unsigned long x)
++static inline unsigned long __intentional_overflow(-1) __phys_addr_nodebug(unsigned \
long x) + {
+ 	unsigned long y = x - __START_KERNEL_map;
+ 
+diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
+index cfdc9ee..3f7b5d6 100644
+--- a/arch/x86/include/asm/paravirt.h
++++ b/arch/x86/include/asm/paravirt.h
+@@ -560,7 +560,7 @@ static inline pmd_t __pmd(pmdval_t val)
+ 	return (pmd_t) { ret };
+ }
+ 
+-static inline pmdval_t pmd_val(pmd_t pmd)
++static inline __intentional_overflow(-1) pmdval_t pmd_val(pmd_t pmd)
+ {
+ 	pmdval_t ret;
+ 
+@@ -626,6 +626,18 @@ static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
+ 			    val);
+ }
+ 
++static inline void set_pgd_batched(pgd_t *pgdp, pgd_t pgd)
++{
++	pgdval_t val = native_pgd_val(pgd);
++
++	if (sizeof(pgdval_t) > sizeof(long))
++		PVOP_VCALL3(pv_mmu_ops.set_pgd_batched, pgdp,
++			    val, (u64)val >> 32);
++	else
++		PVOP_VCALL2(pv_mmu_ops.set_pgd_batched, pgdp,
++			    val);
++}
++
+ static inline void pgd_clear(pgd_t *pgdp)
+ {
+ 	set_pgd(pgdp, __pgd(0));
+@@ -710,6 +722,21 @@ static inline void __set_fixmap(unsigned /* enum \
fixed_addresses */ idx, + 	pv_mmu_ops.set_fixmap(idx, phys, flags);
+ }
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++static inline unsigned long pax_open_kernel(void)
++{
++	return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_open_kernel);
++}
++
++static inline unsigned long pax_close_kernel(void)
++{
++	return PVOP_CALL0(unsigned long, pv_mmu_ops.pax_close_kernel);
++}
++#else
++static inline unsigned long pax_open_kernel(void) { return 0; }
++static inline unsigned long pax_close_kernel(void) { return 0; }
++#endif
++
+ #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
+ 
+ static inline int arch_spin_is_locked(struct arch_spinlock *lock)
+@@ -926,7 +953,7 @@ extern void default_banner(void);
+ 
+ #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 4)
+ #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
+-#define PARA_INDIRECT(addr)	*%cs:addr
++#define PARA_INDIRECT(addr)	*%ss:addr
+ #endif
+ 
+ #define INTERRUPT_RETURN						\
+@@ -1001,6 +1028,21 @@ extern void default_banner(void);
+ 	PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit),	\
+ 		  CLBR_NONE,						\
+ 		  jmp PARA_INDIRECT(pv_cpu_ops+PV_CPU_irq_enable_sysexit))
++
++#define GET_CR0_INTO_RDI				\
++	call PARA_INDIRECT(pv_cpu_ops+PV_CPU_read_cr0);	\
++	mov %rax,%rdi
++
++#define SET_RDI_INTO_CR0				\
++	call PARA_INDIRECT(pv_cpu_ops+PV_CPU_write_cr0)
++
++#define GET_CR3_INTO_RDI				\
++	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_read_cr3);	\
++	mov %rax,%rdi
++
++#define SET_RDI_INTO_CR3				\
++	call PARA_INDIRECT(pv_mmu_ops+PV_MMU_write_cr3)
++
+ #endif	/* CONFIG_X86_32 */
+ 
+ #endif /* __ASSEMBLY__ */
+diff --git a/arch/x86/include/asm/paravirt_types.h \
b/arch/x86/include/asm/paravirt_types.h +index 0db1fca..52310cc 100644
+--- a/arch/x86/include/asm/paravirt_types.h
++++ b/arch/x86/include/asm/paravirt_types.h
+@@ -84,7 +84,7 @@ struct pv_init_ops {
+ 	 */
+ 	unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
+ 			  unsigned long addr, unsigned len);
+-};
++} __no_const;
+ 
+ 
+ struct pv_lazy_ops {
+@@ -98,7 +98,7 @@ struct pv_time_ops {
+ 	unsigned long long (*sched_clock)(void);
+ 	unsigned long long (*steal_clock)(int cpu);
+ 	unsigned long (*get_tsc_khz)(void);
+-};
++} __no_const;
+ 
+ struct pv_cpu_ops {
+ 	/* hooks for various privileged instructions */
+@@ -192,7 +192,7 @@ struct pv_cpu_ops {
+ 
+ 	void (*start_context_switch)(struct task_struct *prev);
+ 	void (*end_context_switch)(struct task_struct *next);
+-};
++} __no_const;
+ 
+ struct pv_irq_ops {
+ 	/*
+@@ -223,7 +223,7 @@ struct pv_apic_ops {
+ 				 unsigned long start_eip,
+ 				 unsigned long start_esp);
+ #endif
+-};
++} __no_const;
+ 
+ struct pv_mmu_ops {
+ 	unsigned long (*read_cr2)(void);
+@@ -313,6 +313,7 @@ struct pv_mmu_ops {
+ 	struct paravirt_callee_save make_pud;
+ 
+ 	void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
++	void (*set_pgd_batched)(pgd_t *pudp, pgd_t pgdval);
+ #endif	/* PAGETABLE_LEVELS == 4 */
+ #endif	/* PAGETABLE_LEVELS >= 3 */
+ 
+@@ -324,6 +325,12 @@ struct pv_mmu_ops {
+ 	   an mfn.  We can tell which is which from the index. */
+ 	void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
+ 			   phys_addr_t phys, pgprot_t flags);
++
++#ifdef CONFIG_PAX_KERNEXEC
++	unsigned long (*pax_open_kernel)(void);
++	unsigned long (*pax_close_kernel)(void);
++#endif
++
+ };
+ 
+ struct arch_spinlock;
+@@ -334,7 +341,7 @@ struct pv_lock_ops {
+ 	void (*spin_lock_flags)(struct arch_spinlock *lock, unsigned long flags);
+ 	int (*spin_trylock)(struct arch_spinlock *lock);
+ 	void (*spin_unlock)(struct arch_spinlock *lock);
+-};
++} __no_const;
+ 
+ /* This contains all the paravirt structures: we get a convenient
+  * number for each function using the offset which we use to indicate
+diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h
+index b4389a4..7024269 100644
+--- a/arch/x86/include/asm/pgalloc.h
++++ b/arch/x86/include/asm/pgalloc.h
+@@ -63,6 +63,13 @@ static inline void pmd_populate_kernel(struct mm_struct *mm,
+ 				       pmd_t *pmd, pte_t *pte)
+ {
+ 	paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
++	set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
++}
++
++static inline void pmd_populate_user(struct mm_struct *mm,
++				       pmd_t *pmd, pte_t *pte)
++{
++	paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
+ 	set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
+ }
+ 
+@@ -99,12 +106,22 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t \
*pmd, + 
+ #ifdef CONFIG_X86_PAE
+ extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pudp, pmd_t \
*pmd) ++{
++	pud_populate(mm, pudp, pmd);
++}
+ #else	/* !CONFIG_X86_PAE */
+ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+ 	paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT);
+ 	set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)));
+ }
++
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t \
*pmd) ++{
++	paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT);
++	set_pud(pud, __pud(_KERNPG_TABLE | __pa(pmd)));
++}
+ #endif	/* CONFIG_X86_PAE */
+ 
+ #if PAGETABLE_LEVELS > 3
+@@ -114,6 +131,12 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t \
*pgd, pud_t *pud) + 	set_pgd(pgd, __pgd(_PAGE_TABLE | __pa(pud)));
+ }
+ 
++static inline void pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pud_t \
*pud) ++{
++	paravirt_alloc_pud(mm, __pa(pud) >> PAGE_SHIFT);
++	set_pgd(pgd, __pgd(_KERNPG_TABLE | __pa(pud)));
++}
++
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+ 	return (pud_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
+diff --git a/arch/x86/include/asm/pgtable-2level.h \
b/arch/x86/include/asm/pgtable-2level.h +index 3bf2dd0..23d2a9f 100644
+--- a/arch/x86/include/asm/pgtable-2level.h
++++ b/arch/x86/include/asm/pgtable-2level.h
+@@ -18,7 +18,9 @@ static inline void native_set_pte(pte_t *ptep , pte_t pte)
+ 
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
+ {
++	pax_open_kernel();
+ 	*pmdp = pmd;
++	pax_close_kernel();
+ }
+ 
+ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
+diff --git a/arch/x86/include/asm/pgtable-3level.h \
b/arch/x86/include/asm/pgtable-3level.h +index 81bb91b..9392125 100644
+--- a/arch/x86/include/asm/pgtable-3level.h
++++ b/arch/x86/include/asm/pgtable-3level.h
+@@ -92,12 +92,16 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
+ 
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
+ {
++	pax_open_kernel();
+ 	set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
++	pax_close_kernel();
+ }
+ 
+ static inline void native_set_pud(pud_t *pudp, pud_t pud)
+ {
++	pax_open_kernel();
+ 	set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
++	pax_close_kernel();
+ }
+ 
+ /*
+diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
+index 1c00631..845f898 100644
+--- a/arch/x86/include/asm/pgtable.h
++++ b/arch/x86/include/asm/pgtable.h
+@@ -44,6 +44,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page);
+ 
+ #ifndef __PAGETABLE_PUD_FOLDED
+ #define set_pgd(pgdp, pgd)		native_set_pgd(pgdp, pgd)
++#define set_pgd_batched(pgdp, pgd)	native_set_pgd_batched(pgdp, pgd)
+ #define pgd_clear(pgd)			native_pgd_clear(pgd)
+ #endif
+ 
+@@ -81,12 +82,51 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page);
+ 
+ #define arch_end_context_switch(prev)	do {} while(0)
+ 
++#define pax_open_kernel()	native_pax_open_kernel()
++#define pax_close_kernel()	native_pax_close_kernel()
+ #endif	/* CONFIG_PARAVIRT */
+ 
++#define  __HAVE_ARCH_PAX_OPEN_KERNEL
++#define  __HAVE_ARCH_PAX_CLOSE_KERNEL
++
++#ifdef CONFIG_PAX_KERNEXEC
++static inline unsigned long native_pax_open_kernel(void)
++{
++	unsigned long cr0;
++
++	preempt_disable();
++	barrier();
++	cr0 = read_cr0() ^ X86_CR0_WP;
++	BUG_ON(cr0 & X86_CR0_WP);
++	write_cr0(cr0);
++	return cr0 ^ X86_CR0_WP;
++}
++
++static inline unsigned long native_pax_close_kernel(void)
++{
++	unsigned long cr0;
++
++	cr0 = read_cr0() ^ X86_CR0_WP;
++	BUG_ON(!(cr0 & X86_CR0_WP));
++	write_cr0(cr0);
++	barrier();
++	preempt_enable_no_resched();
++	return cr0 ^ X86_CR0_WP;
++}
++#else
++static inline unsigned long native_pax_open_kernel(void) { return 0; }
++static inline unsigned long native_pax_close_kernel(void) { return 0; }
++#endif
++
+ /*
+  * The following only work if pte_present() is true.
+  * Undefined behaviour if not..
+  */
++static inline int pte_user(pte_t pte)
++{
++	return pte_val(pte) & _PAGE_USER;
++}
++
+ static inline int pte_dirty(pte_t pte)
+ {
+ 	return pte_flags(pte) & _PAGE_DIRTY;
+@@ -147,6 +187,11 @@ static inline unsigned long pud_pfn(pud_t pud)
+ 	return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT;
+ }
+ 
++static inline unsigned long pgd_pfn(pgd_t pgd)
++{
++	return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT;
++}
++
+ #define pte_page(pte)	pfn_to_page(pte_pfn(pte))
+ 
+ static inline int pmd_large(pmd_t pte)
+@@ -200,9 +245,29 @@ static inline pte_t pte_wrprotect(pte_t pte)
+ 	return pte_clear_flags(pte, _PAGE_RW);
+ }
+ 
++static inline pte_t pte_mkread(pte_t pte)
++{
++	return __pte(pte_val(pte) | _PAGE_USER);
++}
++
+ static inline pte_t pte_mkexec(pte_t pte)
+ {
+-	return pte_clear_flags(pte, _PAGE_NX);
++#ifdef CONFIG_X86_PAE
++	if (__supported_pte_mask & _PAGE_NX)
++		return pte_clear_flags(pte, _PAGE_NX);
++	else
++#endif
++		return pte_set_flags(pte, _PAGE_USER);
++}
++
++static inline pte_t pte_exprotect(pte_t pte)
++{
++#ifdef CONFIG_X86_PAE
++	if (__supported_pte_mask & _PAGE_NX)
++		return pte_set_flags(pte, _PAGE_NX);
++	else
++#endif
++		return pte_clear_flags(pte, _PAGE_USER);
+ }
+ 
+ static inline pte_t pte_mkdirty(pte_t pte)
+@@ -444,6 +509,16 @@ pte_t *populate_extra_pte(unsigned long vaddr);
+ #endif
+ 
+ #ifndef __ASSEMBLY__
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++extern pgd_t cpu_pgd[NR_CPUS][2][PTRS_PER_PGD];
++enum cpu_pgd_type {kernel = 0, user = 1};
++static inline pgd_t *get_cpu_pgd(unsigned int cpu, enum cpu_pgd_type type)
++{
++	return cpu_pgd[cpu][type];
++}
++#endif
++
+ #include <linux/mm_types.h>
+ #include <linux/log2.h>
+ 
+@@ -576,7 +651,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
+  * Currently stuck as a macro due to indirect forward reference to
+  * linux/mmzone.h's __section_mem_map_addr() definition:
+  */
+-#define pud_page(pud)		pfn_to_page(pud_val(pud) >> PAGE_SHIFT)
++#define pud_page(pud)		pfn_to_page((pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT)
+ 
+ /* Find an entry in the second-level page table.. */
+ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
+@@ -616,7 +691,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
+  * Currently stuck as a macro due to indirect forward reference to
+  * linux/mmzone.h's __section_mem_map_addr() definition:
+  */
+-#define pgd_page(pgd)		pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
++#define pgd_page(pgd)		pfn_to_page((pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT)
+ 
+ /* to find an entry in a page-table-directory. */
+ static inline unsigned long pud_index(unsigned long address)
+@@ -631,7 +706,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long \
address) + 
+ static inline int pgd_bad(pgd_t pgd)
+ {
+-	return (pgd_flags(pgd) & ~_PAGE_USER) != _KERNPG_TABLE;
++	return (pgd_flags(pgd) & ~(_PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
+ }
+ 
+ static inline int pgd_none(pgd_t pgd)
+@@ -654,7 +729,12 @@ static inline int pgd_none(pgd_t pgd)
+  * pgd_offset() returns a (pgd_t *)
+  * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+  */
+-#define pgd_offset(mm, address) ((mm)->pgd + pgd_index((address)))
++#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++#define pgd_offset_cpu(cpu, type, address) (get_cpu_pgd(cpu, type) + \
pgd_index(address)) ++#endif
++
+ /*
+  * a shortcut which implies the use of the kernel's pgd, instead
+  * of a process's
+@@ -665,6 +745,23 @@ static inline int pgd_none(pgd_t pgd)
+ #define KERNEL_PGD_BOUNDARY	pgd_index(PAGE_OFFSET)
+ #define KERNEL_PGD_PTRS		(PTRS_PER_PGD - KERNEL_PGD_BOUNDARY)
+ 
++#ifdef CONFIG_X86_32
++#define USER_PGD_PTRS		KERNEL_PGD_BOUNDARY
++#else
++#define TASK_SIZE_MAX_SHIFT CONFIG_TASK_SIZE_MAX_SHIFT
++#define USER_PGD_PTRS		(_AC(1,UL) << (TASK_SIZE_MAX_SHIFT - PGDIR_SHIFT))
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++#ifdef __ASSEMBLY__
++#define pax_user_shadow_base	pax_user_shadow_base(%rip)
++#else
++extern unsigned long pax_user_shadow_base;
++extern pgdval_t clone_pgd_mask;
++#endif
++#endif
++
++#endif
++
+ #ifndef __ASSEMBLY__
+ 
+ extern int direct_gbpages;
+@@ -831,11 +928,24 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
+  * dst and src can be on the same page, but the range must not overlap,
+  * and must not cross a page boundary.
+  */
+-static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
++static inline void clone_pgd_range(pgd_t *dst, const pgd_t *src, int count)
+ {
+-       memcpy(dst, src, count * sizeof(pgd_t));
++	pax_open_kernel();
++	while (count--)
++		*dst++ = *src++;
++	pax_close_kernel();
+ }
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++extern void __clone_user_pgds(pgd_t *dst, const pgd_t *src);
++#endif
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++extern void __shadow_user_pgds(pgd_t *dst, const pgd_t *src);
++#else
++static inline void __shadow_user_pgds(pgd_t *dst, const pgd_t *src) {}
++#endif
++
+ #define PTE_SHIFT ilog2(PTRS_PER_PTE)
+ static inline int page_level_shift(enum pg_level level)
+ {
+diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
+index 9ee3221..b979c6b 100644
+--- a/arch/x86/include/asm/pgtable_32.h
++++ b/arch/x86/include/asm/pgtable_32.h
+@@ -25,9 +25,6 @@
+ struct mm_struct;
+ struct vm_area_struct;
+ 
+-extern pgd_t swapper_pg_dir[1024];
+-extern pgd_t initial_page_table[1024];
+-
+ static inline void pgtable_cache_init(void) { }
+ static inline void check_pgt_cache(void) { }
+ void paging_init(void);
+@@ -48,6 +45,12 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
+ # include <asm/pgtable-2level.h>
+ #endif
+ 
++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
++extern pgd_t initial_page_table[PTRS_PER_PGD];
++#ifdef CONFIG_X86_PAE
++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
++#endif
++
+ #if defined(CONFIG_HIGHPTE)
+ #define pte_offset_map(dir, address)					\
+ 	((pte_t *)kmap_atomic(pmd_page(*(dir))) +		\
+@@ -62,12 +65,17 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
+ /* Clear a kernel PTE and flush it from the TLB */
+ #define kpte_clear_flush(ptep, vaddr)		\
+ do {						\
++	pax_open_kernel();			\
+ 	pte_clear(&init_mm, (vaddr), (ptep));	\
++	pax_close_kernel();			\
+ 	__flush_tlb_one((vaddr));		\
+ } while (0)
+ 
+ #endif /* !__ASSEMBLY__ */
+ 
++#define HAVE_ARCH_UNMAPPED_AREA
++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
++
+ /*
+  * kern_addr_valid() is (1) for FLATMEM and (0) for
+  * SPARSEMEM and DISCONTIGMEM
+diff --git a/arch/x86/include/asm/pgtable_32_types.h \
b/arch/x86/include/asm/pgtable_32_types.h +index ed5903b..c7fe163 100644
+--- a/arch/x86/include/asm/pgtable_32_types.h
++++ b/arch/x86/include/asm/pgtable_32_types.h
+@@ -8,7 +8,7 @@
+  */
+ #ifdef CONFIG_X86_PAE
+ # include <asm/pgtable-3level_types.h>
+-# define PMD_SIZE	(1UL << PMD_SHIFT)
++# define PMD_SIZE	(_AC(1, UL) << PMD_SHIFT)
+ # define PMD_MASK	(~(PMD_SIZE - 1))
+ #else
+ # include <asm/pgtable-2level_types.h>
+@@ -46,6 +46,19 @@ extern bool __vmalloc_start_set; /* set once high_memory is set \
*/ + # define VMALLOC_END	(FIXADDR_START - 2 * PAGE_SIZE)
+ #endif
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++#ifndef __ASSEMBLY__
++extern unsigned char MODULES_EXEC_VADDR[];
++extern unsigned char MODULES_EXEC_END[];
++#endif
++#include <asm/boot.h>
++#define ktla_ktva(addr)		(addr + LOAD_PHYSICAL_ADDR + PAGE_OFFSET)
++#define ktva_ktla(addr)		(addr - LOAD_PHYSICAL_ADDR - PAGE_OFFSET)
++#else
++#define ktla_ktva(addr)		(addr)
++#define ktva_ktla(addr)		(addr)
++#endif
++
+ #define MODULES_VADDR	VMALLOC_START
+ #define MODULES_END	VMALLOC_END
+ #define MODULES_LEN	(MODULES_VADDR - MODULES_END)
+diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
+index e22c1db..23a625a 100644
+--- a/arch/x86/include/asm/pgtable_64.h
++++ b/arch/x86/include/asm/pgtable_64.h
+@@ -16,10 +16,14 @@
+ 
+ extern pud_t level3_kernel_pgt[512];
+ extern pud_t level3_ident_pgt[512];
++extern pud_t level3_vmalloc_start_pgt[512];
++extern pud_t level3_vmalloc_end_pgt[512];
++extern pud_t level3_vmemmap_pgt[512];
++extern pud_t level2_vmemmap_pgt[512];
+ extern pmd_t level2_kernel_pgt[512];
+ extern pmd_t level2_fixmap_pgt[512];
+-extern pmd_t level2_ident_pgt[512];
+-extern pgd_t init_level4_pgt[];
++extern pmd_t level2_ident_pgt[512*2];
++extern pgd_t init_level4_pgt[512];
+ 
+ #define swapper_pg_dir init_level4_pgt
+ 
+@@ -61,7 +65,9 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
+ 
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
+ {
++	pax_open_kernel();
+ 	*pmdp = pmd;
++	pax_close_kernel();
+ }
+ 
+ static inline void native_pmd_clear(pmd_t *pmd)
+@@ -97,7 +103,9 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *xp)
+ 
+ static inline void native_set_pud(pud_t *pudp, pud_t pud)
+ {
++	pax_open_kernel();
+ 	*pudp = pud;
++	pax_close_kernel();
+ }
+ 
+ static inline void native_pud_clear(pud_t *pud)
+@@ -107,6 +115,13 @@ static inline void native_pud_clear(pud_t *pud)
+ 
+ static inline void native_set_pgd(pgd_t *pgdp, pgd_t pgd)
+ {
++	pax_open_kernel();
++	*pgdp = pgd;
++	pax_close_kernel();
++}
++
++static inline void native_set_pgd_batched(pgd_t *pgdp, pgd_t pgd)
++{
+ 	*pgdp = pgd;
+ }
+ 
+diff --git a/arch/x86/include/asm/pgtable_64_types.h \
b/arch/x86/include/asm/pgtable_64_types.h +index 2d88344..4679fc3 100644
+--- a/arch/x86/include/asm/pgtable_64_types.h
++++ b/arch/x86/include/asm/pgtable_64_types.h
+@@ -61,6 +61,11 @@ typedef struct { pteval_t pte; } pte_t;
+ #define MODULES_VADDR    _AC(0xffffffffa0000000, UL)
+ #define MODULES_END      _AC(0xffffffffff000000, UL)
+ #define MODULES_LEN   (MODULES_END - MODULES_VADDR)
++#define MODULES_EXEC_VADDR MODULES_VADDR
++#define MODULES_EXEC_END MODULES_END
++
++#define ktla_ktva(addr)		(addr)
++#define ktva_ktla(addr)		(addr)
+ 
+ #define EARLY_DYNAMIC_PAGE_TABLES	64
+ 
+diff --git a/arch/x86/include/asm/pgtable_types.h \
b/arch/x86/include/asm/pgtable_types.h +index f4843e0..a2526f8 100644
+--- a/arch/x86/include/asm/pgtable_types.h
++++ b/arch/x86/include/asm/pgtable_types.h
+@@ -16,13 +16,12 @@
+ #define _PAGE_BIT_PSE		7	/* 4 MB (or 2MB) page */
+ #define _PAGE_BIT_PAT		7	/* on 4KB pages */
+ #define _PAGE_BIT_GLOBAL	8	/* Global TLB entry PPro+ */
+-#define _PAGE_BIT_UNUSED1	9	/* available for programmer */
++#define _PAGE_BIT_SPECIAL	9	/* special mappings, no associated struct page */
+ #define _PAGE_BIT_IOMAP		10	/* flag used to indicate IO mapping */
+ #define _PAGE_BIT_HIDDEN	11	/* hidden by kmemcheck */
+ #define _PAGE_BIT_PAT_LARGE	12	/* On 2MB or 1GB pages */
+-#define _PAGE_BIT_SPECIAL	_PAGE_BIT_UNUSED1
+-#define _PAGE_BIT_CPA_TEST	_PAGE_BIT_UNUSED1
+-#define _PAGE_BIT_SPLITTING	_PAGE_BIT_UNUSED1 /* only valid on a PSE pmd */
++#define _PAGE_BIT_CPA_TEST	_PAGE_BIT_SPECIAL
++#define _PAGE_BIT_SPLITTING	_PAGE_BIT_SPECIAL /* only valid on a PSE pmd */
+ #define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check \
*/ + 
+ /* If _PAGE_BIT_PRESENT is clear, we use these: */
+@@ -40,7 +39,6 @@
+ #define _PAGE_DIRTY	(_AT(pteval_t, 1) << _PAGE_BIT_DIRTY)
+ #define _PAGE_PSE	(_AT(pteval_t, 1) << _PAGE_BIT_PSE)
+ #define _PAGE_GLOBAL	(_AT(pteval_t, 1) << _PAGE_BIT_GLOBAL)
+-#define _PAGE_UNUSED1	(_AT(pteval_t, 1) << _PAGE_BIT_UNUSED1)
+ #define _PAGE_IOMAP	(_AT(pteval_t, 1) << _PAGE_BIT_IOMAP)
+ #define _PAGE_PAT	(_AT(pteval_t, 1) << _PAGE_BIT_PAT)
+ #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE)
+@@ -84,8 +82,10 @@
+ 
+ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+ #define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_NX)
+-#else
++#elif defined(CONFIG_KMEMCHECK)
+ #define _PAGE_NX	(_AT(pteval_t, 0))
++#else
++#define _PAGE_NX	(_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)
+ #endif
+ 
+ #define _PAGE_FILE	(_AT(pteval_t, 1) << _PAGE_BIT_FILE)
+@@ -143,6 +143,9 @@
+ #define PAGE_READONLY_EXEC	__pgprot(_PAGE_PRESENT | _PAGE_USER |	\
+ 					 _PAGE_ACCESSED)
+ 
++#define PAGE_READONLY_NOEXEC PAGE_READONLY
++#define PAGE_SHARED_NOEXEC PAGE_SHARED
++
+ #define __PAGE_KERNEL_EXEC						\
+ 	(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
+ #define __PAGE_KERNEL		(__PAGE_KERNEL_EXEC | _PAGE_NX)
+@@ -153,7 +156,7 @@
+ #define __PAGE_KERNEL_WC		(__PAGE_KERNEL | _PAGE_CACHE_WC)
+ #define __PAGE_KERNEL_NOCACHE		(__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
+ #define __PAGE_KERNEL_UC_MINUS		(__PAGE_KERNEL | _PAGE_PCD)
+-#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RX | _PAGE_USER)
++#define __PAGE_KERNEL_VSYSCALL		(__PAGE_KERNEL_RO | _PAGE_USER)
+ #define __PAGE_KERNEL_VVAR		(__PAGE_KERNEL_RO | _PAGE_USER)
+ #define __PAGE_KERNEL_VVAR_NOCACHE	(__PAGE_KERNEL_VVAR | _PAGE_PCD | _PAGE_PWT)
+ #define __PAGE_KERNEL_LARGE		(__PAGE_KERNEL | _PAGE_PSE)
+@@ -215,8 +218,8 @@
+  * bits are combined, this will alow user to access the high address mapped
+  * VDSO in the presence of CONFIG_COMPAT_VDSO
+  */
+-#define PTE_IDENT_ATTR	 0x003		/* PRESENT+RW */
+-#define PDE_IDENT_ATTR	 0x067		/* PRESENT+RW+USER+DIRTY+ACCESSED */
++#define PTE_IDENT_ATTR	 0x063		/* PRESENT+RW+DIRTY+ACCESSED */
++#define PDE_IDENT_ATTR	 0x063		/* PRESENT+RW+DIRTY+ACCESSED */
+ #define PGD_IDENT_ATTR	 0x001		/* PRESENT (no other attributes) */
+ #endif
+ 
+@@ -254,7 +257,17 @@ static inline pgdval_t pgd_flags(pgd_t pgd)
+ {
+ 	return native_pgd_val(pgd) & PTE_FLAGS_MASK;
+ }
++#endif
+ 
++#if PAGETABLE_LEVELS == 3
++#include <asm-generic/pgtable-nopud.h>
++#endif
++
++#if PAGETABLE_LEVELS == 2
++#include <asm-generic/pgtable-nopmd.h>
++#endif
++
++#ifndef __ASSEMBLY__
+ #if PAGETABLE_LEVELS > 3
+ typedef struct { pudval_t pud; } pud_t;
+ 
+@@ -268,8 +281,6 @@ static inline pudval_t native_pud_val(pud_t pud)
+ 	return pud.pud;
+ }
+ #else
+-#include <asm-generic/pgtable-nopud.h>
+-
+ static inline pudval_t native_pud_val(pud_t pud)
+ {
+ 	return native_pgd_val(pud.pgd);
+@@ -289,8 +300,6 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
+ 	return pmd.pmd;
+ }
+ #else
+-#include <asm-generic/pgtable-nopmd.h>
+-
+ static inline pmdval_t native_pmd_val(pmd_t pmd)
+ {
+ 	return native_pgd_val(pmd.pud.pgd);
+@@ -330,7 +339,6 @@ typedef struct page *pgtable_t;
+ 
+ extern pteval_t __supported_pte_mask;
+ extern void set_nx(void);
+-extern int nx_enabled;
+ 
+ #define pgprot_writecombine	pgprot_writecombine
+ extern pgprot_t pgprot_writecombine(pgprot_t prot);
+diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
+index 24cf5ae..4d9fa2d 100644
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -199,9 +199,21 @@ static inline void native_cpuid(unsigned int *eax, unsigned int \
*ebx, + 	    : "memory");
+ }
+ 
++/* invpcid (%rdx),%rax */
++#define __ASM_INVPCID ".byte 0x66,0x0f,0x38,0x82,0x02"
++
++#define INVPCID_SINGLE_ADDRESS	0UL
++#define INVPCID_SINGLE_CONTEXT	1UL
++#define INVPCID_ALL_GLOBAL	2UL
++#define INVPCID_ALL_MONGLOBAL	3UL
++
++#define PCID_KERNEL		0UL
++#define PCID_USER		1UL
++#define PCID_NOFLUSH		(1UL << 63)
++
+ static inline void load_cr3(pgd_t *pgdir)
+ {
+-	write_cr3(__pa(pgdir));
++	write_cr3(__pa(pgdir) | PCID_KERNEL);
+ }
+ 
+ #ifdef CONFIG_X86_32
+@@ -283,7 +295,7 @@ struct tss_struct {
+ 
+ } ____cacheline_aligned;
+ 
+-DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);
++extern struct tss_struct init_tss[NR_CPUS];
+ 
+ /*
+  * Save the original ist values for checking stack pointers during debugging
+@@ -453,6 +465,7 @@ struct thread_struct {
+ 	unsigned short		ds;
+ 	unsigned short		fsindex;
+ 	unsigned short		gsindex;
++	unsigned short		ss;
+ #endif
+ #ifdef CONFIG_X86_32
+ 	unsigned long		ip;
+@@ -553,29 +566,8 @@ static inline void load_sp0(struct tss_struct *tss,
+ extern unsigned long mmu_cr4_features;
+ extern u32 *trampoline_cr4_features;
+ 
+-static inline void set_in_cr4(unsigned long mask)
+-{
+-	unsigned long cr4;
+-
+-	mmu_cr4_features |= mask;
+-	if (trampoline_cr4_features)
+-		*trampoline_cr4_features = mmu_cr4_features;
+-	cr4 = read_cr4();
+-	cr4 |= mask;
+-	write_cr4(cr4);
+-}
+-
+-static inline void clear_in_cr4(unsigned long mask)
+-{
+-	unsigned long cr4;
+-
+-	mmu_cr4_features &= ~mask;
+-	if (trampoline_cr4_features)
+-		*trampoline_cr4_features = mmu_cr4_features;
+-	cr4 = read_cr4();
+-	cr4 &= ~mask;
+-	write_cr4(cr4);
+-}
++extern void set_in_cr4(unsigned long mask);
++extern void clear_in_cr4(unsigned long mask);
+ 
+ typedef struct {
+ 	unsigned long		seg;
+@@ -824,11 +816,18 @@ static inline void spin_lock_prefetch(const void *x)
+  */
+ #define TASK_SIZE		PAGE_OFFSET
+ #define TASK_SIZE_MAX		TASK_SIZE
++
++#ifdef CONFIG_PAX_SEGMEXEC
++#define SEGMEXEC_TASK_SIZE	(TASK_SIZE / 2)
++#define STACK_TOP		((current->mm->pax_flags & \
MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE) ++#else
+ #define STACK_TOP		TASK_SIZE
+-#define STACK_TOP_MAX		STACK_TOP
++#endif
++
++#define STACK_TOP_MAX		TASK_SIZE
+ 
+ #define INIT_THREAD  {							  \
+-	.sp0			= sizeof(init_stack) + (long)&init_stack, \
++	.sp0			= sizeof(init_stack) + (long)&init_stack - 8, \
+ 	.vm86_info		= NULL,					  \
+ 	.sysenter_cs		= __KERNEL_CS,				  \
+ 	.io_bitmap_ptr		= NULL,					  \
+@@ -842,7 +841,7 @@ static inline void spin_lock_prefetch(const void *x)
+  */
+ #define INIT_TSS  {							  \
+ 	.x86_tss = {							  \
+-		.sp0		= sizeof(init_stack) + (long)&init_stack, \
++		.sp0		= sizeof(init_stack) + (long)&init_stack - 8, \
+ 		.ss0		= __KERNEL_DS,				  \
+ 		.ss1		= __KERNEL_CS,				  \
+ 		.io_bitmap_base	= INVALID_IO_BITMAP_OFFSET,		  \
+@@ -853,11 +852,7 @@ static inline void spin_lock_prefetch(const void *x)
+ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ 
+ #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
+-#define KSTK_TOP(info)                                                 \
+-({                                                                     \
+-       unsigned long *__ptr = (unsigned long *)(info);                 \
+-       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
+-})
++#define KSTK_TOP(info)         ((container_of(info, struct task_struct, \
tinfo))->thread.sp0) + 
+ /*
+  * The below -8 is to reserve 8 bytes on top of the ring0 stack.
+@@ -872,7 +867,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ #define task_pt_regs(task)                                             \
+ ({                                                                     \
+        struct pt_regs *__regs__;                                       \
+-       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
++       __regs__ = (struct pt_regs *)((task)->thread.sp0);              \
+        __regs__ - 1;                                                   \
+ })
+ 
+@@ -882,13 +877,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ /*
+  * User space process size. 47bits minus one guard page.
+  */
+-#define TASK_SIZE_MAX	((1UL << 47) - PAGE_SIZE)
++#define TASK_SIZE_MAX	((1UL << TASK_SIZE_MAX_SHIFT) - PAGE_SIZE)
+ 
+ /* This decides where the kernel will search for a free chunk of vm
+  * space during mmap's.
+  */
+ #define IA32_PAGE_OFFSET	((current->personality & ADDR_LIMIT_3GB) ? \
+-					0xc0000000 : 0xFFFFe000)
++					0xc0000000 : 0xFFFFf000)
+ 
+ #define TASK_SIZE		(test_thread_flag(TIF_ADDR32) ? \
+ 					IA32_PAGE_OFFSET : TASK_SIZE_MAX)
+@@ -899,11 +894,11 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
+ #define STACK_TOP_MAX		TASK_SIZE_MAX
+ 
+ #define INIT_THREAD  { \
+-	.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
++	.sp0 = (unsigned long)&init_stack + sizeof(init_stack) - 16 \
+ }
+ 
+ #define INIT_TSS  { \
+-	.x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) \
++	.x86_tss.sp0 = (unsigned long)&init_stack + sizeof(init_stack) - 16 \
+ }
+ 
+ /*
+@@ -931,6 +926,10 @@ extern void start_thread(struct pt_regs *regs, unsigned long \
new_ip, +  */
+ #define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+ 
++#ifdef CONFIG_PAX_SEGMEXEC
++#define SEGMEXEC_TASK_UNMAPPED_BASE	(PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
++#endif
++
+ #define KSTK_EIP(task)		(task_pt_regs(task)->ip)
+ 
+ /* Get/set a process' ability to use the timestamp counter instruction */
+@@ -943,7 +942,8 @@ extern int set_tsc_mode(unsigned int val);
+ extern u16 amd_get_nb_id(int cpu);
+ 
+ struct aperfmperf {
+-	u64 aperf, mperf;
++	u64 aperf __intentional_overflow(0);
++	u64 mperf __intentional_overflow(0);
+ };
+ 
+ static inline void get_aperfmperf(struct aperfmperf *am)
+@@ -971,7 +971,7 @@ unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
+ 	return ratio;
+ }
+ 
+-extern unsigned long arch_align_stack(unsigned long sp);
++#define arch_align_stack(x) ((x) & ~0xfUL)
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
+ 
+ void default_idle(void);
+@@ -981,6 +981,6 @@ bool xen_set_default_idle(void);
+ #define xen_set_default_idle 0
+ #endif
+ 
+-void stop_this_cpu(void *dummy);
++void stop_this_cpu(void *dummy) __noreturn;
+ void df_debug(struct pt_regs *regs, long error_code);
+ #endif /* _ASM_X86_PROCESSOR_H */
+diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h
+index 942a086..6c26446 100644
+--- a/arch/x86/include/asm/ptrace.h
++++ b/arch/x86/include/asm/ptrace.h
+@@ -85,28 +85,29 @@ static inline unsigned long regs_return_value(struct pt_regs \
*regs) + }
+ 
+ /*
+- * user_mode_vm(regs) determines whether a register set came from user mode.
++ * user_mode(regs) determines whether a register set came from user mode.
+  * This is true if V8086 mode was enabled OR if the register set was from
+  * protected mode with RPL-3 CS value.  This tricky test checks that with
+  * one comparison.  Many places in the kernel can bypass this full check
+- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
++ * be used.
+  */
+-static inline int user_mode(struct pt_regs *regs)
++static inline int user_mode_novm(struct pt_regs *regs)
+ {
+ #ifdef CONFIG_X86_32
+ 	return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
+ #else
+-	return !!(regs->cs & 3);
++	return !!(regs->cs & SEGMENT_RPL_MASK);
+ #endif
+ }
+ 
+-static inline int user_mode_vm(struct pt_regs *regs)
++static inline int user_mode(struct pt_regs *regs)
+ {
+ #ifdef CONFIG_X86_32
+ 	return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
+ 		USER_RPL;
+ #else
+-	return user_mode(regs);
++	return user_mode_novm(regs);
+ #endif
+ }
+ 
+@@ -122,15 +123,16 @@ static inline int v8086_mode(struct pt_regs *regs)
+ #ifdef CONFIG_X86_64
+ static inline bool user_64bit_mode(struct pt_regs *regs)
+ {
++	unsigned long cs = regs->cs & 0xffff;
+ #ifndef CONFIG_PARAVIRT
+ 	/*
+ 	 * On non-paravirt systems, this is the only long mode CPL 3
+ 	 * selector.  We do not allow long mode selectors in the LDT.
+ 	 */
+-	return regs->cs == __USER_CS;
++	return cs == __USER_CS;
+ #else
+ 	/* Headers are too twisted for this to go in paravirt.h. */
+-	return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
++	return cs == __USER_CS || cs == pv_info.extra_user_64bit_cs;
+ #endif
+ }
+ 
+@@ -181,9 +183,11 @@ static inline unsigned long regs_get_register(struct pt_regs \
*regs, + 	 * Traps from the kernel do not save sp and ss.
+ 	 * Use the helper function to retrieve sp.
+ 	 */
+-	if (offset == offsetof(struct pt_regs, sp) &&
+-	    regs->cs == __KERNEL_CS)
+-		return kernel_stack_pointer(regs);
++	if (offset == offsetof(struct pt_regs, sp)) {
++		unsigned long cs = regs->cs & 0xffff;
++	 	if (cs == __KERNEL_CS || cs == __KERNEXEC_KERNEL_CS)
++			return kernel_stack_pointer(regs);
++	}
+ #endif
+ 	return *(unsigned long *)((unsigned long)regs + offset);
+ }
+diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
+index 9c6b890..5305f53 100644
+--- a/arch/x86/include/asm/realmode.h
++++ b/arch/x86/include/asm/realmode.h
+@@ -22,16 +22,14 @@ struct real_mode_header {
+ #endif
+ 	/* APM/BIOS reboot */
+ 	u32	machine_real_restart_asm;
+-#ifdef CONFIG_X86_64
+ 	u32	machine_real_restart_seg;
+-#endif
+ };
+ 
+ /* This must match data at trampoline_32/64.S */
+ struct trampoline_header {
+ #ifdef CONFIG_X86_32
+ 	u32 start;
+-	u16 gdt_pad;
++	u16 boot_cs;
+ 	u16 gdt_limit;
+ 	u32 gdt_base;
+ #else
+diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h
+index a82c4f1..ac45053 100644
+--- a/arch/x86/include/asm/reboot.h
++++ b/arch/x86/include/asm/reboot.h
+@@ -6,13 +6,13 @@
+ struct pt_regs;
+ 
+ struct machine_ops {
+-	void (*restart)(char *cmd);
+-	void (*halt)(void);
+-	void (*power_off)(void);
++	void (* __noreturn restart)(char *cmd);
++	void (* __noreturn halt)(void);
++	void (* __noreturn power_off)(void);
+ 	void (*shutdown)(void);
+ 	void (*crash_shutdown)(struct pt_regs *);
+-	void (*emergency_restart)(void);
+-};
++	void (* __noreturn emergency_restart)(void);
++} __no_const;
+ 
+ extern struct machine_ops machine_ops;
+ 
+diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h
+index cad82c9..2e5c5c1 100644
+--- a/arch/x86/include/asm/rwsem.h
++++ b/arch/x86/include/asm/rwsem.h
+@@ -64,6 +64,14 @@ static inline void __down_read(struct rw_semaphore *sem)
+ {
+ 	asm volatile("# beginning down_read\n\t"
+ 		     LOCK_PREFIX _ASM_INC "(%1)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX _ASM_DEC "(%1)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     /* adds 0x00000001 */
+ 		     "  jns        1f\n"
+ 		     "  call call_rwsem_down_read_failed\n"
+@@ -85,6 +93,14 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
+ 		     "1:\n\t"
+ 		     "  mov          %1,%2\n\t"
+ 		     "  add          %3,%2\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     "sub %3,%2\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     "  jle	     2f\n\t"
+ 		     LOCK_PREFIX "  cmpxchg  %2,%0\n\t"
+ 		     "  jnz	     1b\n\t"
+@@ -104,6 +120,14 @@ static inline void __down_write_nested(struct rw_semaphore \
*sem, int subclass) + 	long tmp;
+ 	asm volatile("# beginning down_write\n\t"
+ 		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     "mov %1,(%2)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     /* adds 0xffff0001, returns the old value */
+ 		     "  test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t"
+ 		     /* was the active mask 0 before? */
+@@ -155,6 +179,14 @@ static inline void __up_read(struct rw_semaphore *sem)
+ 	long tmp;
+ 	asm volatile("# beginning __up_read\n\t"
+ 		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     "mov %1,(%2)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     /* subtracts 1, returns the old value */
+ 		     "  jns        1f\n\t"
+ 		     "  call call_rwsem_wake\n" /* expects old value in %edx */
+@@ -173,6 +205,14 @@ static inline void __up_write(struct rw_semaphore *sem)
+ 	long tmp;
+ 	asm volatile("# beginning __up_write\n\t"
+ 		     LOCK_PREFIX "  xadd      %1,(%2)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     "mov %1,(%2)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     /* subtracts 0xffff0001, returns the old value */
+ 		     "  jns        1f\n\t"
+ 		     "  call call_rwsem_wake\n" /* expects old value in %edx */
+@@ -190,6 +230,14 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
+ {
+ 	asm volatile("# beginning __downgrade_write\n\t"
+ 		     LOCK_PREFIX _ASM_ADD "%2,(%1)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX _ASM_SUB "%2,(%1)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     /*
+ 		      * transitions 0xZZZZ0001 -> 0xYYYY0001 (i386)
+ 		      *     0xZZZZZZZZ00000001 -> 0xYYYYYYYY00000001 (x86_64)
+@@ -208,7 +256,15 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
+  */
+ static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+ {
+-	asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0"
++	asm volatile(LOCK_PREFIX _ASM_ADD "%1,%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX _ASM_SUB "%1,%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     : "+m" (sem->count)
+ 		     : "er" (delta));
+ }
+@@ -218,7 +274,7 @@ static inline void rwsem_atomic_add(long delta, struct \
rw_semaphore *sem) +  */
+ static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
+ {
+-	return delta + xadd(&sem->count, delta);
++	return delta + xadd_check_overflow(&sem->count, delta);
+ }
+ 
+ #endif /* __KERNEL__ */
+diff --git a/arch/x86/include/asm/segment.h b/arch/x86/include/asm/segment.h
+index c48a950..bc40804 100644
+--- a/arch/x86/include/asm/segment.h
++++ b/arch/x86/include/asm/segment.h
+@@ -64,10 +64,15 @@
+  *  26 - ESPFIX small SS
+  *  27 - per-cpu			[ offset to per-cpu data area ]
+  *  28 - stack_canary-20		[ for stack protector ]
+- *  29 - unused
+- *  30 - unused
++ *  29 - PCI BIOS CS
++ *  30 - PCI BIOS DS
+  *  31 - TSS for double fault handler
+  */
++#define GDT_ENTRY_KERNEXEC_EFI_CS	(1)
++#define GDT_ENTRY_KERNEXEC_EFI_DS	(2)
++#define __KERNEXEC_EFI_CS	(GDT_ENTRY_KERNEXEC_EFI_CS*8)
++#define __KERNEXEC_EFI_DS	(GDT_ENTRY_KERNEXEC_EFI_DS*8)
++
+ #define GDT_ENTRY_TLS_MIN	6
+ #define GDT_ENTRY_TLS_MAX 	(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
+ 
+@@ -79,6 +84,8 @@
+ 
+ #define GDT_ENTRY_KERNEL_CS		(GDT_ENTRY_KERNEL_BASE+0)
+ 
++#define GDT_ENTRY_KERNEXEC_KERNEL_CS	(4)
++
+ #define GDT_ENTRY_KERNEL_DS		(GDT_ENTRY_KERNEL_BASE+1)
+ 
+ #define GDT_ENTRY_TSS			(GDT_ENTRY_KERNEL_BASE+4)
+@@ -104,6 +111,12 @@
+ #define __KERNEL_STACK_CANARY		0
+ #endif
+ 
++#define GDT_ENTRY_PCIBIOS_CS		(GDT_ENTRY_KERNEL_BASE+17)
++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
++
++#define GDT_ENTRY_PCIBIOS_DS		(GDT_ENTRY_KERNEL_BASE+18)
++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
++
+ #define GDT_ENTRY_DOUBLEFAULT_TSS	31
+ 
+ /*
+@@ -141,7 +154,7 @@
+  */
+ 
+ /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
+-#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
++#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == \
PNP_CS16) + 
+ 
+ #else
+@@ -165,6 +178,8 @@
+ #define __USER32_CS   (GDT_ENTRY_DEFAULT_USER32_CS*8+3)
+ #define __USER32_DS	__USER_DS
+ 
++#define GDT_ENTRY_KERNEXEC_KERNEL_CS 7
++
+ #define GDT_ENTRY_TSS 8	/* needs two entries */
+ #define GDT_ENTRY_LDT 10 /* needs two entries */
+ #define GDT_ENTRY_TLS_MIN 12
+@@ -173,6 +188,8 @@
+ #define GDT_ENTRY_PER_CPU 15	/* Abused to load per CPU data from limit */
+ #define __PER_CPU_SEG	(GDT_ENTRY_PER_CPU * 8 + 3)
+ 
++#define GDT_ENTRY_UDEREF_KERNEL_DS 16
++
+ /* TLS indexes for 64bit - hardcoded in arch_prctl */
+ #define FS_TLS 0
+ #define GS_TLS 1
+@@ -180,12 +197,14 @@
+ #define GS_TLS_SEL ((GDT_ENTRY_TLS_MIN+GS_TLS)*8 + 3)
+ #define FS_TLS_SEL ((GDT_ENTRY_TLS_MIN+FS_TLS)*8 + 3)
+ 
+-#define GDT_ENTRIES 16
++#define GDT_ENTRIES 17
+ 
+ #endif
+ 
+ #define __KERNEL_CS	(GDT_ENTRY_KERNEL_CS*8)
++#define __KERNEXEC_KERNEL_CS	(GDT_ENTRY_KERNEXEC_KERNEL_CS*8)
+ #define __KERNEL_DS	(GDT_ENTRY_KERNEL_DS*8)
++#define __UDEREF_KERNEL_DS	(GDT_ENTRY_UDEREF_KERNEL_DS*8)
+ #define __USER_DS	(GDT_ENTRY_DEFAULT_USER_DS*8+3)
+ #define __USER_CS	(GDT_ENTRY_DEFAULT_USER_CS*8+3)
+ #ifndef CONFIG_PARAVIRT
+@@ -265,7 +284,7 @@ static inline unsigned long get_limit(unsigned long segment)
+ {
+ 	unsigned long __limit;
+ 	asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
+-	return __limit + 1;
++	return __limit;
+ }
+ 
+ #endif /* !__ASSEMBLY__ */
+diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h
+index 8d3120f..352b440 100644
+--- a/arch/x86/include/asm/smap.h
++++ b/arch/x86/include/asm/smap.h
+@@ -25,11 +25,40 @@
+ 
+ #include <asm/alternative-asm.h>
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define ASM_PAX_OPEN_USERLAND					\
++	661: jmp 663f;						\
++	.pushsection .altinstr_replacement, "a" ;		\
++	662: pushq %rax; nop;					\
++	.popsection ;						\
++	.pushsection .altinstructions, "a" ;			\
++	altinstruction_entry 661b, 662b, X86_FEATURE_STRONGUDEREF, 2, 2;\
++	.popsection ;						\
++	call __pax_open_userland;				\
++	popq %rax;						\
++	663:
++
++#define ASM_PAX_CLOSE_USERLAND					\
++	661: jmp 663f;						\
++	.pushsection .altinstr_replacement, "a" ;		\
++	662: pushq %rax; nop;					\
++	.popsection;						\
++	.pushsection .altinstructions, "a" ;			\
++	altinstruction_entry 661b, 662b, X86_FEATURE_STRONGUDEREF, 2, 2;\
++	.popsection;						\
++	call __pax_close_userland;				\
++	popq %rax;						\
++	663:
++#else
++#define ASM_PAX_OPEN_USERLAND
++#define ASM_PAX_CLOSE_USERLAND
++#endif
++
+ #ifdef CONFIG_X86_SMAP
+ 
+ #define ASM_CLAC							\
+ 	661: ASM_NOP3 ;							\
+-	.pushsection .altinstr_replacement, "ax" ;			\
++	.pushsection .altinstr_replacement, "a" ;			\
+ 	662: __ASM_CLAC ;						\
+ 	.popsection ;							\
+ 	.pushsection .altinstructions, "a" ;				\
+@@ -38,7 +67,7 @@
+ 
+ #define ASM_STAC							\
+ 	661: ASM_NOP3 ;							\
+-	.pushsection .altinstr_replacement, "ax" ;			\
++	.pushsection .altinstr_replacement, "a" ;			\
+ 	662: __ASM_STAC ;						\
+ 	.popsection ;							\
+ 	.pushsection .altinstructions, "a" ;				\
+@@ -56,6 +85,37 @@
+ 
+ #include <asm/alternative.h>
+ 
++#define __HAVE_ARCH_PAX_OPEN_USERLAND
++#define __HAVE_ARCH_PAX_CLOSE_USERLAND
++
++extern void __pax_open_userland(void);
++static __always_inline unsigned long pax_open_userland(void)
++{
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	asm volatile(ALTERNATIVE(ASM_NOP5, "call %P[open]", X86_FEATURE_STRONGUDEREF)
++		:
++		: [open] "i" (__pax_open_userland)
++		: "memory", "rax");
++#endif
++
++	return 0;
++}
++
++extern void __pax_close_userland(void);
++static __always_inline unsigned long pax_close_userland(void)
++{
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	asm volatile(ALTERNATIVE(ASM_NOP5, "call %P[close]", X86_FEATURE_STRONGUDEREF)
++		:
++		: [close] "i" (__pax_close_userland)
++		: "memory", "rax");
++#endif
++
++	return 0;
++}
++
+ #ifdef CONFIG_X86_SMAP
+ 
+ static __always_inline void clac(void)
+diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
+index 4137890..03fa172 100644
+--- a/arch/x86/include/asm/smp.h
++++ b/arch/x86/include/asm/smp.h
+@@ -36,7 +36,7 @@ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map);
+ /* cpus sharing the last level cache: */
+ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
+ DECLARE_PER_CPU_READ_MOSTLY(u16, cpu_llc_id);
+-DECLARE_PER_CPU_READ_MOSTLY(int, cpu_number);
++DECLARE_PER_CPU_READ_MOSTLY(unsigned int, cpu_number);
+ 
+ static inline struct cpumask *cpu_sibling_mask(int cpu)
+ {
+@@ -79,7 +79,7 @@ struct smp_ops {
+ 
+ 	void (*send_call_func_ipi)(const struct cpumask *mask);
+ 	void (*send_call_func_single_ipi)(int cpu);
+-};
++} __no_const;
+ 
+ /* Globals due to paravirt */
+ extern void set_cpu_sibling_map(int cpu);
+@@ -191,14 +191,8 @@ extern unsigned disabled_cpus;
+ extern int safe_smp_processor_id(void);
+ 
+ #elif defined(CONFIG_X86_64_SMP)
+-#define raw_smp_processor_id() (this_cpu_read(cpu_number))
+-
+-#define stack_smp_processor_id()					\
+-({								\
+-	struct thread_info *ti;						\
+-	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));	\
+-	ti->cpu;							\
+-})
++#define raw_smp_processor_id()		(this_cpu_read(cpu_number))
++#define stack_smp_processor_id()	raw_smp_processor_id()
+ #define safe_smp_processor_id()		smp_processor_id()
+ 
+ #endif
+diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
+index e3ddd7d..3611fce 100644
+--- a/arch/x86/include/asm/spinlock.h
++++ b/arch/x86/include/asm/spinlock.h
+@@ -172,6 +172,14 @@ static inline int arch_write_can_lock(arch_rwlock_t *lock)
+ static inline void arch_read_lock(arch_rwlock_t *rw)
+ {
+ 	asm volatile(LOCK_PREFIX READ_LOCK_SIZE(dec) " (%0)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX READ_LOCK_SIZE(inc) " (%0)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     "jns 1f\n"
+ 		     "call __read_lock_failed\n\t"
+ 		     "1:\n"
+@@ -181,6 +189,14 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
+ static inline void arch_write_lock(arch_rwlock_t *rw)
+ {
+ 	asm volatile(LOCK_PREFIX WRITE_LOCK_SUB(%1) "(%0)\n\t"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX WRITE_LOCK_ADD(%1) "(%0)\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     "jz 1f\n"
+ 		     "call __write_lock_failed\n\t"
+ 		     "1:\n"
+@@ -210,13 +226,29 @@ static inline int arch_write_trylock(arch_rwlock_t *lock)
+ 
+ static inline void arch_read_unlock(arch_rwlock_t *rw)
+ {
+-	asm volatile(LOCK_PREFIX READ_LOCK_SIZE(inc) " %0"
++	asm volatile(LOCK_PREFIX READ_LOCK_SIZE(inc) " %0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX READ_LOCK_SIZE(dec) " %0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     :"+m" (rw->lock) : : "memory");
+ }
+ 
+ static inline void arch_write_unlock(arch_rwlock_t *rw)
+ {
+-	asm volatile(LOCK_PREFIX WRITE_LOCK_ADD(%1) "%0"
++	asm volatile(LOCK_PREFIX WRITE_LOCK_ADD(%1) "%0\n"
++
++#ifdef CONFIG_PAX_REFCOUNT
++		     "jno 0f\n"
++		     LOCK_PREFIX WRITE_LOCK_SUB(%1) "%0\n"
++		     "int $4\n0:\n"
++		     _ASM_EXTABLE(0b, 0b)
++#endif
++
+ 		     : "+m" (rw->write) : "i" (RW_LOCK_BIAS) : "memory");
+ }
+ 
+diff --git a/arch/x86/include/asm/stackprotector.h \
b/arch/x86/include/asm/stackprotector.h +index 6a99859..03cb807 100644
+--- a/arch/x86/include/asm/stackprotector.h
++++ b/arch/x86/include/asm/stackprotector.h
+@@ -47,7 +47,7 @@
+  * head_32 for boot CPU and setup_per_cpu_areas() for others.
+  */
+ #define GDT_STACK_CANARY_INIT						\
+-	[GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
++	[GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x17),
+ 
+ /*
+  * Initialize the stackprotector canary value.
+@@ -112,7 +112,7 @@ static inline void setup_stack_canary_segment(int cpu)
+ 
+ static inline void load_stack_canary_segment(void)
+ {
+-#ifdef CONFIG_X86_32
++#if defined(CONFIG_X86_32) && !defined(CONFIG_PAX_MEMORY_UDEREF)
+ 	asm volatile ("mov %0, %%gs" : : "r" (0));
+ #endif
+ }
+diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h
+index 70bbe39..4ae2bd4 100644
+--- a/arch/x86/include/asm/stacktrace.h
++++ b/arch/x86/include/asm/stacktrace.h
+@@ -11,28 +11,20 @@
+ 
+ extern int kstack_depth_to_print;
+ 
+-struct thread_info;
++struct task_struct;
+ struct stacktrace_ops;
+ 
+-typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
+-				      unsigned long *stack,
+-				      unsigned long bp,
+-				      const struct stacktrace_ops *ops,
+-				      void *data,
+-				      unsigned long *end,
+-				      int *graph);
++typedef unsigned long walk_stack_t(struct task_struct *task,
++				   void *stack_start,
++				   unsigned long *stack,
++				   unsigned long bp,
++				   const struct stacktrace_ops *ops,
++				   void *data,
++				   unsigned long *end,
++				   int *graph);
+ 
+-extern unsigned long
+-print_context_stack(struct thread_info *tinfo,
+-		    unsigned long *stack, unsigned long bp,
+-		    const struct stacktrace_ops *ops, void *data,
+-		    unsigned long *end, int *graph);
+-
+-extern unsigned long
+-print_context_stack_bp(struct thread_info *tinfo,
+-		       unsigned long *stack, unsigned long bp,
+-		       const struct stacktrace_ops *ops, void *data,
+-		       unsigned long *end, int *graph);
++extern walk_stack_t print_context_stack;
++extern walk_stack_t print_context_stack_bp;
+ 
+ /* Generic stack tracer with callbacks */
+ 
+@@ -40,7 +32,7 @@ struct stacktrace_ops {
+ 	void (*address)(void *data, unsigned long address, int reliable);
+ 	/* On negative return stop dumping */
+ 	int (*stack)(void *data, char *name);
+-	walk_stack_t	walk_stack;
++	walk_stack_t	*walk_stack;
+ };
+ 
+ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+diff --git a/arch/x86/include/asm/switch_to.h b/arch/x86/include/asm/switch_to.h
+index 4ec45b3..a4f0a8a 100644
+--- a/arch/x86/include/asm/switch_to.h
++++ b/arch/x86/include/asm/switch_to.h
+@@ -108,7 +108,7 @@ do {									\
+ 	     "call __switch_to\n\t"					  \
+ 	     "movq "__percpu_arg([current_task])",%%rsi\n\t"		  \
+ 	     __switch_canary						  \
+-	     "movq %P[thread_info](%%rsi),%%r8\n\t"			  \
++	     "movq "__percpu_arg([thread_info])",%%r8\n\t"		  \
+ 	     "movq %%rax,%%rdi\n\t" 					  \
+ 	     "testl  %[_tif_fork],%P[ti_flags](%%r8)\n\t"		  \
+ 	     "jnz   ret_from_fork\n\t"					  \
+@@ -119,7 +119,7 @@ do {									\
+ 	       [threadrsp] "i" (offsetof(struct task_struct, thread.sp)), \
+ 	       [ti_flags] "i" (offsetof(struct thread_info, flags)),	  \
+ 	       [_tif_fork] "i" (_TIF_FORK),			  	  \
+-	       [thread_info] "i" (offsetof(struct task_struct, stack)),   \
++	       [thread_info] "m" (current_tinfo),			  \
+ 	       [current_task] "m" (current_task)			  \
+ 	       __switch_canary_iparam					  \
+ 	     : "memory", "cc" __EXTRA_CLOBBER)
+diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
+index 2781119..618b59b 100644
+--- a/arch/x86/include/asm/thread_info.h
++++ b/arch/x86/include/asm/thread_info.h
+@@ -10,6 +10,7 @@
+ #include <linux/compiler.h>
+ #include <asm/page.h>
+ #include <asm/types.h>
++#include <asm/percpu.h>
+ 
+ /*
+  * low level task data that entry.S needs immediate access to
+@@ -23,7 +24,6 @@ struct exec_domain;
+ #include <linux/atomic.h>
+ 
+ struct thread_info {
+-	struct task_struct	*task;		/* main task structure */
+ 	struct exec_domain	*exec_domain;	/* execution domain */
+ 	__u32			flags;		/* low level flags */
+ 	__u32			status;		/* thread synchronous flags */
+@@ -33,19 +33,13 @@ struct thread_info {
+ 	mm_segment_t		addr_limit;
+ 	struct restart_block    restart_block;
+ 	void __user		*sysenter_return;
+-#ifdef CONFIG_X86_32
+-	unsigned long           previous_esp;   /* ESP of the previous stack in
+-						   case of nested (IRQ) stacks
+-						*/
+-	__u8			supervisor_stack[0];
+-#endif
++	unsigned long		lowest_stack;
+ 	unsigned int		sig_on_uaccess_error:1;
+ 	unsigned int		uaccess_err:1;	/* uaccess failed */
+ };
+ 
+-#define INIT_THREAD_INFO(tsk)			\
++#define INIT_THREAD_INFO			\
+ {						\
+-	.task		= &tsk,			\
+ 	.exec_domain	= &default_exec_domain,	\
+ 	.flags		= 0,			\
+ 	.cpu		= 0,			\
+@@ -56,7 +50,7 @@ struct thread_info {
+ 	},					\
+ }
+ 
+-#define init_thread_info	(init_thread_union.thread_info)
++#define init_thread_info	(init_thread_union.stack)
+ #define init_stack		(init_thread_union.stack)
+ 
+ #else /* !__ASSEMBLY__ */
+@@ -96,6 +90,7 @@ struct thread_info {
+ #define TIF_SYSCALL_TRACEPOINT	28	/* syscall tracepoint instrumentation */
+ #define TIF_ADDR32		29	/* 32-bit address space on 64 bits */
+ #define TIF_X32			30	/* 32-bit native x86-64 binary */
++#define TIF_GRSEC_SETXID	31	/* update credentials on syscall entry/exit */
+ 
+ #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
+ #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
+@@ -119,17 +114,18 @@ struct thread_info {
+ #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_ADDR32		(1 << TIF_ADDR32)
+ #define _TIF_X32		(1 << TIF_X32)
++#define _TIF_GRSEC_SETXID	(1 << TIF_GRSEC_SETXID)
+ 
+ /* work to do in syscall_trace_enter() */
+ #define _TIF_WORK_SYSCALL_ENTRY	\
+ 	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT |	\
+ 	 _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT |	\
+-	 _TIF_NOHZ)
++	 _TIF_NOHZ | _TIF_GRSEC_SETXID)
+ 
+ /* work to do in syscall_trace_leave() */
+ #define _TIF_WORK_SYSCALL_EXIT	\
+ 	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP |	\
+-	 _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ)
++	 _TIF_SYSCALL_TRACEPOINT | _TIF_NOHZ | _TIF_GRSEC_SETXID)
+ 
+ /* work to do on interrupt/exception return */
+ #define _TIF_WORK_MASK							\
+@@ -140,7 +136,7 @@ struct thread_info {
+ /* work to do on any return to user space */
+ #define _TIF_ALLWORK_MASK						\
+ 	((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT |	\
+-	_TIF_NOHZ)
++	_TIF_NOHZ | _TIF_GRSEC_SETXID)
+ 
+ /* Only used for 64 bit */
+ #define _TIF_DO_NOTIFY_MASK						\
+@@ -156,45 +152,40 @@ struct thread_info {
+ 
+ #define PREEMPT_ACTIVE		0x10000000
+ 
+-#ifdef CONFIG_X86_32
+-
+-#define STACK_WARN	(THREAD_SIZE/8)
+-/*
+- * macros/functions for gaining access to the thread information structure
+- *
+- * preempt_count needs to be 1 initially, until the scheduler is functional.
+- */
+-#ifndef __ASSEMBLY__
+-
+-
+-/* how to get the current stack pointer from C */
+-register unsigned long current_stack_pointer asm("esp") __used;
+-
+-/* how to get the thread information struct from C */
+-static inline struct thread_info *current_thread_info(void)
+-{
+-	return (struct thread_info *)
+-		(current_stack_pointer & ~(THREAD_SIZE - 1));
+-}
+-
+-#else /* !__ASSEMBLY__ */
+-
++#ifdef __ASSEMBLY__
+ /* how to get the thread information struct from ASM */
+ #define GET_THREAD_INFO(reg)	 \
+-	movl $-THREAD_SIZE, reg; \
+-	andl %esp, reg
++	mov PER_CPU_VAR(current_tinfo), reg
+ 
+ /* use this one if reg already contains %esp */
+-#define GET_THREAD_INFO_WITH_ESP(reg) \
+-	andl $-THREAD_SIZE, reg
++#define GET_THREAD_INFO_WITH_ESP(reg) GET_THREAD_INFO(reg)
++#else
++/* how to get the thread information struct from C */
++DECLARE_PER_CPU(struct thread_info *, current_tinfo);
++
++static __always_inline struct thread_info *current_thread_info(void)
++{
++	return this_cpu_read_stable(current_tinfo);
++}
++#endif
++
++#ifdef CONFIG_X86_32
++
++#define STACK_WARN	(THREAD_SIZE/8)
++/*
++ * macros/functions for gaining access to the thread information structure
++ *
++ * preempt_count needs to be 1 initially, until the scheduler is functional.
++ */
++#ifndef __ASSEMBLY__
++
++/* how to get the current stack pointer from C */
++register unsigned long current_stack_pointer asm("esp") __used;
+ 
+ #endif
+ 
+ #else /* X86_32 */
+ 
+-#include <asm/percpu.h>
+-#define KERNEL_STACK_OFFSET (5*8)
+-
+ /*
+  * macros/functions for gaining access to the thread information structure
+  * preempt_count needs to be 1 initially, until the scheduler is functional.
+@@ -202,27 +193,8 @@ static inline struct thread_info *current_thread_info(void)
+ #ifndef __ASSEMBLY__
+ DECLARE_PER_CPU(unsigned long, kernel_stack);
+ 
+-static inline struct thread_info *current_thread_info(void)
+-{
+-	struct thread_info *ti;
+-	ti = (void *)(this_cpu_read_stable(kernel_stack) +
+-		      KERNEL_STACK_OFFSET - THREAD_SIZE);
+-	return ti;
+-}
+-
+-#else /* !__ASSEMBLY__ */
+-
+-/* how to get the thread information struct from ASM */
+-#define GET_THREAD_INFO(reg) \
+-	movq PER_CPU_VAR(kernel_stack),reg ; \
+-	subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg
+-
+-/*
+- * Same if PER_CPU_VAR(kernel_stack) is, perhaps with some offset, already in
+- * a certain register (to be used in assembler memory operands).
+- */
+-#define THREAD_INFO(reg, off) KERNEL_STACK_OFFSET+(off)-THREAD_SIZE(reg)
+-
++/* how to get the current stack pointer from C */
++register unsigned long current_stack_pointer asm("rsp") __used;
+ #endif
+ 
+ #endif /* !X86_32 */
+@@ -281,5 +253,12 @@ static inline bool is_ia32_task(void)
+ extern void arch_task_cache_init(void);
+ extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
+ extern void arch_release_task_struct(struct task_struct *tsk);
++
++#define __HAVE_THREAD_FUNCTIONS
++#define task_thread_info(task)	(&(task)->tinfo)
++#define task_stack_page(task)	((task)->stack)
++#define setup_thread_stack(p, org) do {} while (0)
++#define end_of_stack(p) ((unsigned long *)task_stack_page(p) + 1)
++
+ #endif
+ #endif /* _ASM_X86_THREAD_INFO_H */
+diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
+index cf51200..63ff068 100644
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -17,18 +17,44 @@
+ 
+ static inline void __native_flush_tlb(void)
+ {
++	if (static_cpu_has(X86_FEATURE_INVPCID)) {
++		u64 descriptor[2];
++
++		descriptor[0] = PCID_KERNEL;
++		asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : \
"memory"); ++		return;
++	}
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (static_cpu_has(X86_FEATURE_PCID)) {
++		unsigned int cpu = raw_get_cpu();
++
++		native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER);
++		native_write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL);
++		raw_put_cpu_no_resched();
++		return;
++	}
++#endif
++
+ 	native_write_cr3(native_read_cr3());
+ }
+ 
+ static inline void __native_flush_tlb_global_irq_disabled(void)
+ {
+-	unsigned long cr4;
++	if (static_cpu_has(X86_FEATURE_INVPCID)) {
++		u64 descriptor[2];
+ 
+-	cr4 = native_read_cr4();
+-	/* clear PGE */
+-	native_write_cr4(cr4 & ~X86_CR4_PGE);
+-	/* write old PGE again and flush TLBs */
+-	native_write_cr4(cr4);
++		descriptor[0] = PCID_KERNEL;
++		asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : \
"memory"); ++	} else {
++		unsigned long cr4;
++
++		cr4 = native_read_cr4();
++		/* clear PGE */
++		native_write_cr4(cr4 & ~X86_CR4_PGE);
++		/* write old PGE again and flush TLBs */
++		native_write_cr4(cr4);
++	}
+ }
+ 
+ static inline void __native_flush_tlb_global(void)
+@@ -49,6 +75,42 @@ static inline void __native_flush_tlb_global(void)
+ 
+ static inline void __native_flush_tlb_single(unsigned long addr)
+ {
++
++	if (static_cpu_has(X86_FEATURE_INVPCID)) {
++		u64 descriptor[2];
++
++		descriptor[0] = PCID_KERNEL;
++		descriptor[1] = addr;
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		if (!static_cpu_has(X86_FEATURE_STRONGUDEREF) || addr >= TASK_SIZE_MAX) {
++			if (addr < TASK_SIZE_MAX)
++				descriptor[1] += pax_user_shadow_base;
++			asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : \
"memory"); ++		}
++
++		descriptor[0] = PCID_USER;
++		descriptor[1] = addr;
++#endif
++
++		asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : \
"memory"); ++		return;
++	}
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (static_cpu_has(X86_FEATURE_PCID)) {
++		unsigned int cpu = raw_get_cpu();
++
++		native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER | PCID_NOFLUSH);
++		asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
++		native_write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++		raw_put_cpu_no_resched();
++
++		if (!static_cpu_has(X86_FEATURE_STRONGUDEREF) && addr < TASK_SIZE_MAX)
++			addr += pax_user_shadow_base;
++	}
++#endif
++
+ 	asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+ }
+ 
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
+index 5ee2687..74590b9 100644
+--- a/arch/x86/include/asm/uaccess.h
++++ b/arch/x86/include/asm/uaccess.h
+@@ -7,6 +7,7 @@
+ #include <linux/compiler.h>
+ #include <linux/thread_info.h>
+ #include <linux/string.h>
++#include <linux/sched.h>
+ #include <asm/asm.h>
+ #include <asm/page.h>
+ #include <asm/smap.h>
+@@ -29,7 +30,12 @@
+ 
+ #define get_ds()	(KERNEL_DS)
+ #define get_fs()	(current_thread_info()->addr_limit)
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
++void __set_fs(mm_segment_t x);
++void set_fs(mm_segment_t x);
++#else
+ #define set_fs(x)	(current_thread_info()->addr_limit = (x))
++#endif
+ 
+ #define segment_eq(a, b)	((a).seg == (b).seg)
+ 
+@@ -77,8 +83,33 @@
+  * checks that the pointer is in the user space range - after calling
+  * this function, memory access functions may still return -EFAULT.
+  */
+-#define access_ok(type, addr, size) \
+-	(likely(__range_not_ok(addr, size, user_addr_max()) == 0))
++#define __access_ok(type, addr, size) (likely(__range_not_ok(addr, size, \
user_addr_max()) == 0)) ++#define access_ok(type, addr, size)					\
++({									\
++	long __size = size;						\
++	unsigned long __addr = (unsigned long)addr;			\
++	unsigned long __addr_ao = __addr & PAGE_MASK;			\
++	unsigned long __end_ao = __addr + __size - 1;			\
++	bool __ret_ao = __range_not_ok(__addr, __size, user_addr_max()) == 0;\
++	if (__ret_ao && unlikely((__end_ao ^ __addr_ao) & PAGE_MASK)) {	\
++		while(__addr_ao <= __end_ao) {				\
++			char __c_ao;					\
++			__addr_ao += PAGE_SIZE;				\
++			if (__size > PAGE_SIZE)				\
++				cond_resched();				\
++			if (__get_user(__c_ao, (char __user *)__addr))	\
++				break;					\
++			if (type != VERIFY_WRITE) {			\
++				__addr = __addr_ao;			\
++				continue;				\
++			}						\
++			if (__put_user(__c_ao, (char __user *)__addr))	\
++				break;					\
++			__addr = __addr_ao;				\
++		}							\
++	}								\
++	__ret_ao;							\
++})
+ 
+ /*
+  * The exception table consists of pairs of addresses relative to the
+@@ -165,10 +196,12 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), \
0ULL, 0UL)) + 	register __inttype(*(ptr)) __val_gu asm("%edx");		\
+ 	__chk_user_ptr(ptr);						\
+ 	might_fault();							\
++	pax_open_userland();						\
+ 	asm volatile("call __get_user_%P3"				\
+ 		     : "=a" (__ret_gu), "=r" (__val_gu)			\
+ 		     : "0" (ptr), "i" (sizeof(*(ptr))));		\
+ 	(x) = (__typeof__(*(ptr))) __val_gu;				\
++	pax_close_userland();						\
+ 	__ret_gu;							\
+ })
+ 
+@@ -176,13 +209,21 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), \
0ULL, 0UL)) + 	asm volatile("call __put_user_" #size : "=a" (__ret_pu)	\
+ 		     : "0" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
+ 
+-
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define __copyuser_seg "gs;"
++#define __COPYUSER_SET_ES "pushl %%gs; popl %%es\n"
++#define __COPYUSER_RESTORE_ES "pushl %%ss; popl %%es\n"
++#else
++#define __copyuser_seg
++#define __COPYUSER_SET_ES
++#define __COPYUSER_RESTORE_ES
++#endif
+ 
+ #ifdef CONFIG_X86_32
+ #define __put_user_asm_u64(x, addr, err, errret)			\
+ 	asm volatile(ASM_STAC "\n"					\
+-		     "1:	movl %%eax,0(%2)\n"			\
+-		     "2:	movl %%edx,4(%2)\n"			\
++		     "1:	"__copyuser_seg"movl %%eax,0(%2)\n"	\
++		     "2:	"__copyuser_seg"movl %%edx,4(%2)\n"	\
+ 		     "3: " ASM_CLAC "\n"				\
+ 		     ".section .fixup,\"ax\"\n"				\
+ 		     "4:	movl %3,%0\n"				\
+@@ -195,8 +236,8 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, \
0UL)) + 
+ #define __put_user_asm_ex_u64(x, addr)					\
+ 	asm volatile(ASM_STAC "\n"					\
+-		     "1:	movl %%eax,0(%1)\n"			\
+-		     "2:	movl %%edx,4(%1)\n"			\
++		     "1:	"__copyuser_seg"movl %%eax,0(%1)\n"	\
++		     "2:	"__copyuser_seg"movl %%edx,4(%1)\n"	\
+ 		     "3: " ASM_CLAC "\n"				\
+ 		     _ASM_EXTABLE_EX(1b, 2b)				\
+ 		     _ASM_EXTABLE_EX(2b, 3b)				\
+@@ -246,7 +287,8 @@ extern void __put_user_8(void);
+ 	__typeof__(*(ptr)) __pu_val;				\
+ 	__chk_user_ptr(ptr);					\
+ 	might_fault();						\
+-	__pu_val = x;						\
++	__pu_val = (x);						\
++	pax_open_userland();					\
+ 	switch (sizeof(*(ptr))) {				\
+ 	case 1:							\
+ 		__put_user_x(1, __pu_val, ptr, __ret_pu);	\
+@@ -264,6 +306,7 @@ extern void __put_user_8(void);
+ 		__put_user_x(X, __pu_val, ptr, __ret_pu);	\
+ 		break;						\
+ 	}							\
++	pax_close_userland();					\
+ 	__ret_pu;						\
+ })
+ 
+@@ -344,8 +387,10 @@ do {									\
+ } while (0)
+ 
+ #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
++do {									\
++	pax_open_userland();						\
+ 	asm volatile(ASM_STAC "\n"					\
+-		     "1:	mov"itype" %2,%"rtype"1\n"		\
++		     "1:	"__copyuser_seg"mov"itype" %2,%"rtype"1\n"\
+ 		     "2: " ASM_CLAC "\n"				\
+ 		     ".section .fixup,\"ax\"\n"				\
+ 		     "3:	mov %3,%0\n"				\
+@@ -353,8 +398,10 @@ do {									\
+ 		     "	jmp 2b\n"					\
+ 		     ".previous\n"					\
+ 		     _ASM_EXTABLE(1b, 3b)				\
+-		     : "=r" (err), ltype(x)				\
+-		     : "m" (__m(addr)), "i" (errret), "0" (err))
++		     : "=r" (err), ltype (x)				\
++		     : "m" (__m(addr)), "i" (errret), "0" (err));	\
++	pax_close_userland();						\
++} while (0)
+ 
+ #define __get_user_size_ex(x, ptr, size)				\
+ do {									\
+@@ -378,7 +425,7 @@ do {									\
+ } while (0)
+ 
+ #define __get_user_asm_ex(x, addr, itype, rtype, ltype)			\
+-	asm volatile("1:	mov"itype" %1,%"rtype"0\n"		\
++	asm volatile("1:	"__copyuser_seg"mov"itype" %1,%"rtype"0\n"\
+ 		     "2:\n"						\
+ 		     _ASM_EXTABLE_EX(1b, 2b)				\
+ 		     : ltype(x) : "m" (__m(addr)))
+@@ -395,13 +442,24 @@ do {									\
+ 	int __gu_err;							\
+ 	unsigned long __gu_val;						\
+ 	__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);	\
+-	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
++	(x) = (__typeof__(*(ptr)))__gu_val;				\
+ 	__gu_err;							\
+ })
+ 
+ /* FIXME: this hack is definitely wrong -AK */
+ struct __large_struct { unsigned long buf[100]; };
+-#define __m(x) (*(struct __large_struct __user *)(x))
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define ____m(x)					\
++({							\
++	unsigned long ____x = (unsigned long)(x);	\
++	if (____x < pax_user_shadow_base)		\
++		____x += pax_user_shadow_base;		\
++	(typeof(x))____x;				\
++})
++#else
++#define ____m(x) (x)
++#endif
++#define __m(x) (*(struct __large_struct __user *)____m(x))
+ 
+ /*
+  * Tell gcc we read from memory instead of writing: this is because
+@@ -409,8 +467,10 @@ struct __large_struct { unsigned long buf[100]; };
+  * aliasing issues.
+  */
+ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
++do {									\
++	pax_open_userland();						\
+ 	asm volatile(ASM_STAC "\n"					\
+-		     "1:	mov"itype" %"rtype"1,%2\n"		\
++		     "1:	"__copyuser_seg"mov"itype" %"rtype"1,%2\n"\
+ 		     "2: " ASM_CLAC "\n"				\
+ 		     ".section .fixup,\"ax\"\n"				\
+ 		     "3:	mov %3,%0\n"				\
+@@ -418,10 +478,12 @@ struct __large_struct { unsigned long buf[100]; };
+ 		     ".previous\n"					\
+ 		     _ASM_EXTABLE(1b, 3b)				\
+ 		     : "=r"(err)					\
+-		     : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
++		     : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err));\
++	pax_close_userland();						\
++} while (0)
+ 
+ #define __put_user_asm_ex(x, addr, itype, rtype, ltype)			\
+-	asm volatile("1:	mov"itype" %"rtype"0,%1\n"		\
++	asm volatile("1:	"__copyuser_seg"mov"itype" %"rtype"0,%1\n"\
+ 		     "2:\n"						\
+ 		     _ASM_EXTABLE_EX(1b, 2b)				\
+ 		     : : ltype(x), "m" (__m(addr)))
+@@ -431,11 +493,13 @@ struct __large_struct { unsigned long buf[100]; };
+  */
+ #define uaccess_try	do {						\
+ 	current_thread_info()->uaccess_err = 0;				\
++	pax_open_userland();						\
+ 	stac();								\
+ 	barrier();
+ 
+ #define uaccess_catch(err)						\
+ 	clac();								\
++	pax_close_userland();						\
+ 	(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0);	\
+ } while (0)
+ 
+@@ -460,8 +524,12 @@ struct __large_struct { unsigned long buf[100]; };
+  * On error, the variable @x is set to zero.
+  */
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define __get_user(x, ptr)	get_user((x), (ptr))
++#else
+ #define __get_user(x, ptr)						\
+ 	__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
++#endif
+ 
+ /**
+  * __put_user: - Write a simple value into user space, with less checking.
+@@ -483,8 +551,12 @@ struct __large_struct { unsigned long buf[100]; };
+  * Returns zero on success, or -EFAULT on error.
+  */
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define __put_user(x, ptr)	put_user((x), (ptr))
++#else
+ #define __put_user(x, ptr)						\
+ 	__put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
++#endif
+ 
+ #define __get_user_unaligned __get_user
+ #define __put_user_unaligned __put_user
+@@ -502,7 +574,7 @@ struct __large_struct { unsigned long buf[100]; };
+ #define get_user_ex(x, ptr)	do {					\
+ 	unsigned long __gue_val;					\
+ 	__get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr))));	\
+-	(x) = (__force __typeof__(*(ptr)))__gue_val;			\
++	(x) = (__typeof__(*(ptr)))__gue_val;				\
+ } while (0)
+ 
+ #define put_user_try		uaccess_try
+@@ -519,8 +591,8 @@ strncpy_from_user(char *dst, const char __user *src, long \
count); + extern __must_check long strlen_user(const char __user *str);
+ extern __must_check long strnlen_user(const char __user *str, long n);
+ 
+-unsigned long __must_check clear_user(void __user *mem, unsigned long len);
+-unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
++unsigned long __must_check clear_user(void __user *mem, unsigned long len) \
__size_overflow(2); ++unsigned long __must_check __clear_user(void __user *mem, \
unsigned long len) __size_overflow(2); + 
+ /*
+  * movsl can be slow when source and dest are not both 8-byte aligned
+diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
+index 7f760a9..04b1c65 100644
+--- a/arch/x86/include/asm/uaccess_32.h
++++ b/arch/x86/include/asm/uaccess_32.h
+@@ -11,15 +11,15 @@
+ #include <asm/page.h>
+ 
+ unsigned long __must_check __copy_to_user_ll
+-		(void __user *to, const void *from, unsigned long n);
++		(void __user *to, const void *from, unsigned long n) __size_overflow(3);
+ unsigned long __must_check __copy_from_user_ll
+-		(void *to, const void __user *from, unsigned long n);
++		(void *to, const void __user *from, unsigned long n) __size_overflow(3);
+ unsigned long __must_check __copy_from_user_ll_nozero
+-		(void *to, const void __user *from, unsigned long n);
++		(void *to, const void __user *from, unsigned long n) __size_overflow(3);
+ unsigned long __must_check __copy_from_user_ll_nocache
+-		(void *to, const void __user *from, unsigned long n);
++		(void *to, const void __user *from, unsigned long n) __size_overflow(3);
+ unsigned long __must_check __copy_from_user_ll_nocache_nozero
+-		(void *to, const void __user *from, unsigned long n);
++		(void *to, const void __user *from, unsigned long n) __size_overflow(3);
+ 
+ /**
+  * __copy_to_user_inatomic: - Copy a block of data into user space, with less \
checking. +@@ -43,6 +43,11 @@ unsigned long __must_check \
__copy_from_user_ll_nocache_nozero + static __always_inline unsigned long \
__must_check + __copy_to_user_inatomic(void __user *to, const void *from, unsigned \
long n) + {
++	if ((long)n < 0)
++		return n;
++
++	check_object_size(from, n, true);
++
+ 	if (__builtin_constant_p(n)) {
+ 		unsigned long ret;
+ 
+@@ -82,12 +87,16 @@ static __always_inline unsigned long __must_check
+ __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+ 	might_fault();
++
+ 	return __copy_to_user_inatomic(to, from, n);
+ }
+ 
+ static __always_inline unsigned long
+ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
+ {
++	if ((long)n < 0)
++		return n;
++
+ 	/* Avoid zeroing the tail if the copy fails..
+ 	 * If 'n' is constant and 1, 2, or 4, we do still zero on a failure,
+ 	 * but as the zeroing behaviour is only significant when n is not
+@@ -137,6 +146,12 @@ static __always_inline unsigned long
+ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ 	might_fault();
++
++	if ((long)n < 0)
++		return n;
++
++	check_object_size(to, n, false);
++
+ 	if (__builtin_constant_p(n)) {
+ 		unsigned long ret;
+ 
+@@ -159,6 +174,10 @@ static __always_inline unsigned long \
__copy_from_user_nocache(void *to, + 				const void __user *from, unsigned long n)
+ {
+ 	might_fault();
++
++	if ((long)n < 0)
++		return n;
++
+ 	if (__builtin_constant_p(n)) {
+ 		unsigned long ret;
+ 
+@@ -181,15 +200,19 @@ static __always_inline unsigned long
+ __copy_from_user_inatomic_nocache(void *to, const void __user *from,
+ 				  unsigned long n)
+ {
+-       return __copy_from_user_ll_nocache_nozero(to, from, n);
++	if ((long)n < 0)
++		return n;
++
++	return __copy_from_user_ll_nocache_nozero(to, from, n);
+ }
+ 
+-unsigned long __must_check copy_to_user(void __user *to,
+-					const void *from, unsigned long n);
+-unsigned long __must_check _copy_from_user(void *to,
+-					  const void __user *from,
+-					  unsigned long n);
+-
++extern void copy_to_user_overflow(void)
++#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
++	__compiletime_error("copy_to_user() buffer size is not provably correct")
++#else
++	__compiletime_warning("copy_to_user() buffer size is not provably correct")
++#endif
++;
+ 
+ extern void copy_from_user_overflow(void)
+ #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
+@@ -199,17 +222,60 @@ extern void copy_from_user_overflow(void)
+ #endif
+ ;
+ 
+-static inline unsigned long __must_check copy_from_user(void *to,
+-					  const void __user *from,
+-					  unsigned long n)
++/**
++ * copy_to_user: - Copy a block of data into user space.
++ * @to:   Destination address, in user space.
++ * @from: Source address, in kernel space.
++ * @n:    Number of bytes to copy.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * Copy data from kernel space to user space.
++ *
++ * Returns number of bytes that could not be copied.
++ * On success, this will be zero.
++ */
++static inline unsigned long __must_check
++copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+-	int sz = __compiletime_object_size(to);
++	size_t sz = __compiletime_object_size(from);
+ 
+-	if (likely(sz == -1 || sz >= n))
+-		n = _copy_from_user(to, from, n);
+-	else
++	if (unlikely(sz != (size_t)-1 && sz < n))
++		copy_to_user_overflow();
++	else if (access_ok(VERIFY_WRITE, to, n))
++		n = __copy_to_user(to, from, n);
++	return n;
++}
++
++/**
++ * copy_from_user: - Copy a block of data from user space.
++ * @to:   Destination address, in kernel space.
++ * @from: Source address, in user space.
++ * @n:    Number of bytes to copy.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * Copy data from user space to kernel space.
++ *
++ * Returns number of bytes that could not be copied.
++ * On success, this will be zero.
++ *
++ * If some data could not be copied, this function will pad the copied
++ * data to the requested size using zero bytes.
++ */
++static inline unsigned long __must_check
++copy_from_user(void *to, const void __user *from, unsigned long n)
++{
++	size_t sz = __compiletime_object_size(to);
++
++	check_object_size(to, n, false);
++
++	if (unlikely(sz != (size_t)-1 && sz < n))
+ 		copy_from_user_overflow();
+-
++	else if (access_ok(VERIFY_READ, from, n))
++		n = __copy_from_user(to, from, n);
++	else if ((long)n > 0)
++		memset(to, 0, n);
+ 	return n;
+ }
+ 
+diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
+index 4f7923d..20cb24e 100644
+--- a/arch/x86/include/asm/uaccess_64.h
++++ b/arch/x86/include/asm/uaccess_64.h
+@@ -10,6 +10,9 @@
+ #include <asm/alternative.h>
+ #include <asm/cpufeature.h>
+ #include <asm/page.h>
++#include <asm/pgtable.h>
++
++#define set_fs(x)	(current_thread_info()->addr_limit = (x))
+ 
+ /*
+  * Copy To/From Userspace
+@@ -17,13 +20,13 @@
+ 
+ /* Handles exceptions in both to and from, but doesn't do access_ok */
+ __must_check unsigned long
+-copy_user_enhanced_fast_string(void *to, const void *from, unsigned len);
++copy_user_enhanced_fast_string(void *to, const void *from, unsigned len) \
__size_overflow(3); + __must_check unsigned long
+-copy_user_generic_string(void *to, const void *from, unsigned len);
++copy_user_generic_string(void *to, const void *from, unsigned len) \
__size_overflow(3); + __must_check unsigned long
+-copy_user_generic_unrolled(void *to, const void *from, unsigned len);
++copy_user_generic_unrolled(void *to, const void *from, unsigned len) \
__size_overflow(3); + 
+-static __always_inline __must_check unsigned long
++static __always_inline __must_check  __size_overflow(3) unsigned long
+ copy_user_generic(void *to, const void *from, unsigned len)
+ {
+ 	unsigned ret;
+@@ -41,142 +44,204 @@ copy_user_generic(void *to, const void *from, unsigned len)
+ 			 ASM_OUTPUT2("=a" (ret), "=D" (to), "=S" (from),
+ 				     "=d" (len)),
+ 			 "1" (to), "2" (from), "3" (len)
+-			 : "memory", "rcx", "r8", "r9", "r10", "r11");
++			 : "memory", "rcx", "r8", "r9", "r11");
+ 	return ret;
+ }
+ 
++static __always_inline __must_check unsigned long
++__copy_to_user(void __user *to, const void *from, unsigned long len);
++static __always_inline __must_check unsigned long
++__copy_from_user(void *to, const void __user *from, unsigned long len);
+ __must_check unsigned long
+-_copy_to_user(void __user *to, const void *from, unsigned len);
+-__must_check unsigned long
+-_copy_from_user(void *to, const void __user *from, unsigned len);
+-__must_check unsigned long
+-copy_in_user(void __user *to, const void __user *from, unsigned len);
++copy_in_user(void __user *to, const void __user *from, unsigned long len);
++
++extern void copy_to_user_overflow(void)
++#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
++	__compiletime_error("copy_to_user() buffer size is not provably correct")
++#else
++	__compiletime_warning("copy_to_user() buffer size is not provably correct")
++#endif
++;
++
++extern void copy_from_user_overflow(void)
++#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
++	__compiletime_error("copy_from_user() buffer size is not provably correct")
++#else
++	__compiletime_warning("copy_from_user() buffer size is not provably correct")
++#endif
++;
+ 
+ static inline unsigned long __must_check copy_from_user(void *to,
+ 					  const void __user *from,
+ 					  unsigned long n)
+ {
+-	int sz = __compiletime_object_size(to);
+-
+ 	might_fault();
+-	if (likely(sz == -1 || sz >= n))
+-		n = _copy_from_user(to, from, n);
+-#ifdef CONFIG_DEBUG_VM
+-	else
+-		WARN(1, "Buffer overflow detected!\n");
+-#endif
++
++	check_object_size(to, n, false);
++
++	if (access_ok(VERIFY_READ, from, n))
++		n = __copy_from_user(to, from, n);
++	else if (n < INT_MAX)
++		memset(to, 0, n);
+ 	return n;
+ }
+ 
+ static __always_inline __must_check
+-int copy_to_user(void __user *dst, const void *src, unsigned size)
++int copy_to_user(void __user *dst, const void *src, unsigned long size)
+ {
+ 	might_fault();
+ 
+-	return _copy_to_user(dst, src, size);
++	if (access_ok(VERIFY_WRITE, dst, size))
++		size = __copy_to_user(dst, src, size);
++	return size;
+ }
+ 
+ static __always_inline __must_check
+-int __copy_from_user(void *dst, const void __user *src, unsigned size)
++unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long \
size) + {
+-	int ret = 0;
++	size_t sz = __compiletime_object_size(dst);
++	unsigned ret = 0;
+ 
+ 	might_fault();
++
++	if (size > INT_MAX)
++		return size;
++
++	check_object_size(dst, size, false);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_READ, src, size))
++		return size;
++#endif
++
++	if (unlikely(sz != (size_t)-1 && sz < size)) {
++		copy_from_user_overflow();
++		return size;
++	}
++
+ 	if (!__builtin_constant_p(size))
+-		return copy_user_generic(dst, (__force void *)src, size);
++		return copy_user_generic(dst, (__force_kernel const void *)____m(src), size);
+ 	switch (size) {
+-	case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
++	case 1:__get_user_asm(*(u8 *)dst, (const u8 __user *)src,
+ 			      ret, "b", "b", "=q", 1);
+ 		return ret;
+-	case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
++	case 2:__get_user_asm(*(u16 *)dst, (const u16 __user *)src,
+ 			      ret, "w", "w", "=r", 2);
+ 		return ret;
+-	case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
++	case 4:__get_user_asm(*(u32 *)dst, (const u32 __user *)src,
+ 			      ret, "l", "k", "=r", 4);
+ 		return ret;
+-	case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
++	case 8:__get_user_asm(*(u64 *)dst, (const u64 __user *)src,
+ 			      ret, "q", "", "=r", 8);
+ 		return ret;
+ 	case 10:
+-		__get_user_asm(*(u64 *)dst, (u64 __user *)src,
++		__get_user_asm(*(u64 *)dst, (const u64 __user *)src,
+ 			       ret, "q", "", "=r", 10);
+ 		if (unlikely(ret))
+ 			return ret;
+ 		__get_user_asm(*(u16 *)(8 + (char *)dst),
+-			       (u16 __user *)(8 + (char __user *)src),
++			       (const u16 __user *)(8 + (const char __user *)src),
+ 			       ret, "w", "w", "=r", 2);
+ 		return ret;
+ 	case 16:
+-		__get_user_asm(*(u64 *)dst, (u64 __user *)src,
++		__get_user_asm(*(u64 *)dst, (const u64 __user *)src,
+ 			       ret, "q", "", "=r", 16);
+ 		if (unlikely(ret))
+ 			return ret;
+ 		__get_user_asm(*(u64 *)(8 + (char *)dst),
+-			       (u64 __user *)(8 + (char __user *)src),
++			       (const u64 __user *)(8 + (const char __user *)src),
+ 			       ret, "q", "", "=r", 8);
+ 		return ret;
+ 	default:
+-		return copy_user_generic(dst, (__force void *)src, size);
++		return copy_user_generic(dst, (__force_kernel const void *)____m(src), size);
+ 	}
+ }
+ 
+ static __always_inline __must_check
+-int __copy_to_user(void __user *dst, const void *src, unsigned size)
++unsigned long __copy_to_user(void __user *dst, const void *src, unsigned long size)
+ {
+-	int ret = 0;
++	size_t sz = __compiletime_object_size(src);
++	unsigned ret = 0;
+ 
+ 	might_fault();
++
++	if (size > INT_MAX)
++		return size;
++
++	check_object_size(src, size, true);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_WRITE, dst, size))
++		return size;
++#endif
++
++	if (unlikely(sz != (size_t)-1 && sz < size)) {
++		copy_to_user_overflow();
++		return size;
++	}
++
+ 	if (!__builtin_constant_p(size))
+-		return copy_user_generic((__force void *)dst, src, size);
++		return copy_user_generic((__force_kernel void *)____m(dst), src, size);
+ 	switch (size) {
+-	case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
++	case 1:__put_user_asm(*(const u8 *)src, (u8 __user *)dst,
+ 			      ret, "b", "b", "iq", 1);
+ 		return ret;
+-	case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
++	case 2:__put_user_asm(*(const u16 *)src, (u16 __user *)dst,
+ 			      ret, "w", "w", "ir", 2);
+ 		return ret;
+-	case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
++	case 4:__put_user_asm(*(const u32 *)src, (u32 __user *)dst,
+ 			      ret, "l", "k", "ir", 4);
+ 		return ret;
+-	case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
++	case 8:__put_user_asm(*(const u64 *)src, (u64 __user *)dst,
+ 			      ret, "q", "", "er", 8);
+ 		return ret;
+ 	case 10:
+-		__put_user_asm(*(u64 *)src, (u64 __user *)dst,
++		__put_user_asm(*(const u64 *)src, (u64 __user *)dst,
+ 			       ret, "q", "", "er", 10);
+ 		if (unlikely(ret))
+ 			return ret;
+ 		asm("":::"memory");
+-		__put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
++		__put_user_asm(4[(const u16 *)src], 4 + (u16 __user *)dst,
+ 			       ret, "w", "w", "ir", 2);
+ 		return ret;
+ 	case 16:
+-		__put_user_asm(*(u64 *)src, (u64 __user *)dst,
++		__put_user_asm(*(const u64 *)src, (u64 __user *)dst,
+ 			       ret, "q", "", "er", 16);
+ 		if (unlikely(ret))
+ 			return ret;
+ 		asm("":::"memory");
+-		__put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
++		__put_user_asm(1[(const u64 *)src], 1 + (u64 __user *)dst,
+ 			       ret, "q", "", "er", 8);
+ 		return ret;
+ 	default:
+-		return copy_user_generic((__force void *)dst, src, size);
++		return copy_user_generic((__force_kernel void *)____m(dst), src, size);
+ 	}
+ }
+ 
+ static __always_inline __must_check
+-int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
++unsigned long __copy_in_user(void __user *dst, const void __user *src, unsigned \
long size) + {
+-	int ret = 0;
++	unsigned ret = 0;
+ 
+ 	might_fault();
++
++	if (size > INT_MAX)
++		return size;
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_READ, src, size))
++		return size;
++	if (!__access_ok(VERIFY_WRITE, dst, size))
++		return size;
++#endif
++
+ 	if (!__builtin_constant_p(size))
+-		return copy_user_generic((__force void *)dst,
+-					 (__force void *)src, size);
++		return copy_user_generic((__force_kernel void *)____m(dst),
++					 (__force_kernel const void *)____m(src), size);
+ 	switch (size) {
+ 	case 1: {
+ 		u8 tmp;
+-		__get_user_asm(tmp, (u8 __user *)src,
++		__get_user_asm(tmp, (const u8 __user *)src,
+ 			       ret, "b", "b", "=q", 1);
+ 		if (likely(!ret))
+ 			__put_user_asm(tmp, (u8 __user *)dst,
+@@ -185,7 +250,7 @@ int __copy_in_user(void __user *dst, const void __user *src, \
unsigned size) + 	}
+ 	case 2: {
+ 		u16 tmp;
+-		__get_user_asm(tmp, (u16 __user *)src,
++		__get_user_asm(tmp, (const u16 __user *)src,
+ 			       ret, "w", "w", "=r", 2);
+ 		if (likely(!ret))
+ 			__put_user_asm(tmp, (u16 __user *)dst,
+@@ -195,7 +260,7 @@ int __copy_in_user(void __user *dst, const void __user *src, \
unsigned size) + 
+ 	case 4: {
+ 		u32 tmp;
+-		__get_user_asm(tmp, (u32 __user *)src,
++		__get_user_asm(tmp, (const u32 __user *)src,
+ 			       ret, "l", "k", "=r", 4);
+ 		if (likely(!ret))
+ 			__put_user_asm(tmp, (u32 __user *)dst,
+@@ -204,7 +269,7 @@ int __copy_in_user(void __user *dst, const void __user *src, \
unsigned size) + 	}
+ 	case 8: {
+ 		u64 tmp;
+-		__get_user_asm(tmp, (u64 __user *)src,
++		__get_user_asm(tmp, (const u64 __user *)src,
+ 			       ret, "q", "", "=r", 8);
+ 		if (likely(!ret))
+ 			__put_user_asm(tmp, (u64 __user *)dst,
+@@ -212,41 +277,74 @@ int __copy_in_user(void __user *dst, const void __user *src, \
unsigned size) + 		return ret;
+ 	}
+ 	default:
+-		return copy_user_generic((__force void *)dst,
+-					 (__force void *)src, size);
++		return copy_user_generic((__force_kernel void *)____m(dst),
++					 (__force_kernel const void *)____m(src), size);
+ 	}
+ }
+ 
+-static __must_check __always_inline int
+-__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
++static __must_check __always_inline unsigned long
++__copy_from_user_inatomic(void *dst, const void __user *src, unsigned long size)
+ {
+-	return copy_user_generic(dst, (__force const void *)src, size);
++	if (size > INT_MAX)
++		return size;
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_READ, src, size))
++		return size;
++#endif
++
++	return copy_user_generic(dst, (__force_kernel const void *)____m(src), size);
+ }
+ 
+-static __must_check __always_inline int
+-__copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
++static __must_check __always_inline unsigned long
++__copy_to_user_inatomic(void __user *dst, const void *src, unsigned long size)
+ {
+-	return copy_user_generic((__force void *)dst, src, size);
++	if (size > INT_MAX)
++		return size;
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_WRITE, dst, size))
++		return size;
++#endif
++
++	return copy_user_generic((__force_kernel void *)____m(dst), src, size);
+ }
+ 
+-extern long __copy_user_nocache(void *dst, const void __user *src,
+-				unsigned size, int zerorest);
++extern unsigned long __copy_user_nocache(void *dst, const void __user *src,
++				unsigned long size, int zerorest) __size_overflow(3);
+ 
+-static inline int
+-__copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
++static inline unsigned long
++__copy_from_user_nocache(void *dst, const void __user *src, unsigned long size)
+ {
+ 	might_fault();
++
++	if (size > INT_MAX)
++		return size;
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_READ, src, size))
++		return size;
++#endif
++
+ 	return __copy_user_nocache(dst, src, size, 1);
+ }
+ 
+-static inline int
++static inline unsigned long
+ __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
+-				  unsigned size)
++				  unsigned long size)
+ {
++	if (size > INT_MAX)
++		return size;
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (!__access_ok(VERIFY_READ, src, size))
++		return size;
++#endif
++
+ 	return __copy_user_nocache(dst, src, size, 0);
+ }
+ 
+ unsigned long
+-copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
++copy_user_handle_tail(char __user *to, char __user *from, unsigned long len, \
unsigned zerorest) __size_overflow(3); + 
+ #endif /* _ASM_X86_UACCESS_64_H */
+diff --git a/arch/x86/include/asm/word-at-a-time.h \
b/arch/x86/include/asm/word-at-a-time.h +index 5b238981..77fdd78 100644
+--- a/arch/x86/include/asm/word-at-a-time.h
++++ b/arch/x86/include/asm/word-at-a-time.h
+@@ -11,7 +11,7 @@
+  * and shift, for example.
+  */
+ struct word_at_a_time {
+-	const unsigned long one_bits, high_bits;
++	unsigned long one_bits, high_bits;
+ };
+ 
+ #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
+index 828a156..650e625 100644
+--- a/arch/x86/include/asm/x86_init.h
++++ b/arch/x86/include/asm/x86_init.h
+@@ -129,7 +129,7 @@ struct x86_init_ops {
+ 	struct x86_init_timers		timers;
+ 	struct x86_init_iommu		iommu;
+ 	struct x86_init_pci		pci;
+-};
++} __no_const;
+ 
+ /**
+  * struct x86_cpuinit_ops - platform specific cpu hotplug setups
+@@ -140,7 +140,7 @@ struct x86_cpuinit_ops {
+ 	void (*setup_percpu_clockev)(void);
+ 	void (*early_percpu_clock_init)(void);
+ 	void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node);
+-};
++} __no_const;
+ 
+ struct timespec;
+ 
+@@ -168,7 +168,7 @@ struct x86_platform_ops {
+ 	void (*save_sched_clock_state)(void);
+ 	void (*restore_sched_clock_state)(void);
+ 	void (*apic_post_init)(void);
+-};
++} __no_const;
+ 
+ struct pci_dev;
+ struct msi_msg;
+@@ -182,7 +182,7 @@ struct x86_msi_ops {
+ 	void (*teardown_msi_irqs)(struct pci_dev *dev);
+ 	void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
+ 	int  (*setup_hpet_msi)(unsigned int irq, unsigned int id);
+-};
++} __no_const;
+ 
+ struct IO_APIC_route_entry;
+ struct io_apic_irq_attr;
+@@ -203,7 +203,7 @@ struct x86_io_apic_ops {
+ 				       unsigned int destination, int vector,
+ 				       struct io_apic_irq_attr *attr);
+ 	void		(*eoi_ioapic_pin)(int apic, int pin, int vector);
+-};
++} __no_const;
+ 
+ extern struct x86_init_ops x86_init;
+ extern struct x86_cpuinit_ops x86_cpuinit;
+diff --git a/arch/x86/include/asm/xsave.h b/arch/x86/include/asm/xsave.h
+index 0415cda..3b22adc 100644
+--- a/arch/x86/include/asm/xsave.h
++++ b/arch/x86/include/asm/xsave.h
+@@ -70,8 +70,11 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+ 	if (unlikely(err))
+ 		return -EFAULT;
+ 
++	pax_open_userland();
+ 	__asm__ __volatile__(ASM_STAC "\n"
+-			     "1: .byte " REX_PREFIX "0x0f,0xae,0x27\n"
++			     "1:"
++			     __copyuser_seg
++			     ".byte " REX_PREFIX "0x0f,0xae,0x27\n"
+ 			     "2: " ASM_CLAC "\n"
+ 			     ".section .fixup,\"ax\"\n"
+ 			     "3:  movl $-1,%[err]\n"
+@@ -81,18 +84,22 @@ static inline int xsave_user(struct xsave_struct __user *buf)
+ 			     : [err] "=r" (err)
+ 			     : "D" (buf), "a" (-1), "d" (-1), "0" (0)
+ 			     : "memory");
++	pax_close_userland();
+ 	return err;
+ }
+ 
+ static inline int xrestore_user(struct xsave_struct __user *buf, u64 mask)
+ {
+ 	int err;
+-	struct xsave_struct *xstate = ((__force struct xsave_struct *)buf);
++	struct xsave_struct *xstate = ((__force_kernel struct xsave_struct *)buf);
+ 	u32 lmask = mask;
+ 	u32 hmask = mask >> 32;
+ 
++	pax_open_userland();
+ 	__asm__ __volatile__(ASM_STAC "\n"
+-			     "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n"
++			     "1:"
++			     __copyuser_seg
++			     ".byte " REX_PREFIX "0x0f,0xae,0x2f\n"
+ 			     "2: " ASM_CLAC "\n"
+ 			     ".section .fixup,\"ax\"\n"
+ 			     "3:  movl $-1,%[err]\n"
+@@ -102,6 +109,7 @@ static inline int xrestore_user(struct xsave_struct __user *buf, \
u64 mask) + 			     : [err] "=r" (err)
+ 			     : "D" (xstate), "a" (lmask), "d" (hmask), "0" (0)
+ 			     : "memory");	/* memory required? */
++	pax_close_userland();
+ 	return err;
+ }
+ 
+diff --git a/arch/x86/include/uapi/asm/e820.h b/arch/x86/include/uapi/asm/e820.h
+index bbae024..e1528f9 100644
+--- a/arch/x86/include/uapi/asm/e820.h
++++ b/arch/x86/include/uapi/asm/e820.h
+@@ -63,7 +63,7 @@ struct e820map {
+ #define ISA_START_ADDRESS	0xa0000
+ #define ISA_END_ADDRESS		0x100000
+ 
+-#define BIOS_BEGIN		0x000a0000
++#define BIOS_BEGIN		0x000c0000
+ #define BIOS_END		0x00100000
+ 
+ #define BIOS_ROM_BASE		0xffe00000
+diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
+index 88d99ea..9fc7e17 100644
+--- a/arch/x86/kernel/Makefile
++++ b/arch/x86/kernel/Makefile
+@@ -24,7 +24,7 @@ obj-y			+= time.o ioport.o ldt.o dumpstack.o nmi.o
+ obj-y			+= setup.o x86_init.o i8259.o irqinit.o jump_label.o
+ obj-$(CONFIG_IRQ_WORK)  += irq_work.o
+ obj-y			+= probe_roms.o
+-obj-$(CONFIG_X86_32)	+= i386_ksyms_32.o
++obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
+ obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
+ obj-y			+= syscall_$(BITS).o
+ obj-$(CONFIG_X86_64)	+= vsyscall_64.o
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index 2627a81..cd8325e 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -1368,7 +1368,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct \
dmi_system_id *d) +  * If your system is blacklisted here, but you find that \
acpi=force +  * works for you, please contact linux-acpi at vger.kernel.org
+  */
+-static struct dmi_system_id __initdata acpi_dmi_table[] = {
++static const struct dmi_system_id __initconst acpi_dmi_table[] = {
+ 	/*
+ 	 * Boxes that need ACPI disabled
+ 	 */
+@@ -1443,7 +1443,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
+ };
+ 
+ /* second table for DMI checks that should run after early-quirks */
+-static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
++static const struct dmi_system_id __initconst acpi_dmi_table_late[] = {
+ 	/*
+ 	 * HP laptops which use a DSDT reporting as HP/SB400/10000,
+ 	 * which includes some code which overrides all temperature
+diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
+index 3312010..a65ca7b 100644
+--- a/arch/x86/kernel/acpi/sleep.c
++++ b/arch/x86/kernel/acpi/sleep.c
+@@ -88,8 +88,12 @@ int x86_acpi_suspend_lowlevel(void)
+ #else /* CONFIG_64BIT */
+ #ifdef CONFIG_SMP
+ 	stack_start = (unsigned long)temp_stack + sizeof(temp_stack);
++
++	pax_open_kernel();
+ 	early_gdt_descr.address =
+ 			(unsigned long)get_cpu_gdt_table(smp_processor_id());
++	pax_close_kernel();
++
+ 	initial_gs = per_cpu_offset(smp_processor_id());
+ #endif
+ 	initial_code = (unsigned long)wakeup_long64;
+diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
+index d1daa66..59fecba 100644
+--- a/arch/x86/kernel/acpi/wakeup_32.S
++++ b/arch/x86/kernel/acpi/wakeup_32.S
+@@ -29,13 +29,11 @@ wakeup_pmode_return:
+ 	# and restore the stack ... but you need gdt for this to work
+ 	movl	saved_context_esp, %esp
+ 
+-	movl	%cs:saved_magic, %eax
+-	cmpl	$0x12345678, %eax
++	cmpl	$0x12345678, saved_magic
+ 	jne	bogus_magic
+ 
+ 	# jump to place where we left off
+-	movl	saved_eip, %eax
+-	jmp	*%eax
++	jmp	*(saved_eip)
+ 
+ bogus_magic:
+ 	jmp	bogus_magic
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index c15cf9a..0e63558 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -268,6 +268,13 @@ void __init_or_module apply_alternatives(struct alt_instr \
*start, + 	 */
+ 	for (a = start; a < end; a++) {
+ 		instr = (u8 *)&a->instr_offset + a->instr_offset;
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		instr += ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++		if (instr < (u8 *)_text || (u8 *)_einittext <= instr)
++			instr -= ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
+ 		replacement = (u8 *)&a->repl_offset + a->repl_offset;
+ 		BUG_ON(a->replacementlen > a->instrlen);
+ 		BUG_ON(a->instrlen > sizeof(insnbuf));
+@@ -299,10 +306,16 @@ static void alternatives_smp_lock(const s32 *start, const s32 \
*end, + 	for (poff = start; poff < end; poff++) {
+ 		u8 *ptr = (u8 *)poff + *poff;
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		ptr += ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++		if (ptr < (u8 *)_text || (u8 *)_einittext <= ptr)
++			ptr -= ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
+ 		if (!*poff || ptr < text || ptr >= text_end)
+ 			continue;
+ 		/* turn DS segment override prefix into lock prefix */
+-		if (*ptr == 0x3e)
++		if (*ktla_ktva(ptr) == 0x3e)
+ 			text_poke(ptr, ((unsigned char []){0xf0}), 1);
+ 	}
+ 	mutex_unlock(&text_mutex);
+@@ -317,10 +330,16 @@ static void alternatives_smp_unlock(const s32 *start, const \
s32 *end, + 	for (poff = start; poff < end; poff++) {
+ 		u8 *ptr = (u8 *)poff + *poff;
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		ptr += ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++		if (ptr < (u8 *)_text || (u8 *)_einittext <= ptr)
++			ptr -= ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
+ 		if (!*poff || ptr < text || ptr >= text_end)
+ 			continue;
+ 		/* turn lock prefix into DS segment override prefix */
+-		if (*ptr == 0xf0)
++		if (*ktla_ktva(ptr) == 0xf0)
+ 			text_poke(ptr, ((unsigned char []){0x3E}), 1);
+ 	}
+ 	mutex_unlock(&text_mutex);
+@@ -468,7 +487,7 @@ void __init_or_module apply_paravirt(struct paravirt_patch_site \
*start, + 
+ 		BUG_ON(p->len > MAX_PATCH_LEN);
+ 		/* prep the buffer with the original instructions */
+-		memcpy(insnbuf, p->instr, p->len);
++		memcpy(insnbuf, ktla_ktva(p->instr), p->len);
+ 		used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
+ 					 (unsigned long)p->instr, p->len);
+ 
+@@ -515,7 +534,7 @@ void __init alternative_instructions(void)
+ 	if (!uniproc_patched || num_possible_cpus() == 1)
+ 		free_init_pages("SMP alternatives",
+ 				(unsigned long)__smp_locks,
+-				(unsigned long)__smp_locks_end);
++				PAGE_ALIGN((unsigned long)__smp_locks_end));
+ #endif
+ 
+ 	apply_paravirt(__parainstructions, __parainstructions_end);
+@@ -535,13 +554,17 @@ void __init alternative_instructions(void)
+  * instructions. And on the local CPU you need to be protected again NMI or MCE
+  * handlers seeing an inconsistent instruction while you patch.
+  */
+-void *__init_or_module text_poke_early(void *addr, const void *opcode,
++void *__kprobes text_poke_early(void *addr, const void *opcode,
+ 					      size_t len)
+ {
+ 	unsigned long flags;
+ 	local_irq_save(flags);
+-	memcpy(addr, opcode, len);
++
++	pax_open_kernel();
++	memcpy(ktla_ktva(addr), opcode, len);
+ 	sync_core();
++	pax_close_kernel();
++
+ 	local_irq_restore(flags);
+ 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
+ 	   that causes hangs on some VIA CPUs. */
+@@ -563,36 +586,22 @@ void *__init_or_module text_poke_early(void *addr, const void \
*opcode, +  */
+ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
+ {
+-	unsigned long flags;
+-	char *vaddr;
++	unsigned char *vaddr = ktla_ktva(addr);
+ 	struct page *pages[2];
+-	int i;
++	size_t i;
+ 
+ 	if (!core_kernel_text((unsigned long)addr)) {
+-		pages[0] = vmalloc_to_page(addr);
+-		pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
++		pages[0] = vmalloc_to_page(vaddr);
++		pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
+ 	} else {
+-		pages[0] = virt_to_page(addr);
++		pages[0] = virt_to_page(vaddr);
+ 		WARN_ON(!PageReserved(pages[0]));
+-		pages[1] = virt_to_page(addr + PAGE_SIZE);
++		pages[1] = virt_to_page(vaddr + PAGE_SIZE);
+ 	}
+ 	BUG_ON(!pages[0]);
+-	local_irq_save(flags);
+-	set_fixmap(FIX_TEXT_POKE0, page_to_phys(pages[0]));
+-	if (pages[1])
+-		set_fixmap(FIX_TEXT_POKE1, page_to_phys(pages[1]));
+-	vaddr = (char *)fix_to_virt(FIX_TEXT_POKE0);
+-	memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
+-	clear_fixmap(FIX_TEXT_POKE0);
+-	if (pages[1])
+-		clear_fixmap(FIX_TEXT_POKE1);
+-	local_flush_tlb();
+-	sync_core();
+-	/* Could also do a CLFLUSH here to speed up CPU recovery; but
+-	   that causes hangs on some VIA CPUs. */
++	text_poke_early(addr, opcode, len);
+ 	for (i = 0; i < len; i++)
+-		BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
+-	local_irq_restore(flags);
++		BUG_ON((vaddr)[i] != ((const unsigned char *)opcode)[i]);
+ 	return addr;
+ }
+ 
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index eca89c5..d566b78 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -190,7 +190,7 @@ int first_system_vector = 0xfe;
+ /*
+  * Debug level, exported for io_apic.c
+  */
+-unsigned int apic_verbosity;
++int apic_verbosity;
+ 
+ int pic_mode;
+ 
+@@ -1985,7 +1985,7 @@ static inline void __smp_error_interrupt(struct pt_regs *regs)
+ 	apic_write(APIC_ESR, 0);
+ 	v1 = apic_read(APIC_ESR);
+ 	ack_APIC_irq();
+-	atomic_inc(&irq_err_count);
++	atomic_inc_unchecked(&irq_err_count);
+ 
+ 	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
+ 		    smp_processor_id(), v0 , v1);
+diff --git a/arch/x86/kernel/apic/apic_flat_64.c \
b/arch/x86/kernel/apic/apic_flat_64.c +index 00c77cf..2dc6a2d 100644
+--- a/arch/x86/kernel/apic/apic_flat_64.c
++++ b/arch/x86/kernel/apic/apic_flat_64.c
+@@ -157,7 +157,7 @@ static int flat_probe(void)
+ 	return 1;
+ }
+ 
+-static struct apic apic_flat =  {
++static struct apic apic_flat __read_only =  {
+ 	.name				= "flat",
+ 	.probe				= flat_probe,
+ 	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
+@@ -271,7 +271,7 @@ static int physflat_probe(void)
+ 	return 0;
+ }
+ 
+-static struct apic apic_physflat =  {
++static struct apic apic_physflat __read_only =  {
+ 
+ 	.name				= "physical flat",
+ 	.probe				= physflat_probe,
+diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
+index e145f28..2752888 100644
+--- a/arch/x86/kernel/apic/apic_noop.c
++++ b/arch/x86/kernel/apic/apic_noop.c
+@@ -119,7 +119,7 @@ static void noop_apic_write(u32 reg, u32 v)
+ 	WARN_ON_ONCE(cpu_has_apic && !disable_apic);
+ }
+ 
+-struct apic apic_noop = {
++struct apic apic_noop __read_only = {
+ 	.name				= "noop",
+ 	.probe				= noop_probe,
+ 	.acpi_madt_oem_check		= NULL,
+diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
+index d50e364..543bee3 100644
+--- a/arch/x86/kernel/apic/bigsmp_32.c
++++ b/arch/x86/kernel/apic/bigsmp_32.c
+@@ -152,7 +152,7 @@ static int probe_bigsmp(void)
+ 	return dmi_bigsmp;
+ }
+ 
+-static struct apic apic_bigsmp = {
++static struct apic apic_bigsmp __read_only = {
+ 
+ 	.name				= "bigsmp",
+ 	.probe				= probe_bigsmp,
+diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
+index c552247..587a316 100644
+--- a/arch/x86/kernel/apic/es7000_32.c
++++ b/arch/x86/kernel/apic/es7000_32.c
+@@ -608,8 +608,7 @@ static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, \
char *oem, + 	return ret && es7000_apic_is_cluster();
+ }
+ 
+-/* We've been warned by a false positive warning.Use __refdata to keep calm. */
+-static struct apic __refdata apic_es7000_cluster = {
++static struct apic apic_es7000_cluster __read_only = {
+ 
+ 	.name				= "es7000",
+ 	.probe				= probe_es7000,
+@@ -675,7 +674,7 @@ static struct apic __refdata apic_es7000_cluster = {
+ 	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
+ };
+ 
+-static struct apic __refdata apic_es7000 = {
++static struct apic apic_es7000 __read_only = {
+ 
+ 	.name				= "es7000",
+ 	.probe				= probe_es7000,
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index 9ed796c..e930fe4 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -1060,7 +1060,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,
+ }
+ EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+ 
+-void lock_vector_lock(void)
++void lock_vector_lock(void) __acquires(vector_lock)
+ {
+ 	/* Used to the online set of cpus does not change
+ 	 * during assign_irq_vector.
+@@ -1068,7 +1068,7 @@ void lock_vector_lock(void)
+ 	raw_spin_lock(&vector_lock);
+ }
+ 
+-void unlock_vector_lock(void)
++void unlock_vector_lock(void) __releases(vector_lock)
+ {
+ 	raw_spin_unlock(&vector_lock);
+ }
+@@ -2362,7 +2362,7 @@ static void ack_apic_edge(struct irq_data *data)
+ 	ack_APIC_irq();
+ }
+ 
+-atomic_t irq_mis_count;
++atomic_unchecked_t irq_mis_count;
+ 
+ #ifdef CONFIG_GENERIC_PENDING_IRQ
+ static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
+@@ -2503,7 +2503,7 @@ static void ack_apic_level(struct irq_data *data)
+ 	 * at the cpu.
+ 	 */
+ 	if (!(v & (1 << (i & 0x1f)))) {
+-		atomic_inc(&irq_mis_count);
++		atomic_inc_unchecked(&irq_mis_count);
+ 
+ 		eoi_ioapic_irq(irq, cfg);
+ 	}
+diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
+index 1e42e8f..daacf44 100644
+--- a/arch/x86/kernel/apic/numaq_32.c
++++ b/arch/x86/kernel/apic/numaq_32.c
+@@ -455,8 +455,7 @@ static void numaq_setup_portio_remap(void)
+ 		(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
+ }
+ 
+-/* Use __refdata to keep false positive warning calm.  */
+-static struct apic __refdata apic_numaq = {
++static struct apic apic_numaq __read_only = {
+ 
+ 	.name				= "NUMAQ",
+ 	.probe				= probe_numaq,
+diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
+index eb35ef9..f184a21 100644
+--- a/arch/x86/kernel/apic/probe_32.c
++++ b/arch/x86/kernel/apic/probe_32.c
+@@ -72,7 +72,7 @@ static int probe_default(void)
+ 	return 1;
+ }
+ 
+-static struct apic apic_default = {
++static struct apic apic_default __read_only = {
+ 
+ 	.name				= "default",
+ 	.probe				= probe_default,
+diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
+index 77c95c0..434f8a4 100644
+--- a/arch/x86/kernel/apic/summit_32.c
++++ b/arch/x86/kernel/apic/summit_32.c
+@@ -486,7 +486,7 @@ void setup_summit(void)
+ }
+ #endif
+ 
+-static struct apic apic_summit = {
++static struct apic apic_summit __read_only = {
+ 
+ 	.name				= "summit",
+ 	.probe				= probe_summit,
+diff --git a/arch/x86/kernel/apic/x2apic_cluster.c \
b/arch/x86/kernel/apic/x2apic_cluster.c +index 140e29d..d88bc95 100644
+--- a/arch/x86/kernel/apic/x2apic_cluster.c
++++ b/arch/x86/kernel/apic/x2apic_cluster.c
+@@ -183,7 +183,7 @@ update_clusterinfo(struct notifier_block *nfb, unsigned long \
action, void *hcpu) + 	return notifier_from_errno(err);
+ }
+ 
+-static struct notifier_block __refdata x2apic_cpu_notifier = {
++static struct notifier_block x2apic_cpu_notifier = {
+ 	.notifier_call = update_clusterinfo,
+ };
+ 
+@@ -235,7 +235,7 @@ static void cluster_vector_allocation_domain(int cpu, struct \
cpumask *retmask, + 		cpumask_and(retmask, mask, per_cpu(cpus_in_cluster, cpu));
+ }
+ 
+-static struct apic apic_x2apic_cluster = {
++static struct apic apic_x2apic_cluster __read_only = {
+ 
+ 	.name				= "cluster x2apic",
+ 	.probe				= x2apic_cluster_probe,
+diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c
+index 562a76d..a003c0f 100644
+--- a/arch/x86/kernel/apic/x2apic_phys.c
++++ b/arch/x86/kernel/apic/x2apic_phys.c
+@@ -89,7 +89,7 @@ static int x2apic_phys_probe(void)
+ 	return apic == &apic_x2apic_phys;
+ }
+ 
+-static struct apic apic_x2apic_phys = {
++static struct apic apic_x2apic_phys __read_only = {
+ 
+ 	.name				= "physical x2apic",
+ 	.probe				= x2apic_phys_probe,
+diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
+index 1191ac1..2335fa4 100644
+--- a/arch/x86/kernel/apic/x2apic_uv_x.c
++++ b/arch/x86/kernel/apic/x2apic_uv_x.c
+@@ -357,7 +357,7 @@ static int uv_probe(void)
+ 	return apic == &apic_x2apic_uv_x;
+ }
+ 
+-static struct apic __refdata apic_x2apic_uv_x = {
++static struct apic apic_x2apic_uv_x __read_only = {
+ 
+ 	.name				= "UV large system",
+ 	.probe				= uv_probe,
+diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
+index 53a4e27..038760a 100644
+--- a/arch/x86/kernel/apm_32.c
++++ b/arch/x86/kernel/apm_32.c
+@@ -433,7 +433,7 @@ static DEFINE_MUTEX(apm_mutex);
+  * This is for buggy BIOS's that refer to (real mode) segment 0x40
+  * even though they are called in protected mode.
+  */
+-static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
++static const struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4093,
+ 			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
+ 
+ static const char driver_version[] = "1.16ac";	/* no spaces */
+@@ -611,7 +611,10 @@ static long __apm_bios_call(void *_call)
+ 	BUG_ON(cpu != 0);
+ 	gdt = get_cpu_gdt_table(cpu);
+ 	save_desc_40 = gdt[0x40 / 8];
++
++	pax_open_kernel();
+ 	gdt[0x40 / 8] = bad_bios_desc;
++	pax_close_kernel();
+ 
+ 	apm_irq_save(flags);
+ 	APM_DO_SAVE_SEGS;
+@@ -620,7 +623,11 @@ static long __apm_bios_call(void *_call)
+ 			  &call->esi);
+ 	APM_DO_RESTORE_SEGS;
+ 	apm_irq_restore(flags);
++
++	pax_open_kernel();
+ 	gdt[0x40 / 8] = save_desc_40;
++	pax_close_kernel();
++
+ 	put_cpu();
+ 
+ 	return call->eax & 0xff;
+@@ -687,7 +694,10 @@ static long __apm_bios_call_simple(void *_call)
+ 	BUG_ON(cpu != 0);
+ 	gdt = get_cpu_gdt_table(cpu);
+ 	save_desc_40 = gdt[0x40 / 8];
++
++	pax_open_kernel();
+ 	gdt[0x40 / 8] = bad_bios_desc;
++	pax_close_kernel();
+ 
+ 	apm_irq_save(flags);
+ 	APM_DO_SAVE_SEGS;
+@@ -695,7 +705,11 @@ static long __apm_bios_call_simple(void *_call)
+ 					 &call->eax);
+ 	APM_DO_RESTORE_SEGS;
+ 	apm_irq_restore(flags);
++
++	pax_open_kernel();
+ 	gdt[0x40 / 8] = save_desc_40;
++	pax_close_kernel();
++
+ 	put_cpu();
+ 	return error;
+ }
+@@ -2362,12 +2376,15 @@ static int __init apm_init(void)
+ 	 * code to that CPU.
+ 	 */
+ 	gdt = get_cpu_gdt_table(0);
++
++	pax_open_kernel();
+ 	set_desc_base(&gdt[APM_CS >> 3],
+ 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
+ 	set_desc_base(&gdt[APM_CS_16 >> 3],
+ 		 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
+ 	set_desc_base(&gdt[APM_DS >> 3],
+ 		 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
++	pax_close_kernel();
+ 
+ 	proc_create("apm", 0, NULL, &apm_file_ops);
+ 
+diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
+index 2861082..6d4718e 100644
+--- a/arch/x86/kernel/asm-offsets.c
++++ b/arch/x86/kernel/asm-offsets.c
+@@ -33,6 +33,8 @@ void common(void) {
+ 	OFFSET(TI_status, thread_info, status);
+ 	OFFSET(TI_addr_limit, thread_info, addr_limit);
+ 	OFFSET(TI_preempt_count, thread_info, preempt_count);
++	OFFSET(TI_lowest_stack, thread_info, lowest_stack);
++	DEFINE(TI_task_thread_sp0, offsetof(struct task_struct, thread.sp0) - \
offsetof(struct task_struct, tinfo)); + 
+ 	BLANK();
+ 	OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
+@@ -53,8 +55,26 @@ void common(void) {
+ 	OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
+ 	OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
+ 	OFFSET(PV_MMU_read_cr2, pv_mmu_ops, read_cr2);
++
++#ifdef CONFIG_PAX_KERNEXEC
++	OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
+ #endif
+ 
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	OFFSET(PV_MMU_read_cr3, pv_mmu_ops, read_cr3);
++	OFFSET(PV_MMU_write_cr3, pv_mmu_ops, write_cr3);
++#ifdef CONFIG_X86_64
++	OFFSET(PV_MMU_set_pgd_batched, pv_mmu_ops, set_pgd_batched);
++#endif
++#endif
++
++#endif
++
++	BLANK();
++	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
++	DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT);
++	DEFINE(THREAD_SIZE_asm, THREAD_SIZE);
++
+ #ifdef CONFIG_XEN
+ 	BLANK();
+ 	OFFSET(XEN_vcpu_info_mask, vcpu_info, evtchn_upcall_mask);
+diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
+index e7c798b..2b2019b 100644
+--- a/arch/x86/kernel/asm-offsets_64.c
++++ b/arch/x86/kernel/asm-offsets_64.c
+@@ -77,6 +77,7 @@ int main(void)
+ 	BLANK();
+ #undef ENTRY
+ 
++	DEFINE(TSS_size, sizeof(struct tss_struct));
+ 	OFFSET(TSS_ist, tss_struct, x86_tss.ist);
+ 	BLANK();
+ 
+diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
+index 47b56a7..efc2bc6 100644
+--- a/arch/x86/kernel/cpu/Makefile
++++ b/arch/x86/kernel/cpu/Makefile
+@@ -8,10 +8,6 @@ CFLAGS_REMOVE_common.o = -pg
+ CFLAGS_REMOVE_perf_event.o = -pg
+ endif
+ 
+-# Make sure load_percpu_segment has no stackprotector
+-nostackp := $(call cc-option, -fno-stack-protector)
+-CFLAGS_common.o		:= $(nostackp)
+-
+ obj-y			:= intel_cacheinfo.o scattered.o topology.o
+ obj-y			+= proc.o capflags.o powerflags.o common.o
+ obj-y			+= rdrand.o
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 08a0890..e557865 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -743,7 +743,7 @@ static void init_amd(struct cpuinfo_x86 *c)
+ static unsigned int amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
+ {
+ 	/* AMD errata T13 (order #21922) */
+-	if ((c->x86 == 6)) {
++	if (c->x86 == 6) {
+ 		/* Duron Rev A0 */
+ 		if (c->x86_model == 3 && c->x86_mask == 0)
+ 			size = 64;
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 25eb274..3a92d93 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -88,60 +88,6 @@ static const struct cpu_dev default_cpu = {
+ 
+ static const struct cpu_dev *this_cpu = &default_cpu;
+ 
+-DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
+-#ifdef CONFIG_X86_64
+-	/*
+-	 * We need valid kernel segments for data and code in long mode too
+-	 * IRET will check the segment types  kkeil 2000/10/28
+-	 * Also sysret mandates a special GDT layout
+-	 *
+-	 * TLS descriptors are currently at a different place compared to i386.
+-	 * Hopefully nobody expects them at a fixed place (Wine?)
+-	 */
+-	[GDT_ENTRY_KERNEL32_CS]		= GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
+-	[GDT_ENTRY_KERNEL_CS]		= GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
+-	[GDT_ENTRY_KERNEL_DS]		= GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
+-	[GDT_ENTRY_DEFAULT_USER32_CS]	= GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
+-	[GDT_ENTRY_DEFAULT_USER_DS]	= GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
+-	[GDT_ENTRY_DEFAULT_USER_CS]	= GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
+-#else
+-	[GDT_ENTRY_KERNEL_CS]		= GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
+-	[GDT_ENTRY_KERNEL_DS]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+-	[GDT_ENTRY_DEFAULT_USER_CS]	= GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
+-	[GDT_ENTRY_DEFAULT_USER_DS]	= GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
+-	/*
+-	 * Segments used for calling PnP BIOS have byte granularity.
+-	 * They code segments and data segments have fixed 64k limits,
+-	 * the transfer segment sizes are set at run time.
+-	 */
+-	/* 32-bit code */
+-	[GDT_ENTRY_PNPBIOS_CS32]	= GDT_ENTRY_INIT(0x409a, 0, 0xffff),
+-	/* 16-bit code */
+-	[GDT_ENTRY_PNPBIOS_CS16]	= GDT_ENTRY_INIT(0x009a, 0, 0xffff),
+-	/* 16-bit data */
+-	[GDT_ENTRY_PNPBIOS_DS]		= GDT_ENTRY_INIT(0x0092, 0, 0xffff),
+-	/* 16-bit data */
+-	[GDT_ENTRY_PNPBIOS_TS1]		= GDT_ENTRY_INIT(0x0092, 0, 0),
+-	/* 16-bit data */
+-	[GDT_ENTRY_PNPBIOS_TS2]		= GDT_ENTRY_INIT(0x0092, 0, 0),
+-	/*
+-	 * The APM segments have byte granularity and their bases
+-	 * are set at run time.  All have 64k limits.
+-	 */
+-	/* 32-bit code */
+-	[GDT_ENTRY_APMBIOS_BASE]	= GDT_ENTRY_INIT(0x409a, 0, 0xffff),
+-	/* 16-bit code */
+-	[GDT_ENTRY_APMBIOS_BASE+1]	= GDT_ENTRY_INIT(0x009a, 0, 0xffff),
+-	/* data */
+-	[GDT_ENTRY_APMBIOS_BASE+2]	= GDT_ENTRY_INIT(0x4092, 0, 0xffff),
+-
+-	[GDT_ENTRY_ESPFIX_SS]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+-	[GDT_ENTRY_PERCPU]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+-	GDT_STACK_CANARY_INIT
+-#endif
+-} };
+-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
+-
+ static int __init x86_xsave_setup(char *s)
+ {
+ 	setup_clear_cpu_cap(X86_FEATURE_XSAVE);
+@@ -288,6 +234,57 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
+ 		set_in_cr4(X86_CR4_SMAP);
+ }
+ 
++#ifdef CONFIG_X86_64
++static __init int setup_disable_pcid(char *arg)
++{
++	setup_clear_cpu_cap(X86_FEATURE_PCID);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	if (clone_pgd_mask != ~(pgdval_t)0UL)
++		pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT;
++#endif
++
++	return 1;
++}
++__setup("nopcid", setup_disable_pcid);
++
++static void setup_pcid(struct cpuinfo_x86 *c)
++{
++	if (!cpu_has(c, X86_FEATURE_PCID)) {
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++		if (clone_pgd_mask != ~(pgdval_t)0UL) {
++			pax_open_kernel();
++			pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT;
++			pax_close_kernel();
++			printk("PAX: slow and weak UDEREF enabled\n");
++		} else
++			printk("PAX: UDEREF disabled\n");
++#endif
++
++		return;
++	}
++
++	printk("PAX: PCID detected\n");
++	set_in_cr4(X86_CR4_PCIDE);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pax_open_kernel();
++	clone_pgd_mask = ~(pgdval_t)0UL;
++	pax_close_kernel();
++	if (pax_user_shadow_base)
++		printk("PAX: weak UDEREF enabled\n");
++	else {
++		set_cpu_cap(c, X86_FEATURE_STRONGUDEREF);
++		printk("PAX: strong UDEREF enabled\n");
++	}
++#endif
++
++	if (cpu_has(c, X86_FEATURE_INVPCID))
++		printk("PAX: INVPCID detected\n");
++}
++#endif
++
+ /*
+  * Some CPU features depend on higher CPUID levels, which may not always
+  * be available due to CPUID level capping or broken virtualization
+@@ -386,7 +383,7 @@ void switch_to_new_gdt(int cpu)
+ {
+ 	struct desc_ptr gdt_descr;
+ 
+-	gdt_descr.address = (long)get_cpu_gdt_table(cpu);
++	gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
+ 	gdt_descr.size = GDT_SIZE - 1;
+ 	load_gdt(&gdt_descr);
+ 	/* Reload the per-cpu base */
+@@ -875,6 +872,10 @@ static void identify_cpu(struct cpuinfo_x86 *c)
+ 	setup_smep(c);
+ 	setup_smap(c);
+ 
++#ifdef CONFIG_X86_64
++	setup_pcid(c);
++#endif
++
+ 	/*
+ 	 * The vendor-specific functions might have changed features.
+ 	 * Now we do "generic changes."
+@@ -883,6 +884,10 @@ static void identify_cpu(struct cpuinfo_x86 *c)
+ 	/* Filter out anything that depends on CPUID levels we don't have */
+ 	filter_cpuid_features(c, true);
+ 
++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_SEGMEXEC) || \
defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)) \
++	setup_clear_cpu_cap(X86_FEATURE_SEP); ++#endif
++
+ 	/* If the model name is still unset, do table lookup. */
+ 	if (!c->x86_model_id[0]) {
+ 		const char *p;
+@@ -1070,10 +1075,12 @@ static __init int setup_disablecpuid(char *arg)
+ }
+ __setup("clearcpuid=", setup_disablecpuid);
+ 
++DEFINE_PER_CPU(struct thread_info *, current_tinfo) = &init_task.tinfo;
++EXPORT_PER_CPU_SYMBOL(current_tinfo);
++
+ #ifdef CONFIG_X86_64
+-struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table };
+-struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1,
+-				    (unsigned long) debug_idt_table };
++struct desc_ptr idt_descr __read_only = { NR_VECTORS * 16 - 1, (unsigned long) \
idt_table }; ++const struct desc_ptr debug_idt_descr = { NR_VECTORS * 16 - 1, \
(unsigned long) debug_idt_table }; + 
+ DEFINE_PER_CPU_FIRST(union irq_stack_union,
+ 		     irq_stack_union) __aligned(PAGE_SIZE);
+@@ -1087,7 +1094,7 @@ DEFINE_PER_CPU(struct task_struct *, current_task) \
____cacheline_aligned = + EXPORT_PER_CPU_SYMBOL(current_task);
+ 
+ DEFINE_PER_CPU(unsigned long, kernel_stack) =
+-	(unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
++	(unsigned long)&init_thread_union - 16 + THREAD_SIZE;
+ EXPORT_PER_CPU_SYMBOL(kernel_stack);
+ 
+ DEFINE_PER_CPU(char *, irq_stack_ptr) =
+@@ -1232,7 +1239,7 @@ void cpu_init(void)
+ 	load_ucode_ap();
+ 
+ 	cpu = stack_smp_processor_id();
+-	t = &per_cpu(init_tss, cpu);
++	t = init_tss + cpu;
+ 	oist = &per_cpu(orig_ist, cpu);
+ 
+ #ifdef CONFIG_NUMA
+@@ -1267,7 +1274,6 @@ void cpu_init(void)
+ 	wrmsrl(MSR_KERNEL_GS_BASE, 0);
+ 	barrier();
+ 
+-	x86_configure_nx();
+ 	enable_x2apic();
+ 
+ 	/*
+@@ -1319,7 +1325,7 @@ void cpu_init(void)
+ {
+ 	int cpu = smp_processor_id();
+ 	struct task_struct *curr = current;
+-	struct tss_struct *t = &per_cpu(init_tss, cpu);
++	struct tss_struct *t = init_tss + cpu;
+ 	struct thread_struct *thread = &curr->thread;
+ 
+ 	show_ucode_info_early();
+diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c \
b/arch/x86/kernel/cpu/intel_cacheinfo.c +index 1414c90..1159406 100644
+--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
++++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
+@@ -1014,6 +1014,22 @@ static struct attribute *default_attrs[] = {
+ };
+ 
+ #ifdef CONFIG_AMD_NB
++static struct attribute *default_attrs_amd_nb[] = {
++	&type.attr,
++	&level.attr,
++	&coherency_line_size.attr,
++	&physical_line_partition.attr,
++	&ways_of_associativity.attr,
++	&number_of_sets.attr,
++	&size.attr,
++	&shared_cpu_map.attr,
++	&shared_cpu_list.attr,
++	NULL,
++	NULL,
++	NULL,
++	NULL
++};
++
+ static struct attribute **amd_l3_attrs(void)
+ {
+ 	static struct attribute **attrs;
+@@ -1024,18 +1040,7 @@ static struct attribute **amd_l3_attrs(void)
+ 
+ 	n = ARRAY_SIZE(default_attrs);
+ 
+-	if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
+-		n += 2;
+-
+-	if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
+-		n += 1;
+-
+-	attrs = kzalloc(n * sizeof (struct attribute *), GFP_KERNEL);
+-	if (attrs == NULL)
+-		return attrs = default_attrs;
+-
+-	for (n = 0; default_attrs[n]; n++)
+-		attrs[n] = default_attrs[n];
++	attrs = default_attrs_amd_nb;
+ 
+ 	if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) {
+ 		attrs[n++] = &cache_disable_0.attr;
+@@ -1086,6 +1091,13 @@ static struct kobj_type ktype_cache = {
+ 	.default_attrs	= default_attrs,
+ };
+ 
++#ifdef CONFIG_AMD_NB
++static struct kobj_type ktype_cache_amd_nb = {
++	.sysfs_ops	= &sysfs_ops,
++	.default_attrs	= default_attrs_amd_nb,
++};
++#endif
++
+ static struct kobj_type ktype_percpu_entry = {
+ 	.sysfs_ops	= &sysfs_ops,
+ };
+@@ -1151,20 +1163,26 @@ static int cache_add_dev(struct device *dev)
+ 		return retval;
+ 	}
+ 
++#ifdef CONFIG_AMD_NB
++	amd_l3_attrs();
++#endif
++
+ 	for (i = 0; i < num_cache_leaves; i++) {
++		struct kobj_type *ktype;
++
+ 		this_object = INDEX_KOBJECT_PTR(cpu, i);
+ 		this_object->cpu = cpu;
+ 		this_object->index = i;
+ 
+ 		this_leaf = CPUID4_INFO_IDX(cpu, i);
+ 
+-		ktype_cache.default_attrs = default_attrs;
++		ktype = &ktype_cache;
+ #ifdef CONFIG_AMD_NB
+ 		if (this_leaf->base.nb)
+-			ktype_cache.default_attrs = amd_l3_attrs();
++			ktype = &ktype_cache_amd_nb;
+ #endif
+ 		retval = kobject_init_and_add(&(this_object->kobj),
+-					      &ktype_cache,
++					      ktype,
+ 					      per_cpu(ici_cache_kobject, cpu),
+ 					      "index%1lu", i);
+ 		if (unlikely(retval)) {
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index 87a65c9..92fcce6 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -45,6 +45,7 @@
+ #include <asm/processor.h>
+ #include <asm/mce.h>
+ #include <asm/msr.h>
++#include <asm/local.h>
+ 
+ #include "mce-internal.h"
+ 
+@@ -249,7 +250,7 @@ static void print_mce(struct mce *m)
+ 			!(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
+ 				m->cs, m->ip);
+ 
+-		if (m->cs == __KERNEL_CS)
++		if (m->cs == __KERNEL_CS || m->cs == __KERNEXEC_KERNEL_CS)
+ 			print_symbol("{%s}", m->ip);
+ 		pr_cont("\n");
+ 	}
+@@ -282,10 +283,10 @@ static void print_mce(struct mce *m)
+ 
+ #define PANIC_TIMEOUT 5 /* 5 seconds */
+ 
+-static atomic_t mce_paniced;
++static atomic_unchecked_t mce_paniced;
+ 
+ static int fake_panic;
+-static atomic_t mce_fake_paniced;
++static atomic_unchecked_t mce_fake_paniced;
+ 
+ /* Panic in progress. Enable interrupts and wait for final IPI */
+ static void wait_for_panic(void)
+@@ -309,7 +310,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
+ 		/*
+ 		 * Make sure only one CPU runs in machine check panic
+ 		 */
+-		if (atomic_inc_return(&mce_paniced) > 1)
++		if (atomic_inc_return_unchecked(&mce_paniced) > 1)
+ 			wait_for_panic();
+ 		barrier();
+ 
+@@ -317,7 +318,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
+ 		console_verbose();
+ 	} else {
+ 		/* Don't log too much for fake panic */
+-		if (atomic_inc_return(&mce_fake_paniced) > 1)
++		if (atomic_inc_return_unchecked(&mce_fake_paniced) > 1)
+ 			return;
+ 	}
+ 	/* First print corrected ones that are still unlogged */
+@@ -356,7 +357,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
+ 	if (!fake_panic) {
+ 		if (panic_timeout == 0)
+ 			panic_timeout = mca_cfg.panic_timeout;
+-		panic(msg);
++		panic("%s", msg);
+ 	} else
+ 		pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg);
+ }
+@@ -686,7 +687,7 @@ static int mce_timed_out(u64 *t)
+ 	 * might have been modified by someone else.
+ 	 */
+ 	rmb();
+-	if (atomic_read(&mce_paniced))
++	if (atomic_read_unchecked(&mce_paniced))
+ 		wait_for_panic();
+ 	if (!mca_cfg.monarch_timeout)
+ 		goto out;
+@@ -1657,7 +1658,7 @@ static void unexpected_machine_check(struct pt_regs *regs, \
long error_code) + }
+ 
+ /* Call the installed machine check handler for this CPU setup. */
+-void (*machine_check_vector)(struct pt_regs *, long error_code) =
++void (*machine_check_vector)(struct pt_regs *, long error_code) __read_only =
+ 						unexpected_machine_check;
+ 
+ /*
+@@ -1680,7 +1681,9 @@ void mcheck_cpu_init(struct cpuinfo_x86 *c)
+ 		return;
+ 	}
+ 
++	pax_open_kernel();
+ 	machine_check_vector = do_machine_check;
++	pax_close_kernel();
+ 
+ 	__mcheck_cpu_init_generic();
+ 	__mcheck_cpu_init_vendor(c);
+@@ -1694,7 +1697,7 @@ void mcheck_cpu_init(struct cpuinfo_x86 *c)
+  */
+ 
+ static DEFINE_SPINLOCK(mce_chrdev_state_lock);
+-static int mce_chrdev_open_count;	/* #times opened */
++static local_t mce_chrdev_open_count;	/* #times opened */
+ static int mce_chrdev_open_exclu;	/* already open exclusive? */
+ 
+ static int mce_chrdev_open(struct inode *inode, struct file *file)
+@@ -1702,7 +1705,7 @@ static int mce_chrdev_open(struct inode *inode, struct file \
*file) + 	spin_lock(&mce_chrdev_state_lock);
+ 
+ 	if (mce_chrdev_open_exclu ||
+-	    (mce_chrdev_open_count && (file->f_flags & O_EXCL))) {
++	    (local_read(&mce_chrdev_open_count) && (file->f_flags & O_EXCL))) {
+ 		spin_unlock(&mce_chrdev_state_lock);
+ 
+ 		return -EBUSY;
+@@ -1710,7 +1713,7 @@ static int mce_chrdev_open(struct inode *inode, struct file \
*file) + 
+ 	if (file->f_flags & O_EXCL)
+ 		mce_chrdev_open_exclu = 1;
+-	mce_chrdev_open_count++;
++	local_inc(&mce_chrdev_open_count);
+ 
+ 	spin_unlock(&mce_chrdev_state_lock);
+ 
+@@ -1721,7 +1724,7 @@ static int mce_chrdev_release(struct inode *inode, struct file \
*file) + {
+ 	spin_lock(&mce_chrdev_state_lock);
+ 
+-	mce_chrdev_open_count--;
++	local_dec(&mce_chrdev_open_count);
+ 	mce_chrdev_open_exclu = 0;
+ 
+ 	spin_unlock(&mce_chrdev_state_lock);
+@@ -2376,7 +2379,7 @@ static __init void mce_init_banks(void)
+ 
+ 	for (i = 0; i < mca_cfg.banks; i++) {
+ 		struct mce_bank *b = &mce_banks[i];
+-		struct device_attribute *a = &b->attr;
++		device_attribute_no_const *a = &b->attr;
+ 
+ 		sysfs_attr_init(&a->attr);
+ 		a->attr.name	= b->attrname;
+@@ -2444,7 +2447,7 @@ struct dentry *mce_get_debugfs_dir(void)
+ static void mce_reset(void)
+ {
+ 	cpu_missing = 0;
+-	atomic_set(&mce_fake_paniced, 0);
++	atomic_set_unchecked(&mce_fake_paniced, 0);
+ 	atomic_set(&mce_executing, 0);
+ 	atomic_set(&mce_callin, 0);
+ 	atomic_set(&global_nwo, 0);
+diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
+index 1c044b1..37a2a43 100644
+--- a/arch/x86/kernel/cpu/mcheck/p5.c
++++ b/arch/x86/kernel/cpu/mcheck/p5.c
+@@ -11,6 +11,7 @@
+ #include <asm/processor.h>
+ #include <asm/mce.h>
+ #include <asm/msr.h>
++#include <asm/pgtable.h>
+ 
+ /* By default disabled */
+ int mce_p5_enabled __read_mostly;
+@@ -49,7 +50,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+ 	if (!cpu_has(c, X86_FEATURE_MCE))
+ 		return;
+ 
++	pax_open_kernel();
+ 	machine_check_vector = pentium_machine_check;
++	pax_close_kernel();
+ 	/* Make sure the vector pointer is visible before we enable MCEs: */
+ 	wmb();
+ 
+diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c \
b/arch/x86/kernel/cpu/mcheck/winchip.c +index e9a701a..35317d6 100644
+--- a/arch/x86/kernel/cpu/mcheck/winchip.c
++++ b/arch/x86/kernel/cpu/mcheck/winchip.c
+@@ -10,6 +10,7 @@
+ #include <asm/processor.h>
+ #include <asm/mce.h>
+ #include <asm/msr.h>
++#include <asm/pgtable.h>
+ 
+ /* Machine check handler for WinChip C6: */
+ static void winchip_machine_check(struct pt_regs *regs, long error_code)
+@@ -23,7 +24,9 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
+ {
+ 	u32 lo, hi;
+ 
++	pax_open_kernel();
+ 	machine_check_vector = winchip_machine_check;
++	pax_close_kernel();
+ 	/* Make sure the vector pointer is visible before we enable MCEs: */
+ 	wmb();
+ 
+diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
+index f961de9..8a9d332 100644
+--- a/arch/x86/kernel/cpu/mtrr/main.c
++++ b/arch/x86/kernel/cpu/mtrr/main.c
+@@ -66,7 +66,7 @@ static DEFINE_MUTEX(mtrr_mutex);
+ u64 size_or_mask, size_and_mask;
+ static bool mtrr_aps_delayed_init;
+ 
+-static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
++static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM] __read_only;
+ 
+ const struct mtrr_ops *mtrr_if;
+ 
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
+index df5e41f..816c719 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
+@@ -25,7 +25,7 @@ struct mtrr_ops {
+ 	int	(*validate_add_page)(unsigned long base, unsigned long size,
+ 				     unsigned int type);
+ 	int	(*have_wrcomb)(void);
+-};
++} __do_const;
+ 
+ extern int generic_get_free_region(unsigned long base, unsigned long size,
+ 				   int replace_reg);
+diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
+index a7c7305..b9705ab 100644
+--- a/arch/x86/kernel/cpu/perf_event.c
++++ b/arch/x86/kernel/cpu/perf_event.c
+@@ -1348,7 +1348,7 @@ static void __init pmu_check_apic(void)
+ 	pr_info("no hardware sampling interrupt available.\n");
+ }
+ 
+-static struct attribute_group x86_pmu_format_group = {
++static attribute_group_no_const x86_pmu_format_group = {
+ 	.name = "format",
+ 	.attrs = NULL,
+ };
+@@ -1447,7 +1447,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,
+ };
+@@ -1957,7 +1957,7 @@ static unsigned long get_segment_base(unsigned int segment)
+ 		if (idx > GDT_ENTRIES)
+ 			return 0;
+ 
+-		desc = __this_cpu_ptr(&gdt_page.gdt[0]);
++		desc = get_cpu_gdt_table(smp_processor_id());
+ 	}
+ 
+ 	return get_desc_base(desc + idx);
+@@ -2047,7 +2047,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct \
pt_regs *regs) + 			break;
+ 
+ 		perf_callchain_store(entry, frame.return_address);
+-		fp = frame.next_frame;
++		fp = (const void __force_user *)frame.next_frame;
+ 	}
+ }
+ 
+diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c \
b/arch/x86/kernel/cpu/perf_event_amd_iommu.c +index 639d128..e92d7e5 100644
+--- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c
++++ b/arch/x86/kernel/cpu/perf_event_amd_iommu.c
+@@ -405,7 +405,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/kernel/cpu/perf_event_intel.c \
b/arch/x86/kernel/cpu/perf_event_intel.c +index a45d8d4..8abd32c 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel.c
++++ b/arch/x86/kernel/cpu/perf_event_intel.c
+@@ -2099,10 +2099,10 @@ __init int intel_pmu_init(void)
+ 	 * v2 and above have a perf capabilities MSR
+ 	 */
+ 	if (version > 1) {
+-		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/kernel/cpu/perf_event_intel_uncore.c \
b/arch/x86/kernel/cpu/perf_event_intel_uncore.c +index 1fb6c72..f5fa2a3 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
++++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+@@ -3095,7 +3095,7 @@ static void __init uncore_types_exit(struct intel_uncore_type \
**types) + static int __init uncore_type_init(struct intel_uncore_type *type)
+ {
+ 	struct intel_uncore_pmu *pmus;
+-	struct attribute_group *attr_group;
++	attribute_group_no_const *attr_group;
+ 	struct attribute **attrs;
+ 	int i, j;
+ 
+diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h \
b/arch/x86/kernel/cpu/perf_event_intel_uncore.h +index 47b3d00c..2cf1751 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
++++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+@@ -488,7 +488,7 @@ struct intel_uncore_box {
+ struct uncore_event_desc {
+ 	struct kobj_attribute attr;
+ 	const char *config;
+-};
++} __do_const;
+ 
+ #define INTEL_UNCORE_EVENT_DESC(_name, _config)			\
+ {								\
+diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
+index 7d9481c..99c7e4b 100644
+--- a/arch/x86/kernel/cpuid.c
++++ b/arch/x86/kernel/cpuid.c
+@@ -170,7 +170,7 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb,
+ 	return notifier_from_errno(err);
+ }
+ 
+-static struct notifier_block __refdata cpuid_class_cpu_notifier =
++static struct notifier_block cpuid_class_cpu_notifier =
+ {
+ 	.notifier_call = cpuid_class_cpu_callback,
+ };
+diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
+index 74467fe..18793d5 100644
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -58,10 +58,8 @@ static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
+ {
+ #ifdef CONFIG_X86_32
+ 	struct pt_regs fixed_regs;
+-#endif
+ 
+-#ifdef CONFIG_X86_32
+-	if (!user_mode_vm(regs)) {
++	if (!user_mode(regs)) {
+ 		crash_fixup_ss_esp(&fixed_regs, regs);
+ 		regs = &fixed_regs;
+ 	}
+diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
+index afa64ad..dce67dd 100644
+--- a/arch/x86/kernel/crash_dump_64.c
++++ b/arch/x86/kernel/crash_dump_64.c
+@@ -36,7 +36,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ 		return -ENOMEM;
+ 
+ 	if (userbuf) {
+-		if (copy_to_user(buf, vaddr + offset, csize)) {
++		if (copy_to_user((char __force_user *)buf, vaddr + offset, csize)) {
+ 			iounmap(vaddr);
+ 			return -EFAULT;
+ 		}
+diff --git a/arch/x86/kernel/doublefault.c b/arch/x86/kernel/doublefault.c
+index 5d3fe8d..02e1429 100644
+--- a/arch/x86/kernel/doublefault.c
++++ b/arch/x86/kernel/doublefault.c
+@@ -13,7 +13,7 @@
+ 
+ #define DOUBLEFAULT_STACKSIZE (1024)
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
+-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
+ 
+ #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
+ 
+@@ -23,7 +23,7 @@ static void doublefault_fn(void)
+ 	unsigned long gdt, tss;
+ 
+ 	native_store_gdt(&gdt_desc);
+-	gdt = gdt_desc.address;
++	gdt = (unsigned long)gdt_desc.address;
+ 
+ 	printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, \
gdt_desc.size); + 
+@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cacheline_aligned = {
+ 		/* 0x2 bit is always set */
+ 		.flags		= X86_EFLAGS_SF | 0x2,
+ 		.sp		= STACK_START,
+-		.es		= __USER_DS,
++		.es		= __KERNEL_DS,
+ 		.cs		= __KERNEL_CS,
+ 		.ss		= __KERNEL_DS,
+-		.ds		= __USER_DS,
++		.ds		= __KERNEL_DS,
+ 		.fs		= __KERNEL_PERCPU,
+ 
+ 		.__cr3		= __pa_nodebug(swapper_pg_dir),
+diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
+index deb6421..76bbc12 100644
+--- a/arch/x86/kernel/dumpstack.c
++++ b/arch/x86/kernel/dumpstack.c
+@@ -2,6 +2,9 @@
+  *  Copyright (C) 1991, 1992  Linus Torvalds
+  *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
+  */
++#ifdef CONFIG_GRKERNSEC_HIDESYM
++#define __INCLUDED_BY_HIDESYM 1
++#endif
+ #include <linux/kallsyms.h>
+ #include <linux/kprobes.h>
+ #include <linux/uaccess.h>
+@@ -35,16 +38,14 @@ void printk_address(unsigned long address, int reliable)
+ static void
+ print_ftrace_graph_addr(unsigned long addr, void *data,
+ 			const struct stacktrace_ops *ops,
+-			struct thread_info *tinfo, int *graph)
++			struct task_struct *task, int *graph)
+ {
+-	struct task_struct *task;
+ 	unsigned long ret_addr;
+ 	int index;
+ 
+ 	if (addr != (unsigned long)return_to_handler)
+ 		return;
+ 
+-	task = tinfo->task;
+ 	index = task->curr_ret_stack;
+ 
+ 	if (!task->ret_stack || index < *graph)
+@@ -61,7 +62,7 @@ print_ftrace_graph_addr(unsigned long addr, void *data,
+ static inline void
+ print_ftrace_graph_addr(unsigned long addr, void *data,
+ 			const struct stacktrace_ops *ops,
+-			struct thread_info *tinfo, int *graph)
++			struct task_struct *task, int *graph)
+ { }
+ #endif
+ 
+@@ -72,10 +73,8 @@ print_ftrace_graph_addr(unsigned long addr, void *data,
+  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
+  */
+ 
+-static inline int valid_stack_ptr(struct thread_info *tinfo,
+-			void *p, unsigned int size, void *end)
++static inline int valid_stack_ptr(void *t, void *p, unsigned int size, void *end)
+ {
+-	void *t = tinfo;
+ 	if (end) {
+ 		if (p < end && p >= (end-THREAD_SIZE))
+ 			return 1;
+@@ -86,14 +85,14 @@ static inline int valid_stack_ptr(struct thread_info *tinfo,
+ }
+ 
+ unsigned long
+-print_context_stack(struct thread_info *tinfo,
++print_context_stack(struct task_struct *task, void *stack_start,
+ 		unsigned long *stack, unsigned long bp,
+ 		const struct stacktrace_ops *ops, void *data,
+ 		unsigned long *end, int *graph)
+ {
+ 	struct stack_frame *frame = (struct stack_frame *)bp;
+ 
+-	while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) {
++	while (valid_stack_ptr(stack_start, stack, sizeof(*stack), end)) {
+ 		unsigned long addr;
+ 
+ 		addr = *stack;
+@@ -105,7 +104,7 @@ print_context_stack(struct thread_info *tinfo,
+ 			} else {
+ 				ops->address(data, addr, 0);
+ 			}
+-			print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
++			print_ftrace_graph_addr(addr, data, ops, task, graph);
+ 		}
+ 		stack++;
+ 	}
+@@ -114,7 +113,7 @@ print_context_stack(struct thread_info *tinfo,
+ EXPORT_SYMBOL_GPL(print_context_stack);
+ 
+ unsigned long
+-print_context_stack_bp(struct thread_info *tinfo,
++print_context_stack_bp(struct task_struct *task, void *stack_start,
+ 		       unsigned long *stack, unsigned long bp,
+ 		       const struct stacktrace_ops *ops, void *data,
+ 		       unsigned long *end, int *graph)
+@@ -122,7 +121,7 @@ print_context_stack_bp(struct thread_info *tinfo,
+ 	struct stack_frame *frame = (struct stack_frame *)bp;
+ 	unsigned long *ret_addr = &frame->return_address;
+ 
+-	while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
++	while (valid_stack_ptr(stack_start, ret_addr, sizeof(*ret_addr), end)) {
+ 		unsigned long addr = *ret_addr;
+ 
+ 		if (!__kernel_text_address(addr))
+@@ -131,7 +130,7 @@ print_context_stack_bp(struct thread_info *tinfo,
+ 		ops->address(data, addr, 1);
+ 		frame = frame->next_frame;
+ 		ret_addr = &frame->return_address;
+-		print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
++		print_ftrace_graph_addr(addr, data, ops, task, graph);
+ 	}
+ 
+ 	return (unsigned long)frame;
+@@ -150,7 +149,7 @@ static int print_trace_stack(void *data, char *name)
+ static void print_trace_address(void *data, unsigned long addr, int reliable)
+ {
+ 	touch_nmi_watchdog();
+-	printk(data);
++	printk("%s", (char *)data);
+ 	printk_address(addr, reliable);
+ }
+ 
+@@ -219,6 +218,8 @@ unsigned __kprobes long oops_begin(void)
+ }
+ EXPORT_SYMBOL_GPL(oops_begin);
+ 
++extern void gr_handle_kernel_exploit(void);
++
+ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+ {
+ 	if (regs && kexec_should_crash(current))
+@@ -240,7 +241,10 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs \
*regs, int signr) + 		panic("Fatal exception in interrupt");
+ 	if (panic_on_oops)
+ 		panic("Fatal exception");
+-	do_exit(signr);
++
++	gr_handle_kernel_exploit();
++
++	do_group_exit(signr);
+ }
+ 
+ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
+@@ -268,7 +272,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long \
err) + 	print_modules();
+ 	show_regs(regs);
+ #ifdef CONFIG_X86_32
+-	if (user_mode_vm(regs)) {
++	if (user_mode(regs)) {
+ 		sp = regs->sp;
+ 		ss = regs->ss & 0xffff;
+ 	} else {
+@@ -296,7 +300,7 @@ void die(const char *str, struct pt_regs *regs, long err)
+ 	unsigned long flags = oops_begin();
+ 	int sig = SIGSEGV;
+ 
+-	if (!user_mode_vm(regs))
++	if (!user_mode(regs))
+ 		report_bug(regs->ip, regs);
+ 
+ 	if (__die(str, regs, err))
+diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
+index f2a1770..540657f 100644
+--- a/arch/x86/kernel/dumpstack_32.c
++++ b/arch/x86/kernel/dumpstack_32.c
+@@ -38,15 +38,13 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 		bp = stack_frame(task, regs);
+ 
+ 	for (;;) {
+-		struct thread_info *context;
++		void *stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1));
+ 
+-		context = (struct thread_info *)
+-			((unsigned long)stack & (~(THREAD_SIZE - 1)));
+-		bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
++		bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph);
+ 
+-		stack = (unsigned long *)context->previous_esp;
+-		if (!stack)
++		if (stack_start == task_stack_page(task))
+ 			break;
++		stack = *(unsigned long **)stack_start;
+ 		if (ops->stack(data, "IRQ") < 0)
+ 			break;
+ 		touch_nmi_watchdog();
+@@ -87,27 +85,28 @@ void show_regs(struct pt_regs *regs)
+ 	int i;
+ 
+ 	show_regs_print_info(KERN_EMERG);
+-	__show_regs(regs, !user_mode_vm(regs));
++	__show_regs(regs, !user_mode(regs));
+ 
+ 	/*
+ 	 * When in-kernel, we also print out the stack and code at the
+ 	 * time of the fault..
+ 	 */
+-	if (!user_mode_vm(regs)) {
++	if (!user_mode(regs)) {
+ 		unsigned int code_prologue = code_bytes * 43 / 64;
+ 		unsigned int code_len = code_bytes;
+ 		unsigned char c;
+ 		u8 *ip;
++		unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(0)[(0xffff & regs->cs) \
>> 3]); + 
+ 		pr_emerg("Stack:\n");
+ 		show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
+ 
+ 		pr_emerg("Code:");
+ 
+-		ip = (u8 *)regs->ip - code_prologue;
++		ip = (u8 *)regs->ip - code_prologue + cs_base;
+ 		if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
+ 			/* try starting at IP */
+-			ip = (u8 *)regs->ip;
++			ip = (u8 *)regs->ip + cs_base;
+ 			code_len = code_len - code_prologue + 1;
+ 		}
+ 		for (i = 0; i < code_len; i++, ip++) {
+@@ -116,7 +115,7 @@ void show_regs(struct pt_regs *regs)
+ 				pr_cont("  Bad EIP value.");
+ 				break;
+ 			}
+-			if (ip == (u8 *)regs->ip)
++			if (ip == (u8 *)regs->ip + cs_base)
+ 				pr_cont(" <%02x>", c);
+ 			else
+ 				pr_cont(" %02x", c);
+@@ -129,6 +128,7 @@ int is_valid_bugaddr(unsigned long ip)
+ {
+ 	unsigned short ud2;
+ 
++	ip = ktla_ktva(ip);
+ 	if (ip < PAGE_OFFSET)
+ 		return 0;
+ 	if (probe_kernel_address((unsigned short *)ip, ud2))
+@@ -136,3 +136,15 @@ int is_valid_bugaddr(unsigned long ip)
+ 
+ 	return ud2 == 0x0b0f;
+ }
++
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++void pax_check_alloca(unsigned long size)
++{
++	unsigned long sp = (unsigned long)&sp, stack_left;
++
++	/* all kernel stacks are of the same size */
++	stack_left = sp & (THREAD_SIZE - 1);
++	BUG_ON(stack_left < 256 || size >= stack_left - 256);
++}
++EXPORT_SYMBOL(pax_check_alloca);
++#endif
+diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
+index addb207..99635fa 100644
+--- a/arch/x86/kernel/dumpstack_64.c
++++ b/arch/x86/kernel/dumpstack_64.c
+@@ -119,9 +119,9 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 	unsigned long *irq_stack_end =
+ 		(unsigned long *)per_cpu(irq_stack_ptr, cpu);
+ 	unsigned used = 0;
+-	struct thread_info *tinfo;
+ 	int graph = 0;
+ 	unsigned long dummy;
++	void *stack_start;
+ 
+ 	if (!task)
+ 		task = current;
+@@ -142,10 +142,10 @@ void dump_trace(struct task_struct *task, struct pt_regs \
*regs, + 	 * current stack address. If the stacks consist of nested
+ 	 * exceptions
+ 	 */
+-	tinfo = task_thread_info(task);
+ 	for (;;) {
+ 		char *id;
+ 		unsigned long *estack_end;
++
+ 		estack_end = in_exception_stack(cpu, (unsigned long)stack,
+ 						&used, &id);
+ 
+@@ -153,7 +153,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 			if (ops->stack(data, id) < 0)
+ 				break;
+ 
+-			bp = ops->walk_stack(tinfo, stack, bp, ops,
++			bp = ops->walk_stack(task, estack_end - EXCEPTION_STKSZ, stack, bp, ops,
+ 					     data, estack_end, &graph);
+ 			ops->stack(data, "<EOE>");
+ 			/*
+@@ -161,6 +161,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 			 * second-to-last pointer (index -2 to end) in the
+ 			 * exception stack:
+ 			 */
++			if ((u16)estack_end[-1] != __KERNEL_DS)
++				goto out;
+ 			stack = (unsigned long *) estack_end[-2];
+ 			continue;
+ 		}
+@@ -172,7 +174,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 			if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
+ 				if (ops->stack(data, "IRQ") < 0)
+ 					break;
+-				bp = ops->walk_stack(tinfo, stack, bp,
++				bp = ops->walk_stack(task, irq_stack, stack, bp,
+ 					ops, data, irq_stack_end, &graph);
+ 				/*
+ 				 * We link to the next stack (which would be
+@@ -191,7 +193,9 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
+ 	/*
+ 	 * This handles the process stack:
+ 	 */
+-	bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
++	stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1));
++	bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph);
++out:
+ 	put_cpu();
+ }
+ EXPORT_SYMBOL(dump_trace);
+@@ -300,3 +304,50 @@ int is_valid_bugaddr(unsigned long ip)
+ 
+ 	return ud2 == 0x0b0f;
+ }
++
++#ifdef CONFIG_PAX_MEMORY_STACKLEAK
++void pax_check_alloca(unsigned long size)
++{
++	unsigned long sp = (unsigned long)&sp, stack_start, stack_end;
++	unsigned cpu, used;
++	char *id;
++
++	/* check the process stack first */
++	stack_start = (unsigned long)task_stack_page(current);
++	stack_end = stack_start + THREAD_SIZE;
++	if (likely(stack_start <= sp && sp < stack_end)) {
++		unsigned long stack_left = sp & (THREAD_SIZE - 1);
++		BUG_ON(stack_left < 256 || size >= stack_left - 256);
++		return;
++	}
++
++	cpu = get_cpu();
++
++	/* check the irq stacks */
++	stack_end = (unsigned long)per_cpu(irq_stack_ptr, cpu);
++	stack_start = stack_end - IRQ_STACK_SIZE;
++	if (stack_start <= sp && sp < stack_end) {
++		unsigned long stack_left = sp & (IRQ_STACK_SIZE - 1);
++		put_cpu();
++		BUG_ON(stack_left < 256 || size >= stack_left - 256);
++		return;
++	}
++
++	/* check the exception stacks */
++	used = 0;
++	stack_end = (unsigned long)in_exception_stack(cpu, sp, &used, &id);
++	stack_start = stack_end - EXCEPTION_STKSZ;
++	if (stack_end && stack_start <= sp && sp < stack_end) {
++		unsigned long stack_left = sp & (EXCEPTION_STKSZ - 1);
++		put_cpu();
++		BUG_ON(stack_left < 256 || size >= stack_left - 256);
++		return;
++	}
++
++	put_cpu();
++
++	/* unknown stack */
++	BUG();
++}
++EXPORT_SYMBOL(pax_check_alloca);
++#endif
+diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
+index 174da5f..5e55606 100644
+--- a/arch/x86/kernel/e820.c
++++ b/arch/x86/kernel/e820.c
+@@ -803,8 +803,8 @@ unsigned long __init e820_end_of_low_ram_pfn(void)
+ 
+ static void early_panic(char *msg)
+ {
+-	early_printk(msg);
+-	panic(msg);
++	early_printk("%s", msg);
++	panic("%s", msg);
+ }
+ 
+ static int userdef __initdata;
+diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
+index d15f575..d692043 100644
+--- a/arch/x86/kernel/early_printk.c
++++ b/arch/x86/kernel/early_printk.c
+@@ -7,6 +7,7 @@
+ #include <linux/pci_regs.h>
+ #include <linux/pci_ids.h>
+ #include <linux/errno.h>
++#include <linux/sched.h>
+ #include <asm/io.h>
+ #include <asm/processor.h>
+ #include <asm/fcntl.h>
+diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
+index 2cfbc3a..b756682 100644
+--- a/arch/x86/kernel/entry_32.S
++++ b/arch/x86/kernel/entry_32.S
+@@ -177,13 +177,153 @@
+ 	/*CFI_REL_OFFSET gs, PT_GS*/
+ .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
++.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 $16, %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 $16, %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
++
++	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
++	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 %eax
++	popl %ecx
++	popl %edi
++	ret
++ENDPROC(pax_erase_kstack)
++#endif
++
++.macro __SAVE_ALL _DS
+ 	cld
+ 	PUSH_GS
+ 	pushl_cfi %fs
+@@ -206,7 +346,7 @@
+ 	CFI_REL_OFFSET ecx, 0
+ 	pushl_cfi %ebx
+ 	CFI_REL_OFFSET ebx, 0
+-	movl $(__USER_DS), %edx
++	movl $\_DS, %edx
+ 	movl %edx, %ds
+ 	movl %edx, %es
+ 	movl $(__KERNEL_PERCPU), %edx
+@@ -214,6 +354,15 @@
+ 	SET_KERNEL_GS %edx
+ .endm
+ 
++.macro SAVE_ALL
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_PAGEEXEC) || \
defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) ++	__SAVE_ALL \
__KERNEL_DS ++	pax_enter_kernel
++#else
++	__SAVE_ALL __USER_DS
++#endif
++.endm
++
+ .macro RESTORE_INT_REGS
+ 	popl_cfi %ebx
+ 	CFI_RESTORE ebx
+@@ -297,7 +446,7 @@ ENTRY(ret_from_fork)
+ 	popfl_cfi
+ 	jmp syscall_exit
+ 	CFI_ENDPROC
+-END(ret_from_fork)
++ENDPROC(ret_from_fork)
+ 
+ ENTRY(ret_from_kernel_thread)
+ 	CFI_STARTPROC
+@@ -344,7 +493,15 @@ 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)
+ 	LOCKDEP_SYS_EXIT
+@@ -356,8 +513,8 @@ ENTRY(resume_userspace)
+ 	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done on
+ 					# int/exception return?
+ 	jne work_pending
+-	jmp restore_all
+-END(ret_from_exception)
++	jmp restore_all_pax
++ENDPROC(ret_from_exception)
+ 
+ #ifdef CONFIG_PREEMPT
+ ENTRY(resume_kernel)
+@@ -372,7 +529,7 @@ need_resched:
+ 	jz restore_all
+ 	call preempt_schedule_irq
+ 	jmp need_resched
+-END(resume_kernel)
++ENDPROC(resume_kernel)
+ #endif
+ 	CFI_ENDPROC
+ /*
+@@ -406,30 +563,45 @@ sysenter_past_esp:
+ 	/*CFI_REL_OFFSET cs, 0*/
+ 	/*
+ 	 * Push current_thread_info()->sysenter_return to the stack.
+-	 * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
+-	 * pushed above; +8 corresponds to copy_thread's esp0 setting.
+ 	 */
+-	pushl_cfi ((TI_sysenter_return)-THREAD_SIZE+8+4*4)(%esp)
++	pushl_cfi $0
+ 	CFI_REL_OFFSET eip, 0
+ 
+ 	pushl_cfi %eax
+ 	SAVE_ALL
++	GET_THREAD_INFO(%ebp)
++	movl TI_sysenter_return(%ebp),%ebp
++	movl %ebp,PT_EIP(%esp)
+ 	ENABLE_INTERRUPTS(CLBR_NONE)
+ 
+ /*
+  * Load the potential sixth argument from user stack.
+  * Careful about security.
+  */
++	movl PT_OLDESP(%esp),%ebp
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	mov PT_OLDSS(%esp),%ds
++1:	movl %ds:(%ebp),%ebp
++	push %ss
++	pop %ds
++#else
+ 	cmpl $__PAGE_OFFSET-3,%ebp
+ 	jae syscall_fault
+ 	ASM_STAC
+ 1:	movl (%ebp),%ebp
+ 	ASM_CLAC
++#endif
++
+ 	movl %ebp,PT_EBP(%esp)
+ 	_ASM_EXTABLE(1b,syscall_fault)
+ 
+ 	GET_THREAD_INFO(%ebp)
+ 
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
+ 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+ 	jnz sysenter_audit
+ sysenter_do_call:
+@@ -444,12 +616,24 @@ sysenter_do_call:
+ 	testl $_TIF_ALLWORK_MASK, %ecx
+ 	jne sysexit_audit
+ sysenter_exit:
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pushl_cfi %eax
++	movl %esp, %eax
++	call pax_randomize_kstack
++	popl_cfi %eax
++#endif
++
++	pax_erase_kstack
++
+ /* if something modifies registers it must also disable sysexit */
+ 	movl PT_EIP(%esp), %edx
+ 	movl PT_OLDESP(%esp), %ecx
+ 	xorl %ebp,%ebp
+ 	TRACE_IRQS_ON
+ 1:	mov  PT_FS(%esp), %fs
++2:	mov  PT_DS(%esp), %ds
++3:	mov  PT_ES(%esp), %es
+ 	PTGS_TO_GS
+ 	ENABLE_INTERRUPTS_SYSEXIT
+ 
+@@ -466,6 +650,9 @@ sysenter_audit:
+ 	movl %eax,%edx			/* 2nd arg: syscall number */
+ 	movl $AUDIT_ARCH_I386,%eax	/* 1st arg: audit arch */
+ 	call __audit_syscall_entry
++
++	pax_erase_kstack
++
+ 	pushl_cfi %ebx
+ 	movl PT_EAX(%esp),%eax		/* reload syscall number */
+ 	jmp sysenter_do_call
+@@ -491,10 +678,16 @@ sysexit_audit:
+ 
+ 	CFI_ENDPROC
+ .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
+ ENDPROC(ia32_sysenter_target)
+ 
+@@ -509,6 +702,11 @@ ENTRY(system_call)
+ 	pushl_cfi %eax			# save orig_eax
+ 	SAVE_ALL
+ 	GET_THREAD_INFO(%ebp)
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
+ 					# system call tracing in operation / emulation
+ 	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
+ 	jnz syscall_trace_entry
+@@ -527,6 +725,15 @@ syscall_exit:
+ 	testl $_TIF_ALLWORK_MASK, %ecx	# current->work
+ 	jne syscall_exit_work
+ 
++restore_all_pax:
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	movl %esp, %eax
++	call pax_randomize_kstack
++#endif
++
++	pax_erase_kstack
++
+ restore_all:
+ 	TRACE_IRQS_IRET
+ restore_all_notrace:
+@@ -583,14 +790,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 $16, %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 $16, %esi
++	mov %esi, %cr0
++#endif
++
+ 	pushl_cfi $__ESPFIX_SS
+ 	pushl_cfi %eax			/* new kernel esp */
+ 	/* Disable interrupts, but do not irqtrace this section: we
+@@ -619,20 +846,18 @@ work_resched:
+ 	movl TI_flags(%ebp), %ecx
+ 	andl $_TIF_WORK_MASK, %ecx	# is there any work to be done other
+ 					# than syscall tracing?
+-	jz restore_all
++	jz restore_all_pax
+ 	testb $_TIF_NEED_RESCHED, %cl
+ 	jnz work_resched
+ 
+ work_notifysig:				# deal with pending signals and
+ 					# notify-resume requests
++	movl %esp, %eax
+ #ifdef CONFIG_VM86
+ 	testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
+-	movl %esp, %eax
+ 	jne work_notifysig_v86		# returning to kernel-space or
+ 					# vm86-space
+ 1:
+-#else
+-	movl %esp, %eax
+ #endif
+ 	TRACE_IRQS_ON
+ 	ENABLE_INTERRUPTS(CLBR_NONE)
+@@ -653,7 +878,7 @@ work_notifysig_v86:
+ 	movl %eax, %esp
+ 	jmp 1b
+ #endif
+-END(work_pending)
++ENDPROC(work_pending)
+ 
+ 	# perform syscall exit tracing
+ 	ALIGN
+@@ -661,11 +886,14 @@ syscall_trace_entry:
+ 	movl $-ENOSYS,PT_EAX(%esp)
+ 	movl %esp, %eax
+ 	call syscall_trace_enter
++
++	pax_erase_kstack
++
+ 	/* What it returned is what we'll actually use.  */
+ 	cmpl $(NR_syscalls), %eax
+ 	jnae syscall_call
+ 	jmp syscall_exit
+-END(syscall_trace_entry)
++ENDPROC(syscall_trace_entry)
+ 
+ 	# perform syscall exit tracing
+ 	ALIGN
+@@ -678,21 +906,25 @@ syscall_exit_work:
+ 	movl %esp, %eax
+ 	call syscall_trace_leave
+ 	jmp resume_userspace
+-END(syscall_exit_work)
++ENDPROC(syscall_exit_work)
+ 	CFI_ENDPROC
+ 
+ 	RING0_INT_FRAME			# can't unwind into user space anyway
+ syscall_fault:
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	push %ss
++	pop %ds
++#endif
+ 	ASM_CLAC
+ 	GET_THREAD_INFO(%ebp)
+ 	movl $-EFAULT,PT_EAX(%esp)
+ 	jmp resume_userspace
+-END(syscall_fault)
++ENDPROC(syscall_fault)
+ 
+ syscall_badsys:
+ 	movl $-ENOSYS,PT_EAX(%esp)
+ 	jmp resume_userspace
+-END(syscall_badsys)
++ENDPROC(syscall_badsys)
+ 	CFI_ENDPROC
+ /*
+  * End of kprobes section
+@@ -708,8 +940,15 @@ END(syscall_badsys)
+  * normal stack and adjusts ESP with the matching offset.
+  */
+ 	/* 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_cfi $__KERNEL_DS
+@@ -762,7 +1001,7 @@ vector=vector+1
+   .endr
+ 2:	jmp common_interrupt
+ .endr
+-END(irq_entries_start)
++ENDPROC(irq_entries_start)
+ 
+ .previous
+ END(interrupt)
+@@ -823,7 +1062,7 @@ ENTRY(coprocessor_error)
+ 	pushl_cfi $do_coprocessor_error
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(coprocessor_error)
++ENDPROC(coprocessor_error)
+ 
+ ENTRY(simd_coprocessor_error)
+ 	RING0_INT_FRAME
+@@ -836,7 +1075,7 @@ ENTRY(simd_coprocessor_error)
+ .section .altinstructions,"a"
+ 	altinstruction_entry 661b, 663f, X86_FEATURE_XMM, 662b-661b, 664f-663f
+ .previous
+-.section .altinstr_replacement,"ax"
++.section .altinstr_replacement,"a"
+ 663:	pushl $do_simd_coprocessor_error
+ 664:
+ .previous
+@@ -845,7 +1084,7 @@ ENTRY(simd_coprocessor_error)
+ #endif
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(simd_coprocessor_error)
++ENDPROC(simd_coprocessor_error)
+ 
+ ENTRY(device_not_available)
+ 	RING0_INT_FRAME
+@@ -854,18 +1093,18 @@ ENTRY(device_not_available)
+ 	pushl_cfi $do_device_not_available
+ 	jmp error_code
+ 	CFI_ENDPROC
+-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)
+ 
+ ENTRY(native_irq_enable_sysexit)
+ 	sti
+ 	sysexit
+-END(native_irq_enable_sysexit)
++ENDPROC(native_irq_enable_sysexit)
+ #endif
+ 
+ ENTRY(overflow)
+@@ -875,7 +1114,7 @@ ENTRY(overflow)
+ 	pushl_cfi $do_overflow
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(overflow)
++ENDPROC(overflow)
+ 
+ ENTRY(bounds)
+ 	RING0_INT_FRAME
+@@ -884,7 +1123,7 @@ ENTRY(bounds)
+ 	pushl_cfi $do_bounds
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(bounds)
++ENDPROC(bounds)
+ 
+ ENTRY(invalid_op)
+ 	RING0_INT_FRAME
+@@ -893,7 +1132,7 @@ ENTRY(invalid_op)
+ 	pushl_cfi $do_invalid_op
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(invalid_op)
++ENDPROC(invalid_op)
+ 
+ ENTRY(coprocessor_segment_overrun)
+ 	RING0_INT_FRAME
+@@ -902,7 +1141,7 @@ ENTRY(coprocessor_segment_overrun)
+ 	pushl_cfi $do_coprocessor_segment_overrun
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(coprocessor_segment_overrun)
++ENDPROC(coprocessor_segment_overrun)
+ 
+ ENTRY(invalid_TSS)
+ 	RING0_EC_FRAME
+@@ -910,7 +1149,7 @@ ENTRY(invalid_TSS)
+ 	pushl_cfi $do_invalid_TSS
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(invalid_TSS)
++ENDPROC(invalid_TSS)
+ 
+ ENTRY(segment_not_present)
+ 	RING0_EC_FRAME
+@@ -918,7 +1157,7 @@ ENTRY(segment_not_present)
+ 	pushl_cfi $do_segment_not_present
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(segment_not_present)
++ENDPROC(segment_not_present)
+ 
+ ENTRY(stack_segment)
+ 	RING0_EC_FRAME
+@@ -926,7 +1165,7 @@ ENTRY(stack_segment)
+ 	pushl_cfi $do_stack_segment
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(stack_segment)
++ENDPROC(stack_segment)
+ 
+ ENTRY(alignment_check)
+ 	RING0_EC_FRAME
+@@ -934,7 +1173,7 @@ ENTRY(alignment_check)
+ 	pushl_cfi $do_alignment_check
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(alignment_check)
++ENDPROC(alignment_check)
+ 
+ ENTRY(divide_error)
+ 	RING0_INT_FRAME
+@@ -943,7 +1182,7 @@ ENTRY(divide_error)
+ 	pushl_cfi $do_divide_error
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(divide_error)
++ENDPROC(divide_error)
+ 
+ #ifdef CONFIG_X86_MCE
+ ENTRY(machine_check)
+@@ -953,7 +1192,7 @@ ENTRY(machine_check)
+ 	pushl_cfi machine_check_vector
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(machine_check)
++ENDPROC(machine_check)
+ #endif
+ 
+ ENTRY(spurious_interrupt_bug)
+@@ -963,7 +1202,7 @@ ENTRY(spurious_interrupt_bug)
+ 	pushl_cfi $do_spurious_interrupt_bug
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(spurious_interrupt_bug)
++ENDPROC(spurious_interrupt_bug)
+ /*
+  * End of kprobes section
+  */
+@@ -1073,7 +1312,7 @@ BUILD_INTERRUPT3(hyperv_callback_vector, \
HYPERVISOR_CALLBACK_VECTOR, + 
+ ENTRY(mcount)
+ 	ret
+-END(mcount)
++ENDPROC(mcount)
+ 
+ ENTRY(ftrace_caller)
+ 	cmpl $0, function_trace_stop
+@@ -1106,7 +1345,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) */
+@@ -1207,7 +1446,7 @@ trace:
+ 	popl %ecx
+ 	popl %eax
+ 	jmp ftrace_stub
+-END(mcount)
++ENDPROC(mcount)
+ #endif /* CONFIG_DYNAMIC_FTRACE */
+ #endif /* CONFIG_FUNCTION_TRACER */
+ 
+@@ -1225,7 +1464,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:
+@@ -1281,15 +1520,18 @@ 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
+ 	CFI_ENDPROC
+-END(page_fault)
++ENDPROC(page_fault)
+ 
+ /*
+  * Debug traps and NMI can happen at the one SYSENTER instruction
+@@ -1332,7 +1574,7 @@ debug_stack_correct:
+ 	call do_debug
+ 	jmp ret_from_exception
+ 	CFI_ENDPROC
+-END(debug)
++ENDPROC(debug)
+ 
+ /*
+  * NMI is doubly nasty. It can happen _while_ we're handling
+@@ -1370,6 +1612,9 @@ nmi_stack_correct:
+ 	xorl %edx,%edx		# zero error code
+ 	movl %esp,%eax		# pt_regs pointer
+ 	call do_nmi
++
++	pax_exit_kernel
++
+ 	jmp restore_all_notrace
+ 	CFI_ENDPROC
+ 
+@@ -1406,12 +1651,15 @@ 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
+ 	CFI_ADJUST_CFA_OFFSET -24
+ 	jmp irq_return
+ 	CFI_ENDPROC
+-END(nmi)
++ENDPROC(nmi)
+ 
+ ENTRY(int3)
+ 	RING0_INT_FRAME
+@@ -1424,14 +1672,14 @@ ENTRY(int3)
+ 	call do_int3
+ 	jmp ret_from_exception
+ 	CFI_ENDPROC
+-END(int3)
++ENDPROC(int3)
+ 
+ ENTRY(general_protection)
+ 	RING0_EC_FRAME
+ 	pushl_cfi $do_general_protection
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(general_protection)
++ENDPROC(general_protection)
+ 
+ #ifdef CONFIG_KVM_GUEST
+ ENTRY(async_page_fault)
+@@ -1440,7 +1688,7 @@ ENTRY(async_page_fault)
+ 	pushl_cfi $do_async_page_fault
+ 	jmp error_code
+ 	CFI_ENDPROC
+-END(async_page_fault)
++ENDPROC(async_page_fault)
+ #endif
+ 
+ /*
+diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
+index 1b69951..8430a6d 100644
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -59,6 +59,8 @@
+ #include <asm/context_tracking.h>
+ #include <asm/smap.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>
+@@ -80,8 +82,9 @@
+ #ifdef CONFIG_DYNAMIC_FTRACE
+ 
+ ENTRY(function_hook)
++	pax_force_retaddr
+ 	retq
+-END(function_hook)
++ENDPROC(function_hook)
+ 
+ /* skip is set if stack has been adjusted */
+ .macro ftrace_caller_setup skip=0
+@@ -122,8 +125,9 @@ GLOBAL(ftrace_graph_call)
+ #endif
+ 
+ GLOBAL(ftrace_stub)
++	pax_force_retaddr
+ 	retq
+-END(ftrace_caller)
++ENDPROC(ftrace_caller)
+ 
+ ENTRY(ftrace_regs_caller)
+ 	/* Save the current flags before compare (in SS location)*/
+@@ -191,7 +195,7 @@ ftrace_restore_flags:
+ 	popfq
+ 	jmp  ftrace_stub
+ 
+-END(ftrace_regs_caller)
++ENDPROC(ftrace_regs_caller)
+ 
+ 
+ #else /* ! CONFIG_DYNAMIC_FTRACE */
+@@ -212,6 +216,7 @@ ENTRY(function_hook)
+ #endif
+ 
+ GLOBAL(ftrace_stub)
++	pax_force_retaddr
+ 	retq
+ 
+ trace:
+@@ -225,12 +230,13 @@ trace:
+ #endif
+ 	subq $MCOUNT_INSN_SIZE, %rdi
+ 
++	pax_force_fptr ftrace_trace_function
+ 	call   *ftrace_trace_function
+ 
+ 	MCOUNT_RESTORE_FRAME
+ 
+ 	jmp ftrace_stub
+-END(function_hook)
++ENDPROC(function_hook)
+ #endif /* CONFIG_DYNAMIC_FTRACE */
+ #endif /* CONFIG_FUNCTION_TRACER */
+ 
+@@ -252,8 +258,9 @@ ENTRY(ftrace_graph_caller)
+ 
+ 	MCOUNT_RESTORE_FRAME
+ 
++	pax_force_retaddr
+ 	retq
+-END(ftrace_graph_caller)
++ENDPROC(ftrace_graph_caller)
+ 
+ GLOBAL(return_to_handler)
+ 	subq  $24, %rsp
+@@ -269,7 +276,9 @@ GLOBAL(return_to_handler)
+ 	movq 8(%rsp), %rdx
+ 	movq (%rsp), %rax
+ 	addq $24, %rsp
++	pax_force_fptr %rdi
+ 	jmp *%rdi
++ENDPROC(return_to_handler)
+ #endif
+ 
+ 
+@@ -284,6 +293,430 @@ 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 $16,%rdi
++	jnc 3f
++	mov %cs,%edi
++	cmp $__KERNEL_CS,%edi
++	jnz 2f
++1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jnz 112f
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++	jmp 111f
++112:	cmp $1,%dil
++	jz 113f
++	ud2
++113:	sub $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__UDEREF_KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
++
++#ifdef CONFIG_PARAVIRT
++	PV_RESTORE_REGS(CLBR_RDI)
++#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 $16,%rdi
++	jnc 4f
++1:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	mov %ss,%edi
++	cmp $__UDEREF_KERNEL_DS,%edi
++	jnz 111f
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jz 112f
++	ud2
++112:	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
++
++#ifdef CONFIG_PARAVIRT
++	PV_RESTORE_REGS(CLBR_RDI);
++#endif
++
++	popq %rdi
++	pax_force_retaddr
++	retq
++
++#ifdef CONFIG_PAX_KERNEXEC
++2:	GET_CR0_INTO_RDI
++	btr $16,%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
++
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $1,%dil
++	jnz 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
++	cmpl $0, pv_info+PARAVIRT_enabled
++	jz 1f
++	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
++	jmp 2f
++1:
++#endif
++
++	i = 0
++	.rept USER_PGD_PTRS
++	movb $0,i*8(%rbx)
++	i = i + 1
++	.endr
++
++2:	SET_RDI_INTO_CR3
++
++#ifdef CONFIG_PAX_KERNEXEC
++	GET_CR0_INTO_RDI
++	bts $16,%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
++	661: jmp 1f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	cmp $0,%dil
++	jnz 3f
++	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	jmp 2f
++1:
++
++	mov %rdi,%rbx
++
++#ifdef CONFIG_PAX_KERNEXEC
++	GET_CR0_INTO_RDI
++	btr $16,%rdi
++	jnc 3f
++	SET_RDI_INTO_CR0
++#endif
++
++	add $__START_KERNEL_map,%rbx
++	sub phys_base(%rip),%rbx
++
++#ifdef CONFIG_PARAVIRT
++	cmpl $0, pv_info+PARAVIRT_enabled
++	jz 1f
++	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
++	jmp 2f
++1:
++#endif
++
++	i = 0
++	.rept USER_PGD_PTRS
++	movb $0x67,i*8(%rbx)
++	i = i + 1
++	.endr
++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 $16,%rdi
++	jc 110f
++	SET_RDI_INTO_CR0
++	or $2,%ebx
++110:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	661: jmp 111f
++	.pushsection .altinstr_replacement, "a"
++	662: ASM_NOP2
++	.popsection
++	.pushsection .altinstructions, "a"
++	altinstruction_entry 661b, 662b, X86_FEATURE_PCID, 2, 2
++	.popsection
++	GET_CR3_INTO_RDI
++	cmp $0,%dil
++	jz 111f
++	sub $4097,%rdi
++	or $4,%ebx
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__UDEREF_KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
++	.endm
++
++	.macro pax_exit_kernel_nmi
++#ifdef CONFIG_PAX_KERNEXEC
++	btr $1,%ebx
++	jnc 110f
++	GET_CR0_INTO_RDI
++	btr $16,%rdi
++	SET_RDI_INTO_CR0
++110:
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	btr $2,%ebx
++	jnc 111f
++	GET_CR3_INTO_RDI
++	add $4097,%rdi
++	bts $63,%rdi
++	SET_RDI_INTO_CR3
++	mov $__KERNEL_DS,%edi
++	mov %edi,%ss
++111:
++#endif
++	.endm
++
++	.macro pax_erase_kstack
++#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
++	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 offset=ARGOFFSET
+ #ifdef CONFIG_TRACE_IRQFLAGS
+@@ -375,8 +808,8 @@ ENDPROC(native_usergs_sysret64)
+ 	.endm
+ 
+ 	.macro UNFAKE_STACK_FRAME
+-	addq $8*6, %rsp
+-	CFI_ADJUST_CFA_OFFSET	-(6*8)
++	addq $8*6 + ARG_SKIP, %rsp
++	CFI_ADJUST_CFA_OFFSET	-(6*8 + ARG_SKIP)
+ 	.endm
+ 
+ /*
+@@ -463,7 +896,7 @@ ENDPROC(native_usergs_sysret64)
+ 	movq %rsp, %rsi
+ 
+ 	leaq -RBP(%rsp),%rdi	/* arg1 for handler */
+-	testl $3, CS-RBP(%rsi)
++	testb $3, CS-RBP(%rsi)
+ 	je 1f
+ 	SWAPGS
+ 	/*
+@@ -498,9 +931,10 @@ ENTRY(save_rest)
+ 	movq_cfi r15, R15+16
+ 	movq %r11, 8(%rsp)	/* return address */
+ 	FIXUP_TOP_OF_STACK %r11, 16
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-END(save_rest)
++ENDPROC(save_rest)
+ 
+ /* save complete stack frame */
+ 	.pushsection .kprobes.text, "ax"
+@@ -529,9 +963,10 @@ ENTRY(save_paranoid)
+ 	js 1f	/* negative -> in kernel */
+ 	SWAPGS
+ 	xorl %ebx,%ebx
+-1:	ret
++1:	pax_force_retaddr_bts
++	ret
+ 	CFI_ENDPROC
+-END(save_paranoid)
++ENDPROC(save_paranoid)
+ 	.popsection
+ 
+ /*
+@@ -553,7 +988,7 @@ ENTRY(ret_from_fork)
+ 
+ 	RESTORE_REST
+ 
+-	testl $3, CS-ARGOFFSET(%rsp)		# from kernel_thread?
++	testb $3, CS-ARGOFFSET(%rsp)		# from kernel_thread?
+ 	jz   1f
+ 
+ 	testl $_TIF_IA32, TI_flags(%rcx)	# 32-bit compat task needs IRET
+@@ -571,7 +1006,7 @@ ENTRY(ret_from_fork)
+ 	RESTORE_REST
+ 	jmp int_ret_from_sys_call
+ 	CFI_ENDPROC
+-END(ret_from_fork)
++ENDPROC(ret_from_fork)
+ 
+ /*
+  * System call entry. Up to 6 arguments in registers are supported.
+@@ -608,7 +1043,7 @@ END(ret_from_fork)
+ ENTRY(system_call)
+ 	CFI_STARTPROC	simple
+ 	CFI_SIGNAL_FRAME
+-	CFI_DEF_CFA	rsp,KERNEL_STACK_OFFSET
++	CFI_DEF_CFA	rsp,0
+ 	CFI_REGISTER	rip,rcx
+ 	/*CFI_REGISTER	rflags,r11*/
+ 	SWAPGS_UNSAFE_STACK
+@@ -621,16 +1056,23 @@ GLOBAL(system_call_after_swapgs)
+ 
+ 	movq	%rsp,PER_CPU_VAR(old_rsp)
+ 	movq	PER_CPU_VAR(kernel_stack),%rsp
++	SAVE_ARGS 8*6,0
++	pax_enter_kernel_user
++
++#ifdef CONFIG_PAX_RANDKSTACK
++	pax_erase_kstack
++#endif
++
+ 	/*
+ 	 * No need to follow this irqs off/on section - it's straight
+ 	 * and short:
+ 	 */
+ 	ENABLE_INTERRUPTS(CLBR_NONE)
+-	SAVE_ARGS 8,0
+ 	movq  %rax,ORIG_RAX-ARGOFFSET(%rsp)
+ 	movq  %rcx,RIP-ARGOFFSET(%rsp)
+ 	CFI_REL_OFFSET rip,RIP-ARGOFFSET
+-	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
++	GET_THREAD_INFO(%rcx)
++	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%rcx)
+ 	jnz tracesys
+ system_call_fastpath:
+ #if __SYSCALL_MASK == ~0
+@@ -640,7 +1082,7 @@ system_call_fastpath:
+ 	cmpl $__NR_syscall_max,%eax
+ #endif
+ 	ja badsys
+-	movq %r10,%rcx
++	movq R10-ARGOFFSET(%rsp),%rcx
+ 	call *sys_call_table(,%rax,8)  # XXX:	 rip relative
+ 	movq %rax,RAX-ARGOFFSET(%rsp)
+ /*
+@@ -654,10 +1096,13 @@ sysret_check:
+ 	LOCKDEP_SYS_EXIT
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF
+-	movl TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET),%edx
++	GET_THREAD_INFO(%rcx)
++	movl TI_flags(%rcx),%edx
+ 	andl %edi,%edx
+ 	jnz  sysret_careful
+ 	CFI_REMEMBER_STATE
++	pax_exit_kernel_user
++	pax_erase_kstack
+ 	/*
+ 	 * sysretq will re-enable interrupts:
+ 	 */
+@@ -709,14 +1154,18 @@ badsys:
+ 	 * jump back to the normal fast path.
+ 	 */
+ auditsys:
+-	movq %r10,%r9			/* 6th arg: 4th syscall arg */
++	movq R10-ARGOFFSET(%rsp),%r9	/* 6th arg: 4th syscall arg */
+ 	movq %rdx,%r8			/* 5th arg: 3rd syscall arg */
+ 	movq %rsi,%rcx			/* 4th arg: 2nd syscall arg */
+ 	movq %rdi,%rdx			/* 3rd arg: 1st syscall arg */
+ 	movq %rax,%rsi			/* 2nd arg: syscall number */
+ 	movl $AUDIT_ARCH_X86_64,%edi	/* 1st arg: audit arch */
+ 	call __audit_syscall_entry
++
++	pax_erase_kstack
++
+ 	LOAD_ARGS 0		/* reload call-clobbered registers */
++	pax_set_fptr_mask
+ 	jmp system_call_fastpath
+ 
+ 	/*
+@@ -737,7 +1186,7 @@ sysret_audit:
+ 	/* Do syscall tracing */
+ tracesys:
+ #ifdef CONFIG_AUDITSYSCALL
+-	testl $(_TIF_WORK_SYSCALL_ENTRY & \
~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET) ++	testl \
$(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%rcx) + 	jz auditsys
+ #endif
+ 	SAVE_REST
+@@ -745,12 +1194,16 @@ tracesys:
+ 	FIXUP_TOP_OF_STACK %rdi
+ 	movq %rsp,%rdi
+ 	call syscall_trace_enter
++
++	pax_erase_kstack
++
+ 	/*
+ 	 * Reload arg registers from stack in case ptrace changed them.
+ 	 * We don't reload %rax because syscall_trace_enter() returned
+ 	 * the value it wants us to use in the table lookup.
+ 	 */
+ 	LOAD_ARGS ARGOFFSET, 1
++	pax_set_fptr_mask
+ 	RESTORE_REST
+ #if __SYSCALL_MASK == ~0
+ 	cmpq $__NR_syscall_max,%rax
+@@ -759,7 +1212,7 @@ tracesys:
+ 	cmpl $__NR_syscall_max,%eax
+ #endif
+ 	ja   int_ret_from_sys_call	/* RAX(%rsp) set to -ENOSYS above */
+-	movq %r10,%rcx	/* fixup for C */
++	movq R10-ARGOFFSET(%rsp),%rcx	/* fixup for C */
+ 	call *sys_call_table(,%rax,8)
+ 	movq %rax,RAX-ARGOFFSET(%rsp)
+ 	/* Use IRET because user could have changed frame */
+@@ -780,7 +1233,9 @@ GLOBAL(int_with_check)
+ 	andl %edi,%edx
+ 	jnz   int_careful
+ 	andl    $~TS_COMPAT,TI_status(%rcx)
+-	jmp   retint_swapgs
++	pax_exit_kernel_user
++	pax_erase_kstack
++	jmp   retint_swapgs_pax
+ 
+ 	/* Either reschedule or signal or syscall exit tracking needed. */
+ 	/* First do a reschedule test. */
+@@ -826,7 +1281,7 @@ int_restore_rest:
+ 	TRACE_IRQS_OFF
+ 	jmp int_with_check
+ 	CFI_ENDPROC
+-END(system_call)
++ENDPROC(system_call)
+ 
+ 	.macro FORK_LIKE func
+ ENTRY(stub_\func)
+@@ -839,9 +1294,10 @@ ENTRY(stub_\func)
+ 	DEFAULT_FRAME 0 8		/* offset 8: return address */
+ 	call sys_\func
+ 	RESTORE_TOP_OF_STACK %r11, 8
++	pax_force_retaddr
+ 	ret $REST_SKIP		/* pop extended registers */
+ 	CFI_ENDPROC
+-END(stub_\func)
++ENDPROC(stub_\func)
+ 	.endm
+ 
+ 	.macro FIXED_FRAME label,func
+@@ -851,9 +1307,10 @@ ENTRY(\label)
+ 	FIXUP_TOP_OF_STACK %r11, 8-ARGOFFSET
+ 	call \func
+ 	RESTORE_TOP_OF_STACK %r11, 8-ARGOFFSET
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-END(\label)
++ENDPROC(\label)
+ 	.endm
+ 
+ 	FORK_LIKE  clone
+@@ -870,9 +1327,10 @@ ENTRY(ptregscall_common)
+ 	movq_cfi_restore R12+8, r12
+ 	movq_cfi_restore RBP+8, rbp
+ 	movq_cfi_restore RBX+8, rbx
++	pax_force_retaddr
+ 	ret $REST_SKIP		/* pop extended registers */
+ 	CFI_ENDPROC
+-END(ptregscall_common)
++ENDPROC(ptregscall_common)
+ 
+ ENTRY(stub_execve)
+ 	CFI_STARTPROC
+@@ -885,7 +1343,7 @@ ENTRY(stub_execve)
+ 	RESTORE_REST
+ 	jmp int_ret_from_sys_call
+ 	CFI_ENDPROC
+-END(stub_execve)
++ENDPROC(stub_execve)
+ 
+ /*
+  * sigreturn is special because it needs to restore all registers on return.
+@@ -902,7 +1360,7 @@ ENTRY(stub_rt_sigreturn)
+ 	RESTORE_REST
+ 	jmp int_ret_from_sys_call
+ 	CFI_ENDPROC
+-END(stub_rt_sigreturn)
++ENDPROC(stub_rt_sigreturn)
+ 
+ #ifdef CONFIG_X86_X32_ABI
+ ENTRY(stub_x32_rt_sigreturn)
+@@ -916,7 +1374,7 @@ ENTRY(stub_x32_rt_sigreturn)
+ 	RESTORE_REST
+ 	jmp int_ret_from_sys_call
+ 	CFI_ENDPROC
+-END(stub_x32_rt_sigreturn)
++ENDPROC(stub_x32_rt_sigreturn)
+ 
+ ENTRY(stub_x32_execve)
+ 	CFI_STARTPROC
+@@ -930,7 +1388,7 @@ ENTRY(stub_x32_execve)
+ 	RESTORE_REST
+ 	jmp int_ret_from_sys_call
+ 	CFI_ENDPROC
+-END(stub_x32_execve)
++ENDPROC(stub_x32_execve)
+ 
+ #endif
+ 
+@@ -967,7 +1425,7 @@ vector=vector+1
+ 2:	jmp common_interrupt
+ .endr
+ 	CFI_ENDPROC
+-END(irq_entries_start)
++ENDPROC(irq_entries_start)
+ 
+ .previous
+ END(interrupt)
+@@ -987,6 +1445,16 @@ END(interrupt)
+ 	subq $ORIG_RAX-RBP, %rsp
+ 	CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
+ 	SAVE_ARGS_IRQ
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rdi)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	call \func
+ 	.endm
+ 
+@@ -1019,7 +1487,7 @@ ret_from_intr:
+ 
+ exit_intr:
+ 	GET_THREAD_INFO(%rcx)
+-	testl $3,CS-ARGOFFSET(%rsp)
++	testb $3,CS-ARGOFFSET(%rsp)
+ 	je retint_kernel
+ 
+ 	/* Interrupt came from user space */
+@@ -1041,12 +1509,16 @@ retint_swapgs:		/* return to user-space */
+ 	 * The iretq could re-enable interrupts:
+ 	 */
+ 	DISABLE_INTERRUPTS(CLBR_ANY)
++	pax_exit_kernel_user
++retint_swapgs_pax:
+ 	TRACE_IRQS_IRETQ
+ 	SWAPGS
+ 	jmp restore_args
+ 
+ retint_restore_args:	/* return to kernel space */
+ 	DISABLE_INTERRUPTS(CLBR_ANY)
++	pax_exit_kernel
++	pax_force_retaddr (RIP-ARGOFFSET)
+ 	/*
+ 	 * The iretq could re-enable interrupts:
+ 	 */
+@@ -1129,7 +1601,7 @@ ENTRY(retint_kernel)
+ #endif
+ 
+ 	CFI_ENDPROC
+-END(common_interrupt)
++ENDPROC(common_interrupt)
+ /*
+  * End of kprobes section
+  */
+@@ -1147,7 +1619,7 @@ ENTRY(\sym)
+ 	interrupt \do_sym
+ 	jmp ret_from_intr
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+ #ifdef CONFIG_TRACING
+@@ -1230,12 +1702,22 @@ ENTRY(\sym)
+ 	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
+ 	call error_entry
+ 	DEFAULT_FRAME 0
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rsp)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	movq %rsp,%rdi		/* pt_regs pointer */
+ 	xorl %esi,%esi		/* no error code */
+ 	call \do_sym
+ 	jmp error_exit		/* %ebx: no swapgs flag */
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+ .macro paranoidzeroentry sym do_sym
+@@ -1248,15 +1730,25 @@ ENTRY(\sym)
+ 	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
+ 	call save_paranoid
+ 	TRACE_IRQS_OFF
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rsp)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	movq %rsp,%rdi		/* pt_regs pointer */
+ 	xorl %esi,%esi		/* no error code */
+ 	call \do_sym
+ 	jmp paranoid_exit	/* %ebx: no swapgs flag */
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+-#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
++#define INIT_TSS_IST(x) (TSS_ist + ((x) - 1) * 8)(%r12)
+ .macro paranoidzeroentry_ist sym do_sym ist
+ ENTRY(\sym)
+ 	INTR_FRAME
+@@ -1267,14 +1759,30 @@ ENTRY(\sym)
+ 	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
+ 	call save_paranoid
+ 	TRACE_IRQS_OFF_DEBUG
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rsp)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	movq %rsp,%rdi		/* pt_regs pointer */
+ 	xorl %esi,%esi		/* no error code */
++#ifdef CONFIG_SMP
++	imul $TSS_size, PER_CPU_VAR(cpu_number), %r12d
++	lea init_tss(%r12), %r12
++#else
++	lea init_tss(%rip), %r12
++#endif
+ 	subq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
+ 	call \do_sym
+ 	addq $EXCEPTION_STKSZ, INIT_TSS_IST(\ist)
+ 	jmp paranoid_exit	/* %ebx: no swapgs flag */
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+ .macro errorentry sym do_sym
+@@ -1286,13 +1794,23 @@ ENTRY(\sym)
+ 	CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
+ 	call error_entry
+ 	DEFAULT_FRAME 0
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rsp)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	movq %rsp,%rdi			/* pt_regs pointer */
+ 	movq ORIG_RAX(%rsp),%rsi	/* get error code */
+ 	movq $-1,ORIG_RAX(%rsp)		/* no syscall to restart */
+ 	call \do_sym
+ 	jmp error_exit			/* %ebx: no swapgs flag */
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+ 	/* error code is on the stack already */
+@@ -1306,13 +1824,23 @@ ENTRY(\sym)
+ 	call save_paranoid
+ 	DEFAULT_FRAME 0
+ 	TRACE_IRQS_OFF
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	testb $3, CS(%rsp)
++	jnz 1f
++	pax_enter_kernel
++	jmp 2f
++1:	pax_enter_kernel_user
++2:
++#else
++	pax_enter_kernel
++#endif
+ 	movq %rsp,%rdi			/* pt_regs pointer */
+ 	movq ORIG_RAX(%rsp),%rsi	/* get error code */
+ 	movq $-1,ORIG_RAX(%rsp)		/* no syscall to restart */
+ 	call \do_sym
+ 	jmp paranoid_exit		/* %ebx: no swapgs flag */
+ 	CFI_ENDPROC
+-END(\sym)
++ENDPROC(\sym)
+ .endm
+ 
+ zeroentry divide_error do_divide_error
+@@ -1342,9 +1870,10 @@ gs_change:
+ 2:	mfence		/* workaround */
+ 	SWAPGS
+ 	popfq_cfi
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-END(native_load_gs_index)
++ENDPROC(native_load_gs_index)
+ 
+ 	_ASM_EXTABLE(gs_change,bad_gs)
+ 	.section .fixup,"ax"
+@@ -1372,9 +1901,10 @@ ENTRY(call_softirq)
+ 	CFI_DEF_CFA_REGISTER	rsp
+ 	CFI_ADJUST_CFA_OFFSET   -8
+ 	decl PER_CPU_VAR(irq_count)
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-END(call_softirq)
++ENDPROC(call_softirq)
+ 
+ #ifdef CONFIG_XEN
+ zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
+@@ -1412,7 +1942,7 @@ ENTRY(xen_do_hypervisor_callback)   # \
do_hypervisor_callback(struct *pt_regs) + 	decl PER_CPU_VAR(irq_count)
+ 	jmp  error_exit
+ 	CFI_ENDPROC
+-END(xen_do_hypervisor_callback)
++ENDPROC(xen_do_hypervisor_callback)
+ 
+ /*
+  * Hypervisor uses this for application faults while it executes.
+@@ -1471,7 +2001,7 @@ ENTRY(xen_failsafe_callback)
+ 	SAVE_ALL
+ 	jmp error_exit
+ 	CFI_ENDPROC
+-END(xen_failsafe_callback)
++ENDPROC(xen_failsafe_callback)
+ 
+ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+ 	xen_hvm_callback_vector xen_evtchn_do_upcall
+@@ -1523,18 +2053,33 @@ ENTRY(paranoid_exit)
+ 	DEFAULT_FRAME
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF_DEBUG
+-	testl %ebx,%ebx				/* swapgs needed? */
++	testl $1,%ebx				/* swapgs needed? */
+ 	jnz paranoid_restore
+-	testl $3,CS(%rsp)
++	testb $3,CS(%rsp)
+ 	jnz   paranoid_userspace
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pax_exit_kernel
++	TRACE_IRQS_IRETQ 0
++	SWAPGS_UNSAFE_STACK
++	RESTORE_ALL 8
++	pax_force_retaddr_bts
++	jmp irq_return
++#endif
+ paranoid_swapgs:
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pax_exit_kernel_user
++#else
++	pax_exit_kernel
++#endif
+ 	TRACE_IRQS_IRETQ 0
+ 	SWAPGS_UNSAFE_STACK
+ 	RESTORE_ALL 8
+ 	jmp irq_return
+ paranoid_restore:
++	pax_exit_kernel
+ 	TRACE_IRQS_IRETQ_DEBUG 0
+ 	RESTORE_ALL 8
++	pax_force_retaddr_bts
+ 	jmp irq_return
+ paranoid_userspace:
+ 	GET_THREAD_INFO(%rcx)
+@@ -1563,7 +2108,7 @@ paranoid_schedule:
+ 	TRACE_IRQS_OFF
+ 	jmp paranoid_userspace
+ 	CFI_ENDPROC
+-END(paranoid_exit)
++ENDPROC(paranoid_exit)
+ 
+ /*
+  * Exception entry point. This expects an error code/orig_rax on the stack.
+@@ -1590,12 +2135,13 @@ ENTRY(error_entry)
+ 	movq_cfi r14, R14+8
+ 	movq_cfi r15, R15+8
+ 	xorl %ebx,%ebx
+-	testl $3,CS+8(%rsp)
++	testb $3,CS+8(%rsp)
+ 	je error_kernelspace
+ error_swapgs:
+ 	SWAPGS
+ error_sti:
+ 	TRACE_IRQS_OFF
++	pax_force_retaddr_bts
+ 	ret
+ 
+ /*
+@@ -1622,7 +2168,7 @@ bstep_iret:
+ 	movq %rcx,RIP+8(%rsp)
+ 	jmp error_swapgs
+ 	CFI_ENDPROC
+-END(error_entry)
++ENDPROC(error_entry)
+ 
+ 
+ /* ebx:	no swapgs flag (1: don't need swapgs, 0: need it) */
+@@ -1633,7 +2179,7 @@ ENTRY(error_exit)
+ 	DISABLE_INTERRUPTS(CLBR_NONE)
+ 	TRACE_IRQS_OFF
+ 	GET_THREAD_INFO(%rcx)
+-	testl %eax,%eax
++	testl $1,%eax
+ 	jne retint_kernel
+ 	LOCKDEP_SYS_EXIT_IRQ
+ 	movl TI_flags(%rcx),%edx
+@@ -1642,7 +2188,7 @@ ENTRY(error_exit)
+ 	jnz retint_careful
+ 	jmp retint_swapgs
+ 	CFI_ENDPROC
+-END(error_exit)
++ENDPROC(error_exit)
+ 
+ /*
+  * Test if a given stack is an NMI stack or not.
+@@ -1700,9 +2246,11 @@ ENTRY(nmi)
+ 	 * If %cs was not the kernel segment, then the NMI triggered in user
+ 	 * space, which means it is definitely not nested.
+ 	 */
++	cmpl $__KERNEXEC_KERNEL_CS, 16(%rsp)
++	je 1f
+ 	cmpl $__KERNEL_CS, 16(%rsp)
+ 	jne first_nmi
+-
++1:
+ 	/*
+ 	 * Check the special variable on the stack to see if NMIs are
+ 	 * executing.
+@@ -1736,8 +2284,7 @@ nested_nmi:
+ 
+ 1:
+ 	/* Set up the interrupted NMIs stack to jump to repeat_nmi */
+-	leaq -1*8(%rsp), %rdx
+-	movq %rdx, %rsp
++	subq $8, %rsp
+ 	CFI_ADJUST_CFA_OFFSET 1*8
+ 	leaq -10*8(%rsp), %rdx
+ 	pushq_cfi $__KERNEL_DS
+@@ -1755,6 +2302,7 @@ nested_nmi_out:
+ 	CFI_RESTORE rdx
+ 
+ 	/* No need to check faults here */
++#	pax_force_retaddr_bts
+ 	INTERRUPT_RETURN
+ 
+ 	CFI_RESTORE_STATE
+@@ -1871,6 +2419,8 @@ end_repeat_nmi:
+ 	 */
+ 	movq %cr2, %r12
+ 
++	pax_enter_kernel_nmi
++
+ 	/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
+ 	movq %rsp,%rdi
+ 	movq $-1,%rsi
+@@ -1883,26 +2433,31 @@ end_repeat_nmi:
+ 	movq %r12, %cr2
+ 1:
+ 	
+-	testl %ebx,%ebx				/* swapgs needed? */
++	testl $1,%ebx				/* swapgs needed? */
+ 	jnz nmi_restore
+ nmi_swapgs:
+ 	SWAPGS_UNSAFE_STACK
+ nmi_restore:
++	pax_exit_kernel_nmi
+ 	/* Pop the extra iret frame at once */
+ 	RESTORE_ALL 6*8
++	testb $3, 8(%rsp)
++	jnz 1f
++	pax_force_retaddr_bts
++1:
+ 
+ 	/* Clear the NMI executing stack variable */
+ 	movq $0, 5*8(%rsp)
+ 	jmp irq_return
+ 	CFI_ENDPROC
+-END(nmi)
++ENDPROC(nmi)
+ 
+ ENTRY(ignore_sysret)
+ 	CFI_STARTPROC
+ 	mov $-ENOSYS,%eax
+ 	sysret
+ 	CFI_ENDPROC
+-END(ignore_sysret)
++ENDPROC(ignore_sysret)
+ 
+ /*
+  * End of kprobes section
+diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
+index 42a392a..fbbd930 100644
+--- a/arch/x86/kernel/ftrace.c
++++ b/arch/x86/kernel/ftrace.c
+@@ -105,6 +105,8 @@ ftrace_modify_code_direct(unsigned long ip, unsigned const char \
*old_code, + {
+ 	unsigned char replaced[MCOUNT_INSN_SIZE];
+ 
++	ip = ktla_ktva(ip);
++
+ 	/*
+ 	 * Note: Due to modules and __init, code can
+ 	 *  disappear and change, we need to protect against faulting
+@@ -227,7 +229,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
+ 	unsigned char old[MCOUNT_INSN_SIZE], *new;
+ 	int ret;
+ 
+-	memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
++	memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
+ 	new = ftrace_call_replace(ip, (unsigned long)func);
+ 
+ 	/* See comment above by declaration of modifying_ftrace_code */
+@@ -238,7 +240,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
+ 	/* Also update the regs callback function */
+ 	if (!ret) {
+ 		ip = (unsigned long)(&ftrace_regs_call);
+-		memcpy(old, &ftrace_regs_call, MCOUNT_INSN_SIZE);
++		memcpy(old, ktla_ktva((void *)&ftrace_regs_call), MCOUNT_INSN_SIZE);
+ 		new = ftrace_call_replace(ip, (unsigned long)func);
+ 		ret = ftrace_modify_code(ip, old, new);
+ 	}
+@@ -279,7 +281,7 @@ static int ftrace_write(unsigned long ip, const char *val, int \
size) + 	 * kernel identity mapping to modify code.
+ 	 */
+ 	if (within(ip, (unsigned long)_text, (unsigned long)_etext))
+-		ip = (unsigned long)__va(__pa_symbol(ip));
++		ip = (unsigned long)__va(__pa_symbol(ktla_ktva(ip)));
+ 
+ 	return probe_kernel_write((void *)ip, val, size);
+ }
+@@ -289,7 +291,7 @@ static int add_break(unsigned long ip, const char *old)
+ 	unsigned char replaced[MCOUNT_INSN_SIZE];
+ 	unsigned char brk = BREAKPOINT_INSTRUCTION;
+ 
+-	if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
++	if (probe_kernel_read(replaced, (void *)ktla_ktva(ip), MCOUNT_INSN_SIZE))
+ 		return -EFAULT;
+ 
+ 	/* Make sure it is what we expect it to be */
+@@ -637,7 +639,7 @@ ftrace_modify_code(unsigned long ip, unsigned const char \
*old_code, + 	return ret;
+ 
+  fail_update:
+-	probe_kernel_write((void *)ip, &old_code[0], 1);
++	probe_kernel_write((void *)ktla_ktva(ip), &old_code[0], 1);
+ 	goto out;
+ }
+ 
+@@ -670,6 +672,8 @@ static int ftrace_mod_jmp(unsigned long ip,
+ {
+ 	unsigned char code[MCOUNT_INSN_SIZE];
+ 
++	ip = ktla_ktva(ip);
++
+ 	if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
+ 		return -EFAULT;
+ 
+diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
+index 55b6761..a6456fc 100644
+--- a/arch/x86/kernel/head64.c
++++ b/arch/x86/kernel/head64.c
+@@ -67,12 +67,12 @@ again:
+ 	pgd = *pgd_p;
+ 
+ 	/*
+-	 * The use of __START_KERNEL_map rather than __PAGE_OFFSET here is
+-	 * critical -- __PAGE_OFFSET would point us back into the dynamic
++	 * The use of __early_va rather than __va here is critical:
++	 * __va would point us back into the dynamic
+ 	 * range and we might end up looping forever...
+ 	 */
+ 	if (pgd)
+-		pud_p = (pudval_t *)((pgd & PTE_PFN_MASK) + __START_KERNEL_map - phys_base);
++		pud_p = (pudval_t *)(__early_va(pgd & PTE_PFN_MASK));
+ 	else {
+ 		if (next_early_pgt >= EARLY_DYNAMIC_PAGE_TABLES) {
+ 			reset_early_page_tables();
+@@ -82,13 +82,13 @@ again:
+ 		pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++];
+ 		for (i = 0; i < PTRS_PER_PUD; i++)
+ 			pud_p[i] = 0;
+-		*pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
++		*pgd_p = (pgdval_t)__pa(pud_p) + _KERNPG_TABLE;
+ 	}
+ 	pud_p += pud_index(address);
+ 	pud = *pud_p;
+ 
+ 	if (pud)
+-		pmd_p = (pmdval_t *)((pud & PTE_PFN_MASK) + __START_KERNEL_map - phys_base);
++		pmd_p = (pmdval_t *)(__early_va(pud & PTE_PFN_MASK));
+ 	else {
+ 		if (next_early_pgt >= EARLY_DYNAMIC_PAGE_TABLES) {
+ 			reset_early_page_tables();
+@@ -98,7 +98,7 @@ again:
+ 		pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++];
+ 		for (i = 0; i < PTRS_PER_PMD; i++)
+ 			pmd_p[i] = 0;
+-		*pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
++		*pud_p = (pudval_t)__pa(pmd_p) + _KERNPG_TABLE;
+ 	}
+ 	pmd = (physaddr & PMD_MASK) + early_pmd_flags;
+ 	pmd_p[pmd_index(address)] = pmd;
+@@ -175,7 +175,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
+ 	if (console_loglevel == 10)
+ 		early_printk("Kernel alive\n");
+ 
+-	clear_page(init_level4_pgt);
+ 	/* set init_level4_pgt kernel high mapping*/
+ 	init_level4_pgt[511] = early_level4_pgt[511];
+ 
+diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
+index 5dd87a8..d68b3f4 100644
+--- a/arch/x86/kernel/head_32.S
++++ b/arch/x86/kernel/head_32.S
+@@ -26,6 +26,12 @@
+ /* Physical address */
+ #define pa(X) ((X) - __PAGE_OFFSET)
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++#define ta(X) (X)
++#else
++#define ta(X) ((X) - __PAGE_OFFSET)
++#endif
++
+ /*
+  * References to members of the new_cpu_data structure.
+  */
+@@ -55,11 +61,7 @@
+  * and small than max_low_pfn, otherwise will waste some page table entries
+  */
+ 
+-#if PTRS_PER_PMD > 1
+-#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
+-#else
+-#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
+-#endif
++#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PTE)
+ 
+ /* Number of possible pages in the lowmem region */
+ LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
+@@ -78,6 +80,12 @@ INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE
+ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
+ 
+ /*
++ * Real beginning of normal "text" segment
++ */
++ENTRY(stext)
++ENTRY(_stext)
++
++/*
+  * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
+  * %esi points to the real-mode code as a 32-bit pointer.
+  * CS and DS must be 4 GB flat segments, but we don't depend on
+@@ -85,6 +93,13 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE)
+  * can.
+  */
+ __HEAD
++
++#ifdef CONFIG_PAX_KERNEXEC
++	jmp startup_32
++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
++.fill PAGE_SIZE-5,1,0xcc
++#endif
++
+ ENTRY(startup_32)
+ 	movl pa(stack_start),%ecx
+ 	
+@@ -106,6 +121,59 @@ ENTRY(startup_32)
+ 2:
+ 	leal -__PAGE_OFFSET(%ecx),%esp
+ 
++#ifdef CONFIG_SMP
++	movl $pa(cpu_gdt_table),%edi
++	movl $__per_cpu_load,%eax
++	movw %ax,GDT_ENTRY_PERCPU * 8 + 2(%edi)
++	rorl $16,%eax
++	movb %al,GDT_ENTRY_PERCPU * 8 + 4(%edi)
++	movb %ah,GDT_ENTRY_PERCPU * 8 + 7(%edi)
++	movl $__per_cpu_end - 1,%eax
++	subl $__per_cpu_start,%eax
++	movw %ax,GDT_ENTRY_PERCPU * 8 + 0(%edi)
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	movl $NR_CPUS,%ecx
++	movl $pa(cpu_gdt_table),%edi
++1:
++	movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS \
* 8 + 4(%edi) ++	movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | \
0x00c0fb00),GDT_ENTRY_DEFAULT_USER_CS * 8 + 4(%edi) ++	movl $((((__PAGE_OFFSET-1) & \
0xf0000000) >> 12) | 0x00c0f300),GDT_ENTRY_DEFAULT_USER_DS * 8 + 4(%edi) ++	addl \
$PAGE_SIZE_asm,%edi ++	loop 1b
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++	movl $pa(boot_gdt),%edi
++	movl $__LOAD_PHYSICAL_ADDR,%eax
++	movw %ax,GDT_ENTRY_BOOT_CS * 8 + 2(%edi)
++	rorl $16,%eax
++	movb %al,GDT_ENTRY_BOOT_CS * 8 + 4(%edi)
++	movb %ah,GDT_ENTRY_BOOT_CS * 8 + 7(%edi)
++	rorl $16,%eax
++
++	ljmp $(__BOOT_CS),$1f
++1:
++
++	movl $NR_CPUS,%ecx
++	movl $pa(cpu_gdt_table),%edi
++	addl $__PAGE_OFFSET,%eax
++1:
++	movb $0xc0,GDT_ENTRY_KERNEL_CS * 8 + 6(%edi)
++	movb $0xc0,GDT_ENTRY_KERNEXEC_KERNEL_CS * 8 + 6(%edi)
++	movw %ax,GDT_ENTRY_KERNEL_CS * 8 + 2(%edi)
++	movw %ax,GDT_ENTRY_KERNEXEC_KERNEL_CS * 8 + 2(%edi)
++	rorl $16,%eax
++	movb %al,GDT_ENTRY_KERNEL_CS * 8 + 4(%edi)
++	movb %al,GDT_ENTRY_KERNEXEC_KERNEL_CS * 8 + 4(%edi)
++	movb %ah,GDT_ENTRY_KERNEL_CS * 8 + 7(%edi)
++	movb %ah,GDT_ENTRY_KERNEXEC_KERNEL_CS * 8 + 7(%edi)
++	rorl $16,%eax
++	addl $PAGE_SIZE_asm,%edi
++	loop 1b
++#endif
++
+ /*
+  * Clear BSS first so that there are no surprises...
+  */
+@@ -201,8 +269,11 @@ ENTRY(startup_32)
+ 	movl %eax, pa(max_pfn_mapped)
+ 
+ 	/* Do early initialization of the fixmap area */
+-	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+-	movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
++#ifdef CONFIG_COMPAT_VDSO
++	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(initial_pg_pmd+0x1000*KPMDS-8)
 ++#else
++	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,pa(initial_pg_pmd+0x1000*KPMDS-8)
++#endif
+ #else	/* Not PAE */
+ 
+ page_pde_offset = (__PAGE_OFFSET >> 20);
+@@ -232,8 +303,11 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
+ 	movl %eax, pa(max_pfn_mapped)
+ 
+ 	/* Do early initialization of the fixmap area */
+-	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+-	movl %eax,pa(initial_page_table+0xffc)
++#ifdef CONFIG_COMPAT_VDSO
++	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR+_PAGE_USER,pa(initial_page_table+0xffc)
++#else
++	movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,pa(initial_page_table+0xffc)
++#endif
+ #endif
+ 
+ #ifdef CONFIG_PARAVIRT
+@@ -247,9 +321,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
+ 	cmpl $num_subarch_entries, %eax
+ 	jae bad_subarch
+ 
+-	movl pa(subarch_entries)(,%eax,4), %eax
+-	subl $__PAGE_OFFSET, %eax
+-	jmp *%eax
++	jmp *pa(subarch_entries)(,%eax,4)
+ 
+ bad_subarch:
+ WEAK(lguest_entry)
+@@ -261,10 +333,10 @@ WEAK(xen_entry)
+ 	__INITDATA
+ 
+ subarch_entries:
+-	.long default_entry		/* normal x86/PC */
+-	.long lguest_entry		/* lguest hypervisor */
+-	.long xen_entry			/* Xen hypervisor */
+-	.long default_entry		/* Moorestown MID */
++	.long ta(default_entry)		/* normal x86/PC */
++	.long ta(lguest_entry)		/* lguest hypervisor */
++	.long ta(xen_entry)		/* Xen hypervisor */
++	.long ta(default_entry)		/* Moorestown MID */
+ num_subarch_entries = (. - subarch_entries) / 4
+ .previous
+ #else
+@@ -354,6 +426,7 @@ default_entry:
+ 	movl pa(mmu_cr4_features),%eax
+ 	movl %eax,%cr4
+ 
++#ifdef CONFIG_X86_PAE
+ 	testb $X86_CR4_PAE, %al		# check if PAE is enabled
+ 	jz enable_paging
+ 
+@@ -382,6 +455,9 @@ default_entry:
+ 	/* Make changes effective */
+ 	wrmsr
+ 
++	btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
++#endif
++
+ enable_paging:
+ 
+ /*
+@@ -449,14 +525,20 @@ is486:
+ 1:	movl $(__KERNEL_DS),%eax	# reload all the segment registers
+ 	movl %eax,%ss			# after changing gdt.
+ 
+-	movl $(__USER_DS),%eax		# DS/ES contains default USER segment
++#	movl $(__KERNEL_DS),%eax	# DS/ES contains default KERNEL segment
+ 	movl %eax,%ds
+ 	movl %eax,%es
+ 
+ 	movl $(__KERNEL_PERCPU), %eax
+ 	movl %eax,%fs			# set this cpu's percpu
+ 
++#ifdef CONFIG_CC_STACKPROTECTOR
+ 	movl $(__KERNEL_STACK_CANARY),%eax
++#elif defined(CONFIG_PAX_MEMORY_UDEREF)
++	movl $(__USER_DS),%eax
++#else
++	xorl %eax,%eax
++#endif
+ 	movl %eax,%gs
+ 
+ 	xorl %eax,%eax			# Clear LDT
+@@ -512,8 +594,11 @@ setup_once:
+ 	 * relocation.  Manually set base address in stack canary
+ 	 * segment descriptor.
+ 	 */
+-	movl $gdt_page,%eax
++	movl $cpu_gdt_table,%eax
+ 	movl $stack_canary,%ecx
++#ifdef CONFIG_SMP
++	addl $__per_cpu_load,%ecx
++#endif
+ 	movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
+ 	shrl $16, %ecx
+ 	movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
+@@ -544,7 +629,7 @@ ENDPROC(early_idt_handlers)
+ 	/* This is global to keep gas from relaxing the jumps */
+ ENTRY(early_idt_handler)
+ 	cld
+-	cmpl $2,%ss:early_recursion_flag
++	cmpl $1,%ss:early_recursion_flag
+ 	je hlt_loop
+ 	incl %ss:early_recursion_flag
+ 
+@@ -582,8 +667,8 @@ ENTRY(early_idt_handler)
+ 	pushl (20+6*4)(%esp)	/* trapno */
+ 	pushl $fault_msg
+ 	call printk
+-#endif
+ 	call dump_stack
++#endif
+ hlt_loop:
+ 	hlt
+ 	jmp hlt_loop
+@@ -602,8 +687,11 @@ ENDPROC(early_idt_handler)
+ /* This is the default interrupt "handler" :-) */
+ 	ALIGN
+ ignore_int:
+-	cld
+ #ifdef CONFIG_PRINTK
++	cmpl $2,%ss:early_recursion_flag
++	je hlt_loop
++	incl %ss:early_recursion_flag
++	cld
+ 	pushl %eax
+ 	pushl %ecx
+ 	pushl %edx
+@@ -612,9 +700,6 @@ ignore_int:
+ 	movl $(__KERNEL_DS),%eax
+ 	movl %eax,%ds
+ 	movl %eax,%es
+-	cmpl $2,early_recursion_flag
+-	je hlt_loop
+-	incl early_recursion_flag
+ 	pushl 16(%esp)
+ 	pushl 24(%esp)
+ 	pushl 32(%esp)
+@@ -648,29 +733,34 @@ ENTRY(setup_once_ref)
+ /*
+  * BSS section
+  */
+-__PAGE_ALIGNED_BSS
+-	.align PAGE_SIZE
+ #ifdef CONFIG_X86_PAE
++.section .initial_pg_pmd,"a", at progbits
+ initial_pg_pmd:
+ 	.fill 1024*KPMDS,4,0
+ #else
++.section .initial_page_table,"a", at progbits
+ ENTRY(initial_page_table)
+ 	.fill 1024,4,0
+ #endif
++.section .initial_pg_fixmap,"a", at progbits
+ initial_pg_fixmap:
+ 	.fill 1024,4,0
++.section .empty_zero_page,"a", at progbits
+ ENTRY(empty_zero_page)
+ 	.fill 4096,1,0
++.section .swapper_pg_dir,"a", at progbits
+ ENTRY(swapper_pg_dir)
++#ifdef CONFIG_X86_PAE
++	.fill 4,8,0
++#else
+ 	.fill 1024,4,0
++#endif
+ 
+ /*
+  * This starts the data section.
+  */
+ #ifdef CONFIG_X86_PAE
+-__PAGE_ALIGNED_DATA
+-	/* Page-aligned for the benefit of paravirt? */
+-	.align PAGE_SIZE
++.section .initial_page_table,"a", at progbits
+ ENTRY(initial_page_table)
+ 	.long	pa(initial_pg_pmd+PGD_IDENT_ATTR),0	/* low identity map */
+ # if KPMDS == 3
+@@ -689,12 +779,20 @@ ENTRY(initial_page_table)
+ #  error "Kernel PMDs should be 1, 2 or 3"
+ # endif
+ 	.align PAGE_SIZE		/* needs to be page-sized too */
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++ENTRY(cpu_pgd)
++	.rept 2*NR_CPUS
++	.fill	4,8,0
++	.endr
++#endif
++
+ #endif
+ 
+ .data
+ .balign 4
+ ENTRY(stack_start)
+-	.long init_thread_union+THREAD_SIZE
++	.long init_thread_union+THREAD_SIZE-8
+ 
+ __INITRODATA
+ int_msg:
+@@ -722,7 +820,7 @@ fault_msg:
+  * segment size, and 32-bit linear address value:
+  */
+ 
+-	.data
++.section .rodata,"a", at progbits
+ .globl boot_gdt_descr
+ .globl idt_descr
+ 
+@@ -731,7 +829,7 @@ fault_msg:
+ 	.word 0				# 32 bit align gdt_desc.address
+ boot_gdt_descr:
+ 	.word __BOOT_DS+7
+-	.long boot_gdt - __PAGE_OFFSET
++	.long pa(boot_gdt)
+ 
+ 	.word 0				# 32-bit align idt_desc.address
+ idt_descr:
+@@ -742,7 +840,7 @@ idt_descr:
+ 	.word 0				# 32 bit align gdt_desc.address
+ ENTRY(early_gdt_descr)
+ 	.word GDT_ENTRIES*8-1
+-	.long gdt_page			/* Overwritten for secondary CPUs */
++	.long cpu_gdt_table		/* Overwritten for secondary CPUs */
+ 
+ /*
+  * The boot_gdt must mirror the equivalent in setup.S and is
+@@ -751,5 +849,65 @@ ENTRY(early_gdt_descr)
+ 	.align L1_CACHE_BYTES
+ ENTRY(boot_gdt)
+ 	.fill GDT_ENTRY_BOOT_CS,8,0
+-	.quad 0x00cf9a000000ffff	/* kernel 4GB code at 0x00000000 */
+-	.quad 0x00cf92000000ffff	/* kernel 4GB data at 0x00000000 */
++	.quad 0x00cf9b000000ffff	/* kernel 4GB code at 0x00000000 */
++	.quad 0x00cf93000000ffff	/* kernel 4GB data at 0x00000000 */
++
++	.align PAGE_SIZE_asm
++ENTRY(cpu_gdt_table)
++	.rept NR_CPUS
++	.quad 0x0000000000000000	/* NULL descriptor */
++	.quad 0x0000000000000000	/* 0x0b reserved */
++	.quad 0x0000000000000000	/* 0x13 reserved */
++	.quad 0x0000000000000000	/* 0x1b reserved */
++
++#ifdef CONFIG_PAX_KERNEXEC
++	.quad 0x00cf9b000000ffff	/* 0x20 alternate kernel 4GB code at 0x00000000 */
++#else
++	.quad 0x0000000000000000	/* 0x20 unused */
++#endif
++
++	.quad 0x0000000000000000	/* 0x28 unused */
++	.quad 0x0000000000000000	/* 0x33 TLS entry 1 */
++	.quad 0x0000000000000000	/* 0x3b TLS entry 2 */
++	.quad 0x0000000000000000	/* 0x43 TLS entry 3 */
++	.quad 0x0000000000000000	/* 0x4b reserved */
++	.quad 0x0000000000000000	/* 0x53 reserved */
++	.quad 0x0000000000000000	/* 0x5b reserved */
++
++	.quad 0x00cf9b000000ffff	/* 0x60 kernel 4GB code at 0x00000000 */
++	.quad 0x00cf93000000ffff	/* 0x68 kernel 4GB data at 0x00000000 */
++	.quad 0x00cffb000000ffff	/* 0x73 user 4GB code at 0x00000000 */
++	.quad 0x00cff3000000ffff	/* 0x7b user 4GB data at 0x00000000 */
++
++	.quad 0x0000000000000000	/* 0x80 TSS descriptor */
++	.quad 0x0000000000000000	/* 0x88 LDT descriptor */
++
++	/*
++	 * Segments used for calling PnP BIOS have byte granularity.
++	 * The code segments and data segments have fixed 64k limits,
++	 * the transfer segment sizes are set at run time.
++	 */
++	.quad 0x00409b000000ffff	/* 0x90 32-bit code */
++	.quad 0x00009b000000ffff	/* 0x98 16-bit code */
++	.quad 0x000093000000ffff	/* 0xa0 16-bit data */
++	.quad 0x0000930000000000	/* 0xa8 16-bit data */
++	.quad 0x0000930000000000	/* 0xb0 16-bit data */
++
++	/*
++	 * The APM segments have byte granularity and their bases
++	 * are set at run time.  All have 64k limits.
++	 */
++	.quad 0x00409b000000ffff	/* 0xb8 APM CS    code */
++	.quad 0x00009b000000ffff	/* 0xc0 APM CS 16 code (16 bit) */
++	.quad 0x004093000000ffff	/* 0xc8 APM DS    data */
++
++	.quad 0x00c0930000000000	/* 0xd0 - ESPFIX SS */
++	.quad 0x0040930000000000	/* 0xd8 - PERCPU */
++	.quad 0x0040910000000017	/* 0xe0 - STACK_CANARY */
++	.quad 0x0000000000000000	/* 0xe8 - PCIBIOS_CS */
++	.quad 0x0000000000000000	/* 0xf0 - PCIBIOS_DS */
++	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
++
++	/* Be sure this is zeroed to avoid false validations in Xen */
++	.fill PAGE_SIZE_asm - GDT_SIZE,1,0
++	.endr
+diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
+index e1aabdb..73dcad8 100644
+--- a/arch/x86/kernel/head_64.S
++++ b/arch/x86/kernel/head_64.S
+@@ -20,6 +20,8 @@
+ #include <asm/processor-flags.h>
+ #include <asm/percpu.h>
+ #include <asm/nops.h>
++#include <asm/cpufeature.h>
++#include <asm/alternative-asm.h>
+ 
+ #ifdef CONFIG_PARAVIRT
+ #include <asm/asm-offsets.h>
+@@ -41,6 +43,12 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET)
+ L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
+ L4_START_KERNEL = pgd_index(__START_KERNEL_map)
+ L3_START_KERNEL = pud_index(__START_KERNEL_map)
++L4_VMALLOC_START = pgd_index(VMALLOC_START)
++L3_VMALLOC_START = pud_index(VMALLOC_START)
++L4_VMALLOC_END = pgd_index(VMALLOC_END)
++L3_VMALLOC_END = pud_index(VMALLOC_END)
++L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
++L3_VMEMMAP_START = pud_index(VMEMMAP_START)
+ 
+ 	.text
+ 	__HEAD
+@@ -89,11 +97,23 @@ startup_64:
+ 	 * Fixup the physical addresses in the page table
+ 	 */
+ 	addq	%rbp, early_level4_pgt + (L4_START_KERNEL*8)(%rip)
++	addq	%rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
++	addq	%rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
++	addq	%rbp, init_level4_pgt + (L4_VMALLOC_END*8)(%rip)
++	addq	%rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
++	addq	%rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
+ 
+-	addq	%rbp, level3_kernel_pgt + (510*8)(%rip)
+-	addq	%rbp, level3_kernel_pgt + (511*8)(%rip)
++	addq	%rbp, level3_ident_pgt + (0*8)(%rip)
++#ifndef CONFIG_XEN
++	addq	%rbp, level3_ident_pgt + (1*8)(%rip)
++#endif
+ 
+-	addq	%rbp, level2_fixmap_pgt + (506*8)(%rip)
++	addq	%rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
++
++	addq	%rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
++	addq	%rbp, level3_kernel_pgt + ((L3_START_KERNEL+1)*8)(%rip)
++
++	addq	%rbp, level2_fixmap_pgt + (507*8)(%rip)
+ 
+ 	/*
+ 	 * Set up the identity mapping for the switchover.  These
+@@ -177,8 +197,8 @@ ENTRY(secondary_startup_64)
+ 	movq	$(init_level4_pgt - __START_KERNEL_map), %rax
+ 1:
+ 
+-	/* Enable PAE mode and PGE */
+-	movl	$(X86_CR4_PAE | X86_CR4_PGE), %ecx
++	/* Enable PAE mode and PSE/PGE */
++	movl	$(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %ecx
+ 	movq	%rcx, %cr4
+ 
+ 	/* Setup early boot stage 4 level pagetables. */
+@@ -199,10 +219,18 @@ ENTRY(secondary_startup_64)
+ 	movl	$MSR_EFER, %ecx
+ 	rdmsr
+ 	btsl	$_EFER_SCE, %eax	/* Enable System Call */
+-	btl	$20,%edi		/* No Execute supported? */
++	btl	$(X86_FEATURE_NX & 31),%edi	/* No Execute supported? */
+ 	jnc     1f
+ 	btsl	$_EFER_NX, %eax
+ 	btsq	$_PAGE_BIT_NX,early_pmd_flags(%rip)
++	leaq	init_level4_pgt(%rip), %rdi
++#ifndef CONFIG_EFI
++	btsq	$_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
++#endif
++	btsq	$_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
++	btsq	$_PAGE_BIT_NX, 8*L4_VMALLOC_END(%rdi)
++	btsq	$_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
++	btsq	$_PAGE_BIT_NX, __supported_pte_mask(%rip)
+ 1:	wrmsr				/* Make changes effective */
+ 
+ 	/* Setup cr0 */
+@@ -282,6 +310,7 @@ ENTRY(secondary_startup_64)
+ 	 *	REX.W + FF /5 JMP m16:64 Jump far, absolute indirect,
+ 	 *		address given in m16:64.
+ 	 */
++	pax_set_fptr_mask
+ 	movq	initial_code(%rip),%rax
+ 	pushq	$0		# fake return address to stop unwinder
+ 	pushq	$__KERNEL_CS	# set correct cs
+@@ -388,7 +417,7 @@ ENTRY(early_idt_handler)
+ 	call dump_stack
+ #ifdef CONFIG_KALLSYMS	
+ 	leaq early_idt_ripmsg(%rip),%rdi
+-	movq 40(%rsp),%rsi	# %rip again
++	movq 88(%rsp),%rsi	# %rip again
+ 	call __print_symbol
+ #endif
+ #endif /* EARLY_PRINTK */
+@@ -416,6 +445,7 @@ ENDPROC(early_idt_handler)
+ early_recursion_flag:
+ 	.long 0
+ 
++	.section .rodata,"a", at progbits
+ #ifdef CONFIG_EARLY_PRINTK
+ early_idt_msg:
+ 	.asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
+@@ -443,29 +473,52 @@ NEXT_PAGE(early_level4_pgt)
+ NEXT_PAGE(early_dynamic_pgts)
+ 	.fill	512*EARLY_DYNAMIC_PAGE_TABLES,8,0
+ 
+-	.data
++	.section .rodata,"a", at progbits
+ 
+-#ifndef CONFIG_XEN
+ NEXT_PAGE(init_level4_pgt)
+-	.fill	512,8,0
+-#else
+-NEXT_PAGE(init_level4_pgt)
+-	.quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
+ 	.org    init_level4_pgt + L4_PAGE_OFFSET*8, 0
+ 	.quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
++	.org	init_level4_pgt + L4_VMALLOC_START*8, 0
++	.quad	level3_vmalloc_start_pgt - __START_KERNEL_map + _KERNPG_TABLE
++	.org	init_level4_pgt + L4_VMALLOC_END*8, 0
++	.quad	level3_vmalloc_end_pgt - __START_KERNEL_map + _KERNPG_TABLE
++	.org	init_level4_pgt + L4_VMEMMAP_START*8, 0
++	.quad	level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
+ 	.org    init_level4_pgt + L4_START_KERNEL*8, 0
+ 	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
+ 	.quad   level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++NEXT_PAGE(cpu_pgd)
++	.rept 2*NR_CPUS
++	.fill	512,8,0
++	.endr
++#endif
++
+ NEXT_PAGE(level3_ident_pgt)
+ 	.quad	level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
++#ifdef CONFIG_XEN
+ 	.fill	511, 8, 0
++#else
++	.quad	level2_ident_pgt + PAGE_SIZE - __START_KERNEL_map + _KERNPG_TABLE
++	.fill	510,8,0
++#endif
++
++NEXT_PAGE(level3_vmalloc_start_pgt)
++	.fill	512,8,0
++
++NEXT_PAGE(level3_vmalloc_end_pgt)
++	.fill	512,8,0
++
++NEXT_PAGE(level3_vmemmap_pgt)
++	.fill	L3_VMEMMAP_START,8,0
++	.quad	level2_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
++
+ NEXT_PAGE(level2_ident_pgt)
+-	/* Since I easily can, map the first 1G.
++	/* Since I easily can, map the first 2G.
+ 	 * Don't set NX because code runs from these pages.
+ 	 */
+-	PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD)
+-#endif
++	PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 2*PTRS_PER_PMD)
+ 
+ NEXT_PAGE(level3_kernel_pgt)
+ 	.fill	L3_START_KERNEL,8,0
+@@ -473,6 +526,9 @@ NEXT_PAGE(level3_kernel_pgt)
+ 	.quad	level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE
+ 	.quad	level2_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
+ 
++NEXT_PAGE(level2_vmemmap_pgt)
++	.fill	512,8,0
++
+ NEXT_PAGE(level2_kernel_pgt)
+ 	/*
+ 	 * 512 MB kernel mapping. We spend a full page on this pagetable
+@@ -488,30 +544,62 @@ NEXT_PAGE(level2_kernel_pgt)
+ 		KERNEL_IMAGE_SIZE/PMD_SIZE)
+ 
+ NEXT_PAGE(level2_fixmap_pgt)
+-	.fill	506,8,0
+-	.quad	level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
+-	/* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
+-	.fill	5,8,0
++	.fill	507,8,0
++	.quad	level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
++	/* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
++	.fill	4,8,0
+ 
+-NEXT_PAGE(level1_fixmap_pgt)
++NEXT_PAGE(level1_vsyscall_pgt)
+ 	.fill	512,8,0
+ 
+ #undef PMDS
+ 
+-	.data
++	.align PAGE_SIZE
++ENTRY(cpu_gdt_table)
++	.rept NR_CPUS
++	.quad	0x0000000000000000	/* NULL descriptor */
++	.quad	0x00cf9b000000ffff	/* __KERNEL32_CS */
++	.quad	0x00af9b000000ffff	/* __KERNEL_CS */
++	.quad	0x00cf93000000ffff	/* __KERNEL_DS */
++	.quad	0x00cffb000000ffff	/* __USER32_CS */
++	.quad	0x00cff3000000ffff	/* __USER_DS, __USER32_DS  */
++	.quad	0x00affb000000ffff	/* __USER_CS */
++
++#ifdef CONFIG_PAX_KERNEXEC
++	.quad	0x00af9b000000ffff	/* __KERNEXEC_KERNEL_CS */
++#else
++	.quad	0x0			/* unused */
++#endif
++
++	.quad	0,0			/* TSS */
++	.quad	0,0			/* LDT */
++	.quad	0,0,0			/* three TLS descriptors */
++	.quad	0x0000f40000000000	/* node/CPU stored in limit */
++	/* asm/segment.h:GDT_ENTRIES must match this */
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	.quad	0x00cf93000000ffff	/* __UDEREF_KERNEL_DS */
++#else
++	.quad	0x0			/* unused */
++#endif
++
++	/* zero the remaining page */
++	.fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
++	.endr
++
+ 	.align 16
+ 	.globl early_gdt_descr
+ early_gdt_descr:
+ 	.word	GDT_ENTRIES*8-1
+ early_gdt_descr_base:
+-	.quad	INIT_PER_CPU_VAR(gdt_page)
++	.quad	cpu_gdt_table
+ 
+ ENTRY(phys_base)
+ 	/* This must match the first entry in level2_kernel_pgt */
+ 	.quad   0x0000000000000000
+ 
+ #include "../../x86/xen/xen-head.S"
+-	
+-	__PAGE_ALIGNED_BSS
++
++	.section .rodata,"a", at progbits
+ NEXT_PAGE(empty_zero_page)
+ 	.skip PAGE_SIZE
+diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
+index 0fa6912..b37438b 100644
+--- a/arch/x86/kernel/i386_ksyms_32.c
++++ b/arch/x86/kernel/i386_ksyms_32.c
+@@ -20,8 +20,12 @@ extern void cmpxchg8b_emu(void);
+ EXPORT_SYMBOL(cmpxchg8b_emu);
+ #endif
+ 
++EXPORT_SYMBOL_GPL(cpu_gdt_table);
++
+ /* Networking helper routines. */
+ EXPORT_SYMBOL(csum_partial_copy_generic);
++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
+ 
+ EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
+@@ -37,3 +41,11 @@ EXPORT_SYMBOL(strstr);
+ 
+ EXPORT_SYMBOL(csum_partial);
+ EXPORT_SYMBOL(empty_zero_page);
++
++#ifdef CONFIG_PAX_KERNEXEC
++EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
++#endif
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++EXPORT_SYMBOL(cpu_pgd);
++#endif
+diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
+index 5d576ab..1403a03 100644
+--- a/arch/x86/kernel/i387.c
++++ b/arch/x86/kernel/i387.c
+@@ -51,7 +51,7 @@ static inline bool interrupted_kernel_fpu_idle(void)
+ static inline bool interrupted_user_mode(void)
+ {
+ 	struct pt_regs *regs = get_irq_regs();
+-	return regs && user_mode_vm(regs);
++	return regs && user_mode(regs);
+ }
+ 
+ /*
+diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c
+index 9a5c460..84868423 100644
+--- a/arch/x86/kernel/i8259.c
++++ b/arch/x86/kernel/i8259.c
+@@ -110,7 +110,7 @@ static int i8259A_irq_pending(unsigned int irq)
+ static void make_8259A_irq(unsigned int irq)
+ {
+ 	disable_irq_nosync(irq);
+-	io_apic_irqs &= ~(1<<irq);
++	io_apic_irqs &= ~(1UL<<irq);
+ 	irq_set_chip_and_handler_name(irq, &i8259A_chip, handle_level_irq,
+ 				      i8259A_chip.name);
+ 	enable_irq(irq);
+@@ -209,7 +209,7 @@ spurious_8259A_irq:
+ 			       "spurious 8259A interrupt: IRQ%d.\n", irq);
+ 			spurious_irq_mask |= irqmask;
+ 		}
+-		atomic_inc(&irq_err_count);
++		atomic_inc_unchecked(&irq_err_count);
+ 		/*
+ 		 * Theoretically we do not have to handle this IRQ,
+ 		 * but in Linux this does not cause problems and is
+@@ -333,14 +333,16 @@ static void init_8259A(int auto_eoi)
+ 	/* (slave's support for AEOI in flat mode is to be investigated) */
+ 	outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR);
+ 
++	pax_open_kernel();
+ 	if (auto_eoi)
+ 		/*
+ 		 * In AEOI mode we just have to mask the interrupt
+ 		 * when acking.
+ 		 */
+-		i8259A_chip.irq_mask_ack = disable_8259A_irq;
++		*(void **)&i8259A_chip.irq_mask_ack = disable_8259A_irq;
+ 	else
+-		i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
++		*(void **)&i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
++	pax_close_kernel();
+ 
+ 	udelay(100);		/* wait for 8259A to initialize */
+ 
+diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
+index a979b5b..1d6db75 100644
+--- a/arch/x86/kernel/io_delay.c
++++ b/arch/x86/kernel/io_delay.c
+@@ -58,7 +58,7 @@ static int __init dmi_io_delay_0xed_port(const struct \
dmi_system_id *id) +  * Quirk table for systems that misbehave (lock up, etc.) if \
port +  * 0x80 is used:
+  */
+-static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
++static const struct dmi_system_id __initconst io_delay_0xed_port_dmi_table[] = {
+ 	{
+ 		.callback	= dmi_io_delay_0xed_port,
+ 		.ident		= "Compaq Presario V6000",
+diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
+index 4ddaf66..6292f4e 100644
+--- a/arch/x86/kernel/ioport.c
++++ b/arch/x86/kernel/ioport.c
+@@ -6,6 +6,7 @@
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/capability.h>
++#include <linux/security.h>
+ #include <linux/errno.h>
+ #include <linux/types.h>
+ #include <linux/ioport.h>
+@@ -28,6 +29,12 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, \
int turn_on) + 
+ 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
+ 		return -EINVAL;
++#ifdef CONFIG_GRKERNSEC_IO
++	if (turn_on && grsec_disable_privio) {
++		gr_handle_ioperm();
++		return -EPERM;
++	}
++#endif
+ 	if (turn_on && !capable(CAP_SYS_RAWIO))
+ 		return -EPERM;
+ 
+@@ -54,7 +61,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, \
int turn_on) + 	 * because the ->io_bitmap_max value must match the bitmap
+ 	 * contents:
+ 	 */
+-	tss = &per_cpu(init_tss, get_cpu());
++	tss = init_tss + get_cpu();
+ 
+ 	if (turn_on)
+ 		bitmap_clear(t->io_bitmap_ptr, from, num);
+@@ -103,6 +110,12 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
+ 		return -EINVAL;
+ 	/* Trying to gain more privileges? */
+ 	if (level > old) {
++#ifdef CONFIG_GRKERNSEC_IO
++		if (grsec_disable_privio) {
++			gr_handle_iopl();
++			return -EPERM;
++		}
++#endif
+ 		if (!capable(CAP_SYS_RAWIO))
+ 			return -EPERM;
+ 	}
+diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
+index 3a8185c..3c042ee 100644
+--- a/arch/x86/kernel/irq.c
++++ b/arch/x86/kernel/irq.c
+@@ -21,7 +21,7 @@
+ #define CREATE_TRACE_POINTS
+ #include <asm/trace/irq_vectors.h>
+ 
+-atomic_t irq_err_count;
++atomic_unchecked_t irq_err_count;
+ 
+ /* Function pointer for generic interrupt vector handling */
+ void (*x86_platform_ipi_callback)(void) = NULL;
+@@ -125,9 +125,9 @@ int arch_show_interrupts(struct seq_file *p, int prec)
+ 		seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
+ 	seq_printf(p, "  Machine check polls\n");
+ #endif
+-	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));
+ #if defined(CONFIG_X86_IO_APIC)
+-	seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
++	seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read_unchecked(&irq_mis_count));
+ #endif
+ 	return 0;
+ }
+@@ -167,7 +167,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
+ 
+ u64 arch_irq_stat(void)
+ {
+-	u64 sum = atomic_read(&irq_err_count);
++	u64 sum = atomic_read_unchecked(&irq_err_count);
+ 	return sum;
+ }
+ 
+diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
+index 4186755..784efa0 100644
+--- a/arch/x86/kernel/irq_32.c
++++ b/arch/x86/kernel/irq_32.c
+@@ -39,7 +39,7 @@ static int check_stack_overflow(void)
+ 	__asm__ __volatile__("andl %%esp,%0" :
+ 			     "=r" (sp) : "0" (THREAD_SIZE - 1));
+ 
+-	return sp < (sizeof(struct thread_info) + STACK_WARN);
++	return sp < STACK_WARN;
+ }
+ 
+ static void print_stack_overflow(void)
+@@ -59,8 +59,8 @@ static inline void print_stack_overflow(void) { }
+  * per-CPU IRQ handling contexts (thread information and stack)
+  */
+ union irq_ctx {
+-	struct thread_info      tinfo;
+-	u32                     stack[THREAD_SIZE/sizeof(u32)];
++	unsigned long		previous_esp;
++	u32			stack[THREAD_SIZE/sizeof(u32)];
+ } __attribute__((aligned(THREAD_SIZE)));
+ 
+ static DEFINE_PER_CPU(union irq_ctx *, hardirq_ctx);
+@@ -80,10 +80,9 @@ static void call_on_stack(void *func, void *stack)
+ static inline int
+ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq)
+ {
+-	union irq_ctx *curctx, *irqctx;
++	union irq_ctx *irqctx;
+ 	u32 *isp, arg1, arg2;
+ 
+-	curctx = (union irq_ctx *) current_thread_info();
+ 	irqctx = __this_cpu_read(hardirq_ctx);
+ 
+ 	/*
+@@ -92,16 +91,16 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int \
irq) + 	 * handler) we can't do that and just have to keep using the
+ 	 * current stack (which is the irq stack already after all)
+ 	 */
+-	if (unlikely(curctx == irqctx))
++	if (unlikely((void *)current_stack_pointer - (void *)irqctx < THREAD_SIZE))
+ 		return 0;
+ 
+ 	/* build the stack frame on the IRQ stack */
+-	isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
+-	irqctx->tinfo.task = curctx->tinfo.task;
+-	irqctx->tinfo.previous_esp = current_stack_pointer;
++	isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
++	irqctx->previous_esp = current_stack_pointer;
+ 
+-	/* Copy the preempt_count so that the [soft]irq checks work. */
+-	irqctx->tinfo.preempt_count = curctx->tinfo.preempt_count;
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	__set_fs(MAKE_MM_SEG(0));
++#endif
+ 
+ 	if (unlikely(overflow))
+ 		call_on_stack(print_stack_overflow, isp);
+@@ -113,6 +112,11 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int \
irq) + 		     :  "0" (irq),   "1" (desc),  "2" (isp),
+ 			"D" (desc->handle_irq)
+ 		     : "memory", "cc", "ecx");
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	__set_fs(current_thread_info()->addr_limit);
++#endif
++
+ 	return 1;
+ }
+ 
+@@ -121,29 +125,14 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int \
irq) +  */
+ void irq_ctx_init(int cpu)
+ {
+-	union irq_ctx *irqctx;
+-
+ 	if (per_cpu(hardirq_ctx, cpu))
+ 		return;
+ 
+-	irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+-					       THREADINFO_GFP,
+-					       THREAD_SIZE_ORDER));
+-	memset(&irqctx->tinfo, 0, sizeof(struct thread_info));
+-	irqctx->tinfo.cpu		= cpu;
+-	irqctx->tinfo.preempt_count	= HARDIRQ_OFFSET;
+-	irqctx->tinfo.addr_limit	= MAKE_MM_SEG(0);
++	per_cpu(hardirq_ctx, cpu) = page_address(alloc_pages_node(cpu_to_node(cpu), \
THREADINFO_GFP, THREAD_SIZE_ORDER)); ++	per_cpu(softirq_ctx, cpu) = \
page_address(alloc_pages_node(cpu_to_node(cpu), THREADINFO_GFP, THREAD_SIZE_ORDER)); \
+  +-	per_cpu(hardirq_ctx, cpu) = irqctx;
+-
+-	irqctx = page_address(alloc_pages_node(cpu_to_node(cpu),
+-					       THREADINFO_GFP,
+-					       THREAD_SIZE_ORDER));
+-	memset(&irqctx->tinfo, 0, sizeof(struct thread_info));
+-	irqctx->tinfo.cpu		= cpu;
+-	irqctx->tinfo.addr_limit	= MAKE_MM_SEG(0);
+-
+-	per_cpu(softirq_ctx, cpu) = irqctx;
++	printk(KERN_DEBUG "CPU %u irqstacks, hard=%p soft=%p\n",
++	       cpu, per_cpu(hardirq_ctx, cpu),  per_cpu(softirq_ctx, cpu));
+ 
+ 	printk(KERN_DEBUG "CPU %u irqstacks, hard=%p soft=%p\n",
+ 	       cpu, per_cpu(hardirq_ctx, cpu),  per_cpu(softirq_ctx, cpu));
+@@ -152,7 +141,6 @@ void irq_ctx_init(int cpu)
+ asmlinkage void do_softirq(void)
+ {
+ 	unsigned long flags;
+-	struct thread_info *curctx;
+ 	union irq_ctx *irqctx;
+ 	u32 *isp;
+ 
+@@ -162,15 +150,22 @@ asmlinkage void do_softirq(void)
+ 	local_irq_save(flags);
+ 
+ 	if (local_softirq_pending()) {
+-		curctx = current_thread_info();
+ 		irqctx = __this_cpu_read(softirq_ctx);
+-		irqctx->tinfo.task = curctx->task;
+-		irqctx->tinfo.previous_esp = current_stack_pointer;
++		irqctx->previous_esp = current_stack_pointer;
+ 
+ 		/* build the stack frame on the softirq stack */
+-		isp = (u32 *) ((char *)irqctx + sizeof(*irqctx));
++		isp = (u32 *) ((char *)irqctx + sizeof(*irqctx) - 8);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++		__set_fs(MAKE_MM_SEG(0));
++#endif
+ 
+ 		call_on_stack(__do_softirq, isp);
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++		__set_fs(current_thread_info()->addr_limit);
++#endif
++
+ 		/*
+ 		 * Shouldn't happen, we returned above if in_interrupt():
+ 		 */
+@@ -191,7 +186,7 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
+ 	if (unlikely(!desc))
+ 		return false;
+ 
+-	if (user_mode_vm(regs) || !execute_on_irq_stack(overflow, desc, irq)) {
++	if (user_mode(regs) || !execute_on_irq_stack(overflow, desc, irq)) {
+ 		if (unlikely(overflow))
+ 			print_stack_overflow();
+ 		desc->handle_irq(irq, desc);
+diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
+index d04d3ec..ea4b374 100644
+--- a/arch/x86/kernel/irq_64.c
++++ b/arch/x86/kernel/irq_64.c
+@@ -44,7 +44,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
+ 	u64 estack_top, estack_bottom;
+ 	u64 curbase = (u64)task_stack_page(current);
+ 
+-	if (user_mode_vm(regs))
++	if (user_mode(regs))
+ 		return;
+ 
+ 	if (regs->sp >= curbase + sizeof(struct thread_info) +
+diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
+index dc1404b..bbc43e7 100644
+--- a/arch/x86/kernel/kdebugfs.c
++++ b/arch/x86/kernel/kdebugfs.c
+@@ -27,7 +27,7 @@ struct setup_data_node {
+ 	u32 len;
+ };
+ 
+-static ssize_t setup_data_read(struct file *file, char __user *user_buf,
++static ssize_t __size_overflow(3) setup_data_read(struct file *file, char __user \
*user_buf, + 			       size_t count, loff_t *ppos)
+ {
+ 	struct setup_data_node *node = file->private_data;
+diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
+index 836f832..a8bda67 100644
+--- a/arch/x86/kernel/kgdb.c
++++ b/arch/x86/kernel/kgdb.c
+@@ -127,11 +127,11 @@ char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+ #ifdef CONFIG_X86_32
+ 	switch (regno) {
+ 	case GDB_SS:
+-		if (!user_mode_vm(regs))
++		if (!user_mode(regs))
+ 			*(unsigned long *)mem = __KERNEL_DS;
+ 		break;
+ 	case GDB_SP:
+-		if (!user_mode_vm(regs))
++		if (!user_mode(regs))
+ 			*(unsigned long *)mem = kernel_stack_pointer(regs);
+ 		break;
+ 	case GDB_GS:
+@@ -229,7 +229,10 @@ static void kgdb_correct_hw_break(void)
+ 		bp->attr.bp_addr = breakinfo[breakno].addr;
+ 		bp->attr.bp_len = breakinfo[breakno].len;
+ 		bp->attr.bp_type = breakinfo[breakno].type;
+-		info->address = breakinfo[breakno].addr;
++		if (breakinfo[breakno].type == X86_BREAKPOINT_EXECUTE)
++			info->address = ktla_ktva(breakinfo[breakno].addr);
++		else
++			info->address = breakinfo[breakno].addr;
+ 		info->len = breakinfo[breakno].len;
+ 		info->type = breakinfo[breakno].type;
+ 		val = arch_install_hw_breakpoint(bp);
+@@ -476,12 +479,12 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int \
err_code, + 	case 'k':
+ 		/* clear the trace bit */
+ 		linux_regs->flags &= ~X86_EFLAGS_TF;
+-		atomic_set(&kgdb_cpu_doing_single_step, -1);
++		atomic_set_unchecked(&kgdb_cpu_doing_single_step, -1);
+ 
+ 		/* set the trace bit if we're stepping */
+ 		if (remcomInBuffer[0] == 's') {
+ 			linux_regs->flags |= X86_EFLAGS_TF;
+-			atomic_set(&kgdb_cpu_doing_single_step,
++			atomic_set_unchecked(&kgdb_cpu_doing_single_step,
+ 				   raw_smp_processor_id());
+ 		}
+ 
+@@ -546,7 +549,7 @@ static int __kgdb_notify(struct die_args *args, unsigned long \
cmd) + 
+ 	switch (cmd) {
+ 	case DIE_DEBUG:
+-		if (atomic_read(&kgdb_cpu_doing_single_step) != -1) {
++		if (atomic_read_unchecked(&kgdb_cpu_doing_single_step) != -1) {
+ 			if (user_mode(regs))
+ 				return single_step_cont(regs, args);
+ 			break;
+@@ -751,11 +754,11 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+ #endif /* CONFIG_DEBUG_RODATA */
+ 
+ 	bpt->type = BP_BREAKPOINT;
+-	err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
++	err = probe_kernel_read(bpt->saved_instr, ktla_ktva((char *)bpt->bpt_addr),
+ 				BREAK_INSTR_SIZE);
+ 	if (err)
+ 		return err;
+-	err = probe_kernel_write((char *)bpt->bpt_addr,
++	err = probe_kernel_write(ktla_ktva((char *)bpt->bpt_addr),
+ 				 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
+ #ifdef CONFIG_DEBUG_RODATA
+ 	if (!err)
+@@ -768,7 +771,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
+ 		return -EBUSY;
+ 	text_poke((void *)bpt->bpt_addr, arch_kgdb_ops.gdb_bpt_instr,
+ 		  BREAK_INSTR_SIZE);
+-	err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
++	err = probe_kernel_read(opc, ktla_ktva((char *)bpt->bpt_addr), BREAK_INSTR_SIZE);
+ 	if (err)
+ 		return err;
+ 	if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE))
+@@ -793,13 +796,13 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
+ 	if (mutex_is_locked(&text_mutex))
+ 		goto knl_write;
+ 	text_poke((void *)bpt->bpt_addr, bpt->saved_instr, BREAK_INSTR_SIZE);
+-	err = probe_kernel_read(opc, (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
++	err = probe_kernel_read(opc, ktla_ktva((char *)bpt->bpt_addr), BREAK_INSTR_SIZE);
+ 	if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE))
+ 		goto knl_write;
+ 	return err;
+ knl_write:
+ #endif /* CONFIG_DEBUG_RODATA */
+-	return probe_kernel_write((char *)bpt->bpt_addr,
++	return probe_kernel_write(ktla_ktva((char *)bpt->bpt_addr),
+ 				  (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
+ }
+ 
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index 211bce4..6e2580a 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -119,9 +119,12 @@ static void __kprobes __synthesize_relative_insn(void *from, \
void *to, u8 op) + 		s32 raddr;
+ 	} __packed *insn;
+ 
+-	insn = (struct __arch_relative_insn *)from;
++	insn = (struct __arch_relative_insn *)ktla_ktva(from);
++
++	pax_open_kernel();
+ 	insn->raddr = (s32)((long)(to) - ((long)(from) + 5));
+ 	insn->op = op;
++	pax_close_kernel();
+ }
+ 
+ /* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
+@@ -164,7 +167,7 @@ int __kprobes can_boost(kprobe_opcode_t *opcodes)
+ 	kprobe_opcode_t opcode;
+ 	kprobe_opcode_t *orig_opcodes = opcodes;
+ 
+-	if (search_exception_tables((unsigned long)opcodes))
++	if (search_exception_tables(ktva_ktla((unsigned long)opcodes)))
+ 		return 0;	/* Page fault may occur on this address. */
+ 
+ retry:
+@@ -238,9 +241,9 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
+ 	 *  for the first byte, we can recover the original instruction
+ 	 *  from it and kp->opcode.
+ 	 */
+-	memcpy(buf, kp->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
++	memcpy(buf, ktla_ktva(kp->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+ 	buf[0] = kp->opcode;
+-	return (unsigned long)buf;
++	return ktva_ktla((unsigned long)buf);
+ }
+ 
+ /*
+@@ -332,7 +335,9 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src)
+ 	/* Another subsystem puts a breakpoint, failed to recover */
+ 	if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION)
+ 		return 0;
++	pax_open_kernel();
+ 	memcpy(dest, insn.kaddr, insn.length);
++	pax_close_kernel();
+ 
+ #ifdef CONFIG_X86_64
+ 	if (insn_rip_relative(&insn)) {
+@@ -359,7 +364,9 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src)
+ 			return 0;
+ 		}
+ 		disp = (u8 *) dest + insn_offset_displacement(&insn);
++		pax_open_kernel();
+ 		*(s32 *) disp = (s32) newdisp;
++		pax_close_kernel();
+ 	}
+ #endif
+ 	return insn.length;
+@@ -498,7 +505,7 @@ setup_singlestep(struct kprobe *p, struct pt_regs *regs, struct \
kprobe_ctlblk *k + 		 * nor set current_kprobe, because it doesn't use single
+ 		 * stepping.
+ 		 */
+-		regs->ip = (unsigned long)p->ainsn.insn;
++		regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
+ 		preempt_enable_no_resched();
+ 		return;
+ 	}
+@@ -515,9 +522,9 @@ setup_singlestep(struct kprobe *p, struct pt_regs *regs, struct \
kprobe_ctlblk *k + 	regs->flags &= ~X86_EFLAGS_IF;
+ 	/* single step inline if the instruction is an int3 */
+ 	if (p->opcode == BREAKPOINT_INSTRUCTION)
+-		regs->ip = (unsigned long)p->addr;
++		regs->ip = ktla_ktva((unsigned long)p->addr);
+ 	else
+-		regs->ip = (unsigned long)p->ainsn.insn;
++		regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
+ }
+ 
+ /*
+@@ -596,7 +603,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
+ 				setup_singlestep(p, regs, kcb, 0);
+ 			return 1;
+ 		}
+-	} else if (*addr != BREAKPOINT_INSTRUCTION) {
++	} else if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != \
BREAKPOINT_INSTRUCTION) { + 		/*
+ 		 * The breakpoint instruction was removed right
+ 		 * after we hit it.  Another cpu has removed
+@@ -642,6 +649,9 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
+ 			"	movq %rax, 152(%rsp)\n"
+ 			RESTORE_REGS_STRING
+ 			"	popfq\n"
++#ifdef KERNEXEC_PLUGIN
++			"	btsq $63,(%rsp)\n"
++#endif
+ #else
+ 			"	pushf\n"
+ 			SAVE_REGS_STRING
+@@ -779,7 +789,7 @@ static void __kprobes
+ resume_execution(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb)
+ {
+ 	unsigned long *tos = stack_addr(regs);
+-	unsigned long copy_ip = (unsigned long)p->ainsn.insn;
++	unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
+ 	unsigned long orig_ip = (unsigned long)p->addr;
+ 	kprobe_opcode_t *insn = p->ainsn.insn;
+ 
+@@ -961,7 +971,7 @@ kprobe_exceptions_notify(struct notifier_block *self, unsigned \
long val, void *d + 	struct die_args *args = data;
+ 	int ret = NOTIFY_DONE;
+ 
+-	if (args->regs && user_mode_vm(args->regs))
++	if (args->regs && user_mode(args->regs))
+ 		return ret;
+ 
+ 	switch (val) {
+diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
+index 76dc6f0..66bdfc3 100644
+--- a/arch/x86/kernel/kprobes/opt.c
++++ b/arch/x86/kernel/kprobes/opt.c
+@@ -79,6 +79,7 @@ found:
+ /* Insert a move instruction which sets a pointer to eax/rdi (1st arg). */
+ static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr, unsigned long val)
+ {
++	pax_open_kernel();
+ #ifdef CONFIG_X86_64
+ 	*addr++ = 0x48;
+ 	*addr++ = 0xbf;
+@@ -86,6 +87,7 @@ static void __kprobes synthesize_set_arg1(kprobe_opcode_t *addr, \
unsigned long v + 	*addr++ = 0xb8;
+ #endif
+ 	*(unsigned long *)addr = val;
++	pax_close_kernel();
+ }
+ 
+ static void __used __kprobes kprobes_optinsn_template_holder(void)
+@@ -338,7 +340,7 @@ int __kprobes arch_prepare_optimized_kprobe(struct \
optimized_kprobe *op) + 	 * Verify if the address gap is in 2GB range, because this \
uses + 	 * a relative jump.
+ 	 */
+-	rel = (long)op->optinsn.insn - (long)op->kp.addr + RELATIVEJUMP_SIZE;
++	rel = (long)op->optinsn.insn - ktla_ktva((long)op->kp.addr) + RELATIVEJUMP_SIZE;
+ 	if (abs(rel) > 0x7fffffff)
+ 		return -ERANGE;
+ 
+@@ -353,16 +355,18 @@ int __kprobes arch_prepare_optimized_kprobe(struct \
optimized_kprobe *op) + 	op->optinsn.size = ret;
+ 
+ 	/* Copy arch-dep-instance from template */
+-	memcpy(buf, &optprobe_template_entry, TMPL_END_IDX);
++	pax_open_kernel();
++	memcpy(buf, ktla_ktva(&optprobe_template_entry), TMPL_END_IDX);
++	pax_close_kernel();
+ 
+ 	/* Set probe information */
+ 	synthesize_set_arg1(buf + TMPL_MOVE_IDX, (unsigned long)op);
+ 
+ 	/* Set probe function call */
+-	synthesize_relcall(buf + TMPL_CALL_IDX, optimized_callback);
++	synthesize_relcall(ktva_ktla(buf) + TMPL_CALL_IDX, optimized_callback);
+ 
+ 	/* Set returning jmp instruction at the tail of out-of-line buffer */
+-	synthesize_reljump(buf + TMPL_END_IDX + op->optinsn.size,
++	synthesize_reljump(ktva_ktla(buf) + TMPL_END_IDX + op->optinsn.size,
+ 			   (u8 *)op->kp.addr + op->optinsn.size);
+ 
+ 	flush_icache_range((unsigned long) buf,
+@@ -385,7 +389,7 @@ static void __kprobes setup_optimize_kprobe(struct \
text_poke_param *tprm, + 			((long)op->kp.addr + RELATIVEJUMP_SIZE));
+ 
+ 	/* Backup instructions which will be replaced by jump address */
+-	memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE,
++	memcpy(op->optinsn.copied_insn, ktla_ktva(op->kp.addr) + INT3_SIZE,
+ 	       RELATIVE_ADDR_SIZE);
+ 
+ 	insn_buf[0] = RELATIVEJUMP_OPCODE;
+@@ -483,7 +487,7 @@ setup_detour_execution(struct kprobe *p, struct pt_regs *regs, \
int reenter) + 		/* This kprobe is really able to run optimized path. */
+ 		op = container_of(p, struct optimized_kprobe, kp);
+ 		/* Detour through copied instructions */
+-		regs->ip = (unsigned long)op->optinsn.insn + TMPL_END_IDX;
++		regs->ip = ktva_ktla((unsigned long)op->optinsn.insn) + TMPL_END_IDX;
+ 		if (!reenter)
+ 			reset_current_kprobe();
+ 		preempt_enable_no_resched();
+diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
+index ebc9873..1b9724b 100644
+--- a/arch/x86/kernel/ldt.c
++++ b/arch/x86/kernel/ldt.c
+@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload)
+ 	if (reload) {
+ #ifdef CONFIG_SMP
+ 		preempt_disable();
+-		load_LDT(pc);
++		load_LDT_nolock(pc);
+ 		if (!cpumask_equal(mm_cpumask(current->mm),
+ 				   cpumask_of(smp_processor_id())))
+ 			smp_call_function(flush_ldt, current->mm, 1);
+ 		preempt_enable();
+ #else
+-		load_LDT(pc);
++		load_LDT_nolock(pc);
+ #endif
+ 	}
+ 	if (oldsize) {
+@@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old)
+ 		return err;
+ 
+ 	for (i = 0; i < old->size; i++)
+-		write_ldt_entry(new->ldt, i, old->ldt + i * LDT_ENTRY_SIZE);
++		write_ldt_entry(new->ldt, i, old->ldt + i);
+ 	return 0;
+ }
+ 
+@@ -115,6 +115,24 @@ int init_new_context(struct task_struct *tsk, struct mm_struct \
*mm) + 		retval = copy_ldt(&mm->context, &old_mm->context);
+ 		mutex_unlock(&old_mm->context.lock);
+ 	}
++
++	if (tsk == current) {
++		mm->context.vdso = 0;
++
++#ifdef CONFIG_X86_32
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++		mm->context.user_cs_base = 0UL;
++		mm->context.user_cs_limit = ~0UL;
++
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
++		cpus_clear(mm->context.cpu_user_cs_mask);
++#endif
++
++#endif
++#endif
++
++	}
++
+ 	return retval;
+ }
+ 
+@@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, \
int oldmode) + 		}
+ 	}
+ 
++#ifdef CONFIG_PAX_SEGMEXEC
++	if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & \
MODIFY_LDT_CONTENTS_CODE)) { ++		error = -EINVAL;
++		goto out_unlock;
++	}
++#endif
++
+ 	fill_ldt(&ldt, &ldt_info);
+ 	if (oldmode)
+ 		ldt.avl = 0;
+diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
+index 5b19e4d..6476a76 100644
+--- a/arch/x86/kernel/machine_kexec_32.c
++++ b/arch/x86/kernel/machine_kexec_32.c
+@@ -26,7 +26,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/debugreg.h>
+ 
+-static void set_idt(void *newidt, __u16 limit)
++static void set_idt(struct desc_struct *newidt, __u16 limit)
+ {
+ 	struct desc_ptr curidt;
+ 
+@@ -38,7 +38,7 @@ static void set_idt(void *newidt, __u16 limit)
+ }
+ 
+ 
+-static void set_gdt(void *newgdt, __u16 limit)
++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
+ {
+ 	struct desc_ptr curgdt;
+ 
+@@ -216,7 +216,7 @@ void machine_kexec(struct kimage *image)
+ 	}
+ 
+ 	control_page = page_address(image->control_code_page);
+-	memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
++	memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), \
KEXEC_CONTROL_CODE_MAX_SIZE); + 
+ 	relocate_kernel_ptr = control_page;
+ 	page_list[PA_CONTROL_PAGE] = __pa(control_page);
+diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
+index 15c9876..0a43909 100644
+--- a/arch/x86/kernel/microcode_core.c
++++ b/arch/x86/kernel/microcode_core.c
+@@ -513,7 +513,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, \
void *hcpu) + 	return NOTIFY_OK;
+ }
+ 
+-static struct notifier_block __refdata mc_cpu_notifier = {
++static struct notifier_block mc_cpu_notifier = {
+ 	.notifier_call	= mc_cpu_callback,
+ };
+ 
+diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
+index 5fb2ceb..3ae90bb 100644
+--- a/arch/x86/kernel/microcode_intel.c
++++ b/arch/x86/kernel/microcode_intel.c
+@@ -293,13 +293,13 @@ static enum ucode_state request_microcode_fw(int cpu, struct \
device *device, + 
+ static int get_ucode_user(void *to, const void *from, size_t n)
+ {
+-	return copy_from_user(to, from, n);
++	return copy_from_user(to, (const void __force_user *)from, n);
+ }
+ 
+ static enum ucode_state
+ request_microcode_user(int cpu, const void __user *buf, size_t size)
+ {
+-	return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
++	return generic_load_microcode(cpu, (__force_kernel void *)buf, size, \
&get_ucode_user); + }
+ 
+ static void microcode_fini_cpu(int cpu)
+diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
+index 216a4d7..228255a 100644
+--- a/arch/x86/kernel/module.c
++++ b/arch/x86/kernel/module.c
+@@ -43,15 +43,60 @@ do {							\
+ } while (0)
+ #endif
+ 
+-void *module_alloc(unsigned long size)
++static inline void *__module_alloc(unsigned long size, pgprot_t prot)
+ {
+-	if (PAGE_ALIGN(size) > MODULES_LEN)
++	if (!size || PAGE_ALIGN(size) > MODULES_LEN)
+ 		return NULL;
+ 	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+-				GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
++				GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, prot,
+ 				-1, __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
++#ifdef CONFIG_X86_32
++void *module_alloc_exec(unsigned long size)
++{
++	struct vm_struct *area;
++
++	if (size == 0)
++		return NULL;
++
++	area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned \
long)&MODULES_EXEC_END); ++	return area ? area->addr : NULL;
++}
++EXPORT_SYMBOL(module_alloc_exec);
++
++void module_free_exec(struct module *mod, void *module_region)
++{
++	vunmap(module_region);
++}
++EXPORT_SYMBOL(module_free_exec);
++#else
++void module_free_exec(struct module *mod, void *module_region)
++{
++	module_free(mod, module_region);
++}
++EXPORT_SYMBOL(module_free_exec);
++
++void *module_alloc_exec(unsigned long size)
++{
++	return __module_alloc(size, PAGE_KERNEL_RX);
++}
++EXPORT_SYMBOL(module_alloc_exec);
++#endif
++#endif
++
+ #ifdef CONFIG_X86_32
+ int apply_relocate(Elf32_Shdr *sechdrs,
+ 		   const char *strtab,
+@@ -62,14 +107,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
+ 	unsigned int i;
+ 	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+ 	Elf32_Sym *sym;
+-	uint32_t *location;
++	uint32_t *plocation, location;
+ 
+ 	DEBUGP("Applying relocate section %u to %u\n",
+ 	       relsec, sechdrs[relsec].sh_info);
+ 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ 		/* This is where to make the change */
+-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+-			+ rel[i].r_offset;
++		plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
++		location = (uint32_t)plocation;
++		if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
++			plocation = ktla_ktva((void *)plocation);
+ 		/* This is the symbol it is referring to.  Note that all
+ 		   undefined symbols have been resolved.  */
+ 		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+@@ -78,11 +125,15 @@ int apply_relocate(Elf32_Shdr *sechdrs,
+ 		switch (ELF32_R_TYPE(rel[i].r_info)) {
+ 		case R_386_32:
+ 			/* We add the value into the location given */
+-			*location += sym->st_value;
++			pax_open_kernel();
++			*plocation += sym->st_value;
++			pax_close_kernel();
+ 			break;
+ 		case R_386_PC32:
+ 			/* Add the value, subtract its position */
+-			*location += sym->st_value - (uint32_t)location;
++			pax_open_kernel();
++			*plocation += sym->st_value - location;
++			pax_close_kernel();
+ 			break;
+ 		default:
+ 			pr_err("%s: Unknown relocation: %u\n",
+@@ -127,21 +178,30 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
+ 		case R_X86_64_NONE:
+ 			break;
+ 		case R_X86_64_64:
++			pax_open_kernel();
+ 			*(u64 *)loc = val;
++			pax_close_kernel();
+ 			break;
+ 		case R_X86_64_32:
++			pax_open_kernel();
+ 			*(u32 *)loc = val;
++			pax_close_kernel();
+ 			if (val != *(u32 *)loc)
+ 				goto overflow;
+ 			break;
+ 		case R_X86_64_32S:
++			pax_open_kernel();
+ 			*(s32 *)loc = val;
++			pax_close_kernel();
+ 			if ((s64)val != *(s32 *)loc)
+ 				goto overflow;
+ 			break;
+ 		case R_X86_64_PC32:
+ 			val -= (u64)loc;
++			pax_open_kernel();
+ 			*(u32 *)loc = val;
++			pax_close_kernel();
++
+ #if 0
+ 			if ((s64)val != *(s32 *)loc)
+ 				goto overflow;
+diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
+index 88458fa..349f7a4 100644
+--- a/arch/x86/kernel/msr.c
++++ b/arch/x86/kernel/msr.c
+@@ -233,7 +233,7 @@ static int msr_class_cpu_callback(struct notifier_block *nfb,
+ 	return notifier_from_errno(err);
+ }
+ 
+-static struct notifier_block __refdata msr_class_cpu_notifier = {
++static struct notifier_block msr_class_cpu_notifier = {
+ 	.notifier_call = msr_class_cpu_callback,
+ };
+ 
+diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
+index ba77ebc..65da999 100644
+--- a/arch/x86/kernel/nmi.c
++++ b/arch/x86/kernel/nmi.c
+@@ -138,7 +138,7 @@ static int __kprobes nmi_handle(unsigned int type, struct \
pt_regs *regs, bool b2 + 	return handled;
+ }
+ 
+-int __register_nmi_handler(unsigned int type, struct nmiaction *action)
++int __register_nmi_handler(unsigned int type, const struct nmiaction *action)
+ {
+ 	struct nmi_desc *desc = nmi_to_desc(type);
+ 	unsigned long flags;
+@@ -162,9 +162,9 @@ int __register_nmi_handler(unsigned int type, struct nmiaction \
*action) + 	 * event confuses some handlers (kdump uses this flag)
+ 	 */
+ 	if (action->flags & NMI_FLAG_FIRST)
+-		list_add_rcu(&action->list, &desc->head);
++		pax_list_add_rcu((struct list_head *)&action->list, &desc->head);
+ 	else
+-		list_add_tail_rcu(&action->list, &desc->head);
++		pax_list_add_tail_rcu((struct list_head *)&action->list, &desc->head);
+ 	
+ 	spin_unlock_irqrestore(&desc->lock, flags);
+ 	return 0;
+@@ -187,7 +187,7 @@ void unregister_nmi_handler(unsigned int type, const char *name)
+ 		if (!strcmp(n->name, name)) {
+ 			WARN(in_nmi(),
+ 				"Trying to free NMI (%s) from NMI context!\n", n->name);
+-			list_del_rcu(&n->list);
++			pax_list_del_rcu((struct list_head *)&n->list);
+ 			break;
+ 		}
+ 	}
+@@ -512,6 +512,17 @@ static inline void nmi_nesting_postprocess(void)
+ dotraplinkage notrace __kprobes void
+ do_nmi(struct pt_regs *regs, long error_code)
+ {
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++	if (!user_mode(regs)) {
++		unsigned long cs = regs->cs & 0xFFFF;
++		unsigned long ip = ktva_ktla(regs->ip);
++
++		if ((cs == __KERNEL_CS || cs == __KERNEXEC_KERNEL_CS) && ip <= (unsigned \
long)_etext) ++			regs->ip = ip;
++	}
++#endif
++
+ 	nmi_nesting_preprocess(regs);
+ 
+ 	nmi_enter();
+diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c
+index 6d9582e..f746287 100644
+--- a/arch/x86/kernel/nmi_selftest.c
++++ b/arch/x86/kernel/nmi_selftest.c
+@@ -43,7 +43,7 @@ static void __init init_nmi_testsuite(void)
+ {
+ 	/* trap all the unknown NMIs we may generate */
+ 	register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk",
+-			__initdata);
++			__initconst);
+ }
+ 
+ static void __init cleanup_nmi_testsuite(void)
+@@ -66,7 +66,7 @@ static void __init test_nmi_ipi(struct cpumask *mask)
+ 	unsigned long timeout;
+ 
+ 	if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback,
+-				 NMI_FLAG_FIRST, "nmi_selftest", __initdata)) {
++				 NMI_FLAG_FIRST, "nmi_selftest", __initconst)) {
+ 		nmi_fail = FAILURE;
+ 		return;
+ 	}
+diff --git a/arch/x86/kernel/paravirt-spinlocks.c \
b/arch/x86/kernel/paravirt-spinlocks.c +index 676b8c7..870ba04 100644
+--- a/arch/x86/kernel/paravirt-spinlocks.c
++++ b/arch/x86/kernel/paravirt-spinlocks.c
+@@ -13,7 +13,7 @@ default_spin_lock_flags(arch_spinlock_t *lock, unsigned long \
flags) + 	arch_spin_lock(lock);
+ }
+ 
+-struct pv_lock_ops pv_lock_ops = {
++struct pv_lock_ops pv_lock_ops __read_only = {
+ #ifdef CONFIG_SMP
+ 	.spin_is_locked = __ticket_spin_is_locked,
+ 	.spin_is_contended = __ticket_spin_is_contended,
+diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
+index cd6de64..27c6af0 100644
+--- a/arch/x86/kernel/paravirt.c
++++ b/arch/x86/kernel/paravirt.c
+@@ -55,6 +55,9 @@ u64 _paravirt_ident_64(u64 x)
+ {
+ 	return x;
+ }
++#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
++PV_CALLEE_SAVE_REGS_THUNK(_paravirt_ident_64);
++#endif
+ 
+ void __init default_banner(void)
+ {
+@@ -147,15 +150,19 @@ unsigned paravirt_patch_default(u8 type, u16 clobbers, void \
*insnbuf, + 	if (opfunc == NULL)
+ 		/* If there's no function, patch it with a ud2a (BUG) */
+ 		ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
+-	else if (opfunc == _paravirt_nop)
++	else if (opfunc == (void *)_paravirt_nop)
+ 		/* If the operation is a nop, then nop the callsite */
+ 		ret = paravirt_patch_nop();
+ 
+ 	/* identity functions just return their single argument */
+-	else if (opfunc == _paravirt_ident_32)
++	else if (opfunc == (void *)_paravirt_ident_32)
+ 		ret = paravirt_patch_ident_32(insnbuf, len);
+-	else if (opfunc == _paravirt_ident_64)
++	else if (opfunc == (void *)_paravirt_ident_64)
+ 		ret = paravirt_patch_ident_64(insnbuf, len);
++#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
++	else if (opfunc == (void *)__raw_callee_save__paravirt_ident_64)
++		ret = paravirt_patch_ident_64(insnbuf, len);
++#endif
+ 
+ 	else if (type == PARAVIRT_PATCH(pv_cpu_ops.iret) ||
+ 		 type == PARAVIRT_PATCH(pv_cpu_ops.irq_enable_sysexit) ||
+@@ -180,7 +187,7 @@ unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
+ 	if (insn_len > len || start == NULL)
+ 		insn_len = len;
+ 	else
+-		memcpy(insnbuf, start, insn_len);
++		memcpy(insnbuf, ktla_ktva(start), insn_len);
+ 
+ 	return insn_len;
+ }
+@@ -304,7 +311,7 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void)
+ 	return this_cpu_read(paravirt_lazy_mode);
+ }
+ 
+-struct pv_info pv_info = {
++struct pv_info pv_info __read_only = {
+ 	.name = "bare hardware",
+ 	.paravirt_enabled = 0,
+ 	.kernel_rpl = 0,
+@@ -315,16 +322,16 @@ struct pv_info pv_info = {
+ #endif
+ };
+ 
+-struct pv_init_ops pv_init_ops = {
++struct pv_init_ops pv_init_ops __read_only = {
+ 	.patch = native_patch,
+ };
+ 
+-struct pv_time_ops pv_time_ops = {
++struct pv_time_ops pv_time_ops __read_only = {
+ 	.sched_clock = native_sched_clock,
+ 	.steal_clock = native_steal_clock,
+ };
+ 
+-struct pv_irq_ops pv_irq_ops = {
++struct pv_irq_ops pv_irq_ops __read_only = {
+ 	.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
+ 	.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
+ 	.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
+@@ -336,7 +343,7 @@ struct pv_irq_ops pv_irq_ops = {
+ #endif
+ };
+ 
+-struct pv_cpu_ops pv_cpu_ops = {
++struct pv_cpu_ops pv_cpu_ops __read_only = {
+ 	.cpuid = native_cpuid,
+ 	.get_debugreg = native_get_debugreg,
+ 	.set_debugreg = native_set_debugreg,
+@@ -394,21 +401,26 @@ struct pv_cpu_ops pv_cpu_ops = {
+ 	.end_context_switch = paravirt_nop,
+ };
+ 
+-struct pv_apic_ops pv_apic_ops = {
++struct pv_apic_ops pv_apic_ops __read_only= {
+ #ifdef CONFIG_X86_LOCAL_APIC
+ 	.startup_ipi_hook = paravirt_nop,
+ #endif
+ };
+ 
+-#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
++#ifdef CONFIG_X86_32
++#ifdef CONFIG_X86_PAE
++/* 64-bit pagetable entries */
++#define PTE_IDENT	PV_CALLEE_SAVE(_paravirt_ident_64)
++#else
+ /* 32-bit pagetable entries */
+ #define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_32)
++#endif
+ #else
+ /* 64-bit pagetable entries */
+ #define PTE_IDENT	__PV_IS_CALLEE_SAVE(_paravirt_ident_64)
+ #endif
+ 
+-struct pv_mmu_ops pv_mmu_ops = {
++struct pv_mmu_ops pv_mmu_ops __read_only = {
+ 
+ 	.read_cr2 = native_read_cr2,
+ 	.write_cr2 = native_write_cr2,
+@@ -458,6 +470,7 @@ struct pv_mmu_ops pv_mmu_ops = {
+ 	.make_pud = PTE_IDENT,
+ 
+ 	.set_pgd = native_set_pgd,
++	.set_pgd_batched = native_set_pgd_batched,
+ #endif
+ #endif /* PAGETABLE_LEVELS >= 3 */
+ 
+@@ -478,6 +491,12 @@ struct pv_mmu_ops pv_mmu_ops = {
+ 	},
+ 
+ 	.set_fixmap = native_set_fixmap,
++
++#ifdef CONFIG_PAX_KERNEXEC
++	.pax_open_kernel = native_pax_open_kernel,
++	.pax_close_kernel = native_pax_close_kernel,
++#endif
++
+ };
+ 
+ EXPORT_SYMBOL_GPL(pv_time_ops);
+diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
+index 299d493..2ccb0ee 100644
+--- a/arch/x86/kernel/pci-calgary_64.c
++++ b/arch/x86/kernel/pci-calgary_64.c
+@@ -1339,7 +1339,7 @@ static void __init get_tce_space_from_tar(void)
+ 			tce_space = be64_to_cpu(readq(target));
+ 			tce_space = tce_space & TAR_SW_BITS;
+ 
+-			tce_space = tce_space & (~specified_table_size);
++			tce_space = tce_space & (~(unsigned long)specified_table_size);
+ 			info->tce_space = (u64 *)__va(tce_space);
+ 		}
+ 	}
+diff --git a/arch/x86/kernel/pci-iommu_table.c b/arch/x86/kernel/pci-iommu_table.c
+index 35ccf75..7a15747 100644
+--- a/arch/x86/kernel/pci-iommu_table.c
++++ b/arch/x86/kernel/pci-iommu_table.c
+@@ -2,7 +2,7 @@
+ #include <asm/iommu_table.h>
+ #include <linux/string.h>
+ #include <linux/kallsyms.h>
+-
++#include <linux/sched.h>
+ 
+ #define DEBUG 1
+ 
+diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
+index 6c483ba..d10ce2f 100644
+--- a/arch/x86/kernel/pci-swiotlb.c
++++ b/arch/x86/kernel/pci-swiotlb.c
+@@ -32,7 +32,7 @@ static void x86_swiotlb_free_coherent(struct device *dev, size_t \
size, + 				      void *vaddr, dma_addr_t dma_addr,
+ 				      struct dma_attrs *attrs)
+ {
+-	swiotlb_free_coherent(dev, size, vaddr, dma_addr);
++	swiotlb_free_coherent(dev, size, vaddr, dma_addr, attrs);
+ }
+ 
+ static struct dma_map_ops swiotlb_dma_ops = {
+diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
+index 83369e5..52b93f0 100644
+--- a/arch/x86/kernel/process.c
++++ b/arch/x86/kernel/process.c
+@@ -36,7 +36,8 @@
+  * section. Since TSS's are completely CPU-local, we want them
+  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+  */
+-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 \
... NR_CPUS-1] = INIT_TSS }; ++EXPORT_SYMBOL(init_tss);
+ 
+ #ifdef CONFIG_X86_64
+ static DEFINE_PER_CPU(unsigned char, is_idle);
+@@ -92,7 +93,7 @@ void arch_task_cache_init(void)
+         task_xstate_cachep =
+         	kmem_cache_create("task_xstate", xstate_size,
+ 				  __alignof__(union thread_xstate),
+-				  SLAB_PANIC | SLAB_NOTRACK, NULL);
++				  SLAB_PANIC | SLAB_NOTRACK | SLAB_USERCOPY, NULL);
+ }
+ 
+ /*
+@@ -105,7 +106,7 @@ void exit_thread(void)
+ 	unsigned long *bp = t->io_bitmap_ptr;
+ 
+ 	if (bp) {
+-		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
++		struct tss_struct *tss = init_tss + get_cpu();
+ 
+ 		t->io_bitmap_ptr = NULL;
+ 		clear_thread_flag(TIF_IO_BITMAP);
+@@ -125,6 +126,9 @@ void flush_thread(void)
+ {
+ 	struct task_struct *tsk = current;
+ 
++#if defined(CONFIG_X86_32) && !defined(CONFIG_CC_STACKPROTECTOR) && \
!defined(CONFIG_PAX_MEMORY_UDEREF) ++	loadsegment(gs, 0);
++#endif
+ 	flush_ptrace_hw_breakpoint(tsk);
+ 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
+ 	drop_init_fpu(tsk);
+@@ -271,7 +275,7 @@ static void __exit_idle(void)
+ void exit_idle(void)
+ {
+ 	/* idle loop has pid 0 */
+-	if (current->pid)
++	if (task_pid_nr(current))
+ 		return;
+ 	__exit_idle();
+ }
+@@ -327,7 +331,7 @@ bool xen_set_default_idle(void)
+ 	return ret;
+ }
+ #endif
+-void stop_this_cpu(void *dummy)
++__noreturn void stop_this_cpu(void *dummy)
+ {
+ 	local_irq_disable();
+ 	/*
+@@ -456,16 +460,37 @@ static int __init idle_setup(char *str)
+ }
+ early_param("idle", idle_setup);
+ 
+-unsigned long arch_align_stack(unsigned long sp)
++#ifdef CONFIG_PAX_RANDKSTACK
++void pax_randomize_kstack(struct pt_regs *regs)
+ {
+-	if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+-		sp -= get_random_int() % 8192;
+-	return sp & ~0xf;
+-}
++	struct thread_struct *thread = &current->thread;
++	unsigned long time;
+ 
+-unsigned long arch_randomize_brk(struct mm_struct *mm)
+-{
+-	unsigned long range_end = mm->brk + 0x02000000;
+-	return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+-}
++	if (!randomize_va_space)
++		return;
++
++	if (v8086_mode(regs))
++		return;
+ 
++	rdtscl(time);
++
++	/* P4 seems to return a 0 LSB, ignore it */
++#ifdef CONFIG_MPENTIUM4
++	time &= 0x3EUL;
++	time <<= 2;
++#elif defined(CONFIG_X86_64)
++	time &= 0xFUL;
++	time <<= 4;
++#else
++	time &= 0x1FUL;
++	time <<= 3;
++#endif
++
++	thread->sp0 ^= time;
++	load_sp0(init_tss + smp_processor_id(), thread);
++
++#ifdef CONFIG_X86_64
++	this_cpu_write(kernel_stack, thread->sp0);
++#endif
++}
++#endif
+diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
+index f8adefc..4bce3d6 100644
+--- a/arch/x86/kernel/process_32.c
++++ b/arch/x86/kernel/process_32.c
+@@ -65,6 +65,7 @@ asmlinkage void ret_from_kernel_thread(void) \
__asm__("ret_from_kernel_thread"); + unsigned long thread_saved_pc(struct task_struct \
*tsk) + {
+ 	return ((unsigned long *)tsk->thread.sp)[3];
++//XXX	return tsk->thread.eip;
+ }
+ 
+ void __show_regs(struct pt_regs *regs, int all)
+@@ -74,19 +75,18 @@ void __show_regs(struct pt_regs *regs, int all)
+ 	unsigned long sp;
+ 	unsigned short ss, gs;
+ 
+-	if (user_mode_vm(regs)) {
++	if (user_mode(regs)) {
+ 		sp = regs->sp;
+ 		ss = regs->ss & 0xffff;
+-		gs = get_user_gs(regs);
+ 	} else {
+ 		sp = kernel_stack_pointer(regs);
+ 		savesegment(ss, ss);
+-		savesegment(gs, gs);
+ 	}
++	gs = get_user_gs(regs);
+ 
+ 	printk(KERN_DEFAULT "EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+ 			(u16)regs->cs, regs->ip, regs->flags,
+-			smp_processor_id());
++			raw_smp_processor_id());
+ 	print_symbol("EIP is at %s\n", regs->ip);
+ 
+ 	printk(KERN_DEFAULT "EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+@@ -133,20 +133,21 @@ void release_thread(struct task_struct *dead_task)
+ int copy_thread(unsigned long clone_flags, unsigned long sp,
+ 	unsigned long arg, struct task_struct *p)
+ {
+-	struct pt_regs *childregs = task_pt_regs(p);
++	struct pt_regs *childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct \
pt_regs) - 8; + 	struct task_struct *tsk;
+ 	int err;
+ 
+ 	p->thread.sp = (unsigned long) childregs;
+ 	p->thread.sp0 = (unsigned long) (childregs+1);
++	p->tinfo.lowest_stack = (unsigned long)task_stack_page(p);
+ 
+ 	if (unlikely(p->flags & PF_KTHREAD)) {
+ 		/* kernel thread */
+ 		memset(childregs, 0, sizeof(struct pt_regs));
+ 		p->thread.ip = (unsigned long) ret_from_kernel_thread;
+-		task_user_gs(p) = __KERNEL_STACK_CANARY;
+-		childregs->ds = __USER_DS;
+-		childregs->es = __USER_DS;
++		savesegment(gs, childregs->gs);
++		childregs->ds = __KERNEL_DS;
++		childregs->es = __KERNEL_DS;
+ 		childregs->fs = __KERNEL_PERCPU;
+ 		childregs->bx = sp;	/* function */
+ 		childregs->bp = arg;
+@@ -253,7 +254,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	struct thread_struct *prev = &prev_p->thread,
+ 				 *next = &next_p->thread;
+ 	int cpu = smp_processor_id();
+-	struct tss_struct *tss = &per_cpu(init_tss, cpu);
++	struct tss_struct *tss = init_tss + cpu;
+ 	fpu_switch_t fpu;
+ 
+ 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
+@@ -277,6 +278,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	 */
+ 	lazy_save_gs(prev->gs);
+ 
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	__set_fs(task_thread_info(next_p)->addr_limit);
++#endif
++
+ 	/*
+ 	 * Load the per-thread Thread-Local Storage descriptor.
+ 	 */
+@@ -307,6 +312,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	 */
+ 	arch_end_context_switch(next_p);
+ 
++	this_cpu_write(current_task, next_p);
++	this_cpu_write(current_tinfo, &next_p->tinfo);
++
+ 	/*
+ 	 * Restore %gs if needed (which is common)
+ 	 */
+@@ -315,8 +323,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 
+ 	switch_fpu_finish(next_p, fpu);
+ 
+-	this_cpu_write(current_task, next_p);
+-
+ 	return prev_p;
+ }
+ 
+@@ -346,4 +352,3 @@ unsigned long get_wchan(struct task_struct *p)
+ 	} while (count++ < 16);
+ 	return 0;
+ }
+-
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index 05646ba..0c2906d 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -158,10 +158,11 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
+ 	struct pt_regs *childregs;
+ 	struct task_struct *me = current;
+ 
+-	p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
++	p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE - 16;
+ 	childregs = task_pt_regs(p);
+ 	p->thread.sp = (unsigned long) childregs;
+ 	p->thread.usersp = me->thread.usersp;
++	p->tinfo.lowest_stack = (unsigned long)task_stack_page(p);
+ 	set_tsk_thread_flag(p, TIF_FORK);
+ 	p->fpu_counter = 0;
+ 	p->thread.io_bitmap_ptr = NULL;
+@@ -172,6 +173,8 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
+ 	p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
+ 	savesegment(es, p->thread.es);
+ 	savesegment(ds, p->thread.ds);
++	savesegment(ss, p->thread.ss);
++	BUG_ON(p->thread.ss == __UDEREF_KERNEL_DS);
+ 	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+ 
+ 	if (unlikely(p->flags & PF_KTHREAD)) {
+@@ -280,7 +283,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	struct thread_struct *prev = &prev_p->thread;
+ 	struct thread_struct *next = &next_p->thread;
+ 	int cpu = smp_processor_id();
+-	struct tss_struct *tss = &per_cpu(init_tss, cpu);
++	struct tss_struct *tss = init_tss + cpu;
+ 	unsigned fsindex, gsindex;
+ 	fpu_switch_t fpu;
+ 
+@@ -303,6 +306,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	if (unlikely(next->ds | prev->ds))
+ 		loadsegment(ds, next->ds);
+ 
++	savesegment(ss, prev->ss);
++	if (unlikely(next->ss != prev->ss))
++		loadsegment(ss, next->ss);
+ 
+ 	/* We must save %fs and %gs before load_TLS() because
+ 	 * %fs and %gs may be cleared by load_TLS().
+@@ -362,10 +368,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct \
*next_p) + 	prev->usersp = this_cpu_read(old_rsp);
+ 	this_cpu_write(old_rsp, next->usersp);
+ 	this_cpu_write(current_task, next_p);
++	this_cpu_write(current_tinfo, &next_p->tinfo);
+ 
+-	this_cpu_write(kernel_stack,
+-		  (unsigned long)task_stack_page(next_p) +
+-		  THREAD_SIZE - KERNEL_STACK_OFFSET);
++	this_cpu_write(kernel_stack, next->sp0);
+ 
+ 	/*
+ 	 * Now maybe reload the debug registers and handle I/O bitmaps
+@@ -434,12 +439,11 @@ unsigned long get_wchan(struct task_struct *p)
+ 	if (!p || p == current || p->state == TASK_RUNNING)
+ 		return 0;
+ 	stack = (unsigned long)task_stack_page(p);
+-	if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
++	if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-16-sizeof(u64))
+ 		return 0;
+ 	fp = *(u64 *)(p->thread.sp);
+ 	do {
+-		if (fp < (unsigned long)stack ||
+-		    fp >= (unsigned long)stack+THREAD_SIZE)
++		if (fp < stack || fp > stack+THREAD_SIZE-16-sizeof(u64))
+ 			return 0;
+ 		ip = *(u64 *)(fp+8);
+ 		if (!in_sched_functions(ip))
+diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
+index 7461f50..1334029 100644
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -184,14 +184,13 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs)
+ {
+ 	unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
+ 	unsigned long sp = (unsigned long)&regs->sp;
+-	struct thread_info *tinfo;
+ 
+-	if (context == (sp & ~(THREAD_SIZE - 1)))
++	if (context == ((sp + 8) & ~(THREAD_SIZE - 1)))
+ 		return sp;
+ 
+-	tinfo = (struct thread_info *)context;
+-	if (tinfo->previous_esp)
+-		return tinfo->previous_esp;
++	sp = *(unsigned long *)context;
++	if (sp)
++		return sp;
+ 
+ 	return (unsigned long)regs;
+ }
+@@ -588,7 +587,7 @@ static void ptrace_triggered(struct perf_event *bp,
+ static unsigned long ptrace_get_dr7(struct perf_event *bp[])
+ {
+ 	int i;
+-	int dr7 = 0;
++	unsigned long dr7 = 0;
+ 	struct arch_hw_breakpoint *info;
+ 
+ 	for (i = 0; i < HBP_NUM; i++) {
+@@ -822,7 +821,7 @@ long arch_ptrace(struct task_struct *child, long request,
+ 		 unsigned long addr, unsigned long data)
+ {
+ 	int ret;
+-	unsigned long __user *datap = (unsigned long __user *)data;
++	unsigned long __user *datap = (__force unsigned long __user *)data;
+ 
+ 	switch (request) {
+ 	/* read the word at location addr in the USER area. */
+@@ -907,14 +906,14 @@ long arch_ptrace(struct task_struct *child, long request,
+ 		if ((int) addr < 0)
+ 			return -EIO;
+ 		ret = do_get_thread_area(child, addr,
+-					(struct user_desc __user *)data);
++					(__force struct user_desc __user *) data);
+ 		break;
+ 
+ 	case PTRACE_SET_THREAD_AREA:
+ 		if ((int) addr < 0)
+ 			return -EIO;
+ 		ret = do_set_thread_area(child, addr,
+-					(struct user_desc __user *)data, 0);
++					(__force struct user_desc __user *) data, 0);
+ 		break;
+ #endif
+ 
+@@ -1292,7 +1291,7 @@ long compat_arch_ptrace(struct task_struct *child, \
compat_long_t request, + 
+ #ifdef CONFIG_X86_64
+ 
+-static struct user_regset x86_64_regsets[] __read_mostly = {
++static user_regset_no_const x86_64_regsets[] __read_only = {
+ 	[REGSET_GENERAL] = {
+ 		.core_note_type = NT_PRSTATUS,
+ 		.n = sizeof(struct user_regs_struct) / sizeof(long),
+@@ -1333,7 +1332,7 @@ static const struct user_regset_view user_x86_64_view = {
+ #endif	/* CONFIG_X86_64 */
+ 
+ #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
+-static struct user_regset x86_32_regsets[] __read_mostly = {
++static user_regset_no_const x86_32_regsets[] __read_only = {
+ 	[REGSET_GENERAL] = {
+ 		.core_note_type = NT_PRSTATUS,
+ 		.n = sizeof(struct user_regs_struct32) / sizeof(u32),
+@@ -1386,7 +1385,7 @@ static const struct user_regset_view user_x86_32_view = {
+  */
+ u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS];
+ 
+-void update_regset_xstate_info(unsigned int size, u64 xstate_mask)
++void __init update_regset_xstate_info(unsigned int size, u64 xstate_mask)
+ {
+ #ifdef CONFIG_X86_64
+ 	x86_64_regsets[REGSET_XSTATE].n = size / sizeof(u64);
+@@ -1421,7 +1420,7 @@ static void fill_sigtrap_info(struct task_struct *tsk,
+ 	memset(info, 0, sizeof(*info));
+ 	info->si_signo = SIGTRAP;
+ 	info->si_code = si_code;
+-	info->si_addr = user_mode_vm(regs) ? (void __user *)regs->ip : NULL;
++	info->si_addr = user_mode(regs) ? (__force void __user *)regs->ip : NULL;
+ }
+ 
+ void user_single_step_siginfo(struct task_struct *tsk,
+@@ -1450,6 +1449,10 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs \
*regs, + # define IS_IA32	0
+ #endif
+ 
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /*
+  * We must return the syscall number to actually look up in the table.
+  * This can be -1L to skip running any syscall at all.
+@@ -1460,6 +1463,11 @@ long syscall_trace_enter(struct pt_regs *regs)
+ 
+ 	user_exit();
+ 
++#ifdef CONFIG_GRKERNSEC_SETXID
++	if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++		gr_delayed_cred_worker();
++#endif
++
+ 	/*
+ 	 * If we stepped into a sysenter/syscall insn, it trapped in
+ 	 * kernel mode; do_debug() cleared TF and set TIF_SINGLESTEP.
+@@ -1515,6 +1523,11 @@ void syscall_trace_leave(struct pt_regs *regs)
+ 	 */
+ 	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/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
+index 2cb9470..ff1fd80 100644
+--- a/arch/x86/kernel/pvclock.c
++++ b/arch/x86/kernel/pvclock.c
+@@ -43,11 +43,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info \
*src) + 	return pv_tsc_khz;
+ }
+ 
+-static atomic64_t last_value = ATOMIC64_INIT(0);
++static atomic64_unchecked_t last_value = ATOMIC64_INIT(0);
+ 
+ void pvclock_resume(void)
+ {
+-	atomic64_set(&last_value, 0);
++	atomic64_set_unchecked(&last_value, 0);
+ }
+ 
+ u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src)
+@@ -92,11 +92,11 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info \
*src) + 	 * updating at the same time, and one of them could be slightly behind,
+ 	 * making the assumption that last_value always go forward fail to hold.
+ 	 */
+-	last = atomic64_read(&last_value);
++	last = atomic64_read_unchecked(&last_value);
+ 	do {
+ 		if (ret < last)
+ 			return last;
+-		last = atomic64_cmpxchg(&last_value, last, ret);
++		last = atomic64_cmpxchg_unchecked(&last_value, last, ret);
+ 	} while (unlikely(last != ret));
+ 
+ 	return ret;
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
+index 5f4ad27..9d96c99 100644
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -68,6 +68,11 @@ static int __init set_bios_reboot(const struct dmi_system_id *d)
+ 
+ void __noreturn machine_real_restart(unsigned int type)
+ {
++
++#if defined(CONFIG_X86_32) && (defined(CONFIG_PAX_KERNEXEC) || \
defined(CONFIG_PAX_MEMORY_UDEREF)) ++	struct desc_struct *gdt;
++#endif
++
+ 	local_irq_disable();
+ 
+ 	/*
+@@ -95,7 +100,29 @@ void __noreturn machine_real_restart(unsigned int type)
+ 
+ 	/* Jump to the identity-mapped low memory code */
+ #ifdef CONFIG_X86_32
+-	asm volatile("jmpl *%0" : :
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++	gdt = get_cpu_gdt_table(smp_processor_id());
++	pax_open_kernel();
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	gdt[GDT_ENTRY_KERNEL_DS].type = 3;
++	gdt[GDT_ENTRY_KERNEL_DS].limit = 0xf;
++	loadsegment(ds, __KERNEL_DS);
++	loadsegment(es, __KERNEL_DS);
++	loadsegment(ss, __KERNEL_DS);
++#endif
++#ifdef CONFIG_PAX_KERNEXEC
++	gdt[GDT_ENTRY_KERNEL_CS].base0 = 0;
++	gdt[GDT_ENTRY_KERNEL_CS].base1 = 0;
++	gdt[GDT_ENTRY_KERNEL_CS].base2 = 0;
++	gdt[GDT_ENTRY_KERNEL_CS].limit0 = 0xffff;
++	gdt[GDT_ENTRY_KERNEL_CS].limit = 0xf;
++	gdt[GDT_ENTRY_KERNEL_CS].g = 1;
++#endif
++	pax_close_kernel();
++#endif
++
++	asm volatile("ljmpl *%0" : :
+ 		     "rm" (real_mode_header->machine_real_restart_asm),
+ 		     "a" (type));
+ #else
+@@ -458,7 +485,7 @@ void __attribute__((weak)) mach_reboot_fixups(void)
+  * try to force a triple fault and then cycle between hitting the keyboard
+  * controller and doing that
+  */
+-static void native_machine_emergency_restart(void)
++static void __noreturn native_machine_emergency_restart(void)
+ {
+ 	int i;
+ 	int attempt = 0;
+@@ -567,13 +594,13 @@ void native_machine_shutdown(void)
+ #endif
+ }
+ 
+-static void __machine_emergency_restart(int emergency)
++static void __noreturn __machine_emergency_restart(int emergency)
+ {
+ 	reboot_emergency = emergency;
+ 	machine_ops.emergency_restart();
+ }
+ 
+-static void native_machine_restart(char *__unused)
++static void __noreturn native_machine_restart(char *__unused)
+ {
+ 	pr_notice("machine restart\n");
+ 
+@@ -582,7 +609,7 @@ static void native_machine_restart(char *__unused)
+ 	__machine_emergency_restart(0);
+ }
+ 
+-static void native_machine_halt(void)
++static void __noreturn native_machine_halt(void)
+ {
+ 	/* Stop other cpus and apics */
+ 	machine_shutdown();
+@@ -592,7 +619,7 @@ static void native_machine_halt(void)
+ 	stop_this_cpu(NULL);
+ }
+ 
+-static void native_machine_power_off(void)
++static void __noreturn native_machine_power_off(void)
+ {
+ 	if (pm_power_off) {
+ 		if (!reboot_force)
+@@ -601,9 +628,10 @@ static void native_machine_power_off(void)
+ 	}
+ 	/* A fallback in case there is no PM info available */
+ 	tboot_shutdown(TB_SHUTDOWN_HALT);
++	unreachable();
+ }
+ 
+-struct machine_ops machine_ops = {
++struct machine_ops machine_ops __read_only = {
+ 	.power_off = native_machine_power_off,
+ 	.shutdown = native_machine_shutdown,
+ 	.emergency_restart = native_machine_emergency_restart,
+diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
+index c8e41e9..64049ef 100644
+--- a/arch/x86/kernel/reboot_fixups_32.c
++++ b/arch/x86/kernel/reboot_fixups_32.c
+@@ -57,7 +57,7 @@ struct device_fixup {
+ 	unsigned int vendor;
+ 	unsigned int device;
+ 	void (*reboot_fixup)(struct pci_dev *);
+-};
++} __do_const;
+ 
+ /*
+  * PCI ids solely used for fixups_table go here
+diff --git a/arch/x86/kernel/relocate_kernel_64.S \
b/arch/x86/kernel/relocate_kernel_64.S +index 3fd2c69..16ef367 100644
+--- a/arch/x86/kernel/relocate_kernel_64.S
++++ b/arch/x86/kernel/relocate_kernel_64.S
+@@ -11,6 +11,7 @@
+ #include <asm/kexec.h>
+ #include <asm/processor-flags.h>
+ #include <asm/pgtable_types.h>
++#include <asm/alternative-asm.h>
+ 
+ /*
+  * Must be relocatable PIC code callable as a C function
+@@ -96,8 +97,7 @@ relocate_kernel:
+ 
+ 	/* jump to identity mapped page */
+ 	addq	$(identity_mapped - relocate_kernel), %r8
+-	pushq	%r8
+-	ret
++	jmp	*%r8
+ 
+ identity_mapped:
+ 	/* set return address to 0 if not preserving context */
+@@ -167,6 +167,7 @@ identity_mapped:
+ 	xorl	%r14d, %r14d
+ 	xorl	%r15d, %r15d
+ 
++	pax_force_retaddr 0, 1
+ 	ret
+ 
+ 1:
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 234e1e3..1246d05 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -110,6 +110,7 @@
+ #include <asm/mce.h>
+ #include <asm/alternative.h>
+ #include <asm/prom.h>
++#include <asm/boot.h>
+ 
+ /*
+  * max_low_pfn_mapped: highest direct mapped pfn under 4GB
+@@ -205,12 +206,50 @@ EXPORT_SYMBOL(boot_cpu_data);
+ #endif
+ 
+ 
+-#if !defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
+-unsigned long mmu_cr4_features;
++#ifdef CONFIG_X86_64
++unsigned long mmu_cr4_features __read_only = X86_CR4_PSE | X86_CR4_PAE | \
X86_CR4_PGE; ++#elif defined(CONFIG_X86_PAE)
++unsigned long mmu_cr4_features __read_only = X86_CR4_PAE;
+ #else
+-unsigned long mmu_cr4_features = X86_CR4_PAE;
++unsigned long mmu_cr4_features __read_only;
+ #endif
+ 
++void set_in_cr4(unsigned long mask)
++{
++	unsigned long cr4 = read_cr4();
++
++	if ((cr4 & mask) == mask && cr4 == mmu_cr4_features)
++		return;
++
++	pax_open_kernel();
++	mmu_cr4_features |= mask;
++	pax_close_kernel();
++
++	if (trampoline_cr4_features)
++		*trampoline_cr4_features = mmu_cr4_features;
++	cr4 |= mask;
++	write_cr4(cr4);
++}
++EXPORT_SYMBOL(set_in_cr4);
++
++void clear_in_cr4(unsigned long mask)
++{
++	unsigned long cr4 = read_cr4();
++
++	if (!(cr4 & mask) && cr4 == mmu_cr4_features)
++		return;
++
++	pax_open_kernel();
++	mmu_cr4_features &= ~mask;
++	pax_close_kernel();
++
++	if (trampoline_cr4_features)
++		*trampoline_cr4_features = mmu_cr4_features;
++	cr4 &= ~mask;
++	write_cr4(cr4);
++}
++EXPORT_SYMBOL(clear_in_cr4);
++
+ /* Boot loader ID and version as integers, for the benefit of proc_dointvec */
+ int bootloader_type, bootloader_version;
+ 
+@@ -442,7 +481,7 @@ static void __init parse_setup_data(void)
+ 
+ 		switch (data_type) {
+ 		case SETUP_E820_EXT:
+-			parse_e820_ext(pa_data, data_len);
++			parse_e820_ext((struct setup_data __force_kernel *)pa_data, data_len);
+ 			break;
+ 		case SETUP_DTB:
+ 			add_dtb(pa_data);
+@@ -768,7 +807,7 @@ static void __init trim_bios_range(void)
+ 	 * area (640->1Mb) as ram even though it is not.
+ 	 * take them out.
+ 	 */
+-	e820_remove_range(BIOS_BEGIN, BIOS_END - BIOS_BEGIN, E820_RAM, 1);
++	e820_remove_range(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, \
E820_RAM, 1); + 
+ 	sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+ }
+@@ -776,7 +815,7 @@ static void __init trim_bios_range(void)
+ /* called before trim_bios_range() to spare extra sanitize */
+ static void __init e820_add_kernel_range(void)
+ {
+-	u64 start = __pa_symbol(_text);
++	u64 start = __pa_symbol(ktla_ktva(_text));
+ 	u64 size = __pa_symbol(_end) - start;
+ 
+ 	/*
+@@ -838,8 +877,12 @@ static void __init trim_low_memory_range(void)
+ 
+ void __init setup_arch(char **cmdline_p)
+ {
++#ifdef CONFIG_X86_32
++	memblock_reserve(LOAD_PHYSICAL_ADDR, __pa_symbol(__bss_stop) - \
LOAD_PHYSICAL_ADDR); ++#else
+ 	memblock_reserve(__pa_symbol(_text),
+ 			 (unsigned long)__bss_stop - (unsigned long)_text);
++#endif
+ 
+ 	early_reserve_initrd();
+ 
+@@ -931,14 +974,14 @@ void __init setup_arch(char **cmdline_p)
+ 
+ 	if (!boot_params.hdr.root_flags)
+ 		root_mountflags &= ~MS_RDONLY;
+-	init_mm.start_code = (unsigned long) _text;
+-	init_mm.end_code = (unsigned long) _etext;
++	init_mm.start_code = ktla_ktva((unsigned long) _text);
++	init_mm.end_code = ktla_ktva((unsigned long) _etext);
+ 	init_mm.end_data = (unsigned long) _edata;
+ 	init_mm.brk = _brk_end;
+ 
+-	code_resource.start = __pa_symbol(_text);
+-	code_resource.end = __pa_symbol(_etext)-1;
+-	data_resource.start = __pa_symbol(_etext);
++	code_resource.start = __pa_symbol(ktla_ktva(_text));
++	code_resource.end = __pa_symbol(ktla_ktva(_etext))-1;
++	data_resource.start = __pa_symbol(_sdata);
+ 	data_resource.end = __pa_symbol(_edata)-1;
+ 	bss_resource.start = __pa_symbol(__bss_start);
+ 	bss_resource.end = __pa_symbol(__bss_stop)-1;
+diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
+index 5cdff03..80fa283 100644
+--- a/arch/x86/kernel/setup_percpu.c
++++ b/arch/x86/kernel/setup_percpu.c
+@@ -21,19 +21,17 @@
+ #include <asm/cpu.h>
+ #include <asm/stackprotector.h>
+ 
+-DEFINE_PER_CPU_READ_MOSTLY(int, cpu_number);
++#ifdef CONFIG_SMP
++DEFINE_PER_CPU_READ_MOSTLY(unsigned int, cpu_number);
+ EXPORT_PER_CPU_SYMBOL(cpu_number);
++#endif
+ 
+-#ifdef CONFIG_X86_64
+ #define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
+-#else
+-#define BOOT_PERCPU_OFFSET 0
+-#endif
+ 
+ DEFINE_PER_CPU(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
+ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
+ 
+-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
++unsigned long __per_cpu_offset[NR_CPUS] __read_only = {
+ 	[0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
+ };
+ EXPORT_SYMBOL(__per_cpu_offset);
+@@ -66,7 +64,7 @@ static bool __init pcpu_need_numa(void)
+ {
+ #ifdef CONFIG_NEED_MULTIPLE_NODES
+ 	pg_data_t *last = NULL;
+-	unsigned int cpu;
++	int cpu;
+ 
+ 	for_each_possible_cpu(cpu) {
+ 		int node = early_cpu_to_node(cpu);
+@@ -155,10 +153,10 @@ static inline void setup_percpu_segment(int cpu)
+ {
+ #ifdef CONFIG_X86_32
+ 	struct desc_struct gdt;
++	unsigned long base = per_cpu_offset(cpu);
+ 
+-	pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF,
+-			0x2 | DESCTYPE_S, 0x8);
+-	gdt.s = 1;
++	pack_descriptor(&gdt, base, (VMALLOC_END - base - 1) >> PAGE_SHIFT,
++			0x83 | DESCTYPE_S, 0xC);
+ 	write_gdt_entry(get_cpu_gdt_table(cpu),
+ 			GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
+ #endif
+@@ -219,6 +217,11 @@ void __init setup_per_cpu_areas(void)
+ 	/* alrighty, percpu areas up and running */
+ 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+ 	for_each_possible_cpu(cpu) {
++#ifdef CONFIG_CC_STACKPROTECTOR
++#ifdef CONFIG_X86_32
++		unsigned long canary = per_cpu(stack_canary.canary, cpu);
++#endif
++#endif
+ 		per_cpu_offset(cpu) = delta + pcpu_unit_offsets[cpu];
+ 		per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
+ 		per_cpu(cpu_number, cpu) = cpu;
+@@ -259,6 +262,12 @@ void __init setup_per_cpu_areas(void)
+ 		 */
+ 		set_cpu_numa_node(cpu, early_cpu_to_node(cpu));
+ #endif
++#ifdef CONFIG_CC_STACKPROTECTOR
++#ifdef CONFIG_X86_32
++		if (!cpu)
++			per_cpu(stack_canary.canary, cpu) = canary;
++#endif
++#endif
+ 		/*
+ 		 * Up to this point, the boot CPU has been using .init.data
+ 		 * area.  Reload any changed state for the boot CPU.
+diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
+index d859eea..44e17c4 100644
+--- a/arch/x86/kernel/signal.c
++++ b/arch/x86/kernel/signal.c
+@@ -190,7 +190,7 @@ static unsigned long align_sigframe(unsigned long sp)
+ 	 * 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;
+ #else /* !CONFIG_X86_32 */
+ 	sp = round_down(sp, 16) - 8;
+ #endif
+@@ -298,9 +298,9 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
+ 	}
+ 
+ 	if (current->mm->context.vdso)
+-		restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
++		restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, \
sigreturn); + 	else
+-		restorer = &frame->retcode;
++		restorer = (void __user *)&frame->retcode;
+ 	if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ 		restorer = ksig->ka.sa.sa_restorer;
+ 
+@@ -314,7 +314,7 @@ __setup_frame(int sig, struct ksignal *ksig, sigset_t *set,
+ 	 * reasons and because gdb uses it as a signature to notice
+ 	 * signal handler stack frames.
+ 	 */
+-	err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);
++	err |= __put_user(*((u64 *)&retcode), (u64 __user *)frame->retcode);
+ 
+ 	if (err)
+ 		return -EFAULT;
+@@ -361,7 +361,10 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
+ 		save_altstack_ex(&frame->uc.uc_stack, regs->sp);
+ 
+ 		/* Set up to return from userspace.  */
+-		restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
++		if (current->mm->context.vdso)
++			restorer = (__force void __user *)VDSO32_SYMBOL(current->mm->context.vdso, \
rt_sigreturn); ++		else
++		restorer = (void __user *)&frame->retcode;
+ 		if (ksig->ka.sa.sa_flags & SA_RESTORER)
+ 			restorer = ksig->ka.sa.sa_restorer;
+ 		put_user_ex(restorer, &frame->pretcode);
+@@ -373,7 +376,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
+ 		 * reasons and because gdb uses it as a signature to notice
+ 		 * signal handler stack frames.
+ 		 */
+-		put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
++		put_user_ex(*((u64 *)&rt_retcode), (u64 __user *)frame->retcode);
+ 	} put_user_catch(err);
+ 	
+ 	err |= copy_siginfo_to_user(&frame->info, &ksig->info);
+@@ -609,7 +612,12 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
+ {
+ 	int usig = signr_convert(ksig->sig);
+ 	sigset_t *set = sigmask_to_save();
+-	compat_sigset_t *cset = (compat_sigset_t *) set;
++	sigset_t sigcopy;
++	compat_sigset_t *cset;
++
++	sigcopy = *set;
++
++	cset = (compat_sigset_t *) &sigcopy;
+ 
+ 	/* Set up the stack frame */
+ 	if (is_ia32_frame()) {
+@@ -620,7 +628,7 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
+ 	} else if (is_x32_frame()) {
+ 		return x32_setup_rt_frame(ksig, cset, regs);
+ 	} else {
+-		return __setup_rt_frame(ksig->sig, ksig, set, regs);
++		return __setup_rt_frame(ksig->sig, ksig, &sigcopy, regs);
+ 	}
+ }
+ 
+diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c
+index cdaa347..f5af55d 100644
+--- a/arch/x86/kernel/smp.c
++++ b/arch/x86/kernel/smp.c
+@@ -341,7 +341,7 @@ static int __init nonmi_ipi_setup(char *str)
+ 
+ __setup("nonmi_ipi", nonmi_ipi_setup);
+ 
+-struct smp_ops smp_ops = {
++struct smp_ops smp_ops __read_only = {
+ 	.smp_prepare_boot_cpu	= native_smp_prepare_boot_cpu,
+ 	.smp_prepare_cpus	= native_smp_prepare_cpus,
+ 	.smp_cpus_done		= native_smp_cpus_done,
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index aecc98a..0244a53 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -251,14 +251,18 @@ static void notrace start_secondary(void *unused)
+ 
+ 	enable_start_cpu0 = 0;
+ 
+-#ifdef CONFIG_X86_32
+-	/* switch away from the initial page table */
+-	load_cr3(swapper_pg_dir);
+-	__flush_tlb_all();
+-#endif
+-
+ 	/* otherwise gcc will move up smp_processor_id before the cpu_init */
+ 	barrier();
++
++	/* switch away from the initial page table */
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	load_cr3(get_cpu_pgd(smp_processor_id(), kernel));
++	__flush_tlb_all();
++#elif defined(CONFIG_X86_32)
++	load_cr3(swapper_pg_dir);
++	__flush_tlb_all();
++#endif
++
+ 	/*
+ 	 * Check TSC synchronization with the BP:
+ 	 */
+@@ -748,6 +752,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct \
*idle) + 	idle->thread.sp = (unsigned long) (((struct pt_regs *)
+ 			  (THREAD_SIZE +  task_stack_page(idle))) - 1);
+ 	per_cpu(current_task, cpu) = idle;
++	per_cpu(current_tinfo, cpu) = &idle->tinfo;
+ 
+ #ifdef CONFIG_X86_32
+ 	/* Stack for startup_32 can be just as for start_secondary onwards */
+@@ -755,11 +760,13 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct \
*idle) + #else
+ 	clear_tsk_thread_flag(idle, TIF_FORK);
+ 	initial_gs = per_cpu_offset(cpu);
+-	per_cpu(kernel_stack, cpu) =
+-		(unsigned long)task_stack_page(idle) -
+-		KERNEL_STACK_OFFSET + THREAD_SIZE;
++	per_cpu(kernel_stack, cpu) = (unsigned long)task_stack_page(idle) - 16 + \
THREAD_SIZE; + #endif
++
++	pax_open_kernel();
+ 	early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
++	pax_close_kernel();
++
+ 	initial_code = (unsigned long)start_secondary;
+ 	stack_start  = idle->thread.sp;
+ 
+@@ -908,6 +915,15 @@ int native_cpu_up(unsigned int cpu, struct task_struct *tidle)
+ 	/* the FPU context is blank, nobody can own it */
+ 	__cpu_disable_lazy_restore(cpu);
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	clone_pgd_range(get_cpu_pgd(cpu, kernel) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++	clone_pgd_range(get_cpu_pgd(cpu, user) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++#endif
++
+ 	err = do_boot_cpu(apicid, cpu, tidle);
+ 	if (err) {
+ 		pr_debug("do_boot_cpu failed %d\n", err);
+diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
+index 9b4d51d..5d28b58 100644
+--- a/arch/x86/kernel/step.c
++++ b/arch/x86/kernel/step.c
+@@ -27,10 +27,10 @@ unsigned long convert_ip_to_linear(struct task_struct *child, \
struct pt_regs *re + 		struct desc_struct *desc;
+ 		unsigned long base;
+ 
+-		seg &= ~7UL;
++		seg >>= 3;
+ 
+ 		mutex_lock(&child->mm->context.lock);
+-		if (unlikely((seg >> 3) >= child->mm->context.size))
++		if (unlikely(seg >= child->mm->context.size))
+ 			addr = -1L; /* bogus selector, access would fault */
+ 		else {
+ 			desc = child->mm->context.ldt + seg;
+@@ -42,7 +42,8 @@ unsigned long convert_ip_to_linear(struct task_struct *child, \
struct pt_regs *re + 			addr += base;
+ 		}
+ 		mutex_unlock(&child->mm->context.lock);
+-	}
++	} else if (seg == __KERNEL_CS || seg == __KERNEXEC_KERNEL_CS)
++		addr = ktla_ktva(addr);
+ 
+ 	return addr;
+ }
+@@ -53,6 +54,9 @@ static int is_setting_trap_flag(struct task_struct *child, struct \
pt_regs *regs) + 	unsigned char opcode[15];
+ 	unsigned long addr = convert_ip_to_linear(child, regs);
+ 
++	if (addr == -EINVAL)
++		return 0;
++
+ 	copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
+ 	for (i = 0; i < copied; i++) {
+ 		switch (opcode[i]) {
+diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
+new file mode 100644
+index 0000000..5877189
+--- /dev/null
++++ b/arch/x86/kernel/sys_i386_32.c
+@@ -0,0 +1,189 @@
++/*
++ * This file contains various random system calls that
++ * have a non-standard calling sequence on the Linux/i386
++ * platform.
++ */
++
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/fs.h>
++#include <linux/smp.h>
++#include <linux/sem.h>
++#include <linux/msg.h>
++#include <linux/shm.h>
++#include <linux/stat.h>
++#include <linux/syscalls.h>
++#include <linux/mman.h>
++#include <linux/file.h>
++#include <linux/utsname.h>
++#include <linux/ipc.h>
++#include <linux/elf.h>
++
++#include <linux/uaccess.h>
++#include <linux/unistd.h>
++
++#include <asm/syscalls.h>
++
++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
++{
++	unsigned long pax_task_size = TASK_SIZE;
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
++		pax_task_size = SEGMEXEC_TASK_SIZE;
++#endif
++
++	if (flags & MAP_FIXED)
++		if (len > pax_task_size || addr > pax_task_size - len)
++			return -EINVAL;
++
++	return 0;
++}
++
++/*
++ * Align a virtual address to avoid aliasing in the I$ on AMD F15h.
++ */
++static unsigned long get_align_mask(void)
++{
++	if (va_align.flags < 0 || !(va_align.flags & ALIGN_VA_32))
++		return 0;
++
++	if (!(current->flags & PF_RANDOMIZE))
++		return 0;
++
++	return va_align.mask;
++}
++
++unsigned long
++arch_get_unmapped_area(struct file *filp, unsigned long addr,
++		unsigned long len, unsigned long pgoff, unsigned long flags)
++{
++	struct mm_struct *mm = current->mm;
++	struct vm_area_struct *vma;
++	unsigned long pax_task_size = TASK_SIZE;
++	struct vm_unmapped_area_info info;
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (mm->pax_flags & MF_PAX_SEGMEXEC)
++		pax_task_size = SEGMEXEC_TASK_SIZE;
++#endif
++
++	pax_task_size -= PAGE_SIZE;
++
++	if (len > pax_task_size)
++		return -ENOMEM;
++
++	if (flags & MAP_FIXED)
++		return addr;
++
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
++	if (addr) {
++		addr = PAGE_ALIGN(addr);
++		if (pax_task_size - len >= addr) {
++			vma = find_vma(mm, addr);
++			if (check_heap_stack_gap(vma, addr, len, offset))
++				return addr;
++		}
++	}
++
++	info.flags = 0;
++	info.length = len;
++	info.align_mask = filp ? get_align_mask() : 0;
++	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++	if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && \
(flags & MAP_EXECUTABLE)) { ++		info.low_limit = 0x00110000UL;
++		info.high_limit = mm->start_code;
++
++#ifdef CONFIG_PAX_RANDMMAP
++		if (mm->pax_flags & MF_PAX_RANDMMAP)
++			info.low_limit += mm->delta_mmap & 0x03FFF000UL;
++#endif
++
++		if (info.low_limit < info.high_limit) {
++			addr = vm_unmapped_area(&info);
++			if (!IS_ERR_VALUE(addr))
++				return addr;
++		}
++	} else
++#endif
++
++	info.low_limit = mm->mmap_base;
++	info.high_limit = pax_task_size;
++
++	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)
++{
++	struct vm_area_struct *vma;
++	struct mm_struct *mm = current->mm;
++	unsigned long addr = addr0, pax_task_size = TASK_SIZE;
++	struct vm_unmapped_area_info info;
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (mm->pax_flags & MF_PAX_SEGMEXEC)
++		pax_task_size = SEGMEXEC_TASK_SIZE;
++#endif
++
++	pax_task_size -= PAGE_SIZE;
++
++	/* requested length too big for entire address space */
++	if (len > pax_task_size)
++		return -ENOMEM;
++
++	if (flags & MAP_FIXED)
++		return addr;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++	if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && \
(flags & MAP_EXECUTABLE)) ++		goto bottomup;
++#endif
++
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
++	/* requesting a specific address */
++	if (addr) {
++		addr = PAGE_ALIGN(addr);
++		if (pax_task_size - len >= addr) {
++			vma = find_vma(mm, addr);
++			if (check_heap_stack_gap(vma, addr, len, offset))
++				return addr;
++		}
++	}
++
++	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
++	info.length = len;
++	info.low_limit = PAGE_SIZE;
++	info.high_limit = mm->mmap_base;
++	info.align_mask = filp ? get_align_mask() : 0;
++	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
++
++	addr = vm_unmapped_area(&info);
++	if (!(addr & ~PAGE_MASK))
++		return addr;
++	VM_BUG_ON(addr != -ENOMEM);
++
++bottomup:
++	/*
++	 * A failed mmap() very likely causes application failure,
++	 * so fall back to the bottom-up function here. This scenario
++	 * can happen with large stack limits and large mmap()
++	 * allocations.
++	 */
++	return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
++}
+diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
+index 30277e2..5664a29 100644
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -81,8 +81,8 @@ out:
+ 	return error;
+ }
+ 
+-static void find_start_end(unsigned long flags, unsigned long *begin,
+-			   unsigned long *end)
++static void find_start_end(struct mm_struct *mm, unsigned long flags,
++			   unsigned long *begin, unsigned long *end)
+ {
+ 	if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT)) {
+ 		unsigned long new_begin;
+@@ -101,7 +101,7 @@ static void find_start_end(unsigned long flags, unsigned long \
*begin, + 				*begin = new_begin;
+ 		}
+ 	} else {
+-		*begin = current->mm->mmap_legacy_base;
++		*begin = mm->mmap_legacy_base;
+ 		*end = TASK_SIZE;
+ 	}
+ }
+@@ -114,20 +114,24 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 	struct vm_area_struct *vma;
+ 	struct vm_unmapped_area_info info;
+ 	unsigned long begin, end;
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ 
+ 	if (flags & MAP_FIXED)
+ 		return addr;
+ 
+-	find_start_end(flags, &begin, &end);
++	find_start_end(mm, flags, &begin, &end);
+ 
+ 	if (len > end)
+ 		return -ENOMEM;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ 	if (addr) {
+ 		addr = PAGE_ALIGN(addr);
+ 		vma = find_vma(mm, addr);
+-		if (end - len >= addr &&
+-		    (!vma || addr + len <= vma->vm_start))
++		if (end - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ 			return addr;
+ 	}
+ 
+@@ -137,6 +141,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ 	info.high_limit = end;
+ 	info.align_mask = filp ? get_align_mask() : 0;
+ 	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
+ 	return vm_unmapped_area(&info);
+ }
+ 
+@@ -149,6 +154,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	struct mm_struct *mm = current->mm;
+ 	unsigned long addr = addr0;
+ 	struct vm_unmapped_area_info info;
++	unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ 
+ 	/* requested length too big for entire address space */
+ 	if (len > TASK_SIZE)
+@@ -161,12 +167,15 @@ arch_get_unmapped_area_topdown(struct file *filp, const \
unsigned long addr0, + 	if (!test_thread_flag(TIF_ADDR32) && (flags & MAP_32BIT))
+ 		goto bottomup;
+ 
++#ifdef CONFIG_PAX_RANDMMAP
++	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ 	/* requesting a specific address */
+ 	if (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;
+ 	}
+ 
+@@ -176,6 +185,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned \
long addr0, + 	info.high_limit = mm->mmap_base;
+ 	info.align_mask = filp ? get_align_mask() : 0;
+ 	info.align_offset = pgoff << PAGE_SHIFT;
++	info.threadstack_offset = offset;
+ 	addr = vm_unmapped_area(&info);
+ 	if (!(addr & ~PAGE_MASK))
+ 		return addr;
+diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
+index addf7b5..f960685 100644
+--- a/arch/x86/kernel/tboot.c
++++ b/arch/x86/kernel/tboot.c
+@@ -221,7 +221,7 @@ static int tboot_setup_sleep(void)
+ 
+ void tboot_shutdown(u32 shutdown_type)
+ {
+-	void (*shutdown)(void);
++	void (* __noreturn shutdown)(void);
+ 
+ 	if (!tboot_enabled())
+ 		return;
+@@ -243,7 +243,7 @@ void tboot_shutdown(u32 shutdown_type)
+ 
+ 	switch_to_tboot_pt();
+ 
+-	shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry;
++	shutdown = (void *)tboot->shutdown_entry;
+ 	shutdown();
+ 
+ 	/* should not reach here */
+@@ -301,7 +301,7 @@ static int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 \
pm1b_control) + 	return 0;
+ }
+ 
+-static atomic_t ap_wfs_count;
++static atomic_unchecked_t ap_wfs_count;
+ 
+ static int tboot_wait_for_aps(int num_aps)
+ {
+@@ -325,9 +325,9 @@ static int tboot_cpu_callback(struct notifier_block *nfb, \
unsigned long action, + {
+ 	switch (action) {
+ 	case CPU_DYING:
+-		atomic_inc(&ap_wfs_count);
++		atomic_inc_unchecked(&ap_wfs_count);
+ 		if (num_online_cpus() == 1)
+-			if (tboot_wait_for_aps(atomic_read(&ap_wfs_count)))
++			if (tboot_wait_for_aps(atomic_read_unchecked(&ap_wfs_count)))
+ 				return NOTIFY_BAD;
+ 		break;
+ 	}
+@@ -413,7 +413,7 @@ static __init int tboot_late_init(void)
+ 
+ 	tboot_create_trampoline();
+ 
+-	atomic_set(&ap_wfs_count, 0);
++	atomic_set_unchecked(&ap_wfs_count, 0);
+ 	register_hotcpu_notifier(&tboot_cpu_notifier);
+ 
+ #ifdef CONFIG_DEBUG_FS
+diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
+index 24d3c91..d06b473 100644
+--- a/arch/x86/kernel/time.c
++++ b/arch/x86/kernel/time.c
+@@ -30,9 +30,9 @@ unsigned long profile_pc(struct pt_regs *regs)
+ {
+ 	unsigned long pc = instruction_pointer(regs);
+ 
+-	if (!user_mode_vm(regs) && in_lock_functions(pc)) {
++	if (!user_mode(regs) && in_lock_functions(pc)) {
+ #ifdef CONFIG_FRAME_POINTER
+-		return *(unsigned long *)(regs->bp + sizeof(long));
++		return ktla_ktva(*(unsigned long *)(regs->bp + sizeof(long)));
+ #else
+ 		unsigned long *sp =
+ 			(unsigned long *)kernel_stack_pointer(regs);
+@@ -41,11 +41,17 @@ unsigned long profile_pc(struct pt_regs *regs)
+ 		 * or above a saved flags. Eflags has bits 22-31 zero,
+ 		 * kernel addresses don't.
+ 		 */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		return ktla_ktva(sp[0]);
++#else
+ 		if (sp[0] >> 22)
+ 			return sp[0];
+ 		if (sp[1] >> 22)
+ 			return sp[1];
+ #endif
++
++#endif
+ 	}
+ 	return pc;
+ }
+diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
+index f7fec09..9991981 100644
+--- a/arch/x86/kernel/tls.c
++++ b/arch/x86/kernel/tls.c
+@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struct *p, int idx,
+ 	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+ 		return -EINVAL;
+ 
++#ifdef CONFIG_PAX_SEGMEXEC
++	if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & \
MODIFY_LDT_CONTENTS_CODE)) ++		return -EINVAL;
++#endif
++
+ 	set_tls_desc(p, idx, &info, 1);
+ 
+ 	return 0;
+@@ -200,7 +205,7 @@ int regset_tls_set(struct task_struct *target, const struct \
user_regset *regset, + 
+ 	if (kbuf)
+ 		info = kbuf;
+-	else if (__copy_from_user(infobuf, ubuf, count))
++	else if (count > sizeof infobuf || __copy_from_user(infobuf, ubuf, count))
+ 		return -EFAULT;
+ 	else
+ 		info = infobuf;
+diff --git a/arch/x86/kernel/tracepoint.c b/arch/x86/kernel/tracepoint.c
+index 1c113db..287b42e 100644
+--- a/arch/x86/kernel/tracepoint.c
++++ b/arch/x86/kernel/tracepoint.c
+@@ -9,11 +9,11 @@
+ #include <linux/atomic.h>
+ 
+ atomic_t trace_idt_ctr = ATOMIC_INIT(0);
+-struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1,
++const struct desc_ptr trace_idt_descr = { NR_VECTORS * 16 - 1,
+ 				(unsigned long) trace_idt_table };
+ 
+ /* No need to be aligned, but done to keep all IDTs defined the same way. */
+-gate_desc trace_idt_table[NR_VECTORS] __page_aligned_bss;
++gate_desc trace_idt_table[NR_VECTORS] __page_aligned_rodata;
+ 
+ static int trace_irq_vector_refcount;
+ static DEFINE_MUTEX(irq_vector_mutex);
+diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
+index 1b23a1c..910de0d 100644
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -65,7 +65,7 @@
+ #include <asm/proto.h>
+ 
+ /* No need to be aligned, but done to keep all IDTs defined the same way. */
+-gate_desc debug_idt_table[NR_VECTORS] __page_aligned_bss;
++gate_desc debug_idt_table[NR_VECTORS] __page_aligned_rodata;
+ #else
+ #include <asm/processor-flags.h>
+ #include <asm/setup.h>
+@@ -74,7 +74,7 @@ asmlinkage int system_call(void);
+ #endif
+ 
+ /* Must be page-aligned because the real IDT is used in a fixmap. */
+-gate_desc idt_table[NR_VECTORS] __page_aligned_bss;
++gate_desc idt_table[NR_VECTORS] __page_aligned_rodata;
+ 
+ DECLARE_BITMAP(used_vectors, NR_VECTORS);
+ EXPORT_SYMBOL_GPL(used_vectors);
+@@ -106,11 +106,11 @@ static inline void preempt_conditional_cli(struct pt_regs \
*regs) + }
+ 
+ static int __kprobes
+-do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
++do_trap_no_signal(struct task_struct *tsk, int trapnr, const char *str,
+ 		  struct pt_regs *regs,	long error_code)
+ {
+ #ifdef CONFIG_X86_32
+-	if (regs->flags & X86_VM_MASK) {
++	if (v8086_mode(regs)) {
+ 		/*
+ 		 * Traps 0, 1, 3, 4, and 5 should be forwarded to vm86.
+ 		 * On nmi (interrupt 2), do_trap should not be called.
+@@ -123,12 +123,24 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char \
*str, + 		return -1;
+ 	}
+ #endif
+-	if (!user_mode(regs)) {
++	if (!user_mode_novm(regs)) {
+ 		if (!fixup_exception(regs)) {
+ 			tsk->thread.error_code = error_code;
+ 			tsk->thread.trap_nr = trapnr;
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++			if (trapnr == 12 && ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) \
== __KERNEXEC_KERNEL_CS)) ++				str = "PAX: suspicious stack segment fault";
++#endif
++
+ 			die(str, regs, error_code);
+ 		}
++
++#ifdef CONFIG_PAX_REFCOUNT
++		if (trapnr == 4)
++			pax_report_refcount_overflow(regs);
++#endif
++
+ 		return 0;
+ 	}
+ 
+@@ -136,7 +148,7 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char \
*str, + }
+ 
+ static void __kprobes
+-do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
++do_trap(int trapnr, int signr, const char *str, struct pt_regs *regs,
+ 	long error_code, siginfo_t *info)
+ {
+ 	struct task_struct *tsk = current;
+@@ -160,7 +172,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
+ 	if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
+ 	    printk_ratelimit()) {
+ 		pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx",
+-			tsk->comm, tsk->pid, str,
++			tsk->comm, task_pid_nr(tsk), str,
+ 			regs->ip, regs->sp, error_code);
+ 		print_vma_addr(" in ", regs->ip);
+ 		pr_cont("\n");
+@@ -276,7 +288,7 @@ do_general_protection(struct pt_regs *regs, long error_code)
+ 	conditional_sti(regs);
+ 
+ #ifdef CONFIG_X86_32
+-	if (regs->flags & X86_VM_MASK) {
++	if (v8086_mode(regs)) {
+ 		local_irq_enable();
+ 		handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
+ 		goto exit;
+@@ -284,18 +296,42 @@ do_general_protection(struct pt_regs *regs, long error_code)
+ #endif
+ 
+ 	tsk = current;
+-	if (!user_mode(regs)) {
++	if (!user_mode_novm(regs)) {
+ 		if (fixup_exception(regs))
+ 			goto exit;
+ 
+ 		tsk->thread.error_code = error_code;
+ 		tsk->thread.trap_nr = X86_TRAP_GP;
+ 		if (notify_die(DIE_GPF, "general protection fault", regs, error_code,
+-			       X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
++			       X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP) {
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		if ((regs->cs & 0xFFFF) == __KERNEL_CS || (regs->cs & 0xFFFF) == \
__KERNEXEC_KERNEL_CS) ++			die("PAX: suspicious general protection fault", regs, \
error_code); ++		else
++#endif
++
+ 			die("general protection fault", regs, error_code);
++		}
+ 		goto exit;
+ 	}
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
++	if (!(__supported_pte_mask & _PAGE_NX) && tsk->mm && (tsk->mm->pax_flags & \
MF_PAX_PAGEEXEC)) { ++		struct mm_struct *mm = tsk->mm;
++		unsigned long limit;
++
++		down_write(&mm->mmap_sem);
++		limit = mm->context.user_cs_limit;
++		if (limit < TASK_SIZE) {
++			track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
++			up_write(&mm->mmap_sem);
++			return;
++		}
++		up_write(&mm->mmap_sem);
++	}
++#endif
++
+ 	tsk->thread.error_code = error_code;
+ 	tsk->thread.trap_nr = X86_TRAP_GP;
+ 
+@@ -453,7 +489,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long \
error_code) + 	/* It's safe to allow irq's after DR6 has been saved */
+ 	preempt_conditional_sti(regs);
+ 
+-	if (regs->flags & X86_VM_MASK) {
++	if (v8086_mode(regs)) {
+ 		handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code,
+ 					X86_TRAP_DB);
+ 		preempt_conditional_cli(regs);
+@@ -468,7 +504,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long \
error_code) + 	 * We already checked v86 mode above, so we can check for kernel mode
+ 	 * by just checking the CPL of CS.
+ 	 */
+-	if ((dr6 & DR_STEP) && !user_mode(regs)) {
++	if ((dr6 & DR_STEP) && !user_mode_novm(regs)) {
+ 		tsk->thread.debugreg6 &= ~DR_STEP;
+ 		set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+ 		regs->flags &= ~X86_EFLAGS_TF;
+@@ -500,7 +536,7 @@ void math_error(struct pt_regs *regs, int error_code, int \
trapnr) + 		return;
+ 	conditional_sti(regs);
+ 
+-	if (!user_mode_vm(regs))
++	if (!user_mode(regs))
+ 	{
+ 		if (!fixup_exception(regs)) {
+ 			task->thread.error_code = error_code;
+diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
+index 2ed8459..7cf329f 100644
+--- a/arch/x86/kernel/uprobes.c
++++ b/arch/x86/kernel/uprobes.c
+@@ -629,7 +629,7 @@ int arch_uprobe_exception_notify(struct notifier_block *self, \
unsigned long val, + 	int ret = NOTIFY_DONE;
+ 
+ 	/* We are only interested in userspace traps */
+-	if (regs && !user_mode_vm(regs))
++	if (regs && !user_mode(regs))
+ 		return NOTIFY_DONE;
+ 
+ 	switch (val) {
+@@ -719,7 +719,7 @@ arch_uretprobe_hijack_return_addr(unsigned long \
trampoline_vaddr, struct pt_regs + 
+ 	if (ncopied != rasize) {
+ 		pr_err("uprobe: return address clobbered: pid=%d, %%sp=%#lx, "
+-			"%%ip=%#lx\n", current->pid, regs->sp, regs->ip);
++			"%%ip=%#lx\n", task_pid_nr(current), regs->sp, regs->ip);
+ 
+ 		force_sig_info(SIGSEGV, SEND_SIG_FORCED, current);
+ 	}
+diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
+index b9242ba..50c5edd 100644
+--- a/arch/x86/kernel/verify_cpu.S
++++ b/arch/x86/kernel/verify_cpu.S
+@@ -20,6 +20,7 @@
+  *	arch/x86/boot/compressed/head_64.S: Boot cpu verification
+  *	arch/x86/kernel/trampoline_64.S: secondary processor verification
+  *	arch/x86/kernel/head_32.S: processor startup
++ *	arch/x86/kernel/acpi/realmode/wakeup.S: 32bit processor resume
+  *
+  *	verify_cpu, returns the status of longmode and SSE in register %eax.
+  *		0: Success    1: Failure
+diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
+index e8edcf5..27f9344 100644
+--- a/arch/x86/kernel/vm86_32.c
++++ b/arch/x86/kernel/vm86_32.c
+@@ -44,6 +44,7 @@
+ #include <linux/ptrace.h>
+ #include <linux/audit.h>
+ #include <linux/stddef.h>
++#include <linux/grsecurity.h>
+ 
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -150,7 +151,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs)
+ 		do_exit(SIGSEGV);
+ 	}
+ 
+-	tss = &per_cpu(init_tss, get_cpu());
++	tss = init_tss + get_cpu();
+ 	current->thread.sp0 = current->thread.saved_sp0;
+ 	current->thread.sysenter_cs = __KERNEL_CS;
+ 	load_sp0(tss, &current->thread);
+@@ -214,6 +215,14 @@ SYSCALL_DEFINE1(vm86old, struct vm86_struct __user *, v86)
+ 
+ 	if (tsk->thread.saved_sp0)
+ 		return -EPERM;
++
++#ifdef CONFIG_GRKERNSEC_VM86
++	if (!capable(CAP_SYS_RAWIO)) {
++		gr_handle_vm86();
++		return -EPERM;
++	}
++#endif
++
+ 	tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
+ 				       offsetof(struct kernel_vm86_struct, vm86plus) -
+ 				       sizeof(info.regs));
+@@ -238,6 +247,13 @@ SYSCALL_DEFINE2(vm86, unsigned long, cmd, unsigned long, arg)
+ 	int tmp;
+ 	struct vm86plus_struct __user *v86;
+ 
++#ifdef CONFIG_GRKERNSEC_VM86
++	if (!capable(CAP_SYS_RAWIO)) {
++		gr_handle_vm86();
++		return -EPERM;
++	}
++#endif
++
+ 	tsk = current;
+ 	switch (cmd) {
+ 	case VM86_REQUEST_IRQ:
+@@ -318,7 +334,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct \
task_struct *tsk + 	tsk->thread.saved_fs = info->regs32->fs;
+ 	tsk->thread.saved_gs = get_user_gs(info->regs32);
+ 
+-	tss = &per_cpu(init_tss, get_cpu());
++	tss = init_tss + get_cpu();
+ 	tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
+ 	if (cpu_has_sep)
+ 		tsk->thread.sysenter_cs = 0;
+@@ -525,7 +541,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
+ 		goto cannot_handle;
+ 	if (i == 0x21 && is_revectored(AH(regs), &KVM86->int21_revectored))
+ 		goto cannot_handle;
+-	intr_ptr = (unsigned long __user *) (i << 2);
++	intr_ptr = (__force unsigned long __user *) (i << 2);
+ 	if (get_user(segoffs, intr_ptr))
+ 		goto cannot_handle;
+ 	if ((segoffs >> 16) == BIOSSEG)
+diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
+index 10c4f30..65408b9 100644
+--- a/arch/x86/kernel/vmlinux.lds.S
++++ b/arch/x86/kernel/vmlinux.lds.S
+@@ -26,6 +26,13 @@
+ #include <asm/page_types.h>
+ #include <asm/cache.h>
+ #include <asm/boot.h>
++#include <asm/segment.h>
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++#define __KERNEL_TEXT_OFFSET	(LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR)
++#else
++#define __KERNEL_TEXT_OFFSET	0
++#endif
+ 
+ #undef i386     /* in case the preprocessor is a 32bit one */
+ 
+@@ -69,30 +76,43 @@ jiffies_64 = jiffies;
+ 
+ PHDRS {
+ 	text PT_LOAD FLAGS(5);          /* R_E */
++#ifdef CONFIG_X86_32
++	module PT_LOAD FLAGS(5);        /* R_E */
++#endif
++#ifdef CONFIG_XEN
++	rodata PT_LOAD FLAGS(5);        /* R_E */
++#else
++	rodata PT_LOAD FLAGS(4);        /* R__ */
++#endif
+ 	data PT_LOAD FLAGS(6);          /* RW_ */
+-#ifdef CONFIG_X86_64
++	init.begin PT_LOAD FLAGS(6);    /* RW_ */
+ #ifdef CONFIG_SMP
+ 	percpu PT_LOAD FLAGS(6);        /* RW_ */
+ #endif
++	text.init PT_LOAD FLAGS(5);     /* R_E */
++	text.exit PT_LOAD FLAGS(5);     /* R_E */
+ 	init PT_LOAD FLAGS(7);          /* RWE */
+-#endif
+ 	note PT_NOTE FLAGS(0);          /* ___ */
+ }
+ 
+ SECTIONS
+ {
+ #ifdef CONFIG_X86_32
+-        . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
+-        phys_startup_32 = startup_32 - LOAD_OFFSET;
++	. = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
+ #else
+-        . = __START_KERNEL;
+-        phys_startup_64 = startup_64 - LOAD_OFFSET;
++	. = __START_KERNEL;
+ #endif
+ 
+ 	/* Text and read-only data */
+-	.text :  AT(ADDR(.text) - LOAD_OFFSET) {
+-		_text = .;
++	.text (. - __KERNEL_TEXT_OFFSET): AT(ADDR(.text) - LOAD_OFFSET + \
__KERNEL_TEXT_OFFSET) { + 		/* bootstrapping code */
++#ifdef CONFIG_X86_32
++		phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
++#else
++		phys_startup_64 = startup_64 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
++#endif
++		__LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
++		_text = .;
+ 		HEAD_TEXT
+ 		. = ALIGN(8);
+ 		_stext = .;
+@@ -104,13 +124,47 @@ SECTIONS
+ 		IRQENTRY_TEXT
+ 		*(.fixup)
+ 		*(.gnu.warning)
+-		/* End of text section */
+-		_etext = .;
+ 	} :text = 0x9090
+ 
+-	NOTES :text :note
++	. += __KERNEL_TEXT_OFFSET;
+ 
+-	EXCEPTION_TABLE(16) :text = 0x9090
++#ifdef CONFIG_X86_32
++	. = ALIGN(PAGE_SIZE);
++	.module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
++
++#ifdef CONFIG_PAX_KERNEXEC
++		MODULES_EXEC_VADDR = .;
++		BYTE(0)
++		. += (CONFIG_PAX_KERNEXEC_MODULE_TEXT * 1024 * 1024);
++		. = ALIGN(HPAGE_SIZE) - 1;
++		MODULES_EXEC_END = .;
++#endif
++
++	} :module
++#endif
++
++	.text.end : AT(ADDR(.text.end) - LOAD_OFFSET) {
++		/* End of text section */
++		BYTE(0)
++		_etext = . - __KERNEL_TEXT_OFFSET;
++	}
++
++#ifdef CONFIG_X86_32
++	. = ALIGN(PAGE_SIZE);
++	.rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
++		. = ALIGN(PAGE_SIZE);
++		*(.empty_zero_page)
++		*(.initial_pg_fixmap)
++		*(.initial_pg_pmd)
++		*(.initial_page_table)
++		*(.swapper_pg_dir)
++	} :rodata
++#endif
++
++	. = ALIGN(PAGE_SIZE);
++	NOTES :rodata :note
++
++	EXCEPTION_TABLE(16) :rodata
+ 
+ #if defined(CONFIG_DEBUG_RODATA)
+ 	/* .text should occupy whole number of pages */
+@@ -122,16 +176,20 @@ SECTIONS
+ 
+ 	/* Data */
+ 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
++
++#ifdef CONFIG_PAX_KERNEXEC
++		. = ALIGN(HPAGE_SIZE);
++#else
++		. = ALIGN(PAGE_SIZE);
++#endif
++
+ 		/* Start of data section */
+ 		_sdata = .;
+ 
+ 		/* init_task */
+ 		INIT_TASK_DATA(THREAD_SIZE)
+ 
+-#ifdef CONFIG_X86_32
+-		/* 32 bit has nosave before _edata */
+ 		NOSAVE_DATA
+-#endif
+ 
+ 		PAGE_ALIGNED_DATA(PAGE_SIZE)
+ 
+@@ -172,12 +230,19 @@ SECTIONS
+ #endif /* CONFIG_X86_64 */
+ 
+ 	/* Init code and data - will be freed after init */
+-	. = ALIGN(PAGE_SIZE);
+ 	.init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
++		BYTE(0)
++
++#ifdef CONFIG_PAX_KERNEXEC
++		. = ALIGN(HPAGE_SIZE);
++#else
++		. = ALIGN(PAGE_SIZE);
++#endif
++
+ 		__init_begin = .; /* paired with __init_end */
+-	}
++	} :init.begin
+ 
+-#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
++#ifdef CONFIG_SMP
+ 	/*
+ 	 * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
+ 	 * output PHDR, so the next output section - .init.text - should
+@@ -186,12 +251,27 @@ SECTIONS
+ 	PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
+ #endif
+ 
+-	INIT_TEXT_SECTION(PAGE_SIZE)
+-#ifdef CONFIG_X86_64
+-	:init
+-#endif
++	. = ALIGN(PAGE_SIZE);
++	init_begin = .;
++	.init.text (. - __KERNEL_TEXT_OFFSET): AT(init_begin - LOAD_OFFSET) {
++		VMLINUX_SYMBOL(_sinittext) = .;
++		INIT_TEXT
++		VMLINUX_SYMBOL(_einittext) = .;
++		. = ALIGN(PAGE_SIZE);
++	} :text.init
+ 
+-	INIT_DATA_SECTION(16)
++	/*
++	 * .exit.text is discard at runtime, not link time, to deal with
++	 *  references from .altinstructions and .eh_frame
++	 */
++	.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
++		EXIT_TEXT
++		. = ALIGN(16);
++	} :text.exit
++	. = init_begin + SIZEOF(.init.text) + SIZEOF(.exit.text);
++
++	. = ALIGN(PAGE_SIZE);
++	INIT_DATA_SECTION(16) :init
+ 
+ 	.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
+ 		__x86_cpu_dev_start = .;
+@@ -253,19 +333,12 @@ SECTIONS
+ 	}
+ 
+ 	. = ALIGN(8);
+-	/*
+-	 * .exit.text is discard at runtime, not link time, to deal with
+-	 *  references from .altinstructions and .eh_frame
+-	 */
+-	.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
+-		EXIT_TEXT
+-	}
+ 
+ 	.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
+ 		EXIT_DATA
+ 	}
+ 
+-#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
++#ifndef CONFIG_SMP
+ 	PERCPU_SECTION(INTERNODE_CACHE_BYTES)
+ #endif
+ 
+@@ -284,16 +357,10 @@ SECTIONS
+ 	.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+ 		__smp_locks = .;
+ 		*(.smp_locks)
+-		. = ALIGN(PAGE_SIZE);
+ 		__smp_locks_end = .;
++		. = ALIGN(PAGE_SIZE);
+ 	}
+ 
+-#ifdef CONFIG_X86_64
+-	.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+-		NOSAVE_DATA
+-	}
+-#endif
+-
+ 	/* BSS */
+ 	. = ALIGN(PAGE_SIZE);
+ 	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+@@ -309,6 +376,7 @@ SECTIONS
+ 		__brk_base = .;
+ 		. += 64 * 1024;		/* 64k alignment slop space */
+ 		*(.brk_reservation)	/* areas brk users have reserved */
++		. = ALIGN(HPAGE_SIZE);
+ 		__brk_limit = .;
+ 	}
+ 
+@@ -335,13 +403,12 @@ SECTIONS
+  * for the boot processor.
+  */
+ #define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
+-INIT_PER_CPU(gdt_page);
+ INIT_PER_CPU(irq_stack_union);
+ 
+ /*
+  * Build-time check on the image size:
+  */
+-. = ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
++. = ASSERT((_end - _text - __KERNEL_TEXT_OFFSET <= KERNEL_IMAGE_SIZE),
+ 	   "kernel image bigger than KERNEL_IMAGE_SIZE");
+ 
+ #ifdef CONFIG_SMP
+diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
+index 1f96f93..d5c8f7a 100644
+--- a/arch/x86/kernel/vsyscall_64.c
++++ b/arch/x86/kernel/vsyscall_64.c
+@@ -56,15 +56,13 @@
+ DEFINE_VVAR(int, vgetcpu_mode);
+ DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data);
+ 
+-static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
++static enum { EMULATE, NONE } vsyscall_mode = EMULATE;
+ 
+ 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
+@@ -323,8 +321,7 @@ do_ret:
+ 	return true;
+ 
+ sigsegv:
+-	force_sig(SIGSEGV, current);
+-	return true;
++	do_group_exit(SIGKILL);
+ }
+ 
+ /*
+@@ -377,10 +374,7 @@ void __init map_vsyscall(void)
+ 	extern char __vvar_page;
+ 	unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page);
+ 
+-	__set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall,
+-		     vsyscall_mode == NATIVE
+-		     ? PAGE_KERNEL_VSYSCALL
+-		     : PAGE_KERNEL_VVAR);
++	__set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall, PAGE_KERNEL_VVAR);
+ 	BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_FIRST_PAGE) !=
+ 		     (unsigned long)VSYSCALL_START);
+ 
+diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
+index b014d94..e775258 100644
+--- a/arch/x86/kernel/x8664_ksyms_64.c
++++ b/arch/x86/kernel/x8664_ksyms_64.c
+@@ -34,8 +34,6 @@ EXPORT_SYMBOL(copy_user_generic_string);
+ EXPORT_SYMBOL(copy_user_generic_unrolled);
+ EXPORT_SYMBOL(copy_user_enhanced_fast_string);
+ EXPORT_SYMBOL(__copy_user_nocache);
+-EXPORT_SYMBOL(_copy_from_user);
+-EXPORT_SYMBOL(_copy_to_user);
+ 
+ EXPORT_SYMBOL(copy_page);
+ EXPORT_SYMBOL(clear_page);
+@@ -66,3 +64,7 @@ EXPORT_SYMBOL(empty_zero_page);
+ #ifndef CONFIG_PARAVIRT
+ EXPORT_SYMBOL(native_load_gs_index);
+ #endif
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++EXPORT_SYMBOL(cpu_pgd);
++#endif
+diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
+index 5f24c71..1dadf09 100644
+--- a/arch/x86/kernel/x86_init.c
++++ b/arch/x86/kernel/x86_init.c
+@@ -93,7 +93,7 @@ struct x86_cpuinit_ops x86_cpuinit = {
+ static void default_nmi_init(void) { };
+ static int default_i8042_detect(void) { return 1; };
+ 
+-struct x86_platform_ops x86_platform = {
++struct x86_platform_ops x86_platform __read_only = {
+ 	.calibrate_tsc			= native_calibrate_tsc,
+ 	.get_wallclock			= mach_get_cmos_time,
+ 	.set_wallclock			= mach_set_rtc_mmss,
+@@ -107,7 +107,7 @@ struct x86_platform_ops x86_platform = {
+ };
+ 
+ EXPORT_SYMBOL_GPL(x86_platform);
+-struct x86_msi_ops x86_msi = {
++struct x86_msi_ops x86_msi __read_only = {
+ 	.setup_msi_irqs		= native_setup_msi_irqs,
+ 	.compose_msi_msg	= native_compose_msi_msg,
+ 	.teardown_msi_irq	= native_teardown_msi_irq,
+@@ -116,7 +116,7 @@ struct x86_msi_ops x86_msi = {
+ 	.setup_hpet_msi		= default_setup_hpet_msi,
+ };
+ 
+-struct x86_io_apic_ops x86_io_apic_ops = {
++struct x86_io_apic_ops x86_io_apic_ops __read_only = {
+ 	.init			= native_io_apic_init_mappings,
+ 	.read			= native_io_apic_read,
+ 	.write			= native_io_apic_write,
+diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
+index 422fd82..c3687ca 100644
+--- a/arch/x86/kernel/xsave.c
++++ b/arch/x86/kernel/xsave.c
+@@ -199,6 +199,7 @@ static inline int save_user_xstate(struct xsave_struct __user \
*buf) + {
+ 	int err;
+ 
++	buf = (struct xsave_struct __user *)____m(buf);
+ 	if (use_xsave())
+ 		err = xsave_user(buf);
+ 	else if (use_fxsr())
+@@ -311,6 +312,7 @@ sanitize_restored_xstate(struct task_struct *tsk,
+  */
+ static inline int restore_user_xstate(void __user *buf, u64 xbv, int fx_only)
+ {
++	buf = (void __user *)____m(buf);
+ 	if (use_xsave()) {
+ 		if ((unsigned long)buf % 64 || fx_only) {
+ 			u64 init_bv = pcntxt_mask & ~XSTATE_FPSSE;
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index a20ecb5..d0e2194 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -124,15 +124,20 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
+ 			      struct kvm_cpuid2 *cpuid,
+ 			      struct kvm_cpuid_entry2 __user *entries)
+ {
+-	int r;
++	int r, i;
+ 
+ 	r = -E2BIG;
+ 	if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
+ 		goto out;
+ 	r = -EFAULT;
+-	if (copy_from_user(&vcpu->arch.cpuid_entries, entries,
+-			   cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
++	if (!access_ok(VERIFY_READ, entries, cpuid->nent * sizeof(struct \
kvm_cpuid_entry2))) + 		goto out;
++	for (i = 0; i < cpuid->nent; ++i) {
++		struct kvm_cpuid_entry2 cpuid_entry;
++		if (__copy_from_user(&cpuid_entry, entries + i, sizeof(cpuid_entry)))
++			goto out;
++		vcpu->arch.cpuid_entries[i] = cpuid_entry;
++	}
+ 	vcpu->arch.cpuid_nent = cpuid->nent;
+ 	kvm_apic_set_version(vcpu);
+ 	kvm_x86_ops->cpuid_update(vcpu);
+@@ -147,15 +152,19 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
+ 			      struct kvm_cpuid2 *cpuid,
+ 			      struct kvm_cpuid_entry2 __user *entries)
+ {
+-	int r;
++	int r, i;
+ 
+ 	r = -E2BIG;
+ 	if (cpuid->nent < vcpu->arch.cpuid_nent)
+ 		goto out;
+ 	r = -EFAULT;
+-	if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
+-			 vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
++	if (!access_ok(VERIFY_WRITE, entries, vcpu->arch.cpuid_nent * sizeof(struct \
kvm_cpuid_entry2))) + 		goto out;
++	for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
++		struct kvm_cpuid_entry2 cpuid_entry = vcpu->arch.cpuid_entries[i];
++		if (__copy_to_user(entries + i, &cpuid_entry, sizeof(cpuid_entry)))
++			goto out;
++	}
+ 	return 0;
+ 
+ out:
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index afc1124..3e431f2 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -55,7 +55,7 @@
+ #define APIC_BUS_CYCLE_NS 1
+ 
+ /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
+-#define apic_debug(fmt, arg...)
++#define apic_debug(fmt, arg...) do {} while (0)
+ 
+ #define APIC_LVT_NUM			6
+ /* 14 is the version for Xeon and Pentium 8.4.8*/
+diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
+index 7769699..c8aca4a7f 100644
+--- a/arch/x86/kvm/paging_tmpl.h
++++ b/arch/x86/kvm/paging_tmpl.h
+@@ -208,7 +208,7 @@ retry_walk:
+ 		if (unlikely(kvm_is_error_hva(host_addr)))
+ 			goto error;
+ 
+-		ptep_user = (pt_element_t __user *)((void *)host_addr + offset);
++		ptep_user = (pt_element_t __force_user *)((void *)host_addr + offset);
+ 		if (unlikely(__copy_from_user(&pte, ptep_user, sizeof(pte))))
+ 			goto error;
+ 		walker->ptep_user[walker->level - 1] = ptep_user;
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index c0bc803..6837a50 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -3501,7 +3501,11 @@ static void reload_tss(struct kvm_vcpu *vcpu)
+ 	int cpu = raw_smp_processor_id();
+ 
+ 	struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
++
++	pax_open_kernel();
+ 	sd->tss_desc->type = 9; /* available 32/64-bit TSS */
++	pax_close_kernel();
++
+ 	load_TR_desc();
+ }
+ 
+@@ -3902,6 +3906,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ #endif
+ #endif
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	__set_fs(current_thread_info()->addr_limit);
++#endif
++
+ 	reload_tss(vcpu);
+ 
+ 	local_irq_disable();
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 064d0be..f5f758e 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1311,12 +1311,12 @@ static void vmcs_write64(unsigned long field, u64 value)
+ #endif
+ }
+ 
+-static void vmcs_clear_bits(unsigned long field, u32 mask)
++static void vmcs_clear_bits(unsigned long field, unsigned long mask)
+ {
+ 	vmcs_writel(field, vmcs_readl(field) & ~mask);
+ }
+ 
+-static void vmcs_set_bits(unsigned long field, u32 mask)
++static void vmcs_set_bits(unsigned long field, unsigned long mask)
+ {
+ 	vmcs_writel(field, vmcs_readl(field) | mask);
+ }
+@@ -1517,7 +1517,11 @@ static void reload_tss(void)
+ 	struct desc_struct *descs;
+ 
+ 	descs = (void *)gdt->address;
++
++	pax_open_kernel();
+ 	descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
++	pax_close_kernel();
++
+ 	load_TR_desc();
+ }
+ 
+@@ -1741,6 +1745,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ 		vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
+ 		vmcs_writel(HOST_GDTR_BASE, gdt->address);   /* 22.2.4 */
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		vmcs_writel(HOST_CR3, read_cr3());  /* 22.2.3  FIXME: shadow tables */
++#endif
++
+ 		rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
+ 		vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
+ 		vmx->loaded_vmcs->cpu = cpu;
+@@ -2940,8 +2948,11 @@ static __init int hardware_setup(void)
+ 	if (!cpu_has_vmx_flexpriority())
+ 		flexpriority_enabled = 0;
+ 
+-	if (!cpu_has_vmx_tpr_shadow())
+-		kvm_x86_ops->update_cr8_intercept = NULL;
++	if (!cpu_has_vmx_tpr_shadow()) {
++		pax_open_kernel();
++		*(void **)&kvm_x86_ops->update_cr8_intercept = NULL;
++		pax_close_kernel();
++	}
+ 
+ 	if (enable_ept && !cpu_has_vmx_ept_2m_page())
+ 		kvm_disable_largepages();
+@@ -2952,13 +2963,15 @@ static __init int hardware_setup(void)
+ 	if (!cpu_has_vmx_apicv())
+ 		enable_apicv = 0;
+ 
++	pax_open_kernel();
+ 	if (enable_apicv)
+-		kvm_x86_ops->update_cr8_intercept = NULL;
++		*(void **)&kvm_x86_ops->update_cr8_intercept = NULL;
+ 	else {
+-		kvm_x86_ops->hwapic_irr_update = NULL;
+-		kvm_x86_ops->deliver_posted_interrupt = NULL;
+-		kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
++		*(void **)&kvm_x86_ops->hwapic_irr_update = NULL;
++		*(void **)&kvm_x86_ops->deliver_posted_interrupt = NULL;
++		*(void **)&kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
+ 	}
++	pax_close_kernel();
+ 
+ 	if (nested)
+ 		nested_vmx_setup_ctls_msrs();
+@@ -4081,7 +4094,10 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
+ 
+ 	vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS);  /* 22.2.3 */
+ 	vmcs_writel(HOST_CR4, read_cr4());  /* 22.2.3, 22.2.5 */
++
++#ifndef CONFIG_PAX_PER_CPU_PGD
+ 	vmcs_writel(HOST_CR3, read_cr3());  /* 22.2.3  FIXME: shadow tables */
++#endif
+ 
+ 	vmcs_write16(HOST_CS_SELECTOR, __KERNEL_CS);  /* 22.2.4 */
+ #ifdef CONFIG_X86_64
+@@ -4103,7 +4119,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
+ 	vmcs_writel(HOST_IDTR_BASE, dt.address);   /* 22.2.4 */
+ 	vmx->host_idt_base = dt.address;
+ 
+-	vmcs_writel(HOST_RIP, vmx_return); /* 22.2.5 */
++	vmcs_writel(HOST_RIP, ktla_ktva(vmx_return)); /* 22.2.5 */
+ 
+ 	rdmsr(MSR_IA32_SYSENTER_CS, low32, high32);
+ 	vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
+@@ -7039,6 +7055,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ 		"jmp 2f \n\t"
+ 		"1: " __ex(ASM_VMX_VMRESUME) "\n\t"
+ 		"2: "
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		"ljmp %[cs],$3f\n\t"
++		"3: "
++#endif
++
+ 		/* Save guest registers, load host registers, keep flags */
+ 		"mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"
+ 		"pop %0 \n\t"
+@@ -7091,6 +7113,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ #endif
+ 		[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
+ 		[wordsize]"i"(sizeof(ulong))
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		,[cs]"i"(__KERNEL_CS)
++#endif
++
+ 	      : "cc", "memory"
+ #ifdef CONFIG_X86_64
+ 		, "rax", "rbx", "rdi", "rsi"
+@@ -7104,7 +7131,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ 	if (debugctlmsr)
+ 		update_debugctlmsr(debugctlmsr);
+ 
+-#ifndef CONFIG_X86_64
++#ifdef CONFIG_X86_32
+ 	/*
+ 	 * The sysexit path does not restore ds/es, so we must set them to
+ 	 * a reasonable value ourselves.
+@@ -7113,8 +7140,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ 	 * may be executed in interrupt context, which saves and restore segments
+ 	 * around it, nullifying its effect.
+ 	 */
+-	loadsegment(ds, __USER_DS);
+-	loadsegment(es, __USER_DS);
++	loadsegment(ds, __KERNEL_DS);
++	loadsegment(es, __KERNEL_DS);
++	loadsegment(ss, __KERNEL_DS);
++
++#ifdef CONFIG_PAX_KERNEXEC
++	loadsegment(fs, __KERNEL_PERCPU);
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	__set_fs(current_thread_info()->addr_limit);
++#endif
++
+ #endif
+ 
+ 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index d21bce5..fdae9f1 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1766,8 +1766,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
+ {
+ 	struct kvm *kvm = vcpu->kvm;
+ 	int lm = is_long_mode(vcpu);
+-	u8 *blob_addr = lm ? (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_64
+-		: (u8 *)(long)kvm->arch.xen_hvm_config.blob_addr_32;
++	u8 __user *blob_addr = lm ? (u8 __user \
*)(long)kvm->arch.xen_hvm_config.blob_addr_64 ++		: (u8 __user \
*)(long)kvm->arch.xen_hvm_config.blob_addr_32; + 	u8 blob_size = lm ? \
kvm->arch.xen_hvm_config.blob_size_64 + 		: kvm->arch.xen_hvm_config.blob_size_32;
+ 	u32 page_num = data & ~PAGE_MASK;
+@@ -2650,6 +2650,8 @@ long kvm_arch_dev_ioctl(struct file *filp,
+ 		if (n < msr_list.nmsrs)
+ 			goto out;
+ 		r = -EFAULT;
++		if (num_msrs_to_save > ARRAY_SIZE(msrs_to_save))
++			goto out;
+ 		if (copy_to_user(user_msr_list->indices, &msrs_to_save,
+ 				 num_msrs_to_save * sizeof(u32)))
+ 			goto out;
+@@ -5344,7 +5346,7 @@ static struct notifier_block pvclock_gtod_notifier = {
+ };
+ #endif
+ 
+-int kvm_arch_init(void *opaque)
++int kvm_arch_init(const void *opaque)
+ {
+ 	int r;
+ 	struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
+diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
+index 6a22c19..1763f04 100644
+--- a/arch/x86/lguest/boot.c
++++ b/arch/x86/lguest/boot.c
+@@ -1201,9 +1201,10 @@ static __init int early_put_chars(u32 vtermno, const char \
*buf, int count) +  * Rebooting also tells the Host we're finished, but the RESTART \
flag tells the +  * Launcher to reboot us.
+  */
+-static void lguest_restart(char *reason)
++static __noreturn void lguest_restart(char *reason)
+ {
+ 	hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
++	BUG();
+ }
+ 
+ /*G:050
+diff --git a/arch/x86/lib/atomic64_386_32.S b/arch/x86/lib/atomic64_386_32.S
+index 00933d5..3a64af9 100644
+--- a/arch/x86/lib/atomic64_386_32.S
++++ b/arch/x86/lib/atomic64_386_32.S
+@@ -48,6 +48,10 @@ BEGIN(read)
+ 	movl  (v), %eax
+ 	movl 4(v), %edx
+ RET_ENDP
++BEGIN(read_unchecked)
++	movl  (v), %eax
++	movl 4(v), %edx
++RET_ENDP
+ #undef v
+ 
+ #define v %esi
+@@ -55,6 +59,10 @@ BEGIN(set)
+ 	movl %ebx,  (v)
+ 	movl %ecx, 4(v)
+ RET_ENDP
++BEGIN(set_unchecked)
++	movl %ebx,  (v)
++	movl %ecx, 4(v)
++RET_ENDP
+ #undef v
+ 
+ #define v  %esi
+@@ -70,6 +78,20 @@ RET_ENDP
+ BEGIN(add)
+ 	addl %eax,  (v)
+ 	adcl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 0f
++	subl %eax,  (v)
++	sbbl %edx, 4(v)
++	int $4
++0:
++	_ASM_EXTABLE(0b, 0b)
++#endif
++
++RET_ENDP
++BEGIN(add_unchecked)
++	addl %eax,  (v)
++	adcl %edx, 4(v)
+ RET_ENDP
+ #undef v
+ 
+@@ -77,6 +99,24 @@ RET_ENDP
+ BEGIN(add_return)
+ 	addl  (v), %eax
+ 	adcl 4(v), %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
++	movl %eax,  (v)
++	movl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++2:
++#endif
++
++RET_ENDP
++BEGIN(add_return_unchecked)
++	addl  (v), %eax
++	adcl 4(v), %edx
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+ RET_ENDP
+@@ -86,6 +126,20 @@ RET_ENDP
+ BEGIN(sub)
+ 	subl %eax,  (v)
+ 	sbbl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 0f
++	addl %eax,  (v)
++	adcl %edx, 4(v)
++	int $4
++0:
++	_ASM_EXTABLE(0b, 0b)
++#endif
++
++RET_ENDP
++BEGIN(sub_unchecked)
++	subl %eax,  (v)
++	sbbl %edx, 4(v)
+ RET_ENDP
+ #undef v
+ 
+@@ -96,6 +150,27 @@ BEGIN(sub_return)
+ 	sbbl $0, %edx
+ 	addl  (v), %eax
+ 	adcl 4(v), %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
++	movl %eax,  (v)
++	movl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++2:
++#endif
++
++RET_ENDP
++BEGIN(sub_return_unchecked)
++	negl %edx
++	negl %eax
++	sbbl $0, %edx
++	addl  (v), %eax
++	adcl 4(v), %edx
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+ RET_ENDP
+@@ -105,6 +180,20 @@ RET_ENDP
+ BEGIN(inc)
+ 	addl $1,  (v)
+ 	adcl $0, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 0f
++	subl $1,  (v)
++	sbbl $0, 4(v)
++	int $4
++0:
++	_ASM_EXTABLE(0b, 0b)
++#endif
++
++RET_ENDP
++BEGIN(inc_unchecked)
++	addl $1,  (v)
++	adcl $0, 4(v)
+ RET_ENDP
+ #undef v
+ 
+@@ -114,6 +203,26 @@ BEGIN(inc_return)
+ 	movl 4(v), %edx
+ 	addl $1, %eax
+ 	adcl $0, %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
++	movl %eax,  (v)
++	movl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++2:
++#endif
++
++RET_ENDP
++BEGIN(inc_return_unchecked)
++	movl  (v), %eax
++	movl 4(v), %edx
++	addl $1, %eax
++	adcl $0, %edx
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+ RET_ENDP
+@@ -123,6 +232,20 @@ RET_ENDP
+ BEGIN(dec)
+ 	subl $1,  (v)
+ 	sbbl $0, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 0f
++	addl $1,  (v)
++	adcl $0, 4(v)
++	int $4
++0:
++	_ASM_EXTABLE(0b, 0b)
++#endif
++
++RET_ENDP
++BEGIN(dec_unchecked)
++	subl $1,  (v)
++	sbbl $0, 4(v)
+ RET_ENDP
+ #undef v
+ 
+@@ -132,6 +255,26 @@ BEGIN(dec_return)
+ 	movl 4(v), %edx
+ 	subl $1, %eax
+ 	sbbl $0, %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
++	movl %eax,  (v)
++	movl %edx, 4(v)
++
++#ifdef CONFIG_PAX_REFCOUNT
++2:
++#endif
++
++RET_ENDP
++BEGIN(dec_return_unchecked)
++	movl  (v), %eax
++	movl 4(v), %edx
++	subl $1, %eax
++	sbbl $0, %edx
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+ RET_ENDP
+@@ -143,6 +286,13 @@ BEGIN(add_unless)
+ 	adcl %edx, %edi
+ 	addl  (v), %eax
+ 	adcl 4(v), %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
+ 	cmpl %eax, %ecx
+ 	je 3f
+ 1:
+@@ -168,6 +318,13 @@ BEGIN(inc_not_zero)
+ 1:
+ 	addl $1, %eax
+ 	adcl $0, %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+ 	movl $1, %eax
+@@ -186,6 +343,13 @@ BEGIN(dec_if_positive)
+ 	movl 4(v), %edx
+ 	subl $1, %eax
+ 	sbbl $0, %edx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 1f)
++#endif
++
+ 	js 1f
+ 	movl %eax,  (v)
+ 	movl %edx, 4(v)
+diff --git a/arch/x86/lib/atomic64_cx8_32.S b/arch/x86/lib/atomic64_cx8_32.S
+index f5cc9eb..51fa319 100644
+--- a/arch/x86/lib/atomic64_cx8_32.S
++++ b/arch/x86/lib/atomic64_cx8_32.S
+@@ -35,10 +35,20 @@ ENTRY(atomic64_read_cx8)
+ 	CFI_STARTPROC
+ 
+ 	read64 %ecx
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(atomic64_read_cx8)
+ 
++ENTRY(atomic64_read_unchecked_cx8)
++	CFI_STARTPROC
++
++	read64 %ecx
++	pax_force_retaddr
++	ret
++	CFI_ENDPROC
++ENDPROC(atomic64_read_unchecked_cx8)
++
+ ENTRY(atomic64_set_cx8)
+ 	CFI_STARTPROC
+ 
+@@ -48,10 +58,25 @@ ENTRY(atomic64_set_cx8)
+ 	cmpxchg8b (%esi)
+ 	jne 1b
+ 
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(atomic64_set_cx8)
+ 
++ENTRY(atomic64_set_unchecked_cx8)
++	CFI_STARTPROC
++
++1:
++/* we don't need LOCK_PREFIX since aligned 64-bit writes
++ * are atomic on 586 and newer */
++	cmpxchg8b (%esi)
++	jne 1b
++
++	pax_force_retaddr
++	ret
++	CFI_ENDPROC
++ENDPROC(atomic64_set_unchecked_cx8)
++
+ ENTRY(atomic64_xchg_cx8)
+ 	CFI_STARTPROC
+ 
+@@ -60,12 +85,13 @@ ENTRY(atomic64_xchg_cx8)
+ 	cmpxchg8b (%esi)
+ 	jne 1b
+ 
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(atomic64_xchg_cx8)
+ 
+-.macro addsub_return func ins insc
+-ENTRY(atomic64_\func\()_return_cx8)
++.macro addsub_return func ins insc unchecked=""
++ENTRY(atomic64_\func\()_return\unchecked\()_cx8)
+ 	CFI_STARTPROC
+ 	SAVE ebp
+ 	SAVE ebx
+@@ -82,27 +108,44 @@ ENTRY(atomic64_\func\()_return_cx8)
+ 	movl %edx, %ecx
+ 	\ins\()l %esi, %ebx
+ 	\insc\()l %edi, %ecx
++
++.ifb \unchecked
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++2:
++	_ASM_EXTABLE(2b, 3f)
++#endif
++.endif
++
+ 	LOCK_PREFIX
+ 	cmpxchg8b (%ebp)
+ 	jne 1b
+-
+-10:
+ 	movl %ebx, %eax
+ 	movl %ecx, %edx
++
++.ifb \unchecked
++#ifdef CONFIG_PAX_REFCOUNT
++3:
++#endif
++.endif
++
+ 	RESTORE edi
+ 	RESTORE esi
+ 	RESTORE ebx
+ 	RESTORE ebp
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-ENDPROC(atomic64_\func\()_return_cx8)
++ENDPROC(atomic64_\func\()_return\unchecked\()_cx8)
+ .endm
+ 
+ addsub_return add add adc
+ addsub_return sub sub sbb
++addsub_return add add adc _unchecked
++addsub_return sub sub sbb _unchecked
+ 
+-.macro incdec_return func ins insc
+-ENTRY(atomic64_\func\()_return_cx8)
++.macro incdec_return func ins insc unchecked=""
++ENTRY(atomic64_\func\()_return\unchecked\()_cx8)
+ 	CFI_STARTPROC
+ 	SAVE ebx
+ 
+@@ -112,21 +155,39 @@ ENTRY(atomic64_\func\()_return_cx8)
+ 	movl %edx, %ecx
+ 	\ins\()l $1, %ebx
+ 	\insc\()l $0, %ecx
++
++.ifb \unchecked
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++2:
++	_ASM_EXTABLE(2b, 3f)
++#endif
++.endif
++
+ 	LOCK_PREFIX
+ 	cmpxchg8b (%esi)
+ 	jne 1b
+ 
+-10:
+ 	movl %ebx, %eax
+ 	movl %ecx, %edx
++
++.ifb \unchecked
++#ifdef CONFIG_PAX_REFCOUNT
++3:
++#endif
++.endif
++
+ 	RESTORE ebx
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+-ENDPROC(atomic64_\func\()_return_cx8)
++ENDPROC(atomic64_\func\()_return\unchecked\()_cx8)
+ .endm
+ 
+ incdec_return inc add adc
+ incdec_return dec sub sbb
++incdec_return inc add adc _unchecked
++incdec_return dec sub sbb _unchecked
+ 
+ ENTRY(atomic64_dec_if_positive_cx8)
+ 	CFI_STARTPROC
+@@ -138,6 +199,13 @@ ENTRY(atomic64_dec_if_positive_cx8)
+ 	movl %edx, %ecx
+ 	subl $1, %ebx
+ 	sbb $0, %ecx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 2f)
++#endif
++
+ 	js 2f
+ 	LOCK_PREFIX
+ 	cmpxchg8b (%esi)
+@@ -147,6 +215,7 @@ ENTRY(atomic64_dec_if_positive_cx8)
+ 	movl %ebx, %eax
+ 	movl %ecx, %edx
+ 	RESTORE ebx
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(atomic64_dec_if_positive_cx8)
+@@ -171,6 +240,13 @@ ENTRY(atomic64_add_unless_cx8)
+ 	movl %edx, %ecx
+ 	addl %ebp, %ebx
+ 	adcl %edi, %ecx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 3f)
++#endif
++
+ 	LOCK_PREFIX
+ 	cmpxchg8b (%esi)
+ 	jne 1b
+@@ -181,6 +257,7 @@ ENTRY(atomic64_add_unless_cx8)
+ 	CFI_ADJUST_CFA_OFFSET -8
+ 	RESTORE ebx
+ 	RESTORE ebp
++	pax_force_retaddr
+ 	ret
+ 4:
+ 	cmpl %edx, 4(%esp)
+@@ -203,6 +280,13 @@ ENTRY(atomic64_inc_not_zero_cx8)
+ 	xorl %ecx, %ecx
+ 	addl $1, %ebx
+ 	adcl %edx, %ecx
++
++#ifdef CONFIG_PAX_REFCOUNT
++	into
++1234:
++	_ASM_EXTABLE(1234b, 3f)
++#endif
++
+ 	LOCK_PREFIX
+ 	cmpxchg8b (%esi)
+ 	jne 1b
+@@ -210,6 +294,7 @@ ENTRY(atomic64_inc_not_zero_cx8)
+ 	movl $1, %eax
+ 3:
+ 	RESTORE ebx
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(atomic64_inc_not_zero_cx8)
+diff --git a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S
+index e78b8ee..7e173a8 100644
+--- a/arch/x86/lib/checksum_32.S
++++ b/arch/x86/lib/checksum_32.S
+@@ -29,7 +29,8 @@
+ #include <asm/dwarf2.h>
+ #include <asm/errno.h>
+ #include <asm/asm.h>
+-				
++#include <asm/segment.h>
++
+ /*
+  * computes a partial checksum, e.g. for TCP/UDP fragments
+  */
+@@ -293,9 +294,24 @@ unsigned int csum_partial_copy_generic (const char *src, char \
*dst, + 
+ #define ARGBASE 16		
+ #define FP		12
+-		
+-ENTRY(csum_partial_copy_generic)
++
++ENTRY(csum_partial_copy_generic_to_user)
+ 	CFI_STARTPROC
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pushl_cfi %gs
++	popl_cfi %es
++	jmp csum_partial_copy_generic
++#endif
++
++ENTRY(csum_partial_copy_generic_from_user)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pushl_cfi %gs
++	popl_cfi %ds
++#endif
++
++ENTRY(csum_partial_copy_generic)
+ 	subl  $4,%esp	
+ 	CFI_ADJUST_CFA_OFFSET 4
+ 	pushl_cfi %edi
+@@ -317,7 +333,7 @@ ENTRY(csum_partial_copy_generic)
+ 	jmp 4f
+ SRC(1:	movw (%esi), %bx	)
+ 	addl $2, %esi
+-DST(	movw %bx, (%edi)	)
++DST(	movw %bx, %es:(%edi)	)
+ 	addl $2, %edi
+ 	addw %bx, %ax	
+ 	adcl $0, %eax
+@@ -329,30 +345,30 @@ DST(	movw %bx, (%edi)	)
+ SRC(1:	movl (%esi), %ebx	)
+ SRC(	movl 4(%esi), %edx	)
+ 	adcl %ebx, %eax
+-DST(	movl %ebx, (%edi)	)
++DST(	movl %ebx, %es:(%edi)	)
+ 	adcl %edx, %eax
+-DST(	movl %edx, 4(%edi)	)
++DST(	movl %edx, %es:4(%edi)	)
+ 
+ SRC(	movl 8(%esi), %ebx	)
+ SRC(	movl 12(%esi), %edx	)
+ 	adcl %ebx, %eax
+-DST(	movl %ebx, 8(%edi)	)
++DST(	movl %ebx, %es:8(%edi)	)
+ 	adcl %edx, %eax
+-DST(	movl %edx, 12(%edi)	)
++DST(	movl %edx, %es:12(%edi)	)
+ 
+ SRC(	movl 16(%esi), %ebx 	)
+ SRC(	movl 20(%esi), %edx	)
+ 	adcl %ebx, %eax
+-DST(	movl %ebx, 16(%edi)	)
++DST(	movl %ebx, %es:16(%edi)	)
+ 	adcl %edx, %eax
+-DST(	movl %edx, 20(%edi)	)
++DST(	movl %edx, %es:20(%edi)	)
+ 
+ SRC(	movl 24(%esi), %ebx	)
+ SRC(	movl 28(%esi), %edx	)
+ 	adcl %ebx, %eax
+-DST(	movl %ebx, 24(%edi)	)
++DST(	movl %ebx, %es:24(%edi)	)
+ 	adcl %edx, %eax
+-DST(	movl %edx, 28(%edi)	)
++DST(	movl %edx, %es:28(%edi)	)
+ 
+ 	lea 32(%esi), %esi
+ 	lea 32(%edi), %edi
+@@ -366,7 +382,7 @@ DST(	movl %edx, 28(%edi)	)
+ 	shrl $2, %edx			# This clears CF
+ SRC(3:	movl (%esi), %ebx	)
+ 	adcl %ebx, %eax
+-DST(	movl %ebx, (%edi)	)
++DST(	movl %ebx, %es:(%edi)	)
+ 	lea 4(%esi), %esi
+ 	lea 4(%edi), %edi
+ 	dec %edx
+@@ -378,12 +394,12 @@ DST(	movl %ebx, (%edi)	)
+ 	jb 5f
+ SRC(	movw (%esi), %cx	)
+ 	leal 2(%esi), %esi
+-DST(	movw %cx, (%edi)	)
++DST(	movw %cx, %es:(%edi)	)
+ 	leal 2(%edi), %edi
+ 	je 6f
+ 	shll $16,%ecx
+ SRC(5:	movb (%esi), %cl	)
+-DST(	movb %cl, (%edi)	)
++DST(	movb %cl, %es:(%edi)	)
+ 6:	addl %ecx, %eax
+ 	adcl $0, %eax
+ 7:
+@@ -394,7 +410,7 @@ DST(	movb %cl, (%edi)	)
+ 
+ 6001:
+ 	movl ARGBASE+20(%esp), %ebx	# src_err_ptr
+-	movl $-EFAULT, (%ebx)
++	movl $-EFAULT, %ss:(%ebx)
+ 
+ 	# zero the complete destination - computing the rest
+ 	# is too much work 
+@@ -407,11 +423,15 @@ DST(	movb %cl, (%edi)	)
+ 
+ 6002:
+ 	movl ARGBASE+24(%esp), %ebx	# dst_err_ptr
+-	movl $-EFAULT,(%ebx)
++	movl $-EFAULT,%ss:(%ebx)
+ 	jmp 5000b
+ 
+ .previous
+ 
++	pushl_cfi %ss
++	popl_cfi %ds
++	pushl_cfi %ss
++	popl_cfi %es
+ 	popl_cfi %ebx
+ 	CFI_RESTORE ebx
+ 	popl_cfi %esi
+@@ -421,26 +441,43 @@ DST(	movb %cl, (%edi)	)
+ 	popl_cfi %ecx			# equivalent to addl $4,%esp
+ 	ret	
+ 	CFI_ENDPROC
+-ENDPROC(csum_partial_copy_generic)
++ENDPROC(csum_partial_copy_generic_to_user)
+ 
+ #else
+ 
+ /* Version for PentiumII/PPro */
+ 
+ #define ROUND1(x) \
++	nop; nop; nop;				\
+ 	SRC(movl x(%esi), %ebx	)	;	\
+ 	addl %ebx, %eax			;	\
+-	DST(movl %ebx, x(%edi)	)	; 
++	DST(movl %ebx, %es:x(%edi))	;
+ 
+ #define ROUND(x) \
++	nop; nop; nop;				\
+ 	SRC(movl x(%esi), %ebx	)	;	\
+ 	adcl %ebx, %eax			;	\
+-	DST(movl %ebx, x(%edi)	)	;
++	DST(movl %ebx, %es:x(%edi))	;
+ 
+ #define ARGBASE 12
+-		
+-ENTRY(csum_partial_copy_generic)
++
++ENTRY(csum_partial_copy_generic_to_user)
+ 	CFI_STARTPROC
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pushl_cfi %gs
++	popl_cfi %es
++	jmp csum_partial_copy_generic
++#endif
++
++ENTRY(csum_partial_copy_generic_from_user)
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pushl_cfi %gs
++	popl_cfi %ds
++#endif
++
++ENTRY(csum_partial_copy_generic)
+ 	pushl_cfi %ebx
+ 	CFI_REL_OFFSET ebx, 0
+ 	pushl_cfi %edi
+@@ -461,7 +498,7 @@ ENTRY(csum_partial_copy_generic)
+ 	subl %ebx, %edi  
+ 	lea  -1(%esi),%edx
+ 	andl $-32,%edx
+-	lea 3f(%ebx,%ebx), %ebx
++	lea 3f(%ebx,%ebx,2), %ebx
+ 	testl %esi, %esi 
+ 	jmp *%ebx
+ 1:	addl $64,%esi
+@@ -482,19 +519,19 @@ ENTRY(csum_partial_copy_generic)
+ 	jb 5f
+ SRC(	movw (%esi), %dx         )
+ 	leal 2(%esi), %esi
+-DST(	movw %dx, (%edi)         )
++DST(	movw %dx, %es:(%edi)     )
+ 	leal 2(%edi), %edi
+ 	je 6f
+ 	shll $16,%edx
+ 5:
+ SRC(	movb (%esi), %dl         )
+-DST(	movb %dl, (%edi)         )
++DST(	movb %dl, %es:(%edi)     )
+ 6:	addl %edx, %eax
+ 	adcl $0, %eax
+ 7:
+ .section .fixup, "ax"
+ 6001:	movl	ARGBASE+20(%esp), %ebx	# src_err_ptr	
+-	movl $-EFAULT, (%ebx)
++	movl $-EFAULT, %ss:(%ebx)
+ 	# zero the complete destination (computing the rest is too much work)
+ 	movl ARGBASE+8(%esp),%edi	# dst
+ 	movl ARGBASE+12(%esp),%ecx	# len
+@@ -502,10 +539,17 @@ DST(	movb %dl, (%edi)         )
+ 	rep; stosb
+ 	jmp 7b
+ 6002:	movl ARGBASE+24(%esp), %ebx	# dst_err_ptr
+-	movl $-EFAULT, (%ebx)
++	movl $-EFAULT, %ss:(%ebx)
+ 	jmp  7b			
+ .previous				
+ 
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	pushl_cfi %ss
++	popl_cfi %ds
++	pushl_cfi %ss
++	popl_cfi %es
++#endif
++
+ 	popl_cfi %esi
+ 	CFI_RESTORE esi
+ 	popl_cfi %edi
+@@ -514,7 +558,7 @@ DST(	movb %dl, (%edi)         )
+ 	CFI_RESTORE ebx
+ 	ret
+ 	CFI_ENDPROC
+-ENDPROC(csum_partial_copy_generic)
++ENDPROC(csum_partial_copy_generic_to_user)
+ 				
+ #undef ROUND
+ #undef ROUND1		
+diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S
+index f2145cf..cea889d 100644
+--- a/arch/x86/lib/clear_page_64.S
++++ b/arch/x86/lib/clear_page_64.S
+@@ -11,6 +11,7 @@ ENTRY(clear_page_c)
+ 	movl $4096/8,%ecx
+ 	xorl %eax,%eax
+ 	rep stosq
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(clear_page_c)
+@@ -20,6 +21,7 @@ ENTRY(clear_page_c_e)
+ 	movl $4096,%ecx
+ 	xorl %eax,%eax
+ 	rep stosb
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(clear_page_c_e)
+@@ -43,6 +45,7 @@ ENTRY(clear_page)
+ 	leaq	64(%rdi),%rdi
+ 	jnz	.Lloop
+ 	nop
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ .Lclear_page_end:
+@@ -58,7 +61,7 @@ ENDPROC(clear_page)
+ 
+ #include <asm/cpufeature.h>
+ 
+-	.section .altinstr_replacement,"ax"
++	.section .altinstr_replacement,"a"
+ 1:	.byte 0xeb					/* jmp <disp8> */
+ 	.byte (clear_page_c - clear_page) - (2f - 1b)	/* offset */
+ 2:	.byte 0xeb					/* jmp <disp8> */
+diff --git a/arch/x86/lib/cmpxchg16b_emu.S b/arch/x86/lib/cmpxchg16b_emu.S
+index 1e572c5..2a162cd 100644
+--- a/arch/x86/lib/cmpxchg16b_emu.S
++++ b/arch/x86/lib/cmpxchg16b_emu.S
+@@ -53,11 +53,13 @@ this_cpu_cmpxchg16b_emu:
+ 
+ 	popf
+ 	mov $1, %al
++	pax_force_retaddr
+ 	ret
+ 
+  not_same:
+ 	popf
+ 	xor %al,%al
++	pax_force_retaddr
+ 	ret
+ 
+ CFI_ENDPROC
+diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
+index 176cca6..1166c50 100644
+--- a/arch/x86/lib/copy_page_64.S
++++ b/arch/x86/lib/copy_page_64.S
+@@ -9,6 +9,7 @@ copy_page_rep:
+ 	CFI_STARTPROC
+ 	movl	$4096/8, %ecx
+ 	rep	movsq
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(copy_page_rep)
+@@ -20,12 +21,14 @@ ENDPROC(copy_page_rep)
+ 
+ ENTRY(copy_page)
+ 	CFI_STARTPROC
+-	subq	$2*8,	%rsp
+-	CFI_ADJUST_CFA_OFFSET 2*8
++	subq	$3*8,	%rsp
++	CFI_ADJUST_CFA_OFFSET 3*8
+ 	movq	%rbx,	(%rsp)
+ 	CFI_REL_OFFSET rbx, 0
+ 	movq	%r12,	1*8(%rsp)
+ 	CFI_REL_OFFSET r12, 1*8
++	movq	%r13,	2*8(%rsp)
++	CFI_REL_OFFSET r13, 2*8
+ 
+ 	movl	$(4096/64)-5,	%ecx
+ 	.p2align 4
+@@ -36,7 +39,7 @@ ENTRY(copy_page)
+ 	movq	0x8*2(%rsi), %rdx
+ 	movq	0x8*3(%rsi), %r8
+ 	movq	0x8*4(%rsi), %r9
+-	movq	0x8*5(%rsi), %r10
++	movq	0x8*5(%rsi), %r13
+ 	movq	0x8*6(%rsi), %r11
+ 	movq	0x8*7(%rsi), %r12
+ 
+@@ -47,7 +50,7 @@ ENTRY(copy_page)
+ 	movq	%rdx, 0x8*2(%rdi)
+ 	movq	%r8,  0x8*3(%rdi)
+ 	movq	%r9,  0x8*4(%rdi)
+-	movq	%r10, 0x8*5(%rdi)
++	movq	%r13, 0x8*5(%rdi)
+ 	movq	%r11, 0x8*6(%rdi)
+ 	movq	%r12, 0x8*7(%rdi)
+ 
+@@ -66,7 +69,7 @@ ENTRY(copy_page)
+ 	movq	0x8*2(%rsi), %rdx
+ 	movq	0x8*3(%rsi), %r8
+ 	movq	0x8*4(%rsi), %r9
+-	movq	0x8*5(%rsi), %r10
++	movq	0x8*5(%rsi), %r13
+ 	movq	0x8*6(%rsi), %r11
+ 	movq	0x8*7(%rsi), %r12
+ 
+@@ -75,7 +78,7 @@ ENTRY(copy_page)
+ 	movq	%rdx, 0x8*2(%rdi)
+ 	movq	%r8,  0x8*3(%rdi)
+ 	movq	%r9,  0x8*4(%rdi)
+-	movq	%r10, 0x8*5(%rdi)
++	movq	%r13, 0x8*5(%rdi)
+ 	movq	%r11, 0x8*6(%rdi)
+ 	movq	%r12, 0x8*7(%rdi)
+ 
+@@ -87,8 +90,11 @@ ENTRY(copy_page)
+ 	CFI_RESTORE rbx
+ 	movq	1*8(%rsp), %r12
+ 	CFI_RESTORE r12
+-	addq	$2*8, %rsp
+-	CFI_ADJUST_CFA_OFFSET -2*8
++	movq	2*8(%rsp), %r13
++	CFI_RESTORE r13
++	addq	$3*8, %rsp
++	CFI_ADJUST_CFA_OFFSET -3*8
++	pax_force_retaddr
+ 	ret
+ .Lcopy_page_end:
+ 	CFI_ENDPROC
+@@ -99,7 +105,7 @@ ENDPROC(copy_page)
+ 
+ #include <asm/cpufeature.h>
+ 
+-	.section .altinstr_replacement,"ax"
++	.section .altinstr_replacement,"a"
+ 1:	.byte 0xeb					/* jmp <disp8> */
+ 	.byte (copy_page_rep - copy_page) - (2f - 1b)	/* offset */
+ 2:
+diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
+index a30ca15..6b3f4e1 100644
+--- a/arch/x86/lib/copy_user_64.S
++++ b/arch/x86/lib/copy_user_64.S
+@@ -18,31 +18,7 @@
+ #include <asm/alternative-asm.h>
+ #include <asm/asm.h>
+ #include <asm/smap.h>
+-
+-/*
+- * By placing feature2 after feature1 in altinstructions section, we logically
+- * implement:
+- * If CPU has feature2, jmp to alt2 is used
+- * else if CPU has feature1, jmp to alt1 is used
+- * else jmp to orig is used.
+- */
+-	.macro ALTERNATIVE_JUMP feature1,feature2,orig,alt1,alt2
+-0:
+-	.byte 0xe9	/* 32bit jump */
+-	.long \orig-1f	/* by default jump to orig */
+-1:
+-	.section .altinstr_replacement,"ax"
+-2:	.byte 0xe9			/* near jump with 32bit immediate */
+-	.long \alt1-1b /* offset */   /* or alternatively to alt1 */
+-3:	.byte 0xe9			/* near jump with 32bit immediate */
+-	.long \alt2-1b /* offset */   /* or alternatively to alt2 */
+-	.previous
+-
+-	.section .altinstructions,"a"
+-	altinstruction_entry 0b,2b,\feature1,5,5
+-	altinstruction_entry 0b,3b,\feature2,5,5
+-	.previous
+-	.endm
++#include <asm/pgtable.h>
+ 
+ 	.macro ALIGN_DESTINATION
+ #ifdef FIX_ALIGNMENT
+@@ -70,52 +46,6 @@
+ #endif
+ 	.endm
+ 
+-/* Standard copy_to_user with segment limit checking */
+-ENTRY(_copy_to_user)
+-	CFI_STARTPROC
+-	GET_THREAD_INFO(%rax)
+-	movq %rdi,%rcx
+-	addq %rdx,%rcx
+-	jc bad_to_user
+-	cmpq TI_addr_limit(%rax),%rcx
+-	ja bad_to_user
+-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,X86_FEATURE_ERMS,	\
+-		copy_user_generic_unrolled,copy_user_generic_string,	\
+-		copy_user_enhanced_fast_string
+-	CFI_ENDPROC
+-ENDPROC(_copy_to_user)
+-
+-/* Standard copy_from_user with segment limit checking */
+-ENTRY(_copy_from_user)
+-	CFI_STARTPROC
+-	GET_THREAD_INFO(%rax)
+-	movq %rsi,%rcx
+-	addq %rdx,%rcx
+-	jc bad_from_user
+-	cmpq TI_addr_limit(%rax),%rcx
+-	ja bad_from_user
+-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,X86_FEATURE_ERMS,	\
+-		copy_user_generic_unrolled,copy_user_generic_string,	\
+-		copy_user_enhanced_fast_string
+-	CFI_ENDPROC
+-ENDPROC(_copy_from_user)
+-
+-	.section .fixup,"ax"
+-	/* must zero dest */
+-ENTRY(bad_from_user)
+-bad_from_user:
+-	CFI_STARTPROC
+-	movl %edx,%ecx
+-	xorl %eax,%eax
+-	rep
+-	stosb
+-bad_to_user:
+-	movl %edx,%eax
+-	ret
+-	CFI_ENDPROC
+-ENDPROC(bad_from_user)
+-	.previous
+-
+ /*
+  * copy_user_generic_unrolled - memory copy with exception handling.
+  * This version is for CPUs like P4 that don't have efficient micro
+@@ -131,6 +61,7 @@ ENDPROC(bad_from_user)
+  */
+ ENTRY(copy_user_generic_unrolled)
+ 	CFI_STARTPROC
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	cmpl $8,%edx
+ 	jb 20f		/* less then 8 bytes, go to byte copy loop */
+@@ -141,19 +72,19 @@ ENTRY(copy_user_generic_unrolled)
+ 	jz 17f
+ 1:	movq (%rsi),%r8
+ 2:	movq 1*8(%rsi),%r9
+-3:	movq 2*8(%rsi),%r10
++3:	movq 2*8(%rsi),%rax
+ 4:	movq 3*8(%rsi),%r11
+ 5:	movq %r8,(%rdi)
+ 6:	movq %r9,1*8(%rdi)
+-7:	movq %r10,2*8(%rdi)
++7:	movq %rax,2*8(%rdi)
+ 8:	movq %r11,3*8(%rdi)
+ 9:	movq 4*8(%rsi),%r8
+ 10:	movq 5*8(%rsi),%r9
+-11:	movq 6*8(%rsi),%r10
++11:	movq 6*8(%rsi),%rax
+ 12:	movq 7*8(%rsi),%r11
+ 13:	movq %r8,4*8(%rdi)
+ 14:	movq %r9,5*8(%rdi)
+-15:	movq %r10,6*8(%rdi)
++15:	movq %rax,6*8(%rdi)
+ 16:	movq %r11,7*8(%rdi)
+ 	leaq 64(%rsi),%rsi
+ 	leaq 64(%rdi),%rdi
+@@ -180,6 +111,8 @@ ENTRY(copy_user_generic_unrolled)
+ 	jnz 21b
+ 23:	xor %eax,%eax
+ 	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
++	pax_force_retaddr
+ 	ret
+ 
+ 	.section .fixup,"ax"
+@@ -235,6 +168,7 @@ ENDPROC(copy_user_generic_unrolled)
+  */
+ ENTRY(copy_user_generic_string)
+ 	CFI_STARTPROC
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	andl %edx,%edx
+ 	jz 4f
+@@ -251,6 +185,8 @@ ENTRY(copy_user_generic_string)
+ 	movsb
+ 4:	xorl %eax,%eax
+ 	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
++	pax_force_retaddr
+ 	ret
+ 
+ 	.section .fixup,"ax"
+@@ -278,6 +214,7 @@ ENDPROC(copy_user_generic_string)
+  */
+ ENTRY(copy_user_enhanced_fast_string)
+ 	CFI_STARTPROC
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	andl %edx,%edx
+ 	jz 2f
+@@ -286,6 +223,8 @@ ENTRY(copy_user_enhanced_fast_string)
+ 	movsb
+ 2:	xorl %eax,%eax
+ 	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
++	pax_force_retaddr
+ 	ret
+ 
+ 	.section .fixup,"ax"
+diff --git a/arch/x86/lib/copy_user_nocache_64.S \
b/arch/x86/lib/copy_user_nocache_64.S +index 6a4f43c..55d26f2 100644
+--- a/arch/x86/lib/copy_user_nocache_64.S
++++ b/arch/x86/lib/copy_user_nocache_64.S
+@@ -8,6 +8,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/dwarf2.h>
++#include <asm/alternative-asm.h>
+ 
+ #define FIX_ALIGNMENT 1
+ 
+@@ -16,6 +17,7 @@
+ #include <asm/thread_info.h>
+ #include <asm/asm.h>
+ #include <asm/smap.h>
++#include <asm/pgtable.h>
+ 
+ 	.macro ALIGN_DESTINATION
+ #ifdef FIX_ALIGNMENT
+@@ -49,6 +51,16 @@
+  */
+ ENTRY(__copy_user_nocache)
+ 	CFI_STARTPROC
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	mov pax_user_shadow_base,%rcx
++	cmp %rcx,%rsi
++	jae 1f
++	add %rcx,%rsi
++1:
++#endif
++
++	ASM_PAX_OPEN_USERLAND
+ 	ASM_STAC
+ 	cmpl $8,%edx
+ 	jb 20f		/* less then 8 bytes, go to byte copy loop */
+@@ -59,19 +71,19 @@ ENTRY(__copy_user_nocache)
+ 	jz 17f
+ 1:	movq (%rsi),%r8
+ 2:	movq 1*8(%rsi),%r9
+-3:	movq 2*8(%rsi),%r10
++3:	movq 2*8(%rsi),%rax
+ 4:	movq 3*8(%rsi),%r11
+ 5:	movnti %r8,(%rdi)
+ 6:	movnti %r9,1*8(%rdi)
+-7:	movnti %r10,2*8(%rdi)
++7:	movnti %rax,2*8(%rdi)
+ 8:	movnti %r11,3*8(%rdi)
+ 9:	movq 4*8(%rsi),%r8
+ 10:	movq 5*8(%rsi),%r9
+-11:	movq 6*8(%rsi),%r10
++11:	movq 6*8(%rsi),%rax
+ 12:	movq 7*8(%rsi),%r11
+ 13:	movnti %r8,4*8(%rdi)
+ 14:	movnti %r9,5*8(%rdi)
+-15:	movnti %r10,6*8(%rdi)
++15:	movnti %rax,6*8(%rdi)
+ 16:	movnti %r11,7*8(%rdi)
+ 	leaq 64(%rsi),%rsi
+ 	leaq 64(%rdi),%rdi
+@@ -98,7 +110,9 @@ ENTRY(__copy_user_nocache)
+ 	jnz 21b
+ 23:	xorl %eax,%eax
+ 	ASM_CLAC
++	ASM_PAX_CLOSE_USERLAND
+ 	sfence
++	pax_force_retaddr
+ 	ret
+ 
+ 	.section .fixup,"ax"
+diff --git a/arch/x86/lib/csum-copy_64.S b/arch/x86/lib/csum-copy_64.S
+index 2419d5f..953ee51 100644
+--- a/arch/x86/lib/csum-copy_64.S
++++ b/arch/x86/lib/csum-copy_64.S
+@@ -9,6 +9,7 @@
+ #include <asm/dwarf2.h>
+ #include <asm/errno.h>
+ #include <asm/asm.h>
++#include <asm/alternative-asm.h>
+ 
+ /*
+  * Checksum copy with exception handling.
+@@ -220,6 +221,7 @@ ENTRY(csum_partial_copy_generic)
+ 	CFI_RESTORE rbp
+ 	addq $7*8, %rsp
+ 	CFI_ADJUST_CFA_OFFSET -7*8
++	pax_force_retaddr 0, 1
+ 	ret
+ 	CFI_RESTORE_STATE
+ 
+diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c
+index 7609e0e..b449b98 100644
+--- a/arch/x86/lib/csum-wrappers_64.c
++++ b/arch/x86/lib/csum-wrappers_64.c
+@@ -53,10 +53,12 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
+ 			len -= 2;
+ 		}
+ 	}
++	pax_open_userland();
+ 	stac();
+-	isum = csum_partial_copy_generic((__force const void *)src,
++	isum = csum_partial_copy_generic((const void __force_kernel *)____m(src),
+ 				dst, len, isum, errp, NULL);
+ 	clac();
++	pax_close_userland();
+ 	if (unlikely(*errp))
+ 		goto out_err;
+ 
+@@ -110,10 +112,12 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
+ 	}
+ 
+ 	*errp = 0;
++	pax_open_userland();
+ 	stac();
+-	ret = csum_partial_copy_generic(src, (void __force *)dst,
++	ret = csum_partial_copy_generic(src, (void __force_kernel *)____m(dst),
+ 					len, isum, NULL, errp);
+ 	clac();
++	pax_close_userland();
+ 	return ret;
+ }
+ EXPORT_SYMBOL(csum_partial_copy_to_user);
+diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S
+index a451235..1daa956 100644
+--- a/arch/x86/lib/getuser.S
++++ b/arch/x86/lib/getuser.S
+@@ -33,17 +33,40 @@
+ #include <asm/thread_info.h>
+ #include <asm/asm.h>
+ #include <asm/smap.h>
++#include <asm/segment.h>
++#include <asm/pgtable.h>
++#include <asm/alternative-asm.h>
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define __copyuser_seg gs;
++#else
++#define __copyuser_seg
++#endif
+ 
+ 	.text
+ ENTRY(__get_user_1)
+ 	CFI_STARTPROC
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
+ 	GET_THREAD_INFO(%_ASM_DX)
+ 	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
+ 	jae bad_get_user
+ 	ASM_STAC
+-1:	movzbl (%_ASM_AX),%edx
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_DX
++	cmp %_ASM_DX,%_ASM_AX
++	jae 1234f
++	add %_ASM_DX,%_ASM_AX
++1234:
++#endif
++
++#endif
++
++1:	__copyuser_seg movzbl (%_ASM_AX),%edx
+ 	xor %eax,%eax
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(__get_user_1)
+@@ -51,14 +74,28 @@ ENDPROC(__get_user_1)
+ ENTRY(__get_user_2)
+ 	CFI_STARTPROC
+ 	add $1,%_ASM_AX
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
+ 	jc bad_get_user
+ 	GET_THREAD_INFO(%_ASM_DX)
+ 	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
+ 	jae bad_get_user
+ 	ASM_STAC
+-2:	movzwl -1(%_ASM_AX),%edx
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_DX
++	cmp %_ASM_DX,%_ASM_AX
++	jae 1234f
++	add %_ASM_DX,%_ASM_AX
++1234:
++#endif
++
++#endif
++
++2:	__copyuser_seg movzwl -1(%_ASM_AX),%edx
+ 	xor %eax,%eax
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(__get_user_2)
+@@ -66,14 +103,28 @@ ENDPROC(__get_user_2)
+ ENTRY(__get_user_4)
+ 	CFI_STARTPROC
+ 	add $3,%_ASM_AX
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
+ 	jc bad_get_user
+ 	GET_THREAD_INFO(%_ASM_DX)
+ 	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
+ 	jae bad_get_user
+ 	ASM_STAC
+-3:	movl -3(%_ASM_AX),%edx
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_DX
++	cmp %_ASM_DX,%_ASM_AX
++	jae 1234f
++	add %_ASM_DX,%_ASM_AX
++1234:
++#endif
++
++#endif
++
++3:	__copyuser_seg movl -3(%_ASM_AX),%edx
+ 	xor %eax,%eax
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(__get_user_4)
+@@ -86,10 +137,20 @@ ENTRY(__get_user_8)
+ 	GET_THREAD_INFO(%_ASM_DX)
+ 	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
+ 	jae bad_get_user
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++	mov pax_user_shadow_base,%_ASM_DX
++	cmp %_ASM_DX,%_ASM_AX
++	jae 1234f
++	add %_ASM_DX,%_ASM_AX
++1234:
++#endif
++
+ 	ASM_STAC
+ 4:	movq -7(%_ASM_AX),%rdx
+ 	xor %eax,%eax
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ #else
+ 	add $7,%_ASM_AX
+@@ -98,10 +159,11 @@ ENTRY(__get_user_8)
+ 	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
+ 	jae bad_get_user_8
+ 	ASM_STAC
+-4:	movl -7(%_ASM_AX),%edx
+-5:	movl -3(%_ASM_AX),%ecx
++4:	__copyuser_seg movl -7(%_ASM_AX),%edx
++5:	__copyuser_seg movl -3(%_ASM_AX),%ecx
+ 	xor %eax,%eax
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ #endif
+ 	CFI_ENDPROC
+@@ -113,6 +175,7 @@ bad_get_user:
+ 	xor %edx,%edx
+ 	mov $(-EFAULT),%_ASM_AX
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ END(bad_get_user)
+@@ -124,6 +187,7 @@ bad_get_user_8:
+ 	xor %ecx,%ecx
+ 	mov $(-EFAULT),%_ASM_AX
+ 	ASM_CLAC
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ END(bad_get_user_8)
+diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
+index 54fcffe..7be149e 100644
+--- a/arch/x86/lib/insn.c
++++ b/arch/x86/lib/insn.c
+@@ -20,8 +20,10 @@
+ 
+ #ifdef __KERNEL__
+ #include <linux/string.h>
++#include <asm/pgtable_types.h>
+ #else
+ #include <string.h>
++#define ktla_ktva(addr) addr
+ #endif
+ #include <asm/inat.h>
+ #include <asm/insn.h>
+@@ -53,8 +55,8 @@
+ void insn_init(struct insn *insn, const void *kaddr, int x86_64)
+ {
+ 	memset(insn, 0, sizeof(*insn));
+-	insn->kaddr = kaddr;
+-	insn->next_byte = kaddr;
++	insn->kaddr = ktla_ktva(kaddr);
++	insn->next_byte = ktla_ktva(kaddr);
+ 	insn->x86_64 = x86_64 ? 1 : 0;
+ 	insn->opnd_bytes = 4;
+ 	if (x86_64)
+diff --git a/arch/x86/lib/iomap_copy_64.S b/arch/x86/lib/iomap_copy_64.S
+index 05a95e7..326f2fa 100644
+--- a/arch/x86/lib/iomap_copy_64.S
++++ b/arch/x86/lib/iomap_copy_64.S
+@@ -17,6 +17,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <asm/dwarf2.h>
++#include <asm/alternative-asm.h>
+ 
+ /*
+  * override generic version in lib/iomap_copy.c
+@@ -25,6 +26,7 @@ ENTRY(__iowrite32_copy)
+ 	CFI_STARTPROC
+ 	movl %edx,%ecx
+ 	rep movsd
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(__iowrite32_copy)
+diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
+index 56313a3..9b59269 100644
+--- a/arch/x86/lib/memcpy_64.S
++++ b/arch/x86/lib/memcpy_64.S
+@@ -24,7 +24,7 @@
+  * This gets patched over the unrolled variant (below) via the
+  * alternative instructions framework:
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemcpy_c:
+ 	movq %rdi, %rax
+ 	movq %rdx, %rcx
+@@ -33,6 +33,7 @@
+ 	rep movsq
+ 	movl %edx, %ecx
+ 	rep movsb
++	pax_force_retaddr
+ 	ret
+ .Lmemcpy_e:
+ 	.previous
+@@ -44,11 +45,12 @@
+  * This gets patched over the unrolled variant (below) via the
+  * alternative instructions framework:
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemcpy_c_e:
+ 	movq %rdi, %rax
+ 	movq %rdx, %rcx
+ 	rep movsb
++	pax_force_retaddr
+ 	ret
+ .Lmemcpy_e_e:
+ 	.previous
+@@ -76,13 +78,13 @@ ENTRY(memcpy)
+ 	 */
+ 	movq 0*8(%rsi),	%r8
+ 	movq 1*8(%rsi),	%r9
+-	movq 2*8(%rsi),	%r10
++	movq 2*8(%rsi),	%rcx
+ 	movq 3*8(%rsi),	%r11
+ 	leaq 4*8(%rsi),	%rsi
+ 
+ 	movq %r8,	0*8(%rdi)
+ 	movq %r9,	1*8(%rdi)
+-	movq %r10,	2*8(%rdi)
++	movq %rcx,	2*8(%rdi)
+ 	movq %r11,	3*8(%rdi)
+ 	leaq 4*8(%rdi),	%rdi
+ 	jae  .Lcopy_forward_loop
+@@ -105,12 +107,12 @@ ENTRY(memcpy)
+ 	subq $0x20,	%rdx
+ 	movq -1*8(%rsi),	%r8
+ 	movq -2*8(%rsi),	%r9
+-	movq -3*8(%rsi),	%r10
++	movq -3*8(%rsi),	%rcx
+ 	movq -4*8(%rsi),	%r11
+ 	leaq -4*8(%rsi),	%rsi
+ 	movq %r8,		-1*8(%rdi)
+ 	movq %r9,		-2*8(%rdi)
+-	movq %r10,		-3*8(%rdi)
++	movq %rcx,		-3*8(%rdi)
+ 	movq %r11,		-4*8(%rdi)
+ 	leaq -4*8(%rdi),	%rdi
+ 	jae  .Lcopy_backward_loop
+@@ -130,12 +132,13 @@ ENTRY(memcpy)
+ 	 */
+ 	movq 0*8(%rsi), %r8
+ 	movq 1*8(%rsi),	%r9
+-	movq -2*8(%rsi, %rdx),	%r10
++	movq -2*8(%rsi, %rdx),	%rcx
+ 	movq -1*8(%rsi, %rdx),	%r11
+ 	movq %r8,	0*8(%rdi)
+ 	movq %r9,	1*8(%rdi)
+-	movq %r10,	-2*8(%rdi, %rdx)
++	movq %rcx,	-2*8(%rdi, %rdx)
+ 	movq %r11,	-1*8(%rdi, %rdx)
++	pax_force_retaddr
+ 	retq
+ 	.p2align 4
+ .Lless_16bytes:
+@@ -148,6 +151,7 @@ ENTRY(memcpy)
+ 	movq -1*8(%rsi, %rdx),	%r9
+ 	movq %r8,	0*8(%rdi)
+ 	movq %r9,	-1*8(%rdi, %rdx)
++	pax_force_retaddr
+ 	retq
+ 	.p2align 4
+ .Lless_8bytes:
+@@ -161,6 +165,7 @@ ENTRY(memcpy)
+ 	movl -4(%rsi, %rdx), %r8d
+ 	movl %ecx, (%rdi)
+ 	movl %r8d, -4(%rdi, %rdx)
++	pax_force_retaddr
+ 	retq
+ 	.p2align 4
+ .Lless_3bytes:
+@@ -179,6 +184,7 @@ ENTRY(memcpy)
+ 	movb %cl, (%rdi)
+ 
+ .Lend:
++	pax_force_retaddr
+ 	retq
+ 	CFI_ENDPROC
+ ENDPROC(memcpy)
+diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
+index 65268a6..5aa7815 100644
+--- a/arch/x86/lib/memmove_64.S
++++ b/arch/x86/lib/memmove_64.S
+@@ -61,13 +61,13 @@ ENTRY(memmove)
+ 5:
+ 	sub $0x20, %rdx
+ 	movq 0*8(%rsi), %r11
+-	movq 1*8(%rsi), %r10
++	movq 1*8(%rsi), %rcx
+ 	movq 2*8(%rsi), %r9
+ 	movq 3*8(%rsi), %r8
+ 	leaq 4*8(%rsi), %rsi
+ 
+ 	movq %r11, 0*8(%rdi)
+-	movq %r10, 1*8(%rdi)
++	movq %rcx, 1*8(%rdi)
+ 	movq %r9, 2*8(%rdi)
+ 	movq %r8, 3*8(%rdi)
+ 	leaq 4*8(%rdi), %rdi
+@@ -81,10 +81,10 @@ ENTRY(memmove)
+ 4:
+ 	movq %rdx, %rcx
+ 	movq -8(%rsi, %rdx), %r11
+-	lea -8(%rdi, %rdx), %r10
++	lea -8(%rdi, %rdx), %r9
+ 	shrq $3, %rcx
+ 	rep movsq
+-	movq %r11, (%r10)
++	movq %r11, (%r9)
+ 	jmp 13f
+ .Lmemmove_end_forward:
+ 
+@@ -95,14 +95,14 @@ ENTRY(memmove)
+ 7:
+ 	movq %rdx, %rcx
+ 	movq (%rsi), %r11
+-	movq %rdi, %r10
++	movq %rdi, %r9
+ 	leaq -8(%rsi, %rdx), %rsi
+ 	leaq -8(%rdi, %rdx), %rdi
+ 	shrq $3, %rcx
+ 	std
+ 	rep movsq
+ 	cld
+-	movq %r11, (%r10)
++	movq %r11, (%r9)
+ 	jmp 13f
+ 
+ 	/*
+@@ -127,13 +127,13 @@ ENTRY(memmove)
+ 8:
+ 	subq $0x20, %rdx
+ 	movq -1*8(%rsi), %r11
+-	movq -2*8(%rsi), %r10
++	movq -2*8(%rsi), %rcx
+ 	movq -3*8(%rsi), %r9
+ 	movq -4*8(%rsi), %r8
+ 	leaq -4*8(%rsi), %rsi
+ 
+ 	movq %r11, -1*8(%rdi)
+-	movq %r10, -2*8(%rdi)
++	movq %rcx, -2*8(%rdi)
+ 	movq %r9, -3*8(%rdi)
+ 	movq %r8, -4*8(%rdi)
+ 	leaq -4*8(%rdi), %rdi
+@@ -151,11 +151,11 @@ ENTRY(memmove)
+ 	 * Move data from 16 bytes to 31 bytes.
+ 	 */
+ 	movq 0*8(%rsi), %r11
+-	movq 1*8(%rsi), %r10
++	movq 1*8(%rsi), %rcx
+ 	movq -2*8(%rsi, %rdx), %r9
+ 	movq -1*8(%rsi, %rdx), %r8
+ 	movq %r11, 0*8(%rdi)
+-	movq %r10, 1*8(%rdi)
++	movq %rcx, 1*8(%rdi)
+ 	movq %r9, -2*8(%rdi, %rdx)
+ 	movq %r8, -1*8(%rdi, %rdx)
+ 	jmp 13f
+@@ -167,9 +167,9 @@ ENTRY(memmove)
+ 	 * Move data from 8 bytes to 15 bytes.
+ 	 */
+ 	movq 0*8(%rsi), %r11
+-	movq -1*8(%rsi, %rdx), %r10
++	movq -1*8(%rsi, %rdx), %r9
+ 	movq %r11, 0*8(%rdi)
+-	movq %r10, -1*8(%rdi, %rdx)
++	movq %r9, -1*8(%rdi, %rdx)
+ 	jmp 13f
+ 10:
+ 	cmpq $4, %rdx
+@@ -178,9 +178,9 @@ ENTRY(memmove)
+ 	 * Move data from 4 bytes to 7 bytes.
+ 	 */
+ 	movl (%rsi), %r11d
+-	movl -4(%rsi, %rdx), %r10d
++	movl -4(%rsi, %rdx), %r9d
+ 	movl %r11d, (%rdi)
+-	movl %r10d, -4(%rdi, %rdx)
++	movl %r9d, -4(%rdi, %rdx)
+ 	jmp 13f
+ 11:
+ 	cmp $2, %rdx
+@@ -189,9 +189,9 @@ ENTRY(memmove)
+ 	 * Move data from 2 bytes to 3 bytes.
+ 	 */
+ 	movw (%rsi), %r11w
+-	movw -2(%rsi, %rdx), %r10w
++	movw -2(%rsi, %rdx), %r9w
+ 	movw %r11w, (%rdi)
+-	movw %r10w, -2(%rdi, %rdx)
++	movw %r9w, -2(%rdi, %rdx)
+ 	jmp 13f
+ 12:
+ 	cmp $1, %rdx
+@@ -202,14 +202,16 @@ ENTRY(memmove)
+ 	movb (%rsi), %r11b
+ 	movb %r11b, (%rdi)
+ 13:
++	pax_force_retaddr
+ 	retq
+ 	CFI_ENDPROC
+ 
+-	.section .altinstr_replacement,"ax"
++	.section .altinstr_replacement,"a"
+ .Lmemmove_begin_forward_efs:
+ 	/* Forward moving data. */
+ 	movq %rdx, %rcx
+ 	rep movsb
++	pax_force_retaddr
+ 	retq
+ .Lmemmove_end_forward_efs:
+ 	.previous
+diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
+index 2dcb380..50a78bc 100644
+--- a/arch/x86/lib/memset_64.S
++++ b/arch/x86/lib/memset_64.S
+@@ -16,7 +16,7 @@
+  * 
+  * rax   original destination
+  */	
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemset_c:
+ 	movq %rdi,%r9
+ 	movq %rdx,%rcx
+@@ -30,6 +30,7 @@
+ 	movl %edx,%ecx
+ 	rep stosb
+ 	movq %r9,%rax
++	pax_force_retaddr
+ 	ret
+ .Lmemset_e:
+ 	.previous
+@@ -45,13 +46,14 @@
+  *
+  * rax   original destination
+  */
+-	.section .altinstr_replacement, "ax", @progbits
++	.section .altinstr_replacement, "a", @progbits
+ .Lmemset_c_e:
+ 	movq %rdi,%r9
+ 	movb %sil,%al
+ 	movq %rdx,%rcx
+ 	rep stosb
+ 	movq %r9,%rax
++	pax_force_retaddr
+ 	ret
+ .Lmemset_e_e:
+ 	.previous
+@@ -59,7 +61,7 @@
+ ENTRY(memset)
+ ENTRY(__memset)
+ 	CFI_STARTPROC
+-	movq %rdi,%r10
++	movq %rdi,%r11
+ 
+ 	/* expand byte value  */
+ 	movzbl %sil,%ecx
+@@ -117,7 +119,8 @@ ENTRY(__memset)
+ 	jnz     .Lloop_1
+ 
+ .Lende:
+-	movq	%r10,%rax
++	movq	%r11,%rax
++	pax_force_retaddr
+ 	ret
+ 
+ 	CFI_RESTORE_STATE
+diff --git a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c
+index c9f2d9b..e7fd2c0 100644
+--- a/arch/x86/lib/mmx_32.c
++++ b/arch/x86/lib/mmx_32.c
+@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len)
+ {
+ 	void *p;
+ 	int i;
++	unsigned long cr0;
+ 
+ 	if (unlikely(in_interrupt()))
+ 		return __memcpy(to, from, len);
+@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *from, size_t len)
+ 	kernel_fpu_begin();
+ 
+ 	__asm__ __volatile__ (
+-		"1: prefetch (%0)\n"		/* This set is 28 bytes */
+-		"   prefetch 64(%0)\n"
+-		"   prefetch 128(%0)\n"
+-		"   prefetch 192(%0)\n"
+-		"   prefetch 256(%0)\n"
++		"1: prefetch (%1)\n"		/* This set is 28 bytes */
++		"   prefetch 64(%1)\n"
++		"   prefetch 128(%1)\n"
++		"   prefetch 192(%1)\n"
++		"   prefetch 256(%1)\n"
+ 		"2:  \n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++		"3:  \n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+ 			_ASM_EXTABLE(1b, 3b)
+-			: : "r" (from));
++			: "=&r" (cr0) : "r" (from) : "ax");
+ 
+ 	for ( ; i > 5; i--) {
+ 		__asm__ __volatile__ (
+-		"1:  prefetch 320(%0)\n"
+-		"2:  movq (%0), %%mm0\n"
+-		"  movq 8(%0), %%mm1\n"
+-		"  movq 16(%0), %%mm2\n"
+-		"  movq 24(%0), %%mm3\n"
+-		"  movq %%mm0, (%1)\n"
+-		"  movq %%mm1, 8(%1)\n"
+-		"  movq %%mm2, 16(%1)\n"
+-		"  movq %%mm3, 24(%1)\n"
+-		"  movq 32(%0), %%mm0\n"
+-		"  movq 40(%0), %%mm1\n"
+-		"  movq 48(%0), %%mm2\n"
+-		"  movq 56(%0), %%mm3\n"
+-		"  movq %%mm0, 32(%1)\n"
+-		"  movq %%mm1, 40(%1)\n"
+-		"  movq %%mm2, 48(%1)\n"
+-		"  movq %%mm3, 56(%1)\n"
++		"1:  prefetch 320(%1)\n"
++		"2:  movq (%1), %%mm0\n"
++		"  movq 8(%1), %%mm1\n"
++		"  movq 16(%1), %%mm2\n"
++		"  movq 24(%1), %%mm3\n"
++		"  movq %%mm0, (%2)\n"
++		"  movq %%mm1, 8(%2)\n"
++		"  movq %%mm2, 16(%2)\n"
++		"  movq %%mm3, 24(%2)\n"
++		"  movq 32(%1), %%mm0\n"
++		"  movq 40(%1), %%mm1\n"
++		"  movq 48(%1), %%mm2\n"
++		"  movq 56(%1), %%mm3\n"
++		"  movq %%mm0, 32(%2)\n"
++		"  movq %%mm1, 40(%2)\n"
++		"  movq %%mm2, 48(%2)\n"
++		"  movq %%mm3, 56(%2)\n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++		"3:\n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+ 			_ASM_EXTABLE(1b, 3b)
+-			: : "r" (from), "r" (to) : "memory");
++			: "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
+ 
+ 		from += 64;
+ 		to += 64;
+@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
+ static void fast_copy_page(void *to, void *from)
+ {
+ 	int i;
++	unsigned long cr0;
+ 
+ 	kernel_fpu_begin();
+ 
+@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, void *from)
+ 	 * but that is for later. -AV
+ 	 */
+ 	__asm__ __volatile__(
+-		"1: prefetch (%0)\n"
+-		"   prefetch 64(%0)\n"
+-		"   prefetch 128(%0)\n"
+-		"   prefetch 192(%0)\n"
+-		"   prefetch 256(%0)\n"
++		"1: prefetch (%1)\n"
++		"   prefetch 64(%1)\n"
++		"   prefetch 128(%1)\n"
++		"   prefetch 192(%1)\n"
++		"   prefetch 256(%1)\n"
+ 		"2:  \n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++		"3:  \n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+-			_ASM_EXTABLE(1b, 3b) : : "r" (from));
++			_ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
+ 
+ 	for (i = 0; i < (4096-320)/64; i++) {
+ 		__asm__ __volatile__ (
+-		"1: prefetch 320(%0)\n"
+-		"2: movq (%0), %%mm0\n"
+-		"   movntq %%mm0, (%1)\n"
+-		"   movq 8(%0), %%mm1\n"
+-		"   movntq %%mm1, 8(%1)\n"
+-		"   movq 16(%0), %%mm2\n"
+-		"   movntq %%mm2, 16(%1)\n"
+-		"   movq 24(%0), %%mm3\n"
+-		"   movntq %%mm3, 24(%1)\n"
+-		"   movq 32(%0), %%mm4\n"
+-		"   movntq %%mm4, 32(%1)\n"
+-		"   movq 40(%0), %%mm5\n"
+-		"   movntq %%mm5, 40(%1)\n"
+-		"   movq 48(%0), %%mm6\n"
+-		"   movntq %%mm6, 48(%1)\n"
+-		"   movq 56(%0), %%mm7\n"
+-		"   movntq %%mm7, 56(%1)\n"
++		"1: prefetch 320(%1)\n"
++		"2: movq (%1), %%mm0\n"
++		"   movntq %%mm0, (%2)\n"
++		"   movq 8(%1), %%mm1\n"
++		"   movntq %%mm1, 8(%2)\n"
++		"   movq 16(%1), %%mm2\n"
++		"   movntq %%mm2, 16(%2)\n"
++		"   movq 24(%1), %%mm3\n"
++		"   movntq %%mm3, 24(%2)\n"
++		"   movq 32(%1), %%mm4\n"
++		"   movntq %%mm4, 32(%2)\n"
++		"   movq 40(%1), %%mm5\n"
++		"   movntq %%mm5, 40(%2)\n"
++		"   movq 48(%1), %%mm6\n"
++		"   movntq %%mm6, 48(%2)\n"
++		"   movq 56(%1), %%mm7\n"
++		"   movntq %%mm7, 56(%2)\n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++		"3:\n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+-		_ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
++		_ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
+ 
+ 		from += 64;
+ 		to += 64;
+@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
+ static void fast_copy_page(void *to, void *from)
+ {
+ 	int i;
++	unsigned long cr0;
+ 
+ 	kernel_fpu_begin();
+ 
+ 	__asm__ __volatile__ (
+-		"1: prefetch (%0)\n"
+-		"   prefetch 64(%0)\n"
+-		"   prefetch 128(%0)\n"
+-		"   prefetch 192(%0)\n"
+-		"   prefetch 256(%0)\n"
++		"1: prefetch (%1)\n"
++		"   prefetch 64(%1)\n"
++		"   prefetch 128(%1)\n"
++		"   prefetch 192(%1)\n"
++		"   prefetch 256(%1)\n"
+ 		"2:  \n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++		"3:  \n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x1AEB, 1b\n"	/* jmp on 26 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+-			_ASM_EXTABLE(1b, 3b) : : "r" (from));
++			_ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
+ 
+ 	for (i = 0; i < 4096/64; i++) {
+ 		__asm__ __volatile__ (
+-		"1: prefetch 320(%0)\n"
+-		"2: movq (%0), %%mm0\n"
+-		"   movq 8(%0), %%mm1\n"
+-		"   movq 16(%0), %%mm2\n"
+-		"   movq 24(%0), %%mm3\n"
+-		"   movq %%mm0, (%1)\n"
+-		"   movq %%mm1, 8(%1)\n"
+-		"   movq %%mm2, 16(%1)\n"
+-		"   movq %%mm3, 24(%1)\n"
+-		"   movq 32(%0), %%mm0\n"
+-		"   movq 40(%0), %%mm1\n"
+-		"   movq 48(%0), %%mm2\n"
+-		"   movq 56(%0), %%mm3\n"
+-		"   movq %%mm0, 32(%1)\n"
+-		"   movq %%mm1, 40(%1)\n"
+-		"   movq %%mm2, 48(%1)\n"
+-		"   movq %%mm3, 56(%1)\n"
++		"1: prefetch 320(%1)\n"
++		"2: movq (%1), %%mm0\n"
++		"   movq 8(%1), %%mm1\n"
++		"   movq 16(%1), %%mm2\n"
++		"   movq 24(%1), %%mm3\n"
++		"   movq %%mm0, (%2)\n"
++		"   movq %%mm1, 8(%2)\n"
++		"   movq %%mm2, 16(%2)\n"
++		"   movq %%mm3, 24(%2)\n"
++		"   movq 32(%1), %%mm0\n"
++		"   movq 40(%1), %%mm1\n"
++		"   movq 48(%1), %%mm2\n"
++		"   movq 56(%1), %%mm3\n"
++		"   movq %%mm0, 32(%2)\n"
++		"   movq %%mm1, 40(%2)\n"
++		"   movq %%mm2, 48(%2)\n"
++		"   movq %%mm3, 56(%2)\n"
+ 		".section .fixup, \"ax\"\n"
+-		"3: movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++		"3:\n"
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %%cr0, %0\n"
++		"   movl %0, %%eax\n"
++		"   andl $0xFFFEFFFF, %%eax\n"
++		"   movl %%eax, %%cr0\n"
++#endif
++
++		"   movw $0x05EB, 1b\n"	/* jmp on 5 bytes */
++
++#ifdef CONFIG_PAX_KERNEXEC
++		"   movl %0, %%cr0\n"
++#endif
++
+ 		"   jmp 2b\n"
+ 		".previous\n"
+ 			_ASM_EXTABLE(1b, 3b)
+-			: : "r" (from), "r" (to) : "memory");
++			: "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
+ 
+ 		from += 64;
+ 		to += 64;
+diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
+index f6d13ee..aca5f0b 100644
+--- a/arch/x86/lib/msr-reg.S
++++ b/arch/x86/lib/msr-reg.S
+@@ -3,6 +3,7 @@
+ #include <asm/dwarf2.h>
+ #include <asm/asm.h>
+ #include <asm/msr.h>
++#include <asm/alternative-asm.h>
+ 
+ #ifdef CONFIG_X86_64
+ /*
+@@ -16,7 +17,7 @@ ENTRY(\op\()_safe_regs)
+ 	CFI_STARTPROC
+ 	pushq_cfi %rbx
+ 	pushq_cfi %rbp
+-	movq	%rdi, %r10	/* Save pointer */
++	movq	%rdi, %r9	/* Save pointer */
+ 	xorl	%r11d, %r11d	/* Return value */
+ 	movl    (%rdi), %eax
+ 	movl    4(%rdi), %ecx
+@@ -27,16 +28,17 @@ ENTRY(\op\()_safe_regs)
+ 	movl    28(%rdi), %edi
+ 	CFI_REMEMBER_STATE
+ 1:	\op
+-2:	movl    %eax, (%r10)
++2:	movl    %eax, (%r9)
+ 	movl	%r11d, %eax	/* Return value */
+-	movl    %ecx, 4(%r10)
+-	movl    %edx, 8(%r10)
+-	movl    %ebx, 12(%r10)
+-	movl    %ebp, 20(%r10)
+-	movl    %esi, 24(%r10)
+-	movl    %edi, 28(%r10)
++	movl    %ecx, 4(%r9)
++	movl    %edx, 8(%r9)
++	movl    %ebx, 12(%r9)
++	movl    %ebp, 20(%r9)
++	movl    %esi, 24(%r9)
++	movl    %edi, 28(%r9)
+ 	popq_cfi %rbp
+ 	popq_cfi %rbx
++	pax_force_retaddr
+ 	ret
+ 3:
+ 	CFI_RESTORE_STATE
+diff --git a/arch/x86/lib/putuser.S b/arch/x86/lib/putuser.S
+index fc6ba17..d4d989d 100644
+--- a/arch/x86/lib/putuser.S
++++ b/arch/x86/lib/putuser.S
+@@ -16,7 +16,9 @@
+ #include <asm/errno.h>
+ #include <asm/asm.h>
+ #include <asm/smap.h>
+-
++#include <asm/segment.h>
++#include <asm/pgtable.h>
++#include <asm/alternative-asm.h>
+ 
+ /*
+  * __put_user_X
+@@ -30,57 +32,125 @@
+  * as they get called from within inline assembly.
+  */
+ 
+-#define ENTER	CFI_STARTPROC ; \
+-		GET_THREAD_INFO(%_ASM_BX)
+-#define EXIT	ASM_CLAC ;	\
+-		ret ;		\
++#define ENTER	CFI_STARTPROC
++#define EXIT	ASM_CLAC ;		\
++		pax_force_retaddr ;	\
++		ret ;			\
+ 		CFI_ENDPROC
+ 
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define _DEST %_ASM_CX,%_ASM_BX
++#else
++#define _DEST %_ASM_CX
++#endif
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#define __copyuser_seg gs;
++#else
++#define __copyuser_seg
++#endif
++
+ .text
+ ENTRY(__put_user_1)
+ 	ENTER
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
++	GET_THREAD_INFO(%_ASM_BX)
+ 	cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
+ 	jae bad_put_user
+ 	ASM_STAC
+-1:	movb %al,(%_ASM_CX)
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_BX
++	cmp %_ASM_BX,%_ASM_CX
++	jb 1234f
++	xor %ebx,%ebx
++1234:
++#endif
++
++#endif
++
++1:	__copyuser_seg movb %al,(_DEST)
+ 	xor %eax,%eax
+ 	EXIT
+ ENDPROC(__put_user_1)
+ 
+ ENTRY(__put_user_2)
+ 	ENTER
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
++	GET_THREAD_INFO(%_ASM_BX)
+ 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
+ 	sub $1,%_ASM_BX
+ 	cmp %_ASM_BX,%_ASM_CX
+ 	jae bad_put_user
+ 	ASM_STAC
+-2:	movw %ax,(%_ASM_CX)
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_BX
++	cmp %_ASM_BX,%_ASM_CX
++	jb 1234f
++	xor %ebx,%ebx
++1234:
++#endif
++
++#endif
++
++2:	__copyuser_seg movw %ax,(_DEST)
+ 	xor %eax,%eax
+ 	EXIT
+ ENDPROC(__put_user_2)
+ 
+ ENTRY(__put_user_4)
+ 	ENTER
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
++	GET_THREAD_INFO(%_ASM_BX)
+ 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
+ 	sub $3,%_ASM_BX
+ 	cmp %_ASM_BX,%_ASM_CX
+ 	jae bad_put_user
+ 	ASM_STAC
+-3:	movl %eax,(%_ASM_CX)
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_BX
++	cmp %_ASM_BX,%_ASM_CX
++	jb 1234f
++	xor %ebx,%ebx
++1234:
++#endif
++
++#endif
++
++3:	__copyuser_seg movl %eax,(_DEST)
+ 	xor %eax,%eax
+ 	EXIT
+ ENDPROC(__put_user_4)
+ 
+ ENTRY(__put_user_8)
+ 	ENTER
++
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_MEMORY_UDEREF)
++	GET_THREAD_INFO(%_ASM_BX)
+ 	mov TI_addr_limit(%_ASM_BX),%_ASM_BX
+ 	sub $7,%_ASM_BX
+ 	cmp %_ASM_BX,%_ASM_CX
+ 	jae bad_put_user
+ 	ASM_STAC
+-4:	mov %_ASM_AX,(%_ASM_CX)
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	mov pax_user_shadow_base,%_ASM_BX
++	cmp %_ASM_BX,%_ASM_CX
++	jb 1234f
++	xor %ebx,%ebx
++1234:
++#endif
++
++#endif
++
++4:	__copyuser_seg mov %_ASM_AX,(_DEST)
+ #ifdef CONFIG_X86_32
+-5:	movl %edx,4(%_ASM_CX)
++5:	__copyuser_seg movl %edx,4(_DEST)
+ #endif
+ 	xor %eax,%eax
+ 	EXIT
+diff --git a/arch/x86/lib/rwlock.S b/arch/x86/lib/rwlock.S
+index 1cad221..de671ee 100644
+--- a/arch/x86/lib/rwlock.S
++++ b/arch/x86/lib/rwlock.S
+@@ -16,13 +16,34 @@ ENTRY(__write_lock_failed)
+ 	FRAME
+ 0:	LOCK_PREFIX
+ 	WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 1234f
++	LOCK_PREFIX
++	WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr)
++	int $4
++1234:
++	_ASM_EXTABLE(1234b, 1234b)
++#endif
++
+ 1:	rep; nop
+ 	cmpl	$WRITE_LOCK_CMP, (%__lock_ptr)
+ 	jne	1b
+ 	LOCK_PREFIX
+ 	WRITE_LOCK_SUB($RW_LOCK_BIAS) (%__lock_ptr)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 1234f
++	LOCK_PREFIX
++	WRITE_LOCK_ADD($RW_LOCK_BIAS) (%__lock_ptr)
++	int $4
++1234:
++	_ASM_EXTABLE(1234b, 1234b)
++#endif
++
+ 	jnz	0b
+ 	ENDFRAME
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ END(__write_lock_failed)
+@@ -32,13 +53,34 @@ ENTRY(__read_lock_failed)
+ 	FRAME
+ 0:	LOCK_PREFIX
+ 	READ_LOCK_SIZE(inc) (%__lock_ptr)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 1234f
++	LOCK_PREFIX
++	READ_LOCK_SIZE(dec) (%__lock_ptr)
++	int $4
++1234:
++	_ASM_EXTABLE(1234b, 1234b)
++#endif
++
+ 1:	rep; nop
+ 	READ_LOCK_SIZE(cmp) $1, (%__lock_ptr)
+ 	js	1b
+ 	LOCK_PREFIX
+ 	READ_LOCK_SIZE(dec) (%__lock_ptr)
++
++#ifdef CONFIG_PAX_REFCOUNT
++	jno 1234f
++	LOCK_PREFIX
++	READ_LOCK_SIZE(inc) (%__lock_ptr)
++	int $4
++1234:
++	_ASM_EXTABLE(1234b, 1234b)
++#endif
++
+ 	js	0b
+ 	ENDFRAME
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ END(__read_lock_failed)
+diff --git a/arch/x86/lib/rwsem.S b/arch/x86/lib/rwsem.S
+index 5dff5f0..cadebf4 100644
+--- a/arch/x86/lib/rwsem.S
++++ b/arch/x86/lib/rwsem.S
+@@ -94,6 +94,7 @@ ENTRY(call_rwsem_down_read_failed)
+ 	__ASM_SIZE(pop,_cfi) %__ASM_REG(dx)
+ 	CFI_RESTORE __ASM_REG(dx)
+ 	restore_common_regs
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(call_rwsem_down_read_failed)
+@@ -104,6 +105,7 @@ ENTRY(call_rwsem_down_write_failed)
+ 	movq %rax,%rdi
+ 	call rwsem_down_write_failed
+ 	restore_common_regs
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(call_rwsem_down_write_failed)
+@@ -117,7 +119,8 @@ ENTRY(call_rwsem_wake)
+ 	movq %rax,%rdi
+ 	call rwsem_wake
+ 	restore_common_regs
+-1:	ret
++1:	pax_force_retaddr
++	ret
+ 	CFI_ENDPROC
+ ENDPROC(call_rwsem_wake)
+ 
+@@ -131,6 +134,7 @@ ENTRY(call_rwsem_downgrade_wake)
+ 	__ASM_SIZE(pop,_cfi) %__ASM_REG(dx)
+ 	CFI_RESTORE __ASM_REG(dx)
+ 	restore_common_regs
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+ ENDPROC(call_rwsem_downgrade_wake)
+diff --git a/arch/x86/lib/thunk_64.S b/arch/x86/lib/thunk_64.S
+index a63efd6..ccecad8 100644
+--- a/arch/x86/lib/thunk_64.S
++++ b/arch/x86/lib/thunk_64.S
+@@ -8,6 +8,7 @@
+ #include <linux/linkage.h>
+ #include <asm/dwarf2.h>
+ #include <asm/calling.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
+@@ -41,5 +42,6 @@
+ 	SAVE_ARGS
+ restore:
+ 	RESTORE_ARGS
++	pax_force_retaddr
+ 	ret
+ 	CFI_ENDPROC
+diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
+index 3eb18ac..6890bc3 100644
+--- a/arch/x86/lib/usercopy_32.c
++++ b/arch/x86/lib/usercopy_32.c
+@@ -42,11 +42,13 @@ do {									\
+ 	int __d0;							\
+ 	might_fault();							\
+ 	__asm__ __volatile__(						\
++		__COPYUSER_SET_ES					\
+ 		ASM_STAC "\n"						\
+ 		"0:	rep; stosl\n"					\
+ 		"	movl %2,%0\n"					\
+ 		"1:	rep; stosb\n"					\
+ 		"2: " ASM_CLAC "\n"					\
++		__COPYUSER_RESTORE_ES					\
+ 		".section .fixup,\"ax\"\n"				\
+ 		"3:	lea 0(%2,%0,4),%0\n"				\
+ 		"	jmp 2b\n"					\
+@@ -98,7 +100,7 @@ EXPORT_SYMBOL(__clear_user);
+ 
+ #ifdef CONFIG_X86_INTEL_USERCOPY
+ static unsigned long
+-__copy_user_intel(void __user *to, const void *from, unsigned long size)
++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
+ {
+ 	int d0, d1;
+ 	__asm__ __volatile__(
+@@ -110,36 +112,36 @@ __copy_user_intel(void __user *to, const void *from, unsigned \
long size) + 		       "       .align 2,0x90\n"
+ 		       "3:     movl 0(%4), %%eax\n"
+ 		       "4:     movl 4(%4), %%edx\n"
+-		       "5:     movl %%eax, 0(%3)\n"
+-		       "6:     movl %%edx, 4(%3)\n"
++		       "5:     "__copyuser_seg" movl %%eax, 0(%3)\n"
++		       "6:     "__copyuser_seg" movl %%edx, 4(%3)\n"
+ 		       "7:     movl 8(%4), %%eax\n"
+ 		       "8:     movl 12(%4),%%edx\n"
+-		       "9:     movl %%eax, 8(%3)\n"
+-		       "10:    movl %%edx, 12(%3)\n"
++		       "9:     "__copyuser_seg" movl %%eax, 8(%3)\n"
++		       "10:    "__copyuser_seg" movl %%edx, 12(%3)\n"
+ 		       "11:    movl 16(%4), %%eax\n"
+ 		       "12:    movl 20(%4), %%edx\n"
+-		       "13:    movl %%eax, 16(%3)\n"
+-		       "14:    movl %%edx, 20(%3)\n"
++		       "13:    "__copyuser_seg" movl %%eax, 16(%3)\n"
++		       "14:    "__copyuser_seg" movl %%edx, 20(%3)\n"
+ 		       "15:    movl 24(%4), %%eax\n"
+ 		       "16:    movl 28(%4), %%edx\n"
+-		       "17:    movl %%eax, 24(%3)\n"
+-		       "18:    movl %%edx, 28(%3)\n"
++		       "17:    "__copyuser_seg" movl %%eax, 24(%3)\n"
++		       "18:    "__copyuser_seg" movl %%edx, 28(%3)\n"
+ 		       "19:    movl 32(%4), %%eax\n"
+ 		       "20:    movl 36(%4), %%edx\n"
+-		       "21:    movl %%eax, 32(%3)\n"
+-		       "22:    movl %%edx, 36(%3)\n"
++		       "21:    "__copyuser_seg" movl %%eax, 32(%3)\n"
++		       "22:    "__copyuser_seg" movl %%edx, 36(%3)\n"
+ 		       "23:    movl 40(%4), %%eax\n"
+ 		       "24:    movl 44(%4), %%edx\n"
+-		       "25:    movl %%eax, 40(%3)\n"
+-		       "26:    movl %%edx, 44(%3)\n"
++		       "25:    "__copyuser_seg" movl %%eax, 40(%3)\n"
++		       "26:    "__copyuser_seg" movl %%edx, 44(%3)\n"
+ 		       "27:    movl 48(%4), %%eax\n"
+ 		       "28:    movl 52(%4), %%edx\n"
+-		       "29:    movl %%eax, 48(%3)\n"
+-		       "30:    movl %%edx, 52(%3)\n"
++		       "29:    "__copyuser_seg" movl %%eax, 48(%3)\n"
++		       "30:    "__copyuser_seg" movl %%edx, 52(%3)\n"
+ 		       "31:    movl 56(%4), %%eax\n"
+ 		       "32:    movl 60(%4), %%edx\n"
+-		       "33:    movl %%eax, 56(%3)\n"
+-		       "34:    movl %%edx, 60(%3)\n"
++		       "33:    "__copyuser_seg" movl %%eax, 56(%3)\n"
++		       "34:    "__copyuser_seg" movl %%edx, 60(%3)\n"
+ 		       "       addl $-64, %0\n"
+ 		       "       addl $64, %4\n"
+ 		       "       addl $64, %3\n"
+@@ -149,10 +151,12 @@ __copy_user_intel(void __user *to, const void *from, unsigned \
long size) + 		       "       shrl  $2, %0\n"
+ 		       "       andl  $3, %%eax\n"
+ 		       "       cld\n"
++		       __COPYUSER_SET_ES
+ 		       "99:    rep; movsl\n"
+ 		       "36:    movl %%eax, %0\n"
+ 		       "37:    rep; movsb\n"
+ 		       "100:\n"
++		       __COPYUSER_RESTORE_ES
+ 		       ".section .fixup,\"ax\"\n"
+ 		       "101:   lea 0(%%eax,%0,4),%0\n"
+ 		       "       jmp 100b\n"
+@@ -202,46 +206,150 @@ __copy_user_intel(void __user *to, const void *from, unsigned \
long size) + }
+ 
+ static unsigned long
++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long \
size) ++{
++	int d0, d1;
++	__asm__ __volatile__(
++		       "       .align 2,0x90\n"
++		       "1:     "__copyuser_seg" movl 32(%4), %%eax\n"
++		       "       cmpl $67, %0\n"
++		       "       jbe 3f\n"
++		       "2:     "__copyuser_seg" movl 64(%4), %%eax\n"
++		       "       .align 2,0x90\n"
++		       "3:     "__copyuser_seg" movl 0(%4), %%eax\n"
++		       "4:     "__copyuser_seg" movl 4(%4), %%edx\n"
++		       "5:     movl %%eax, 0(%3)\n"
++		       "6:     movl %%edx, 4(%3)\n"
++		       "7:     "__copyuser_seg" movl 8(%4), %%eax\n"
++		       "8:     "__copyuser_seg" movl 12(%4),%%edx\n"
++		       "9:     movl %%eax, 8(%3)\n"
++		       "10:    movl %%edx, 12(%3)\n"
++		       "11:    "__copyuser_seg" movl 16(%4), %%eax\n"
++		       "12:    "__copyuser_seg" movl 20(%4), %%edx\n"
++		       "13:    movl %%eax, 16(%3)\n"
++		       "14:    movl %%edx, 20(%3)\n"
++		       "15:    "__copyuser_seg" movl 24(%4), %%eax\n"
++		       "16:    "__copyuser_seg" movl 28(%4), %%edx\n"
++		       "17:    movl %%eax, 24(%3)\n"
++		       "18:    movl %%edx, 28(%3)\n"
++		       "19:    "__copyuser_seg" movl 32(%4), %%eax\n"
++		       "20:    "__copyuser_seg" movl 36(%4), %%edx\n"
++		       "21:    movl %%eax, 32(%3)\n"
++		       "22:    movl %%edx, 36(%3)\n"
++		       "23:    "__copyuser_seg" movl 40(%4), %%eax\n"
++		       "24:    "__copyuser_seg" movl 44(%4), %%edx\n"
++		       "25:    movl %%eax, 40(%3)\n"
++		       "26:    movl %%edx, 44(%3)\n"
++		       "27:    "__copyuser_seg" movl 48(%4), %%eax\n"
++		       "28:    "__copyuser_seg" movl 52(%4), %%edx\n"
++		       "29:    movl %%eax, 48(%3)\n"
++		       "30:    movl %%edx, 52(%3)\n"
++		       "31:    "__copyuser_seg" movl 56(%4), %%eax\n"
++		       "32:    "__copyuser_seg" movl 60(%4), %%edx\n"
++		       "33:    movl %%eax, 56(%3)\n"
++		       "34:    movl %%edx, 60(%3)\n"
++		       "       addl $-64, %0\n"
++		       "       addl $64, %4\n"
++		       "       addl $64, %3\n"
++		       "       cmpl $63, %0\n"
++		       "       ja  1b\n"
++		       "35:    movl  %0, %%eax\n"
++		       "       shrl  $2, %0\n"
++		       "       andl  $3, %%eax\n"
++		       "       cld\n"
++		       "99:    rep; "__copyuser_seg" movsl\n"
++		       "36:    movl %%eax, %0\n"
++		       "37:    rep; "__copyuser_seg" movsb\n"
++		       "100:\n"
++		       ".section .fixup,\"ax\"\n"
++		       "101:   lea 0(%%eax,%0,4),%0\n"
++		       "       jmp 100b\n"
++		       ".previous\n"
++		       _ASM_EXTABLE(1b,100b)
++		       _ASM_EXTABLE(2b,100b)
++		       _ASM_EXTABLE(3b,100b)
++		       _ASM_EXTABLE(4b,100b)
++		       _ASM_EXTABLE(5b,100b)
++		       _ASM_EXTABLE(6b,100b)
++		       _ASM_EXTABLE(7b,100b)
++		       _ASM_EXTABLE(8b,100b)
++		       _ASM_EXTABLE(9b,100b)
++		       _ASM_EXTABLE(10b,100b)
++		       _ASM_EXTABLE(11b,100b)
++		       _ASM_EXTABLE(12b,100b)
++		       _ASM_EXTABLE(13b,100b)
++		       _ASM_EXTABLE(14b,100b)
++		       _ASM_EXTABLE(15b,100b)
++		       _ASM_EXTABLE(16b,100b)
++		       _ASM_EXTABLE(17b,100b)
++		       _ASM_EXTABLE(18b,100b)
++		       _ASM_EXTABLE(19b,100b)
++		       _ASM_EXTABLE(20b,100b)
++		       _ASM_EXTABLE(21b,100b)
++		       _ASM_EXTABLE(22b,100b)
++		       _ASM_EXTABLE(23b,100b)
++		       _ASM_EXTABLE(24b,100b)
++		       _ASM_EXTABLE(25b,100b)
++		       _ASM_EXTABLE(26b,100b)
++		       _ASM_EXTABLE(27b,100b)
++		       _ASM_EXTABLE(28b,100b)
++		       _ASM_EXTABLE(29b,100b)
++		       _ASM_EXTABLE(30b,100b)
++		       _ASM_EXTABLE(31b,100b)
++		       _ASM_EXTABLE(32b,100b)
++		       _ASM_EXTABLE(33b,100b)
++		       _ASM_EXTABLE(34b,100b)
++		       _ASM_EXTABLE(35b,100b)
++		       _ASM_EXTABLE(36b,100b)
++		       _ASM_EXTABLE(37b,100b)
++		       _ASM_EXTABLE(99b,101b)
++		       : "=&c"(size), "=&D" (d0), "=&S" (d1)
++		       :  "1"(to), "2"(from), "0"(size)
++		       : "eax", "edx", "memory");
++	return size;
++}
++
++static unsigned long __size_overflow(3)
+ __copy_user_zeroing_intel(void *to, const void __user *from, unsigned long size)
+ {
+ 	int d0, d1;
+ 	__asm__ __volatile__(
+ 		       "        .align 2,0x90\n"
+-		       "0:      movl 32(%4), %%eax\n"
++		       "0:      "__copyuser_seg" movl 32(%4), %%eax\n"
+ 		       "        cmpl $67, %0\n"
+ 		       "        jbe 2f\n"
+-		       "1:      movl 64(%4), %%eax\n"
++		       "1:      "__copyuser_seg" movl 64(%4), %%eax\n"
+ 		       "        .align 2,0x90\n"
+-		       "2:      movl 0(%4), %%eax\n"
+-		       "21:     movl 4(%4), %%edx\n"
++		       "2:      "__copyuser_seg" movl 0(%4), %%eax\n"
++		       "21:     "__copyuser_seg" movl 4(%4), %%edx\n"
+ 		       "        movl %%eax, 0(%3)\n"
+ 		       "        movl %%edx, 4(%3)\n"
+-		       "3:      movl 8(%4), %%eax\n"
+-		       "31:     movl 12(%4),%%edx\n"
++		       "3:      "__copyuser_seg" movl 8(%4), %%eax\n"
++		       "31:     "__copyuser_seg" movl 12(%4),%%edx\n"
+ 		       "        movl %%eax, 8(%3)\n"
+ 		       "        movl %%edx, 12(%3)\n"
+-		       "4:      movl 16(%4), %%eax\n"
+-		       "41:     movl 20(%4), %%edx\n"
++		       "4:      "__copyuser_seg" movl 16(%4), %%eax\n"
++		       "41:     "__copyuser_seg" movl 20(%4), %%edx\n"
+ 		       "        movl %%eax, 16(%3)\n"
+ 		       "        movl %%edx, 20(%3)\n"
+-		       "10:     movl 24(%4), %%eax\n"
+-		       "51:     movl 28(%4), %%edx\n"
++		       "10:     "__copyuser_seg" movl 24(%4), %%eax\n"
++		       "51:     "__copyuser_seg" movl 28(%4), %%edx\n"
+ 		       "        movl %%eax, 24(%3)\n"
+ 		       "        movl %%edx, 28(%3)\n"
+-		       "11:     movl 32(%4), %%eax\n"
+-		       "61:     movl 36(%4), %%edx\n"
++		       "11:     "__copyuser_seg" movl 32(%4), %%eax\n"
++		       "61:     "__copyuser_seg" movl 36(%4), %%edx\n"
+ 		       "        movl %%eax, 32(%3)\n"
+ 		       "        movl %%edx, 36(%3)\n"
+-		       "12:     movl 40(%4), %%eax\n"
+-		       "71:     movl 44(%4), %%edx\n"
++		       "12:     "__copyuser_seg" movl 40(%4), %%eax\n"
++		       "71:     "__copyuser_seg" movl 44(%4), %%edx\n"
+ 		       "        movl %%eax, 40(%3)\n"
+ 		       "        movl %%edx, 44(%3)\n"
+-		       "13:     movl 48(%4), %%eax\n"
+-		       "81:     movl 52(%4), %%edx\n"
++		       "13:     "__copyuser_seg" movl 48(%4), %%eax\n"
++		       "81:     "__copyuser_seg" movl 52(%4), %%edx\n"
+ 		       "        movl %%eax, 48(%3)\n"
+ 		       "        movl %%edx, 52(%3)\n"
+-		       "14:     movl 56(%4), %%eax\n"
+-		       "91:     movl 60(%4), %%edx\n"
++		       "14:     "__copyuser_seg" movl 56(%4), %%eax\n"
++		       "91:     "__copyuser_seg" movl 60(%4), %%edx\n"
+ 		       "        movl %%eax, 56(%3)\n"
+ 		       "        movl %%edx, 60(%3)\n"
+ 		       "        addl $-64, %0\n"
+@@ -253,9 +361,9 @@ __copy_user_zeroing_intel(void *to, const void __user *from, \
unsigned long size) + 		       "        shrl  $2, %0\n"
+ 		       "        andl $3, %%eax\n"
+ 		       "        cld\n"
+-		       "6:      rep; movsl\n"
++		       "6:      rep; "__copyuser_seg" movsl\n"
+ 		       "        movl %%eax,%0\n"
+-		       "7:      rep; movsb\n"
++		       "7:      rep; "__copyuser_seg" movsb\n"
+ 		       "8:\n"
+ 		       ".section .fixup,\"ax\"\n"
+ 		       "9:      lea 0(%%eax,%0,4),%0\n"
+@@ -298,48 +406,48 @@ __copy_user_zeroing_intel(void *to, const void __user *from, \
unsigned long size) +  * hyoshiok at miraclelinux.com
+  */
+ 
+-static unsigned long __copy_user_zeroing_intel_nocache(void *to,
++static unsigned long __size_overflow(3) __copy_user_zeroing_intel_nocache(void *to,
+ 				const void __user *from, unsigned long size)
+ {
+ 	int d0, d1;
+ 
+ 	__asm__ __volatile__(
+ 	       "        .align 2,0x90\n"
+-	       "0:      movl 32(%4), %%eax\n"
++	       "0:      "__copyuser_seg" movl 32(%4), %%eax\n"
+ 	       "        cmpl $67, %0\n"
+ 	       "        jbe 2f\n"
+-	       "1:      movl 64(%4), %%eax\n"
++	       "1:      "__copyuser_seg" movl 64(%4), %%eax\n"
+ 	       "        .align 2,0x90\n"
+-	       "2:      movl 0(%4), %%eax\n"
+-	       "21:     movl 4(%4), %%edx\n"
++	       "2:      "__copyuser_seg" movl 0(%4), %%eax\n"
++	       "21:     "__copyuser_seg" movl 4(%4), %%edx\n"
+ 	       "        movnti %%eax, 0(%3)\n"
+ 	       "        movnti %%edx, 4(%3)\n"
+-	       "3:      movl 8(%4), %%eax\n"
+-	       "31:     movl 12(%4),%%edx\n"
++	       "3:      "__copyuser_seg" movl 8(%4), %%eax\n"
++	       "31:     "__copyuser_seg" movl 12(%4),%%edx\n"
+ 	       "        movnti %%eax, 8(%3)\n"
+ 	       "        movnti %%edx, 12(%3)\n"
+-	       "4:      movl 16(%4), %%eax\n"
+-	       "41:     movl 20(%4), %%edx\n"
++	       "4:      "__copyuser_seg" movl 16(%4), %%eax\n"
++	       "41:     "__copyuser_seg" movl 20(%4), %%edx\n"
+ 	       "        movnti %%eax, 16(%3)\n"
+ 	       "        movnti %%edx, 20(%3)\n"
+-	       "10:     movl 24(%4), %%eax\n"
+-	       "51:     movl 28(%4), %%edx\n"
++	       "10:     "__copyuser_seg" movl 24(%4), %%eax\n"
++	       "51:     "__copyuser_seg" movl 28(%4), %%edx\n"
+ 	       "        movnti %%eax, 24(%3)\n"
+ 	       "        movnti %%edx, 28(%3)\n"
+-	       "11:     movl 32(%4), %%eax\n"
+-	       "61:     movl 36(%4), %%edx\n"
++	       "11:     "__copyuser_seg" movl 32(%4), %%eax\n"
++	       "61:     "__copyuser_seg" movl 36(%4), %%edx\n"
+ 	       "        movnti %%eax, 32(%3)\n"
+ 	       "        movnti %%edx, 36(%3)\n"
+-	       "12:     movl 40(%4), %%eax\n"
+-	       "71:     movl 44(%4), %%edx\n"
++	       "12:     "__copyuser_seg" movl 40(%4), %%eax\n"
++	       "71:     "__copyuser_seg" movl 44(%4), %%edx\n"
+ 	       "        movnti %%eax, 40(%3)\n"
+ 	       "        movnti %%edx, 44(%3)\n"
+-	       "13:     movl 48(%4), %%eax\n"
+-	       "81:     movl 52(%4), %%edx\n"
++	       "13:     "__copyuser_seg" movl 48(%4), %%eax\n"
++	       "81:     "__copyuser_seg" movl 52(%4), %%edx\n"
+ 	       "        movnti %%eax, 48(%3)\n"
+ 	       "        movnti %%edx, 52(%3)\n"
+-	       "14:     movl 56(%4), %%eax\n"
+-	       "91:     movl 60(%4), %%edx\n"
++	       "14:     "__copyuser_seg" movl 56(%4), %%eax\n"
++	       "91:     "__copyuser_seg" movl 60(%4), %%edx\n"
+ 	       "        movnti %%eax, 56(%3)\n"
+ 	       "        movnti %%edx, 60(%3)\n"
+ 	       "        addl $-64, %0\n"
+@@ -352,9 +460,9 @@ static unsigned long __copy_user_zeroing_intel_nocache(void *to,
+ 	       "        shrl  $2, %0\n"
+ 	       "        andl $3, %%eax\n"
+ 	       "        cld\n"
+-	       "6:      rep; movsl\n"
++	       "6:      rep; "__copyuser_seg" movsl\n"
+ 	       "        movl %%eax,%0\n"
+-	       "7:      rep; movsb\n"
++	       "7:      rep; "__copyuser_seg" movsb\n"
+ 	       "8:\n"
+ 	       ".section .fixup,\"ax\"\n"
+ 	       "9:      lea 0(%%eax,%0,4),%0\n"
+@@ -392,48 +500,48 @@ static unsigned long __copy_user_zeroing_intel_nocache(void \
*to, + 	return size;
+ }
+ 
+-static unsigned long __copy_user_intel_nocache(void *to,
++static unsigned long __size_overflow(3) __copy_user_intel_nocache(void *to,
+ 				const void __user *from, unsigned long size)
+ {
+ 	int d0, d1;
+ 
+ 	__asm__ __volatile__(
+ 	       "        .align 2,0x90\n"
+-	       "0:      movl 32(%4), %%eax\n"
++	       "0:      "__copyuser_seg" movl 32(%4), %%eax\n"
+ 	       "        cmpl $67, %0\n"
+ 	       "        jbe 2f\n"
+-	       "1:      movl 64(%4), %%eax\n"
++	       "1:      "__copyuser_seg" movl 64(%4), %%eax\n"
+ 	       "        .align 2,0x90\n"
+-	       "2:      movl 0(%4), %%eax\n"
+-	       "21:     movl 4(%4), %%edx\n"
++	       "2:      "__copyuser_seg" movl 0(%4), %%eax\n"
++	       "21:     "__copyuser_seg" movl 4(%4), %%edx\n"
+ 	       "        movnti %%eax, 0(%3)\n"
+ 	       "        movnti %%edx, 4(%3)\n"
+-	       "3:      movl 8(%4), %%eax\n"
+-	       "31:     movl 12(%4),%%edx\n"
++	       "3:      "__copyuser_seg" movl 8(%4), %%eax\n"
++	       "31:     "__copyuser_seg" movl 12(%4),%%edx\n"
+ 	       "        movnti %%eax, 8(%3)\n"
+ 	       "        movnti %%edx, 12(%3)\n"
+-	       "4:      movl 16(%4), %%eax\n"
+-	       "41:     movl 20(%4), %%edx\n"
++	       "4:      "__copyuser_seg" movl 16(%4), %%eax\n"
++	       "41:     "__copyuser_seg" movl 20(%4), %%edx\n"
+ 	       "        movnti %%eax, 16(%3)\n"
+ 	       "        movnti %%edx, 20(%3)\n"
+-	       "10:     movl 24(%4), %%eax\n"
+-	       "51:     movl 28(%4), %%edx\n"
++	       "10:     "__copyuser_seg" movl 24(%4), %%eax\n"
++	       "51:     "__copyuser_seg" movl 28(%4), %%edx\n"
+ 	       "        movnti %%eax, 24(%3)\n"
+ 	       "        movnti %%edx, 28(%3)\n"
+-	       "11:     movl 32(%4), %%eax\n"
+-	       "61:     movl 36(%4), %%edx\n"
++	       "11:     "__copyuser_seg" movl 32(%4), %%eax\n"
++	       "61:     "__copyuser_seg" movl 36(%4), %%edx\n"
+ 	       "        movnti %%eax, 32(%3)\n"
+ 	       "        movnti %%edx, 36(%3)\n"
+-	       "12:     movl 40(%4), %%eax\n"
+-	       "71:     movl 44(%4), %%edx\n"
++	       "12:     "__copyuser_seg" movl 40(%4), %%eax\n"
++	       "71:     "__copyuser_seg" movl 44(%4), %%edx\n"
+ 	       "        movnti %%eax, 40(%3)\n"
+ 	       "        movnti %%edx, 44(%3)\n"
+-	       "13:     movl 48(%4), %%eax\n"
+-	       "81:     movl 52(%4), %%edx\n"
++	       "13:     "__copyuser_seg" movl 48(%4), %%eax\n"
++	       "81:     "__copyuser_seg" movl 52(%4), %%edx\n"
+ 	       "        movnti %%eax, 48(%3)\n"
+ 	       "        movnti %%edx, 52(%3)\n"
+-	       "14:     movl 56(%4), %%eax\n"
+-	       "91:     movl 60(%4), %%edx\n"
++	       "14:     "__copyuser_seg" movl 56(%4), %%eax\n"
++	       "91:     "__copyuser_seg" movl 60(%4), %%edx\n"
+ 	       "        movnti %%eax, 56(%3)\n"
+ 	       "        movnti %%edx, 60(%3)\n"
+ 	       "        addl $-64, %0\n"
+@@ -446,9 +554,9 @@ static unsigned long __copy_user_intel_nocache(void *to,
+ 	       "        shrl  $2, %0\n"
+ 	       "        andl $3, %%eax\n"
+ 	       "        cld\n"
+-	       "6:      rep; movsl\n"
++	       "6:      rep; "__copyuser_seg" movsl\n"
+ 	       "        movl %%eax,%0\n"
+-	       "7:      rep; movsb\n"
++	       "7:      rep; "__copyuser_seg" movsb\n"
+ 	       "8:\n"
+ 	       ".section .fixup,\"ax\"\n"
+ 	       "9:      lea 0(%%eax,%0,4),%0\n"
+@@ -488,32 +596,36 @@ static unsigned long __copy_user_intel_nocache(void *to,
+  */
+ unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
+ 					unsigned long size);
+-unsigned long __copy_user_intel(void __user *to, const void *from,
++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
++					unsigned long size);
++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
+ 					unsigned long size);
+ unsigned long __copy_user_zeroing_intel_nocache(void *to,
+ 				const void __user *from, unsigned long size);
+ #endif /* CONFIG_X86_INTEL_USERCOPY */
+ 
+ /* Generic arbitrary sized copy.  */
+-#define __copy_user(to, from, size)					\
++#define __copy_user(to, from, size, prefix, set, restore)		\
+ do {									\
+ 	int __d0, __d1, __d2;						\
+ 	__asm__ __volatile__(						\
++		set							\
+ 		"	cmp  $7,%0\n"					\
+ 		"	jbe  1f\n"					\
+ 		"	movl %1,%0\n"					\
+ 		"	negl %0\n"					\
+ 		"	andl $7,%0\n"					\
+ 		"	subl %0,%3\n"					\
+-		"4:	rep; movsb\n"					\
++		"4:	rep; "prefix"movsb\n"				\
+ 		"	movl %3,%0\n"					\
+ 		"	shrl $2,%0\n"					\
+ 		"	andl $3,%3\n"					\
+ 		"	.align 2,0x90\n"				\
+-		"0:	rep; movsl\n"					\
++		"0:	rep; "prefix"movsl\n"				\
+ 		"	movl %3,%0\n"					\
+-		"1:	rep; movsb\n"					\
++		"1:	rep; "prefix"movsb\n"				\
+ 		"2:\n"							\
++		restore							\
+ 		".section .fixup,\"ax\"\n"				\
+ 		"5:	addl %3,%0\n"					\
+ 		"	jmp 2b\n"					\
+@@ -538,14 +650,14 @@ do {									\
+ 		"	negl %0\n"					\
+ 		"	andl $7,%0\n"					\
+ 		"	subl %0,%3\n"					\
+-		"4:	rep; movsb\n"					\
++		"4:	rep; "__copyuser_seg"movsb\n"			\
+ 		"	movl %3,%0\n"					\
+ 		"	shrl $2,%0\n"					\
+ 		"	andl $3,%3\n"					\
+ 		"	.align 2,0x90\n"				\
+-		"0:	rep; movsl\n"					\
++		"0:	rep; "__copyuser_seg"movsl\n"			\
+ 		"	movl %3,%0\n"					\
+-		"1:	rep; movsb\n"					\
++		"1:	rep; "__copyuser_seg"movsb\n"			\
+ 		"2:\n"							\
+ 		".section .fixup,\"ax\"\n"				\
+ 		"5:	addl %3,%0\n"					\
+@@ -572,9 +684,9 @@ unsigned long __copy_to_user_ll(void __user *to, const void \
*from, + {
+ 	stac();
+ 	if (movsl_is_ok(to, from, n))
+-		__copy_user(to, from, n);
++		__copy_user(to, from, n, "", __COPYUSER_SET_ES, __COPYUSER_RESTORE_ES);
+ 	else
+-		n = __copy_user_intel(to, from, n);
++		n = __generic_copy_to_user_intel(to, from, n);
+ 	clac();
+ 	return n;
+ }
+@@ -598,10 +710,9 @@ unsigned long __copy_from_user_ll_nozero(void *to, const void \
__user *from, + {
+ 	stac();
+ 	if (movsl_is_ok(to, from, n))
+-		__copy_user(to, from, n);
++		__copy_user(to, from, n, __copyuser_seg, "", "");
+ 	else
+-		n = __copy_user_intel((void __user *)to,
+-				      (const void *)from, n);
++		n = __generic_copy_from_user_intel(to, from, n);
+ 	clac();
+ 	return n;
+ }
+@@ -632,60 +743,38 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, \
const void __user *fr + 	if (n > 64 && cpu_has_xmm2)
+ 		n = __copy_user_intel_nocache(to, from, n);
+ 	else
+-		__copy_user(to, from, n);
++		__copy_user(to, from, n, __copyuser_seg, "", "");
+ #else
+-	__copy_user(to, from, n);
++	__copy_user(to, from, n, __copyuser_seg, "", "");
+ #endif
+ 	clac();
+ 	return n;
+ }
+ EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
+ 
+-/**
+- * copy_to_user: - Copy a block of data into user space.
+- * @to:   Destination address, in user space.
+- * @from: Source address, in kernel space.
+- * @n:    Number of bytes to copy.
+- *
+- * Context: User context only.  This function may sleep.
+- *
+- * Copy data from kernel space to user space.
+- *
+- * Returns number of bytes that could not be copied.
+- * On success, this will be zero.
+- */
+-unsigned long
+-copy_to_user(void __user *to, const void *from, unsigned long n)
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++void __set_fs(mm_segment_t x)
+ {
+-	if (access_ok(VERIFY_WRITE, to, n))
+-		n = __copy_to_user(to, from, n);
+-	return n;
++	switch (x.seg) {
++	case 0:
++		loadsegment(gs, 0);
++		break;
++	case TASK_SIZE_MAX:
++		loadsegment(gs, __USER_DS);
++		break;
++	case -1UL:
++		loadsegment(gs, __KERNEL_DS);
++		break;
++	default:
++		BUG();
++	}
+ }
+-EXPORT_SYMBOL(copy_to_user);
++EXPORT_SYMBOL(__set_fs);
+ 
+-/**
+- * copy_from_user: - Copy a block of data from user space.
+- * @to:   Destination address, in kernel space.
+- * @from: Source address, in user space.
+- * @n:    Number of bytes to copy.
+- *
+- * Context: User context only.  This function may sleep.
+- *
+- * Copy data from user space to kernel space.
+- *
+- * Returns number of bytes that could not be copied.
+- * On success, this will be zero.
+- *
+- * If some data could not be copied, this function will pad the copied
+- * data to the requested size using zero bytes.
+- */
+-unsigned long
+-_copy_from_user(void *to, const void __user *from, unsigned long n)
++void set_fs(mm_segment_t x)
+ {
+-	if (access_ok(VERIFY_READ, from, n))
+-		n = __copy_from_user(to, from, n);
+-	else
+-		memset(to, 0, n);
+-	return n;
++	current_thread_info()->addr_limit = x;
++	__set_fs(x);
+ }
+-EXPORT_SYMBOL(_copy_from_user);
++EXPORT_SYMBOL(set_fs);
++#endif
+diff --git a/arch/x86/lib/usercopy_64.c b/arch/x86/lib/usercopy_64.c
+index 906fea3..0194a18 100644
+--- a/arch/x86/lib/usercopy_64.c
++++ b/arch/x86/lib/usercopy_64.c
+@@ -18,6 +18,7 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
+ 	might_fault();
+ 	/* no memory constraint because it doesn't change any memory gcc knows
+ 	   about */
++	pax_open_userland();
+ 	stac();
+ 	asm volatile(
+ 		"	testq  %[size8],%[size8]\n"
+@@ -39,9 +40,10 @@ unsigned long __clear_user(void __user *addr, unsigned long size)
+ 		_ASM_EXTABLE(0b,3b)
+ 		_ASM_EXTABLE(1b,2b)
+ 		: [size8] "=&c"(size), [dst] "=&D" (__d0)
+-		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr),
++		: [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(____m(addr)),
+ 		  [zero] "r" (0UL), [eight] "r" (8UL));
+ 	clac();
++	pax_close_userland();
+ 	return size;
+ }
+ EXPORT_SYMBOL(__clear_user);
+@@ -54,12 +56,11 @@ unsigned long clear_user(void __user *to, unsigned long n)
+ }
+ EXPORT_SYMBOL(clear_user);
+ 
+-unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
++unsigned long copy_in_user(void __user *to, const void __user *from, unsigned long \
len) + {
+-	if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) { 
+-		return copy_user_generic((__force void *)to, (__force void *)from, len);
+-	} 
+-	return len;		
++	if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len))
++		return copy_user_generic((void __force_kernel *)____m(to), (void __force_kernel \
*)____m(from), len); ++	return len;
+ }
+ EXPORT_SYMBOL(copy_in_user);
+ 
+@@ -69,11 +70,13 @@ EXPORT_SYMBOL(copy_in_user);
+  * it is not necessary to optimize tail handling.
+  */
+ unsigned long
+-copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)
++copy_user_handle_tail(char __user *to, char __user *from, unsigned long len, \
unsigned zerorest) + {
+ 	char c;
+ 	unsigned zero_len;
+ 
++	clac();
++	pax_close_userland();
+ 	for (; len; --len, to++) {
+ 		if (__get_user_nocheck(c, from++, sizeof(char)))
+ 			break;
+@@ -84,6 +87,5 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned \
zerorest) + 	for (c = 0, zero_len = len; zerorest && zero_len; --zero_len)
+ 		if (__put_user_nocheck(c, to++, sizeof(char)))
+ 			break;
+-	clac();
+ 	return len;
+ }
+diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
+index 23d8e5f..9ccc13a 100644
+--- a/arch/x86/mm/Makefile
++++ b/arch/x86/mm/Makefile
+@@ -28,3 +28,7 @@ obj-$(CONFIG_ACPI_NUMA)		+= srat.o
+ obj-$(CONFIG_NUMA_EMU)		+= numa_emulation.o
+ 
+ obj-$(CONFIG_MEMTEST)		+= memtest.o
++
++quote:="
++obj-$(CONFIG_X86_64)		+= uderef_64.o
++CFLAGS_uderef_64.o		:= $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
+diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
+index 903ec1e..c4166b2 100644
+--- a/arch/x86/mm/extable.c
++++ b/arch/x86/mm/extable.c
+@@ -6,12 +6,24 @@
+ static inline unsigned long
+ ex_insn_addr(const struct exception_table_entry *x)
+ {
+-	return (unsigned long)&x->insn + x->insn;
++	unsigned long reloc = 0;
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++	reloc = ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
++	return (unsigned long)&x->insn + x->insn + reloc;
+ }
+ static inline unsigned long
+ ex_fixup_addr(const struct exception_table_entry *x)
+ {
+-	return (unsigned long)&x->fixup + x->fixup;
++	unsigned long reloc = 0;
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++	reloc = ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
++	return (unsigned long)&x->fixup + x->fixup + reloc;
+ }
+ 
+ int fixup_exception(struct pt_regs *regs)
+@@ -20,7 +32,7 @@ int fixup_exception(struct pt_regs *regs)
+ 	unsigned long new_ip;
+ 
+ #ifdef CONFIG_PNPBIOS
+-	if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
++	if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
+ 		extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
+ 		extern u32 pnp_bios_is_utter_crap;
+ 		pnp_bios_is_utter_crap = 1;
+@@ -145,6 +157,13 @@ void sort_extable(struct exception_table_entry *start,
+ 		i += 4;
+ 		p->fixup -= i;
+ 		i += 4;
++
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
++		BUILD_BUG_ON(!IS_ENABLED(CONFIG_BUILDTIME_EXTABLE_SORT));
++		p->insn -= ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++		p->fixup -= ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR;
++#endif
++
+ 	}
+ }
+ 
+diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
+index 654be4a..a4a3da1 100644
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -14,11 +14,18 @@
+ #include <linux/hugetlb.h>		/* hstate_index_to_shift	*/
+ #include <linux/prefetch.h>		/* prefetchw			*/
+ #include <linux/context_tracking.h>	/* exception_enter(), ...	*/
++#include <linux/unistd.h>
++#include <linux/compiler.h>
+ 
+ #include <asm/traps.h>			/* dotraplinkage, ...		*/
+ #include <asm/pgalloc.h>		/* pgd_*(), ...			*/
+ #include <asm/kmemcheck.h>		/* kmemcheck_*(), ...		*/
+ #include <asm/fixmap.h>			/* VSYSCALL_START		*/
++#include <asm/tlbflush.h>
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++#include <asm/stacktrace.h>
++#endif
+ 
+ /*
+  * Page fault error code bits:
+@@ -56,7 +63,7 @@ static inline int __kprobes notify_page_fault(struct pt_regs \
*regs) + 	int ret = 0;
+ 
+ 	/* kprobe_running() needs smp_processor_id() */
+-	if (kprobes_built_in() && !user_mode_vm(regs)) {
++	if (kprobes_built_in() && !user_mode(regs)) {
+ 		preempt_disable();
+ 		if (kprobe_running() && kprobe_fault_handler(regs, 14))
+ 			ret = 1;
+@@ -117,7 +124,10 @@ check_prefetch_opcode(struct pt_regs *regs, unsigned char \
*instr, + 		return !instr_lo || (instr_lo>>1) == 1;
+ 	case 0x00:
+ 		/* Prefetch instruction is 0x0F0D or 0x0F18 */
+-		if (probe_kernel_address(instr, opcode))
++		if (user_mode(regs)) {
++			if (__copy_from_user_inatomic(&opcode, (unsigned char __force_user *)(instr), \
1)) ++				return 0;
++		} else if (probe_kernel_address(instr, opcode))
+ 			return 0;
+ 
+ 		*prefetch = (instr_lo == 0xF) &&
+@@ -151,7 +161,10 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, \
unsigned long addr) + 	while (instr < max_instr) {
+ 		unsigned char opcode;
+ 
+-		if (probe_kernel_address(instr, opcode))
++		if (user_mode(regs)) {
++			if (__copy_from_user_inatomic(&opcode, (unsigned char __force_user *)(instr), \
1)) ++				break;
++		} else if (probe_kernel_address(instr, opcode))
+ 			break;
+ 
+ 		instr++;
+@@ -182,6 +195,34 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long \
address, + 	force_sig_info(si_signo, &info, tsk);
+ }
+ 
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++static bool pax_is_fetch_fault(struct pt_regs *regs, unsigned long error_code, \
unsigned long address); ++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++static int pax_handle_fetch_fault(struct pt_regs *regs);
++#endif
++
++#ifdef CONFIG_PAX_PAGEEXEC
++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
++{
++	pgd_t *pgd;
++	pud_t *pud;
++	pmd_t *pmd;
++
++	pgd = pgd_offset(mm, address);
++	if (!pgd_present(*pgd))
++		return NULL;
++	pud = pud_offset(pgd, address);
++	if (!pud_present(*pud))
++		return NULL;
++	pmd = pmd_offset(pud, address);
++	if (!pmd_present(*pmd))
++		return NULL;
++	return pmd;
++}
++#endif
++
+ DEFINE_SPINLOCK(pgd_lock);
+ LIST_HEAD(pgd_list);
+ 
+@@ -232,10 +273,27 @@ void vmalloc_sync_all(void)
+ 	for (address = VMALLOC_START & PMD_MASK;
+ 	     address >= TASK_SIZE && address < FIXADDR_TOP;
+ 	     address += PMD_SIZE) {
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		unsigned long cpu;
++#else
+ 		struct page *page;
++#endif
+ 
+ 		spin_lock(&pgd_lock);
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
++			pgd_t *pgd = get_cpu_pgd(cpu, user);
++			pmd_t *ret;
++
++			ret = vmalloc_sync_one(pgd, address);
++			if (!ret)
++				break;
++			pgd = get_cpu_pgd(cpu, kernel);
++#else
+ 		list_for_each_entry(page, &pgd_list, lru) {
++			pgd_t *pgd;
+ 			spinlock_t *pgt_lock;
+ 			pmd_t *ret;
+ 
+@@ -243,8 +301,14 @@ void vmalloc_sync_all(void)
+ 			pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
+ 
+ 			spin_lock(pgt_lock);
+-			ret = vmalloc_sync_one(page_address(page), address);
++			pgd = page_address(page);
++#endif
++
++			ret = vmalloc_sync_one(pgd, address);
++
++#ifndef CONFIG_PAX_PER_CPU_PGD
+ 			spin_unlock(pgt_lock);
++#endif
+ 
+ 			if (!ret)
+ 				break;
+@@ -278,6 +342,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long \
address) + 	 * an interrupt in the middle of a task switch..
+ 	 */
+ 	pgd_paddr = read_cr3();
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	BUG_ON(__pa(get_cpu_pgd(smp_processor_id(), kernel)) != (pgd_paddr & \
__PHYSICAL_MASK)); ++	vmalloc_sync_one(__va(pgd_paddr + PAGE_SIZE), address);
++#endif
++
+ 	pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
+ 	if (!pmd_k)
+ 		return -1;
+@@ -373,11 +443,25 @@ static noinline __kprobes int vmalloc_fault(unsigned long \
address) + 	 * happen within a race in page table update. In the later
+ 	 * case just flush:
+ 	 */
+-	pgd = pgd_offset(current->active_mm, address);
++
+ 	pgd_ref = pgd_offset_k(address);
+ 	if (pgd_none(*pgd_ref))
+ 		return -1;
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	BUG_ON(__pa(get_cpu_pgd(smp_processor_id(), kernel)) != (read_cr3() & \
__PHYSICAL_MASK)); ++	pgd = pgd_offset_cpu(smp_processor_id(), user, address);
++	if (pgd_none(*pgd)) {
++		set_pgd(pgd, *pgd_ref);
++		arch_flush_lazy_mmu_mode();
++	} else {
++		BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
++	}
++	pgd = pgd_offset_cpu(smp_processor_id(), kernel, address);
++#else
++	pgd = pgd_offset(current->active_mm, address);
++#endif
++
+ 	if (pgd_none(*pgd)) {
+ 		set_pgd(pgd, *pgd_ref);
+ 		arch_flush_lazy_mmu_mode();
+@@ -543,7 +627,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long \
address) + static int is_errata100(struct pt_regs *regs, unsigned long address)
+ {
+ #ifdef CONFIG_X86_64
+-	if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) && (address >> 32))
++	if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) && (address >> 32))
+ 		return 1;
+ #endif
+ 	return 0;
+@@ -570,7 +654,7 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long \
address) + }
+ 
+ static const char nx_warning[] = KERN_CRIT
+-"kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n";
++"kernel tried to execute NX-protected page - exploit attempt? (uid: %d, task: %s, \
pid: %d)\n"; + 
+ static void
+ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
+@@ -579,15 +663,27 @@ show_fault_oops(struct pt_regs *regs, unsigned long \
error_code, + 	if (!oops_may_print())
+ 		return;
+ 
+-	if (error_code & PF_INSTR) {
++	if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR)) {
+ 		unsigned int level;
+ 
+ 		pte_t *pte = lookup_address(address, &level);
+ 
+ 		if (pte && pte_present(*pte) && !pte_exec(*pte))
+-			printk(nx_warning, from_kuid(&init_user_ns, current_uid()));
++			printk(nx_warning, from_kuid_munged(&init_user_ns, current_uid()), \
current->comm, task_pid_nr(current)); + 	}
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	if (init_mm.start_code <= address && address < init_mm.end_code) {
++		if (current->signal->curr_ip)
++			printk(KERN_ERR "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_ERR "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
++
+ 	printk(KERN_ALERT "BUG: unable to handle kernel ");
+ 	if (address < PAGE_SIZE)
+ 		printk(KERN_CONT "NULL pointer dereference");
+@@ -750,6 +846,22 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long \
error_code, + 				return;
+ 		}
+ #endif
++
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++		if (pax_is_fetch_fault(regs, error_code, address)) {
++
++#ifdef CONFIG_PAX_EMUTRAMP
++			switch (pax_handle_fetch_fault(regs)) {
++			case 2:
++				return;
++			}
++#endif
++
++			pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
++			do_group_exit(SIGKILL);
++		}
++#endif
++
+ 		/* Kernel addresses are always protection faults: */
+ 		if (address >= TASK_SIZE)
+ 			error_code |= PF_PROT;
+@@ -835,7 +947,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, \
unsigned long address, + 	if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) {
+ 		printk(KERN_ERR
+ 	"MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",
+-			tsk->comm, tsk->pid, address);
++			tsk->comm, task_pid_nr(tsk), address);
+ 		code = BUS_MCEERR_AR;
+ 	}
+ #endif
+@@ -898,6 +1010,99 @@ static int spurious_fault_check(unsigned long error_code, \
pte_t *pte) + 	return 1;
+ }
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
++static int pax_handle_pageexec_fault(struct pt_regs *regs, struct mm_struct *mm, \
unsigned long address, unsigned long error_code) ++{
++	pte_t *pte;
++	pmd_t *pmd;
++	spinlock_t *ptl;
++	unsigned char pte_mask;
++
++	if ((__supported_pte_mask & _PAGE_NX) || (error_code & (PF_PROT|PF_USER)) != \
(PF_PROT|PF_USER) || v8086_mode(regs) || ++	    !(mm->pax_flags & MF_PAX_PAGEEXEC))
++		return 0;
++
++	/* PaX: it's our fault, let's handle it if we can */
++
++	/* PaX: take a look at read faults before acquiring any locks */
++	if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
++		/* instruction fetch attempt from a protected page in user mode */
++		up_read(&mm->mmap_sem);
++
++#ifdef CONFIG_PAX_EMUTRAMP
++		switch (pax_handle_fetch_fault(regs)) {
++		case 2:
++			return 1;
++		}
++#endif
++
++		pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
++		do_group_exit(SIGKILL);
++	}
++
++	pmd = pax_get_pmd(mm, address);
++	if (unlikely(!pmd))
++		return 0;
++
++	pte = pte_offset_map_lock(mm, pmd, address, &ptl);
++	if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
++		pte_unmap_unlock(pte, ptl);
++		return 0;
++	}
++
++	if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
++		/* write attempt to a protected page in user mode */
++		pte_unmap_unlock(pte, ptl);
++		return 0;
++	}
++
++#ifdef CONFIG_SMP
++	if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), \
mm->context.cpu_user_cs_mask))) ++#else
++	if (likely(address > get_limit(regs->cs)))
++#endif
++	{
++		set_pte(pte, pte_mkread(*pte));
++		__flush_tlb_one(address);
++		pte_unmap_unlock(pte, ptl);
++		up_read(&mm->mmap_sem);
++		return 1;
++	}
++
++	pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << \
(_PAGE_BIT_DIRTY-1)); ++
++	/*
++	 * PaX: fill DTLB with user rights and retry
++	 */
++	__asm__ __volatile__ (
++		"orb %2,(%1)\n"
++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
++/*
++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
++ * page fault when examined during a TLB load attempt. this is true not only
++ * for PTEs holding a non-present entry but also present entries that will
++ * raise a page fault (such as those set up by PaX, or the copy-on-write
++ * mechanism). in effect it means that we do *not* need to flush the TLBs
++ * for our target pages since their PTEs are simply not in the TLBs at all.
++
++ * the best thing in omitting it is that we gain around 15-20% speed in the
++ * fast path of the page fault handler and can get rid of tracing since we
++ * can no longer flush unintended entries.
++ */
++		"invlpg (%0)\n"
++#endif
++		__copyuser_seg"testb $0,(%0)\n"
++		"xorb %3,(%1)\n"
++		:
++		: "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER)
++		: "memory", "cc");
++	pte_unmap_unlock(pte, ptl);
++	up_read(&mm->mmap_sem);
++	return 1;
++}
++#endif
++
+ /*
+  * Handle a spurious fault caused by a stale TLB entry.
+  *
+@@ -964,6 +1169,9 @@ int show_unhandled_signals = 1;
+ static inline int
+ access_error(unsigned long error_code, struct vm_area_struct *vma)
+ {
++	if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR) && \
!(vma->vm_flags & VM_EXEC)) ++		return 1;
++
+ 	if (error_code & PF_WRITE) {
+ 		/* write, present and write, not present: */
+ 		if (unlikely(!(vma->vm_flags & VM_WRITE)))
+@@ -992,7 +1200,7 @@ static inline bool smap_violation(int error_code, struct \
pt_regs *regs) + 	if (error_code & PF_USER)
+ 		return false;
+ 
+-	if (!user_mode_vm(regs) && (regs->flags & X86_EFLAGS_AC))
++	if (!user_mode(regs) && (regs->flags & X86_EFLAGS_AC))
+ 		return false;
+ 
+ 	return true;
+@@ -1008,18 +1216,33 @@ __do_page_fault(struct pt_regs *regs, unsigned long \
error_code) + {
+ 	struct vm_area_struct *vma;
+ 	struct task_struct *tsk;
+-	unsigned long address;
+ 	struct mm_struct *mm;
+ 	int fault;
+ 	int write = error_code & PF_WRITE;
+ 	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+ 					(write ? FAULT_FLAG_WRITE : 0);
+ 
+-	tsk = current;
+-	mm = tsk->mm;
+-
+ 	/* Get the faulting address: */
+-	address = read_cr2();
++	unsigned long address = read_cr2();
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++	if (!user_mode(regs) && address < 2 * pax_user_shadow_base) {
++		if (!search_exception_tables(regs->ip)) {
++			printk(KERN_ERR "PAX: please report this to pageexec at freemail.hu\n");
++			bad_area_nosemaphore(regs, error_code, address);
++			return;
++		}
++		if (address < pax_user_shadow_base) {
++			printk(KERN_ERR "PAX: please report this to pageexec at freemail.hu\n");
++			printk(KERN_ERR "PAX: faulting IP: %pS\n", (void *)regs->ip);
++			show_trace_log_lvl(NULL, NULL, (void *)regs->sp, regs->bp, KERN_ERR);
++		} else
++			address -= pax_user_shadow_base;
++	}
++#endif
++
++	tsk = current;
++	mm = tsk->mm;
+ 
+ 	/*
+ 	 * Detect and handle instructions that would cause a page fault for
+@@ -1080,7 +1303,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long \
error_code) + 	 * User-mode registers count as a user access even for any
+ 	 * potential system fault or CPU buglet:
+ 	 */
+-	if (user_mode_vm(regs)) {
++	if (user_mode(regs)) {
+ 		local_irq_enable();
+ 		error_code |= PF_USER;
+ 	} else {
+@@ -1142,6 +1365,11 @@ retry:
+ 		might_sleep();
+ 	}
+ 
++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
++	if (pax_handle_pageexec_fault(regs, mm, address, error_code))
++		return;
++#endif
++
+ 	vma = find_vma(mm, address);
+ 	if (unlikely(!vma)) {
+ 		bad_area(regs, error_code, address);
+@@ -1153,18 +1381,24 @@ retry:
+ 		bad_area(regs, error_code, address);
+ 		return;
+ 	}
+-	if (error_code & PF_USER) {
+-		/*
+-		 * Accessing the stack below %sp is always a bug.
+-		 * The large cushion allows instructions like enter
+-		 * and pusha to work. ("enter $65535, $31" pushes
+-		 * 32 pointers and then decrements %sp by 65535.)
+-		 */
+-		if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
+-			bad_area(regs, error_code, address);
+-			return;
+-		}
++	/*
++	 * Accessing the stack below %sp is always a bug.
++	 * The large cushion allows instructions like enter
++	 * and pusha to work. ("enter $65535, $31" pushes
++	 * 32 pointers and then decrements %sp by 65535.)
++	 */
++	if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < \
task_pt_regs(tsk)->sp)) { ++		bad_area(regs, error_code, address);
++		return;
+ 	}
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (unlikely((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE \
- 1 < address - SEGMEXEC_TASK_SIZE - 1)) { ++		bad_area(regs, error_code, address);
++		return;
++	}
++#endif
++
+ 	if (unlikely(expand_stack(vma, address))) {
+ 		bad_area(regs, error_code, address);
+ 		return;
+@@ -1230,3 +1464,292 @@ do_page_fault(struct pt_regs *regs, unsigned long \
error_code) + 	__do_page_fault(regs, error_code);
+ 	exception_exit(prev_state);
+ }
++
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++static bool pax_is_fetch_fault(struct pt_regs *regs, unsigned long error_code, \
unsigned long address) ++{
++	struct mm_struct *mm = current->mm;
++	unsigned long ip = regs->ip;
++
++	if (v8086_mode(regs))
++		ip = ((regs->cs & 0xffff) << 4) + (ip & 0xffff);
++
++#ifdef CONFIG_PAX_PAGEEXEC
++	if (mm->pax_flags & MF_PAX_PAGEEXEC) {
++		if ((__supported_pte_mask & _PAGE_NX) && (error_code & PF_INSTR))
++			return true;
++		if (!(error_code & (PF_PROT | PF_WRITE)) && ip == address)
++			return true;
++		return false;
++	}
++#endif
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (mm->pax_flags & MF_PAX_SEGMEXEC) {
++		if (!(error_code & (PF_PROT | PF_WRITE)) && (ip + SEGMEXEC_TASK_SIZE == address))
++			return true;
++		return false;
++	}
++#endif
++
++	return false;
++}
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
++{
++	int err;
++
++	do { /* PaX: libffi trampoline emulation */
++		unsigned char mov, jmp;
++		unsigned int addr1, addr2;
++
++#ifdef CONFIG_X86_64
++		if ((regs->ip + 9) >> 32)
++			break;
++#endif
++
++		err = get_user(mov, (unsigned char __user *)regs->ip);
++		err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
++		err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
++		err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
++
++		if (err)
++			break;
++
++		if (mov == 0xB8 && jmp == 0xE9) {
++			regs->ax = addr1;
++			regs->ip = (unsigned int)(regs->ip + addr2 + 10);
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: gcc trampoline emulation #1 */
++		unsigned char mov1, mov2;
++		unsigned short jmp;
++		unsigned int addr1, addr2;
++
++#ifdef CONFIG_X86_64
++		if ((regs->ip + 11) >> 32)
++			break;
++#endif
++
++		err = get_user(mov1, (unsigned char __user *)regs->ip);
++		err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
++		err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
++		err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
++		err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
++
++		if (err)
++			break;
++
++		if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
++			regs->cx = addr1;
++			regs->ax = addr2;
++			regs->ip = addr2;
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: gcc trampoline emulation #2 */
++		unsigned char mov, jmp;
++		unsigned int addr1, addr2;
++
++#ifdef CONFIG_X86_64
++		if ((regs->ip + 9) >> 32)
++			break;
++#endif
++
++		err = get_user(mov, (unsigned char __user *)regs->ip);
++		err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
++		err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
++		err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
++
++		if (err)
++			break;
++
++		if (mov == 0xB9 && jmp == 0xE9) {
++			regs->cx = addr1;
++			regs->ip = (unsigned int)(regs->ip + addr2 + 10);
++			return 2;
++		}
++	} while (0);
++
++	return 1; /* PaX in action */
++}
++
++#ifdef CONFIG_X86_64
++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
++{
++	int err;
++
++	do { /* PaX: libffi trampoline emulation */
++		unsigned short mov1, mov2, jmp1;
++		unsigned char stcclc, jmp2;
++		unsigned long addr1, addr2;
++
++		err = get_user(mov1, (unsigned short __user *)regs->ip);
++		err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
++		err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
++		err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
++		err |= get_user(stcclc, (unsigned char __user *)(regs->ip + 20));
++		err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 21));
++		err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 23));
++
++		if (err)
++			break;
++
++		if (mov1 == 0xBB49 && mov2 == 0xBA49 && (stcclc == 0xF8 || stcclc == 0xF9) && \
jmp1 == 0xFF49 && jmp2 == 0xE3) { ++			regs->r11 = addr1;
++			regs->r10 = addr2;
++			if (stcclc == 0xF8)
++				regs->flags &= ~X86_EFLAGS_CF;
++			else
++				regs->flags |= X86_EFLAGS_CF;
++			regs->ip = addr1;
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: gcc trampoline emulation #1 */
++		unsigned short mov1, mov2, jmp1;
++		unsigned char jmp2;
++		unsigned int addr1;
++		unsigned long addr2;
++
++		err = get_user(mov1, (unsigned short __user *)regs->ip);
++		err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
++		err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
++		err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
++		err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
++		err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
++
++		if (err)
++			break;
++
++		if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
++			regs->r11 = addr1;
++			regs->r10 = addr2;
++			regs->ip = addr1;
++			return 2;
++		}
++	} while (0);
++
++	do { /* PaX: gcc trampoline emulation #2 */
++		unsigned short mov1, mov2, jmp1;
++		unsigned char jmp2;
++		unsigned long addr1, addr2;
++
++		err = get_user(mov1, (unsigned short __user *)regs->ip);
++		err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
++		err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
++		err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
++		err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
++		err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
++
++		if (err)
++			break;
++
++		if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
++			regs->r11 = addr1;
++			regs->r10 = addr2;
++			regs->ip = addr1;
++			return 2;
++		}
++	} while (0);
++
++	return 1; /* PaX in action */
++}
++#endif
++
++/*
++ * PaX: decide what to do with offenders (regs->ip = fault address)
++ *
++ * returns 1 when task should be killed
++ *         2 when gcc trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++	if (v8086_mode(regs))
++		return 1;
++
++	if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
++		return 1;
++
++#ifdef CONFIG_X86_32
++	return pax_handle_fetch_fault_32(regs);
++#else
++	if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
++		return pax_handle_fetch_fault_32(regs);
++	else
++		return pax_handle_fetch_fault_64(regs);
++#endif
++}
++#endif
++
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++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, (unsigned char __force_user *)pc+i))
++			printk(KERN_CONT "?? ");
++		else
++			printk(KERN_CONT "%02x ", c);
++	}
++	printk("\n");
++
++	printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
++	for (i = -1; i < 80 / (long)sizeof(long); i++) {
++		unsigned long c;
++		if (get_user(c, (unsigned long __force_user *)sp+i)) {
++#ifdef CONFIG_X86_32
++			printk(KERN_CONT "???????? ");
++#else
++			if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)))
++				printk(KERN_CONT "???????? ???????? ");
++			else
++				printk(KERN_CONT "???????????????? ");
++#endif
++		} else {
++#ifdef CONFIG_X86_64
++			if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))) {
++				printk(KERN_CONT "%08x ", (unsigned int)c);
++				printk(KERN_CONT "%08x ", (unsigned int)(c >> 32));
++			} else
++#endif
++				printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
++		}
++	}
++	printk("\n");
++}
++#endif
++
++/**
++ * probe_kernel_write(): safely attempt to write to a location
++ * @dst: address to write to
++ * @src: pointer to the data that shall be written
++ * @size: size of the data chunk
++ *
++ * Safely write to address @dst from the buffer at @src.  If a kernel fault
++ * happens, handle that and return -EFAULT.
++ */
++long notrace probe_kernel_write(void *dst, const void *src, size_t size)
++{
++	long ret;
++	mm_segment_t old_fs = get_fs();
++
++	set_fs(KERNEL_DS);
++	pagefault_disable();
++	pax_open_kernel();
++	ret = __copy_to_user_inatomic((void __force_user *)dst, src, size);
++	pax_close_kernel();
++	pagefault_enable();
++	set_fs(old_fs);
++
++	return ret ? -EFAULT : 0;
++}
+diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
+index dd74e46..7d26398 100644
+--- a/arch/x86/mm/gup.c
++++ b/arch/x86/mm/gup.c
+@@ -255,7 +255,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int \
write, + 	addr = start;
+ 	len = (unsigned long) nr_pages << PAGE_SHIFT;
+ 	end = start + len;
+-	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
++	if (unlikely(!__access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+ 					(void __user *)start, len)))
+ 		return 0;
+ 
+diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
+index 4500142..53a363c 100644
+--- a/arch/x86/mm/highmem_32.c
++++ b/arch/x86/mm/highmem_32.c
+@@ -45,7 +45,11 @@ void *kmap_atomic_prot(struct page *page, pgprot_t prot)
+ 	idx = type + KM_TYPE_NR*smp_processor_id();
+ 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ 	BUG_ON(!pte_none(*(kmap_pte-idx)));
++
++	pax_open_kernel();
+ 	set_pte(kmap_pte-idx, mk_pte(page, prot));
++	pax_close_kernel();
++
+ 	arch_flush_lazy_mmu_mode();
+ 
+ 	return (void *)vaddr;
+diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
+index 7e73e8c..11d3b86 100644
+--- a/arch/x86/mm/hugetlbpage.c
++++ b/arch/x86/mm/hugetlbpage.c
+@@ -84,23 +84,30 @@ int pud_huge(pud_t pud)
+ #ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+ static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
+ 		unsigned long addr, unsigned long len,
+-		unsigned long pgoff, unsigned long flags)
++		unsigned long pgoff, unsigned long flags, unsigned long offset)
+ {
+ 	struct hstate *h = hstate_file(file);
+ 	struct vm_unmapped_area_info info;
+-
++	
+ 	info.flags = 0;
+ 	info.length = len;
+ 	info.low_limit = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++	if (current->mm->pax_flags & MF_PAX_RANDMMAP)
++		info.low_limit += current->mm->delta_mmap;
++#endif
++
+ 	info.high_limit = TASK_SIZE;
+ 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+ 	info.align_offset = 0;
++	info.threadstack_offset = offset;
+ 	return vm_unmapped_area(&info);
+ }
+ 
+ static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
+ 		unsigned long addr0, unsigned long len,
+-		unsigned long pgoff, unsigned long flags)
++		unsigned long pgoff, unsigned long flags, unsigned long offset)
+ {
+ 	struct hstate *h = hstate_file(file);
+ 	struct vm_unmapped_area_info info;
+@@ -112,6 +119,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 = offset;
+ 	addr = vm_unmapped_area(&info);
+ 
+ 	/*
+@@ -124,6 +132,12 @@ static unsigned long hugetlb_get_unmapped_area_topdown(struct \
file *file, + 		VM_BUG_ON(addr != -ENOMEM);
+ 		info.flags = 0;
+ 		info.low_limit = TASK_UNMAPPED_BASE;
++
++#ifdef CONFIG_PAX_RANDMMAP
++		if (current->mm->pax_flags & MF_PAX_RANDMMAP)
++			info.low_limit += current->mm->delta_mmap;
++#endif
++
+ 		info.high_limit = TASK_SIZE;
+ 		addr = vm_unmapped_area(&info);
+ 	}
+@@ -138,10 +152,20 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long \
addr, + 	struct hstate *h = hstate_file(file);
+ 	struct mm_struct *mm = current->mm;
+ 	struct vm_area_struct *vma;
++	unsigned long pax_task_size = TASK_SIZE;
++	unsigned long offset = gr_rand_threadstack_offset(mm, file, flags);
+ 
+ 	if (len & ~huge_page_mask(h))
+ 		return -EINVAL;
+-	if (len > TASK_SIZE)
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (mm->pax_flags & MF_PAX_SEGMEXEC)
++		pax_task_size = SEGMEXEC_TASK_SIZE;
++#endif
++
++	pax_task_size -= PAGE_SIZE;
++
++	if (len > pax_task_size)
+ 		return -ENOMEM;
+ 
+ 	if (flags & MAP_FIXED) {
+@@ -150,19 +174,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, huge_page_size(h));
+ 		vma = find_vma(mm, addr);
+-		if (TASK_SIZE - len >= addr &&
+-		    (!vma || addr + len <= vma->vm_start))
++		if (pax_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);
+ }
+ 
+ #endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
+diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
+index 04664cd..dae6e5d 100644
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -4,6 +4,7 @@
+ #include <linux/swap.h>
+ #include <linux/memblock.h>
+ #include <linux/bootmem.h>	/* for max_low_pfn */
++#include <linux/tboot.h>
+ 
+ #include <asm/cacheflush.h>
+ #include <asm/e820.h>
+@@ -17,6 +18,8 @@
+ #include <asm/proto.h>
+ #include <asm/dma.h>		/* for MAX_DMA_PFN */
+ #include <asm/microcode.h>
++#include <asm/desc.h>
++#include <asm/bios_ebda.h>
+ 
+ #include "mm_internal.h"
+ 
+@@ -465,7 +468,18 @@ void __init init_mem_mapping(void)
+ 	early_ioremap_page_table_range_init();
+ #endif
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	clone_pgd_range(get_cpu_pgd(0, kernel) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++	clone_pgd_range(get_cpu_pgd(0, user) + KERNEL_PGD_BOUNDARY,
++			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++			KERNEL_PGD_PTRS);
++	load_cr3(get_cpu_pgd(0, kernel));
++#else
+ 	load_cr3(swapper_pg_dir);
++#endif
++
+ 	__flush_tlb_all();
+ 
+ 	early_memtest(0, max_pfn_mapped << PAGE_SHIFT);
+@@ -481,10 +495,40 @@ void __init init_mem_mapping(void)
+  * Access has to be given to non-kernel-ram areas as well, these contain the PCI
+  * mmio resources as well as potential bios/acpi data regions.
+  */
++
++#ifdef CONFIG_GRKERNSEC_KMEM
++static unsigned int ebda_start __read_only;
++static unsigned int ebda_end __read_only;
++#endif
++
+ int devmem_is_allowed(unsigned long pagenr)
+ {
+-	if (pagenr < 256)
++#ifdef CONFIG_GRKERNSEC_KMEM
++	/* allow BDA */
++	if (!pagenr)
+ 		return 1;
++	/* allow EBDA */
++	if (pagenr >= ebda_start && pagenr < ebda_end)
++		return 1;
++	/* if tboot is in use, allow access to its hardcoded serial log range */
++	if (tboot_enabled() && ((0x60000 >> PAGE_SHIFT) <= pagenr) && (pagenr < (0x68000 \
>> PAGE_SHIFT))) ++		return 1;
++#else
++	if (!pagenr)
++		return 1;
++#ifdef CONFIG_VM86
++	if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
++		return 1;
++#endif
++#endif
++
++	if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> \
PAGE_SHIFT)) ++		return 1;
++#ifdef CONFIG_GRKERNSEC_KMEM
++	/* throw out everything else below 1MB */
++	if (pagenr <= 256)
++		return 0;
++#endif
+ 	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
+ 		return 0;
+ 	if (!page_is_ram(pagenr))
+@@ -530,8 +574,117 @@ void free_init_pages(char *what, unsigned long begin, unsigned \
long end) + #endif
+ }
+ 
++#ifdef CONFIG_GRKERNSEC_KMEM
++static inline void gr_init_ebda(void)
++{
++	unsigned int ebda_addr;
++	unsigned int ebda_size = 0;
++
++	ebda_addr = get_bios_ebda();
++	if (ebda_addr) {
++		ebda_size = *(unsigned char *)phys_to_virt(ebda_addr);
++		ebda_size <<= 10;
++	}
++	if (ebda_addr && ebda_size) {
++		ebda_start = ebda_addr >> PAGE_SHIFT;
++		ebda_end = min((unsigned int)PAGE_ALIGN(ebda_addr + ebda_size), (unsigned \
int)0xa0000) >> PAGE_SHIFT; ++	} else {
++		ebda_start = 0x9f000 >> PAGE_SHIFT;
++		ebda_end = 0xa0000 >> PAGE_SHIFT;
++	}
++}
++#else
++static inline void gr_init_ebda(void) { }
++#endif
++
+ void free_initmem(void)
+ {
++#ifdef CONFIG_PAX_KERNEXEC
++#ifdef CONFIG_X86_32
++	/* PaX: limit KERNEL_CS to actual size */
++	unsigned long addr, limit;
++	struct desc_struct d;
++	int cpu;
++#else
++	pgd_t *pgd;
++	pud_t *pud;
++	pmd_t *pmd;
++	unsigned long addr, end;
++#endif
++#endif
++
++	gr_init_ebda();
++
++#ifdef CONFIG_PAX_KERNEXEC
++#ifdef CONFIG_X86_32
++	limit = paravirt_enabled() ? ktva_ktla(0xffffffff) : (unsigned long)&_etext;
++	limit = (limit - 1UL) >> PAGE_SHIFT;
++
++	memset(__LOAD_PHYSICAL_ADDR + PAGE_OFFSET, POISON_FREE_INITMEM, PAGE_SIZE);
++	for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
++		pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), \
limit, 0x9B, 0xC); ++		write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, \
&d, DESCTYPE_S); ++		write_gdt_entry(get_cpu_gdt_table(cpu), \
GDT_ENTRY_KERNEXEC_KERNEL_CS, &d, DESCTYPE_S); ++	}
++
++	/* PaX: make KERNEL_CS read-only */
++	addr = PFN_ALIGN(ktla_ktva((unsigned long)&_text));
++	if (!paravirt_enabled())
++		set_memory_ro(addr, (PFN_ALIGN(_sdata) - addr) >> PAGE_SHIFT);
++/*
++		for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_sdata; addr \
+= PMD_SIZE) { ++			pgd = pgd_offset_k(addr);
++			pud = pud_offset(pgd, addr);
++			pmd = pmd_offset(pud, addr);
++			set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
++		}
++*/
++#ifdef CONFIG_X86_PAE
++	set_memory_nx(PFN_ALIGN(__init_begin), (PFN_ALIGN(__init_end) - \
PFN_ALIGN(__init_begin)) >> PAGE_SHIFT); ++/*
++	for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr \
+= PMD_SIZE) { ++		pgd = pgd_offset_k(addr);
++		pud = pud_offset(pgd, addr);
++		pmd = pmd_offset(pud, addr);
++	set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
++	}
++*/
++#endif
++
++#ifdef CONFIG_MODULES
++	set_memory_4k((unsigned long)MODULES_EXEC_VADDR, (MODULES_EXEC_END - \
MODULES_EXEC_VADDR) >> PAGE_SHIFT); ++#endif
++
++#else
++	/* PaX: make kernel code/rodata read-only, rest non-executable */
++	for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; \
addr += PMD_SIZE) { ++		pgd = pgd_offset_k(addr);
++		pud = pud_offset(pgd, addr);
++		pmd = pmd_offset(pud, addr);
++		if (!pmd_present(*pmd))
++			continue;
++		if ((unsigned long)_text <= addr && addr < (unsigned long)_sdata)
++			set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
++		else
++			set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
++	}
++
++	addr = (unsigned long)__va(__pa(__START_KERNEL_map));
++	end = addr + KERNEL_IMAGE_SIZE;
++	for (; addr < end; addr += PMD_SIZE) {
++	pgd = pgd_offset_k(addr);
++		pud = pud_offset(pgd, addr);
++		pmd = pmd_offset(pud, addr);
++		if (!pmd_present(*pmd))
++			continue;
++		if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned \
long)__va(__pa(_sdata))) ++			set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
++	}
++#endif
++
++	flush_tlb_all();
++#endif
++
+ 	free_init_pages("unused kernel",
+ 			(unsigned long)(&__init_begin),
+ 			(unsigned long)(&__init_end));
+diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
+index 4287f1f..3b99c71 100644
+--- a/arch/x86/mm/init_32.c
++++ b/arch/x86/mm/init_32.c
+@@ -62,33 +62,6 @@ static noinline int do_test_wp_bit(void);
+ bool __read_mostly __vmalloc_start_set = false;
+ 
+ /*
+- * Creates a middle page table and puts a pointer to it in the
+- * given global directory entry. This only returns the gd entry
+- * in non-PAE compilation mode, since the middle layer is folded.
+- */
+-static pmd_t * __init one_md_table_init(pgd_t *pgd)
+-{
+-	pud_t *pud;
+-	pmd_t *pmd_table;
+-
+-#ifdef CONFIG_X86_PAE
+-	if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
+-		pmd_table = (pmd_t *)alloc_low_page();
+-		paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
+-		set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
+-		pud = pud_offset(pgd, 0);
+-		BUG_ON(pmd_table != pmd_offset(pud, 0));
+-
+-		return pmd_table;
+-	}
+-#endif
+-	pud = pud_offset(pgd, 0);
+-	pmd_table = pmd_offset(pud, 0);
+-
+-	return pmd_table;
+-}
+-
+-/*
+  * Create a page table and place a pointer to it in a middle page
+  * directory entry:
+  */
+@@ -98,13 +71,28 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
+ 		pte_t *page_table = (pte_t *)alloc_low_page();
+ 
+ 		paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
++		set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
++#else
+ 		set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
++#endif
+ 		BUG_ON(page_table != pte_offset_kernel(pmd, 0));
+ 	}
+ 
+ 	return pte_offset_kernel(pmd, 0);
+ }
+ 
++static pmd_t * __init one_md_table_init(pgd_t *pgd)
++{
++	pud_t *pud;
++	pmd_t *pmd_table;
++
++	pud = pud_offset(pgd, 0);
++	pmd_table = pmd_offset(pud, 0);
++
++	return pmd_table;
++}
++
+ pmd_t * __init populate_extra_pmd(unsigned long vaddr)
+ {
+ 	int pgd_idx = pgd_index(vaddr);
+@@ -208,6 +196,7 @@ page_table_range_init(unsigned long start, unsigned long end, \
pgd_t *pgd_base) + 	int pgd_idx, pmd_idx;
+ 	unsigned long vaddr;
+ 	pgd_t *pgd;
++	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte = NULL;
+ 	unsigned long count = page_table_range_init_count(start, end);
+@@ -222,8 +211,13 @@ page_table_range_init(unsigned long start, unsigned long end, \
pgd_t *pgd_base) + 	pgd = pgd_base + pgd_idx;
+ 
+ 	for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+-		pmd = one_md_table_init(pgd);
+-		pmd = pmd + pmd_index(vaddr);
++		pud = pud_offset(pgd, vaddr);
++		pmd = pmd_offset(pud, vaddr);
++
++#ifdef CONFIG_X86_PAE
++		paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
++#endif
++
+ 		for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
+ 							pmd++, pmd_idx++) {
+ 			pte = page_table_kmap_check(one_page_table_init(pmd),
+@@ -235,11 +229,20 @@ page_table_range_init(unsigned long start, unsigned long end, \
pgd_t *pgd_base) + 	}
+ }
+ 
+-static inline int is_kernel_text(unsigned long addr)
++static inline int is_kernel_text(unsigned long start, unsigned long end)
+ {
+-	if (addr >= (unsigned long)_text && addr <= (unsigned long)__init_end)
+-		return 1;
+-	return 0;
++	if ((start > ktla_ktva((unsigned long)_etext) ||
++	     end <= ktla_ktva((unsigned long)_stext)) &&
++	    (start > ktla_ktva((unsigned long)_einittext) ||
++	     end <= ktla_ktva((unsigned long)_sinittext)) &&
++
++#ifdef CONFIG_ACPI_SLEEP
++	    (start > (unsigned long)__va(acpi_wakeup_address) + 0x4000 || end <= (unsigned \
long)__va(acpi_wakeup_address)) && ++#endif
++
++	    (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
++		return 0;
++	return 1;
+ }
+ 
+ /*
+@@ -256,9 +259,10 @@ kernel_physical_mapping_init(unsigned long start,
+ 	unsigned long last_map_addr = end;
+ 	unsigned long start_pfn, end_pfn;
+ 	pgd_t *pgd_base = swapper_pg_dir;
+-	int pgd_idx, pmd_idx, pte_ofs;
++	unsigned int pgd_idx, pmd_idx, pte_ofs;
+ 	unsigned long pfn;
+ 	pgd_t *pgd;
++	pud_t *pud;
+ 	pmd_t *pmd;
+ 	pte_t *pte;
+ 	unsigned pages_2m, pages_4k;
+@@ -291,8 +295,13 @@ repeat:
+ 	pfn = start_pfn;
+ 	pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
+ 	pgd = pgd_base + pgd_idx;
+-	for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
+-		pmd = one_md_table_init(pgd);
++	for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
++		pud = pud_offset(pgd, 0);
++		pmd = pmd_offset(pud, 0);
++
++#ifdef CONFIG_X86_PAE
++		paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
++#endif
+ 
+ 		if (pfn >= end_pfn)
+ 			continue;
+@@ -304,14 +313,13 @@ repeat:
+ #endif
+ 		for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
+ 		     pmd++, pmd_idx++) {
+-			unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
++			unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
+ 
+ 			/*
+ 			 * Map with big pages if possible, otherwise
+ 			 * create normal page tables:
+ 			 */
+ 			if (use_pse) {
+-				unsigned int addr2;
+ 				pgprot_t prot = PAGE_KERNEL_LARGE;
+ 				/*
+ 				 * first pass will use the same initial
+@@ -322,11 +330,7 @@ repeat:
+ 						 _PAGE_PSE);
+ 
+ 				pfn &= PMD_MASK >> PAGE_SHIFT;
+-				addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
+-					PAGE_OFFSET + PAGE_SIZE-1;
+-
+-				if (is_kernel_text(addr) ||
+-				    is_kernel_text(addr2))
++				if (is_kernel_text(address, address + PMD_SIZE))
+ 					prot = PAGE_KERNEL_LARGE_EXEC;
+ 
+ 				pages_2m++;
+@@ -343,7 +347,7 @@ repeat:
+ 			pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
+ 			pte += pte_ofs;
+ 			for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
+-			     pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
++			     pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
+ 				pgprot_t prot = PAGE_KERNEL;
+ 				/*
+ 				 * first pass will use the same initial
+@@ -351,7 +355,7 @@ repeat:
+ 				 */
+ 				pgprot_t init_prot = __pgprot(PTE_IDENT_ATTR);
+ 
+-				if (is_kernel_text(addr))
++				if (is_kernel_text(address, address + PAGE_SIZE))
+ 					prot = PAGE_KERNEL_EXEC;
+ 
+ 				pages_4k++;
+@@ -474,7 +478,7 @@ void __init native_pagetable_init(void)
+ 
+ 		pud = pud_offset(pgd, va);
+ 		pmd = pmd_offset(pud, va);
+-		if (!pmd_present(*pmd))
++		if (!pmd_present(*pmd)) // PAX TODO || pmd_large(*pmd))
+ 			break;
+ 
+ 		/* should not be large page here */
+@@ -532,12 +536,10 @@ void __init early_ioremap_page_table_range_init(void)
+ 
+ static void __init pagetable_init(void)
+ {
+-	pgd_t *pgd_base = swapper_pg_dir;
+-
+-	permanent_kmaps_init(pgd_base);
++	permanent_kmaps_init(swapper_pg_dir);
+ }
+ 
+-pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL | \
_PAGE_IOMAP); ++pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL \
| _PAGE_IOMAP); + EXPORT_SYMBOL_GPL(__supported_pte_mask);
+ 
+ /* user-defined highmem size */
+@@ -787,10 +789,10 @@ void __init mem_init(void)
+ 		((unsigned long)&__init_end -
+ 		 (unsigned long)&__init_begin) >> 10,
+ 
+-		(unsigned long)&_etext, (unsigned long)&_edata,
+-		((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
++		(unsigned long)&_sdata, (unsigned long)&_edata,
++		((unsigned long)&_edata - (unsigned long)&_sdata) >> 10,
+ 
+-		(unsigned long)&_text, (unsigned long)&_etext,
++		ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
+ 		((unsigned long)&_etext - (unsigned long)&_text) >> 10);
+ 
+ 	/*
+@@ -880,6 +882,7 @@ void set_kernel_text_rw(void)
+ 	if (!kernel_set_to_readonly)
+ 		return;
+ 
++	start = ktla_ktva(start);
+ 	pr_debug("Set kernel text: %lx - %lx for read write\n",
+ 		 start, start+size);
+ 
+@@ -894,6 +897,7 @@ void set_kernel_text_ro(void)
+ 	if (!kernel_set_to_readonly)
+ 		return;
+ 
++	start = ktla_ktva(start);
+ 	pr_debug("Set kernel text: %lx - %lx for read only\n",
+ 		 start, start+size);
+ 
+@@ -922,6 +926,7 @@ void mark_rodata_ro(void)
+ 	unsigned long start = PFN_ALIGN(_text);
+ 	unsigned long size = PFN_ALIGN(_etext) - start;
+ 
++	start = ktla_ktva(start);
+ 	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
+ 	printk(KERN_INFO "Write protecting the kernel text: %luk\n",
+ 		size >> 10);
+diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
+index 104d56a..62ba13f 100644
+--- a/arch/x86/mm/init_64.c
++++ b/arch/x86/mm/init_64.c
+@@ -151,7 +151,7 @@ early_param("gbpages", parse_direct_gbpages_on);
+  * around without checking the pgd every time.
+  */
+ 
+-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_IOMAP;
++pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_IOMAP);
+ EXPORT_SYMBOL_GPL(__supported_pte_mask);
+ 
+ int force_personality32;
+@@ -184,12 +184,29 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+ 
+ 	for (address = start; address <= end; address += PGDIR_SIZE) {
+ 		const pgd_t *pgd_ref = pgd_offset_k(address);
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		unsigned long cpu;
++#else
+ 		struct page *page;
++#endif
+ 
+ 		if (pgd_none(*pgd_ref))
+ 			continue;
+ 
+ 		spin_lock(&pgd_lock);
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
++			pgd_t *pgd = pgd_offset_cpu(cpu, user, address);
++
++			if (pgd_none(*pgd))
++				set_pgd(pgd, *pgd_ref);
++			else
++				BUG_ON(pgd_page_vaddr(*pgd)
++				       != pgd_page_vaddr(*pgd_ref));
++			pgd = pgd_offset_cpu(cpu, kernel, address);
++#else
+ 		list_for_each_entry(page, &pgd_list, lru) {
+ 			pgd_t *pgd;
+ 			spinlock_t *pgt_lock;
+@@ -198,6 +215,7 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+ 			/* the pgt_lock only for Xen */
+ 			pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
+ 			spin_lock(pgt_lock);
++#endif
+ 
+ 			if (pgd_none(*pgd))
+ 				set_pgd(pgd, *pgd_ref);
+@@ -205,7 +223,10 @@ void sync_global_pgds(unsigned long start, unsigned long end)
+ 				BUG_ON(pgd_page_vaddr(*pgd)
+ 				       != pgd_page_vaddr(*pgd_ref));
+ 
++#ifndef CONFIG_PAX_PER_CPU_PGD
+ 			spin_unlock(pgt_lock);
++#endif
++
+ 		}
+ 		spin_unlock(&pgd_lock);
+ 	}
+@@ -238,7 +259,7 @@ static pud_t *fill_pud(pgd_t *pgd, unsigned long vaddr)
+ {
+ 	if (pgd_none(*pgd)) {
+ 		pud_t *pud = (pud_t *)spp_getpage();
+-		pgd_populate(&init_mm, pgd, pud);
++		pgd_populate_kernel(&init_mm, pgd, pud);
+ 		if (pud != pud_offset(pgd, 0))
+ 			printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n",
+ 			       pud, pud_offset(pgd, 0));
+@@ -250,7 +271,7 @@ static pmd_t *fill_pmd(pud_t *pud, unsigned long vaddr)
+ {
+ 	if (pud_none(*pud)) {
+ 		pmd_t *pmd = (pmd_t *) spp_getpage();
+-		pud_populate(&init_mm, pud, pmd);
++		pud_populate_kernel(&init_mm, pud, pmd);
+ 		if (pmd != pmd_offset(pud, 0))
+ 			printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
+ 			       pmd, pmd_offset(pud, 0));
+@@ -279,7 +300,9 @@ void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, \
pte_t new_pte) + 	pmd = fill_pmd(pud, vaddr);
+ 	pte = fill_pte(pmd, vaddr);
+ 
++	pax_open_kernel();
+ 	set_pte(pte, new_pte);
++	pax_close_kernel();
+ 
+ 	/*
+ 	 * It's enough to flush this one mapping.
+@@ -338,14 +361,12 @@ static void __init __init_extra_mapping(unsigned long phys, \
unsigned long size, + 		pgd = pgd_offset_k((unsigned long)__va(phys));
+ 		if (pgd_none(*pgd)) {
+ 			pud = (pud_t *) spp_getpage();
+-			set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
+-						_PAGE_USER));
++			set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
+ 		}
+ 		pud = pud_offset(pgd, (unsigned long)__va(phys));
+ 		if (pud_none(*pud)) {
+ 			pmd = (pmd_t *) spp_getpage();
+-			set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
+-						_PAGE_USER));
++			set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
+ 		}
+ 		pmd = pmd_offset(pud, phys);
+ 		BUG_ON(!pmd_none(*pmd));
+@@ -586,7 +607,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long \
end, + 					      prot);
+ 
+ 		spin_lock(&init_mm.page_table_lock);
+-		pud_populate(&init_mm, pud, pmd);
++		pud_populate_kernel(&init_mm, pud, pmd);
+ 		spin_unlock(&init_mm.page_table_lock);
+ 	}
+ 	__flush_tlb_all();
+@@ -627,7 +648,7 @@ kernel_physical_mapping_init(unsigned long start,
+ 						 page_size_mask);
+ 
+ 		spin_lock(&init_mm.page_table_lock);
+-		pgd_populate(&init_mm, pgd, pud);
++		pgd_populate_kernel(&init_mm, pgd, pud);
+ 		spin_unlock(&init_mm.page_table_lock);
+ 		pgd_changed = true;
+ 	}
+@@ -1188,8 +1209,8 @@ int kern_addr_valid(unsigned long addr)
+ static struct vm_area_struct gate_vma = {
+ 	.vm_start	= VSYSCALL_START,
+ 	.vm_end		= VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE),
+-	.vm_page_prot	= PAGE_READONLY_EXEC,
+-	.vm_flags	= VM_READ | VM_EXEC
++	.vm_page_prot	= PAGE_READONLY,
++	.vm_flags	= VM_READ
+ };
+ 
+ struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
+@@ -1223,7 +1244,7 @@ int in_gate_area_no_mm(unsigned long addr)
+ 
+ const char *arch_vma_name(struct vm_area_struct *vma)
+ {
+-	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
++	if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
+ 		return "[vdso]";
+ 	if (vma == &gate_vma)
+ 		return "[vsyscall]";
+diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
+index 7b179b4..6bd17777 100644
+--- a/arch/x86/mm/iomap_32.c
++++ b/arch/x86/mm/iomap_32.c
+@@ -64,7 +64,11 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, pgprot_t prot)
+ 	type = kmap_atomic_idx_push();
+ 	idx = type + KM_TYPE_NR * smp_processor_id();
+ 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
++
++	pax_open_kernel();
+ 	set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
++	pax_close_kernel();
++
+ 	arch_flush_lazy_mmu_mode();
+ 
+ 	return (void *)vaddr;
+diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
+index 0215e2c..1c62dab 100644
+--- a/arch/x86/mm/ioremap.c
++++ b/arch/x86/mm/ioremap.c
+@@ -97,7 +97,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
+ 	for (pfn = phys_addr >> PAGE_SHIFT; pfn <= last_pfn; pfn++) {
+ 		int is_ram = page_is_ram(pfn);
+ 
+-		if (is_ram && pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn)))
++		if (is_ram && pfn_valid(pfn) && (pfn >= 0x100 || \
!PageReserved(pfn_to_page(pfn)))) + 			return NULL;
+ 		WARN_ON_ONCE(is_ram);
+ 	}
+@@ -256,7 +256,7 @@ EXPORT_SYMBOL(ioremap_prot);
+  *
+  * Caller must ensure there is only one unmapping for the same pointer.
+  */
+-void iounmap(volatile void __iomem *addr)
++void iounmap(const volatile void __iomem *addr)
+ {
+ 	struct vm_struct *p, *o;
+ 
+@@ -310,6 +310,9 @@ void *xlate_dev_mem_ptr(unsigned long phys)
+ 
+ 	/* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
+ 	if (page_is_ram(start >> PAGE_SHIFT))
++#ifdef CONFIG_HIGHMEM
++	if ((start >> PAGE_SHIFT) < max_low_pfn)
++#endif
+ 		return __va(phys);
+ 
+ 	addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
+@@ -322,6 +325,9 @@ void *xlate_dev_mem_ptr(unsigned long phys)
+ void unxlate_dev_mem_ptr(unsigned long phys, void *addr)
+ {
+ 	if (page_is_ram(phys >> PAGE_SHIFT))
++#ifdef CONFIG_HIGHMEM
++	if ((phys >> PAGE_SHIFT) < max_low_pfn)
++#endif
+ 		return;
+ 
+ 	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
+@@ -339,7 +345,7 @@ static int __init early_ioremap_debug_setup(char *str)
+ early_param("early_ioremap_debug", early_ioremap_debug_setup);
+ 
+ static __initdata int after_paging_init;
+-static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
++static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __read_only __aligned(PAGE_SIZE);
+ 
+ static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
+ {
+@@ -376,8 +382,7 @@ void __init early_ioremap_init(void)
+ 		slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
+ 
+ 	pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
+-	memset(bm_pte, 0, sizeof(bm_pte));
+-	pmd_populate_kernel(&init_mm, pmd, bm_pte);
++	pmd_populate_user(&init_mm, pmd, bm_pte);
+ 
+ 	/*
+ 	 * The boot-ioremap range spans multiple pmds, for which
+diff --git a/arch/x86/mm/kmemcheck/kmemcheck.c b/arch/x86/mm/kmemcheck/kmemcheck.c
+index d87dd6d..bf3fa66 100644
+--- a/arch/x86/mm/kmemcheck/kmemcheck.c
++++ b/arch/x86/mm/kmemcheck/kmemcheck.c
+@@ -622,9 +622,9 @@ bool kmemcheck_fault(struct pt_regs *regs, unsigned long \
address, + 	 * memory (e.g. tracked pages)? For now, we need this to avoid
+ 	 * invoking kmemcheck for PnP BIOS calls.
+ 	 */
+-	if (regs->flags & X86_VM_MASK)
++	if (v8086_mode(regs))
+ 		return false;
+-	if (regs->cs != __KERNEL_CS)
++	if (regs->cs != __KERNEL_CS && regs->cs != __KERNEXEC_KERNEL_CS)
+ 		return false;
+ 
+ 	pte = kmemcheck_pte_lookup(address);
+diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
+index 25e7e13..1964579 100644
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -52,7 +52,7 @@ static unsigned int stack_maxrandom_size(void)
+  * Leave an at least ~128 MB hole with possible stack randomization.
+  */
+ #define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
+-#define MAX_GAP (TASK_SIZE/6*5)
++#define MAX_GAP (pax_task_size/6*5)
+ 
+ static int mmap_is_legacy(void)
+ {
+@@ -82,27 +82,40 @@ static unsigned long mmap_rnd(void)
+ 	return rnd << PAGE_SHIFT;
+ }
+ 
+-static unsigned long mmap_base(void)
++static unsigned long mmap_base(struct mm_struct *mm)
+ {
+ 	unsigned long gap = rlimit(RLIMIT_STACK);
++	unsigned long pax_task_size = TASK_SIZE;
++
++#ifdef CONFIG_PAX_SEGMEXEC
++	if (mm->pax_flags & MF_PAX_SEGMEXEC)
++		pax_task_size = SEGMEXEC_TASK_SIZE;
++#endif
+ 
+ 	if (gap < MIN_GAP)
+ 		gap = MIN_GAP;
+ 	else if (gap > MAX_GAP)
+ 		gap = MAX_GAP;
+ 
+-	return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
++	return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
+ }
+ 
+ /*
+  * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
+  * does, but not when emulating X86_32
+  */
+-static unsigned long mmap_legacy_base(void)
++static unsigned long mmap_legacy_base(struct mm_struct *mm)
+ {
+-	if (mmap_is_ia32())
++	if (mmap_is_ia32()) {
++
++#ifdef CONFIG_PAX_SEGMEXEC
++		if (mm->pax_flags & MF_PAX_SEGMEXEC)
++			return SEGMEXEC_TASK_UNMAPPED_BASE;
++		else
++#endif
++
+ 		return TASK_UNMAPPED_BASE;
+-	else
++	} else
+ 		return TASK_UNMAPPED_BASE + mmap_rnd();
+ }
+ 
+@@ -112,8 +125,15 @@ static unsigned long mmap_legacy_base(void)
+  */
+ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+-	mm->mmap_legacy_base = mmap_legacy_base();
+-	mm->mmap_base = mmap_base();
++	mm->mmap_legacy_base = mmap_legacy_base(mm);
++	mm->mmap_base = mmap_base(mm);
++
++#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;
+diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
+index 0057a7a..95c7edd 100644
+--- a/arch/x86/mm/mmio-mod.c
++++ b/arch/x86/mm/mmio-mod.c
+@@ -194,7 +194,7 @@ static void pre(struct kmmio_probe *p, struct pt_regs *regs,
+ 		break;
+ 	default:
+ 		{
+-			unsigned char *ip = (unsigned char *)instptr;
++			unsigned char *ip = (unsigned char *)ktla_ktva(instptr);
+ 			my_trace->opcode = MMIO_UNKNOWN_OP;
+ 			my_trace->width = 0;
+ 			my_trace->value = (*ip) << 16 | *(ip + 1) << 8 |
+@@ -234,7 +234,7 @@ static void post(struct kmmio_probe *p, unsigned long condition,
+ static void ioremap_trace_core(resource_size_t offset, unsigned long size,
+ 							void __iomem *addr)
+ {
+-	static atomic_t next_id;
++	static atomic_unchecked_t next_id;
+ 	struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL);
+ 	/* These are page-unaligned. */
+ 	struct mmiotrace_map map = {
+@@ -258,7 +258,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned \
long size, + 			.private = trace
+ 		},
+ 		.phys = offset,
+-		.id = atomic_inc_return(&next_id)
++		.id = atomic_inc_return_unchecked(&next_id)
+ 	};
+ 	map.map_id = trace->id;
+ 
+@@ -290,7 +290,7 @@ void mmiotrace_ioremap(resource_size_t offset, unsigned long \
size, + 	ioremap_trace_core(offset, size, addr);
+ }
+ 
+-static void iounmap_trace_core(volatile void __iomem *addr)
++static void iounmap_trace_core(const volatile void __iomem *addr)
+ {
+ 	struct mmiotrace_map map = {
+ 		.phys = 0,
+@@ -328,7 +328,7 @@ not_enabled:
+ 	}
+ }
+ 
+-void mmiotrace_iounmap(volatile void __iomem *addr)
++void mmiotrace_iounmap(const volatile void __iomem *addr)
+ {
+ 	might_sleep();
+ 	if (is_enabled()) /* recheck and proper locking in *_core() */
+diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
+index 8bf93ba..dbcd670 100644
+--- a/arch/x86/mm/numa.c
++++ b/arch/x86/mm/numa.c
+@@ -474,7 +474,7 @@ static bool __init numa_meminfo_cover_memory(const struct \
numa_meminfo *mi) + 	return true;
+ }
+ 
+-static int __init numa_register_memblks(struct numa_meminfo *mi)
++static int __init __intentional_overflow(-1) numa_register_memblks(struct \
numa_meminfo *mi) + {
+ 	unsigned long uninitialized_var(pfn_align);
+ 	int i, nid;
+diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c
+index d0b1773..4c3327c 100644
+--- a/arch/x86/mm/pageattr-test.c
++++ b/arch/x86/mm/pageattr-test.c
+@@ -36,7 +36,7 @@ enum {
+ 
+ static int pte_testbit(pte_t pte)
+ {
+-	return pte_flags(pte) & _PAGE_UNUSED1;
++	return pte_flags(pte) & _PAGE_CPA_TEST;
+ }
+ 
+ struct split_state {
+diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
+index bb32480..75f2f5e 100644
+--- a/arch/x86/mm/pageattr.c
++++ b/arch/x86/mm/pageattr.c
+@@ -261,7 +261,7 @@ static inline pgprot_t static_protections(pgprot_t prot, \
unsigned long address, + 	 */
+ #ifdef CONFIG_PCI_BIOS
+ 	if (pcibios_enabled && within(pfn, BIOS_BEGIN >> PAGE_SHIFT, BIOS_END >> \
PAGE_SHIFT)) +-		pgprot_val(forbidden) |= _PAGE_NX;
++		pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
+ #endif
+ 
+ 	/*
+@@ -269,9 +269,10 @@ static inline pgprot_t static_protections(pgprot_t prot, \
unsigned long address, + 	 * Does not cover __inittext since that is gone later on. \
On + 	 * 64bit we do not enforce !NX on the low mapping
+ 	 */
+-	if (within(address, (unsigned long)_text, (unsigned long)_etext))
+-		pgprot_val(forbidden) |= _PAGE_NX;
++	if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned \
long)_etext))) ++		pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
+ 
++#ifdef CONFIG_DEBUG_RODATA
+ 	/*
+ 	 * The .rodata section needs to be read-only. Using the pfn
+ 	 * catches all aliases.
+@@ -279,6 +280,7 @@ static inline pgprot_t static_protections(pgprot_t prot, \
unsigned long address, + 	if (within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT,
+ 		   __pa_symbol(__end_rodata) >> PAGE_SHIFT))
+ 		pgprot_val(forbidden) |= _PAGE_RW;
++#endif
+ 
+ #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+ 	/*
+@@ -317,6 +319,13 @@ static inline pgprot_t static_protections(pgprot_t prot, \
unsigned long address, + 	}
+ #endif
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	if (within(pfn, __pa(ktla_ktva((unsigned long)&_text)), __pa((unsigned \
long)&_sdata))) { ++		pgprot_val(forbidden) |= _PAGE_RW;
++		pgprot_val(forbidden) |= _PAGE_NX & __supported_pte_mask;
++	}
++#endif
++
+ 	prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));
+ 
+ 	return prot;
+@@ -400,23 +409,37 @@ EXPORT_SYMBOL_GPL(slow_virt_to_phys);
+ static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
+ {
+ 	/* change init_mm */
++	pax_open_kernel();
+ 	set_pte_atomic(kpte, pte);
++
+ #ifdef CONFIG_X86_32
+ 	if (!SHARED_KERNEL_PMD) {
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		unsigned long cpu;
++#else
+ 		struct page *page;
++#endif
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++		for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
++			pgd_t *pgd = get_cpu_pgd(cpu, kernel);
++#else
+ 		list_for_each_entry(page, &pgd_list, lru) {
+-			pgd_t *pgd;
++			pgd_t *pgd = (pgd_t *)page_address(page);
++#endif
++
+ 			pud_t *pud;
+ 			pmd_t *pmd;
+ 
+-			pgd = (pgd_t *)page_address(page) + pgd_index(address);
++			pgd += pgd_index(address);
+ 			pud = pud_offset(pgd, address);
+ 			pmd = pmd_offset(pud, address);
+ 			set_pte_atomic((pte_t *)pmd, pte);
+ 		}
+ 	}
+ #endif
++	pax_close_kernel();
+ }
+ 
+ static int
+diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+index 6574388..87e9bef 100644
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -376,7 +376,7 @@ int free_memtype(u64 start, u64 end)
+ 
+ 	if (!entry) {
+ 		printk(KERN_INFO "%s:%d freeing invalid memtype [mem %#010Lx-%#010Lx]\n",
+-		       current->comm, current->pid, start, end - 1);
++			current->comm, task_pid_nr(current), start, end - 1);
+ 		return -EINVAL;
+ 	}
+ 
+@@ -506,8 +506,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned \
long size) + 
+ 	while (cursor < to) {
+ 		if (!devmem_is_allowed(pfn)) {
+-			printk(KERN_INFO "Program %s tried to access /dev/mem between [mem \
%#010Lx-%#010Lx]\n", +-				current->comm, from, to - 1);
++			printk(KERN_INFO "Program %s tried to access /dev/mem between [mem \
%#010Lx-%#010Lx] (%#010Lx)\n", ++				current->comm, from, to - 1, cursor);
+ 			return 0;
+ 		}
+ 		cursor += PAGE_SIZE;
+@@ -577,7 +577,7 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, \
unsigned long flags) + 	if (ioremap_change_attr((unsigned long)__va(base), id_sz, \
flags) < 0) { + 		printk(KERN_INFO "%s:%d ioremap_change_attr failed %s "
+ 			"for [mem %#010Lx-%#010Lx]\n",
+-			current->comm, current->pid,
++			current->comm, task_pid_nr(current),
+ 			cattr_name(flags),
+ 			base, (unsigned long long)(base + size-1));
+ 		return -EINVAL;
+@@ -612,7 +612,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, \
pgprot_t *vma_prot, + 		flags = lookup_memtype(paddr);
+ 		if (want_flags != flags) {
+ 			printk(KERN_WARNING "%s:%d map pfn RAM range req %s for [mem %#010Lx-%#010Lx], \
got %s\n", +-				current->comm, current->pid,
++				current->comm, task_pid_nr(current),
+ 				cattr_name(want_flags),
+ 				(unsigned long long)paddr,
+ 				(unsigned long long)(paddr + size - 1),
+@@ -634,7 +634,7 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, \
pgprot_t *vma_prot, + 			free_memtype(paddr, paddr + size);
+ 			printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
+ 				" for [mem %#010Lx-%#010Lx], got %s\n",
+-				current->comm, current->pid,
++				current->comm, task_pid_nr(current),
+ 				cattr_name(want_flags),
+ 				(unsigned long long)paddr,
+ 				(unsigned long long)(paddr + size - 1),
+diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
+index 415f6c4..d319983 100644
+--- a/arch/x86/mm/pat_rbtree.c
++++ b/arch/x86/mm/pat_rbtree.c
+@@ -160,7 +160,7 @@ success:
+ 
+ failure:
+ 	printk(KERN_INFO "%s:%d conflicting memory types "
+-		"%Lx-%Lx %s<->%s\n", current->comm, current->pid, start,
++		"%Lx-%Lx %s<->%s\n", current->comm, task_pid_nr(current), start,
+ 		end, cattr_name(found_type), cattr_name(match->type));
+ 	return -EBUSY;
+ }
+diff --git a/arch/x86/mm/pf_in.c b/arch/x86/mm/pf_in.c
+index 9f0614d..92ae64a 100644
+--- a/arch/x86/mm/pf_in.c
++++ b/arch/x86/mm/pf_in.c
+@@ -148,7 +148,7 @@ enum reason_type get_ins_type(unsigned long ins_addr)
+ 	int i;
+ 	enum reason_type rv = OTHERS;
+ 
+-	p = (unsigned char *)ins_addr;
++	p = (unsigned char *)ktla_ktva(ins_addr);
+ 	p += skip_prefix(p, &prf);
+ 	p += get_opcode(p, &opcode);
+ 
+@@ -168,7 +168,7 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
+ 	struct prefix_bits prf;
+ 	int i;
+ 
+-	p = (unsigned char *)ins_addr;
++	p = (unsigned char *)ktla_ktva(ins_addr);
+ 	p += skip_prefix(p, &prf);
+ 	p += get_opcode(p, &opcode);
+ 
+@@ -191,7 +191,7 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
+ 	struct prefix_bits prf;
+ 	int i;
+ 
+-	p = (unsigned char *)ins_addr;
++	p = (unsigned char *)ktla_ktva(ins_addr);
+ 	p += skip_prefix(p, &prf);
+ 	p += get_opcode(p, &opcode);
+ 
+@@ -415,7 +415,7 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct \
pt_regs *regs) + 	struct prefix_bits prf;
+ 	int i;
+ 
+-	p = (unsigned char *)ins_addr;
++	p = (unsigned char *)ktla_ktva(ins_addr);
+ 	p += skip_prefix(p, &prf);
+ 	p += get_opcode(p, &opcode);
+ 	for (i = 0; i < ARRAY_SIZE(reg_rop); i++)
+@@ -470,7 +470,7 @@ unsigned long get_ins_imm_val(unsigned long ins_addr)
+ 	struct prefix_bits prf;
+ 	int i;
+ 
+-	p = (unsigned char *)ins_addr;
++	p = (unsigned char *)ktla_ktva(ins_addr);
+ 	p += skip_prefix(p, &prf);
+ 	p += get_opcode(p, &opcode);
+ 	for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
+diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
+index dfa537a..fd45c64 100644
+--- a/arch/x86/mm/pgtable.c
++++ b/arch/x86/mm/pgtable.c
+@@ -91,10 +91,67 @@ static inline void pgd_list_del(pgd_t *pgd)
+ 	list_del(&page->lru);
+ }
+ 
+-#define UNSHARED_PTRS_PER_PGD				\
+-	(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++pgdval_t clone_pgd_mask __read_only = ~_PAGE_PRESENT;
+ 
++void __shadow_user_pgds(pgd_t *dst, const pgd_t *src)
++{
++	unsigned int count = USER_PGD_PTRS;
+ 
++	if (!pax_user_shadow_base)
++		return;
++
++	while (count--)
++		*dst++ = __pgd((pgd_val(*src++) | (_PAGE_NX & __supported_pte_mask)) & \
~_PAGE_USER); ++}
++#endif
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++void __clone_user_pgds(pgd_t *dst, const pgd_t *src)
++{
++	unsigned int count = USER_PGD_PTRS;
++
++	while (count--) {
++		pgd_t pgd;
++
++#ifdef CONFIG_X86_64
++		pgd = __pgd(pgd_val(*src++) | _PAGE_USER);
++#else
++		pgd = *src++;
++#endif
++
++#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
++		pgd = __pgd(pgd_val(pgd) & clone_pgd_mask);
++#endif
++
++		*dst++ = pgd;
++	}
++
++}
++#endif
++
++#ifdef CONFIG_X86_64
++#define pxd_t				pud_t
++#define pyd_t				pgd_t
++#define paravirt_release_pxd(pfn)	paravirt_release_pud(pfn)
++#define pxd_free(mm, pud)		pud_free((mm), (pud))
++#define pyd_populate(mm, pgd, pud)	pgd_populate((mm), (pgd), (pud))
++#define pyd_offset(mm, address)		pgd_offset((mm), (address))
++#define PYD_SIZE			PGDIR_SIZE
++#else
++#define pxd_t				pmd_t
++#define pyd_t				pud_t
++#define paravirt_release_pxd(pfn)	paravirt_release_pmd(pfn)
++#define pxd_free(mm, pud)		pmd_free((mm), (pud))
++#define pyd_populate(mm, pgd, pud)	pud_populate((mm), (pgd), (pud))
++#define pyd_offset(mm, address)		pud_offset((mm), (address))
++#define PYD_SIZE			PUD_SIZE
++#endif
++
++#ifdef CONFIG_PAX_PER_CPU_PGD
++static inline void pgd_ctor(struct mm_struct *mm, pgd_t *pgd) {}
++static inline void pgd_dtor(pgd_t *pgd) {}
++#else
+ static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm)
+ {
+ 	BUILD_BUG_ON(sizeof(virt_to_page(pgd)->index) < sizeof(mm));
+@@ -135,6 +192,7 @@ static void pgd_dtor(pgd_t *pgd)
+ 	pgd_list_del(pgd);
+ 	spin_unlock(&pgd_lock);
+ }
++#endif
+ 
+ /*
+  * List of all pgd's needed for non-PAE so it can invalidate entries
+@@ -147,7 +205,7 @@ static void pgd_dtor(pgd_t *pgd)
+  * -- nyc
+  */
+ 
+-#ifdef CONFIG_X86_PAE
++#if defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
+ /*
+  * In PAE mode, we need to do a cr3 reload (=tlb flush) when
+  * updating the top-level pagetable entries to guarantee the
+@@ -159,7 +217,7 @@ static void pgd_dtor(pgd_t *pgd)
+  * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
+  * and initialize the kernel pmds here.
+  */
+-#define PREALLOCATED_PMDS	UNSHARED_PTRS_PER_PGD
++#define PREALLOCATED_PXDS	(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
+ 
+ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
+ {
+@@ -177,36 +235,38 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t \
*pmd) + 	 */
+ 	flush_tlb_mm(mm);
+ }
++#elif defined(CONFIG_X86_64) && defined(CONFIG_PAX_PER_CPU_PGD)
++#define PREALLOCATED_PXDS	USER_PGD_PTRS
+ #else  /* !CONFIG_X86_PAE */
+ 
+ /* No need to prepopulate any pagetable entries in non-PAE modes. */
+-#define PREALLOCATED_PMDS	0
++#define PREALLOCATED_PXDS	0
+ 
+ #endif	/* CONFIG_X86_PAE */
+ 
+-static void free_pmds(pmd_t *pmds[])
++static void free_pxds(pxd_t *pxds[])
+ {
+ 	int i;
+ 
+-	for(i = 0; i < PREALLOCATED_PMDS; i++)
+-		if (pmds[i])
+-			free_page((unsigned long)pmds[i]);
++	for(i = 0; i < PREALLOCATED_PXDS; i++)
++		if (pxds[i])
++			free_page((unsigned long)pxds[i]);
+ }
+ 
+-static int preallocate_pmds(pmd_t *pmds[])
++static int preallocate_pxds(pxd_t *pxds[])
+ {
+ 	int i;
+ 	bool failed = false;
+ 
+-	for(i = 0; i < PREALLOCATED_PMDS; i++) {
+-		pmd_t *pmd = (pmd_t *)__get_free_page(PGALLOC_GFP);
+-		if (pmd == NULL)
++	for(i = 0; i < PREALLOCATED_PXDS; i++) {
++		pxd_t *pxd = (pxd_t *)__get_free_page(PGALLOC_GFP);
++		if (pxd == NULL)
+ 			failed = true;
+-		pmds[i] = pmd;
++		pxds[i] = pxd;
+ 	}
+ 
+ 	if (failed) {
+-		free_pmds(pmds);
++		free_pxds(pxds);
+ 		return -ENOMEM;
+ 	}
+ 
+@@ -219,49 +279,52 @@ static int preallocate_pmds(pmd_t *pmds[])
+  * preallocate which never got a corresponding vma will need to be
+  * freed manually.
+  */
+-static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
++static void pgd_mop_up_pxds(struct mm_struct *mm, pgd_t *pgdp)
+ {
+ 	int i;
+ 
+-	for(i = 0; i < PREALLOCATED_PMDS; i++) {
++	for(i = 0; i < PREALLOCATED_PXDS; i++) {
+ 		pgd_t pgd = pgdp[i];
+ 
+ 		if (pgd_val(pgd) != 0) {
+-			pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
++			pxd_t *pxd = (pxd_t *)pgd_page_vaddr(pgd);
+ 
+-			pgdp[i] = native_make_pgd(0);
++			set_pgd(pgdp + i, native_make_pgd(0));
+ 
+-			paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
+-			pmd_free(mm, pmd);
++			paravirt_release_pxd(pgd_val(pgd) >> PAGE_SHIFT);
++			pxd_free(mm, pxd);
+ 		}
+ 	}
+ }
+ 
+-static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
++static void pgd_prepopulate_pxd(struct mm_struct *mm, pgd_t *pgd, pxd_t *pxds[])
+ {
+-	pud_t *pud;
++	pyd_t *pyd;
+ 	int i;
+ 
+-	if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
++	if (PREALLOCATED_PXDS == 0) /* Work around gcc-3.4.x bug */
+ 		return;
+ 
+-	pud = pud_offset(pgd, 0);
+-
+-	for (i = 0; i < PREALLOCATED_PMDS; i++, pud++) {
+-		pmd_t *pmd = pmds[i];
++#ifdef CONFIG_X86_64
++	pyd = pyd_offset(mm, 0L);
++#else
++	pyd = pyd_offset(pgd, 0L);
++#endif
+ 
++	for (i = 0; i < PREALLOCATED_PXDS; i++, pyd++) {
++		pxd_t *pxd = pxds[i];
+ 		if (i >= KERNEL_PGD_BOUNDARY)
+-			memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
+-			       sizeof(pmd_t) * PTRS_PER_PMD);
++			memcpy(pxd, (pxd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
++			       sizeof(pxd_t) * PTRS_PER_PMD);
+ 
+-		pud_populate(mm, pud, pmd);
++		pyd_populate(mm, pyd, pxd);
+ 	}
+ }
+ 
+ pgd_t *pgd_alloc(struct mm_struct *mm)
+ {
+ 	pgd_t *pgd;
+-	pmd_t *pmds[PREALLOCATED_PMDS];
++	pxd_t *pxds[PREALLOCATED_PXDS];
+ 
+ 	pgd = (pgd_t *)__get_free_page(PGALLOC_GFP);
+ 
+@@ -270,11 +333,11 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+ 
+ 	mm->pgd = pgd;
+ 
+-	if (preallocate_pmds(pmds) != 0)
++	if (preallocate_pxds(pxds) != 0)
+ 		goto out_free_pgd;
+ 
+ 	if (paravirt_pgd_alloc(mm) != 0)
+-		goto out_free_pmds;
++		goto out_free_pxds;
+ 
+ 	/*
+ 	 * Make sure that pre-populating the pmds is atomic with
+@@ -284,14 +347,14 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
+ 	spin_lock(&pgd_lock);
+ 
+ 	pgd_ctor(mm, pgd);
+-	pgd_prepopulate_pmd(mm, pgd, pmds);
++	pgd_prepopulate_pxd(mm, pgd, pxds);
+ 
+ 	spin_unlock(&pgd_lock);
+ 
+ 	return pgd;
+ 
+-out_free_pmds:
+-	free_pmds(pmds);
++out_free_pxds:
++	free_pxds(pxds);
+ out_free_pgd:
+ 	free_page((unsigned long)pgd);
+ out:
+@@ -300,7 +363,7 @@ out:
+ 
+ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+ {
+-	pgd_mop_up_pmds(mm, pgd);
++	pgd_mop_up_pxds(mm, pgd);
+ 	pgd_dtor(pgd);
+ 	paravirt_pgd_free(mm, pgd);
+ 	free_page((unsigned long)pgd);
+diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
+index a69bcb8..19068ab 100644
+--- a/arch/x86/mm/pgtable_32.c
++++ b/arch/x86/mm/pgtable_32.c
+@@ -47,10 +47,13 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
+ 		return;
+ 	}
+ 	pte = pte_offset_kernel(pmd, vaddr);
++
++	pax_open_kernel();
+ 	if (pte_val(pteval))
+ 		set_pte_at(&init_mm, vaddr, pte, pteval);
+ 	else
+ 		pte_clear(&init_mm, vaddr, pte);
++	pax_close_kernel();
+ 
+ 	/*
+ 	 * It's enough to flush this one mapping.
+diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c
+index e666cbb..61788c45 100644
+--- a/arch/x86/mm/physaddr.c
++++ b/arch/x86/mm/physaddr.c
+@@ -10,7 +10,7 @@
+ #ifdef CONFIG_X86_64
+ 
+ #ifdef CONFIG_DEBUG_VIRTUAL
+-unsigned long __phys_addr(unsigned long x)
++unsigned long __intentional_overflow(-1) __phys_addr(unsigned long x)
+ {
+ 	unsigned long y = x - __START_KERNEL_map;
+ 
+@@ -67,7 +67,7 @@ EXPORT_SYMBOL(__virt_addr_valid);
+ #else
+ 
+ #ifdef CONFIG_DEBUG_VIRTUAL
+-unsigned long __phys_addr(unsigned long x)
++unsigned long __intentional_overflow(-1) __phys_addr(unsigned long x)
+ {
+ 	unsigned long phys_addr = x - PAGE_OFFSET;
+ 	/* VMALLOC_* aren't constants  */
+diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c
+index 90555bf..f5f1828 100644
+--- a/arch/x86/mm/setup_nx.c
++++ b/arch/x86/mm/setup_nx.c
+@@ -5,8 +5,10 @@
+ #include <asm/pgtable.h>
+ #include <asm/proto.h>
+ 
++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+ static int disable_nx;
+ 
++#ifndef CONFIG_PAX_PAGEEXEC
+ /*
+  * noexec = on|off
+  *
+@@ -28,12 +30,17 @@ static int __init noexec_setup(char *str)
+ 	return 0;
+ }
+ early_param("noexec", noexec_setup);
++#endif
++
++#endif
+ 
+ void x86_configure_nx(void)
+ {
++#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+ 	if (cpu_has_nx && !disable_nx)
+ 		__supported_pte_mask |= _PAGE_NX;
+ 	else
++#endif
+ 		__supported_pte_mask &= ~_PAGE_NX;
+ }
+ 
+diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
+index 282375f..e03a98f 100644
+--- a/arch/x86/mm/tlb.c
++++ b/arch/x86/mm/tlb.c
+@@ -48,7 +48,11 @@ void leave_mm(int cpu)
+ 		BUG();
+ 	if (cpumask_test_cpu(cpu, mm_cpumask(active_mm))) {
+ 		cpumask_clear_cpu(cpu, mm_cpumask(active_mm));
++
++#ifndef CONFIG_PAX_PER_CPU_PGD
+ 		load_cr3(swapper_pg_dir);
++#endif
++
+ 	}
+ }
+ EXPORT_SYMBOL_GPL(leave_mm);
+diff --git a/arch/x86/mm/uderef_64.c b/arch/x86/mm/uderef_64.c
+new file mode 100644
+index 0000000..dace51c
+--- /dev/null
++++ b/arch/x86/mm/uderef_64.c
+@@ -0,0 +1,37 @@
++#include <linux/mm.h>
++#include <asm/pgtable.h>
++#include <asm/uaccess.h>
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++/* PaX: due to the special call convention these functions must
++ * - remain leaf functions under all configurations,
++ * - never be called directly, only dereferenced from the wrappers.
++ */
++void __pax_open_userland(void)
++{
++	unsigned int cpu;
++
++	if (unlikely(!segment_eq(get_fs(), USER_DS)))
++		return;
++
++	cpu = raw_get_cpu();
++	BUG_ON((read_cr3() & ~PAGE_MASK) != PCID_KERNEL);
++	write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER | PCID_NOFLUSH);
++	raw_put_cpu_no_resched();
++}
++EXPORT_SYMBOL(__pax_open_userland);
++
++void __pax_close_userland(void)
++{
++	unsigned int cpu;
++
++	if (unlikely(!segment_eq(get_fs(), USER_DS)))
++		return;
++
++	cpu = raw_get_cpu();
++	BUG_ON((read_cr3() & ~PAGE_MASK) != PCID_USER);
++	write_cr3(__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL | PCID_NOFLUSH);
++	raw_put_cpu_no_resched();
++}
++EXPORT_SYMBOL(__pax_close_userland);
++#endif
+diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S
+index 877b9a1..a8ecf42 100644
+--- a/arch/x86/net/bpf_jit.S
++++ b/arch/x86/net/bpf_jit.S
+@@ -9,6 +9,7 @@
+  */
+ #include <linux/linkage.h>
+ #include <asm/dwarf2.h>
++#include <asm/alternative-asm.h>
+ 
+ /*
+  * Calling convention :
+@@ -35,6 +36,7 @@ sk_load_word_positive_offset:
+ 	jle	bpf_slow_path_word
+ 	mov     (SKBDATA,%rsi),%eax
+ 	bswap   %eax  			/* ntohl() */
++	pax_force_retaddr
+ 	ret
+ 
+ sk_load_half:
+@@ -52,6 +54,7 @@ sk_load_half_positive_offset:
+ 	jle	bpf_slow_path_half
+ 	movzwl	(SKBDATA,%rsi),%eax
+ 	rol	$8,%ax			# ntohs()
++	pax_force_retaddr
+ 	ret
+ 
+ sk_load_byte:
+@@ -66,6 +69,7 @@ sk_load_byte_positive_offset:
+ 	cmp	%esi,%r9d   /* if (offset >= hlen) goto bpf_slow_path_byte */
+ 	jle	bpf_slow_path_byte
+ 	movzbl	(SKBDATA,%rsi),%eax
++	pax_force_retaddr
+ 	ret
+ 
+ /**
+@@ -87,6 +91,7 @@ sk_load_byte_msh_positive_offset:
+ 	movzbl	(SKBDATA,%rsi),%ebx
+ 	and	$15,%bl
+ 	shl	$2,%bl
++	pax_force_retaddr
+ 	ret
+ 
+ /* rsi contains offset and can be scratched */
+@@ -109,6 +114,7 @@ bpf_slow_path_word:
+ 	js	bpf_error
+ 	mov	-12(%rbp),%eax
+ 	bswap	%eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_half:
+@@ -117,12 +123,14 @@ bpf_slow_path_half:
+ 	mov	-12(%rbp),%ax
+ 	rol	$8,%ax
+ 	movzwl	%ax,%eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_byte:
+ 	bpf_slow_path_common(1)
+ 	js	bpf_error
+ 	movzbl	-12(%rbp),%eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_byte_msh:
+@@ -133,6 +141,7 @@ bpf_slow_path_byte_msh:
+ 	and	$15,%al
+ 	shl	$2,%al
+ 	xchg	%eax,%ebx
++	pax_force_retaddr
+ 	ret
+ 
+ #define sk_negative_common(SIZE)				\
+@@ -157,6 +166,7 @@ sk_load_word_negative_offset:
+ 	sk_negative_common(4)
+ 	mov	(%rax), %eax
+ 	bswap	%eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_half_neg:
+@@ -168,6 +178,7 @@ sk_load_half_negative_offset:
+ 	mov	(%rax),%ax
+ 	rol	$8,%ax
+ 	movzwl	%ax,%eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_byte_neg:
+@@ -177,6 +188,7 @@ sk_load_byte_negative_offset:
+ 	.globl	sk_load_byte_negative_offset
+ 	sk_negative_common(1)
+ 	movzbl	(%rax), %eax
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_slow_path_byte_msh_neg:
+@@ -190,6 +202,7 @@ sk_load_byte_msh_negative_offset:
+ 	and	$15,%al
+ 	shl	$2,%al
+ 	xchg	%eax,%ebx
++	pax_force_retaddr
+ 	ret
+ 
+ bpf_error:
+@@ -197,4 +210,5 @@ bpf_error:
+ 	xor		%eax,%eax
+ 	mov		-8(%rbp),%rbx
+ 	leaveq
++	pax_force_retaddr
+ 	ret
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 79c216a..08d39cc 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -50,13 +50,90 @@ static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int \
len) + 	return ptr + len;
+ }
+ 
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define MAX_INSTR_CODE_SIZE 96
++#else
++#define MAX_INSTR_CODE_SIZE 64
++#endif
++
+ #define EMIT(bytes, len)	do { prog = emit_code(prog, bytes, len); } while (0)
+ 
+ #define EMIT1(b1)		EMIT(b1, 1)
+ #define EMIT2(b1, b2)		EMIT((b1) + ((b2) << 8), 2)
+ #define EMIT3(b1, b2, b3)	EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+ #define EMIT4(b1, b2, b3, b4)   EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << \
24), 4) ++
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++/* original constant will appear in ecx */
++#define DILUTE_CONST_SEQUENCE(_off, _key) 	\
++do {						\
++	/* mov ecx, randkey */			\
++	EMIT1(0xb9);				\
++	EMIT(_key, 4);				\
++	/* xor ecx, randkey ^ off */		\
++	EMIT2(0x81, 0xf1);			\
++	EMIT((_key) ^ (_off), 4);		\
++} while (0)
++
++#define EMIT1_off32(b1, _off)								\
++do { 											\
++	switch (b1) {									\
++		case 0x05: /* add eax, imm32 */						\
++		case 0x2d: /* sub eax, imm32 */						\
++		case 0x25: /* and eax, imm32 */						\
++		case 0x0d: /* or eax, imm32 */						\
++		case 0xb8: /* mov eax, imm32 */						\
++		case 0x35: /* xor eax, imm32 */						\
++		case 0x3d: /* cmp eax, imm32 */						\
++		case 0xa9: /* test eax, imm32 */					\
++			DILUTE_CONST_SEQUENCE(_off, randkey);				\
++			EMIT2((b1) - 4, 0xc8); /* convert imm instruction to eax, ecx */\
++			break;								\
++		case 0xbb: /* mov ebx, imm32 */						\
++			DILUTE_CONST_SEQUENCE(_off, randkey);				\
++			/* mov ebx, ecx */						\
++			EMIT2(0x89, 0xcb);						\
++			break;								\
++		case 0xbe: /* mov esi, imm32 */						\
++			DILUTE_CONST_SEQUENCE(_off, randkey);				\
++			/* mov esi, ecx	*/						\
++			EMIT2(0x89, 0xce);						\
++			break;								\
++		case 0xe8: /* call rel imm32, always to known funcs */			\
++			EMIT1(b1);							\
++			EMIT(_off, 4);							\
++			break;								\
++		case 0xe9: /* jmp rel imm32 */						\
++			EMIT1(b1);							\
++			EMIT(_off, 4);							\
++			/* prevent fall-through, we're not called if off = 0 */		\
++			EMIT(0xcccccccc, 4);						\
++			EMIT(0xcccccccc, 4);						\
++			break;								\
++		default:								\
++			BUILD_BUG();							\
++	}										\
++} while (0)
++
++#define EMIT2_off32(b1, b2, _off) 					\
++do { 									\
++	if ((b1) == 0x8d && (b2) == 0xb3) { /* lea esi, [rbx+imm32] */	\
++		EMIT2(0x8d, 0xb3); /* lea esi, [rbx+randkey] */		\
++		EMIT(randkey, 4);					\
++		EMIT2(0x8d, 0xb6); /* lea esi, [esi+off-randkey] */	\
++		EMIT((_off) - randkey, 4);				\
++	} else if ((b1) == 0x69 && (b2) == 0xc0) { /* imul eax, imm32 */\
++		DILUTE_CONST_SEQUENCE(_off, randkey);			\
++		/* imul eax, ecx */					\
++		EMIT3(0x0f, 0xaf, 0xc1);				\
++	} else {							\
++		BUILD_BUG();						\
++	}								\
++} while (0)
++#else
+ #define EMIT1_off32(b1, off)	do { EMIT1(b1); EMIT(off, 4);} while (0)
++#define EMIT2_off32(b1, b2, off) do { EMIT2(b1, b2); EMIT(off, 4);} while (0)
++#endif
+ 
+ #define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
+ #define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
+@@ -91,6 +168,24 @@ do {									\
+ #define X86_JBE 0x76
+ #define X86_JA  0x77
+ 
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++#define APPEND_FLOW_VERIFY()	\
++do {				\
++	/* mov ecx, randkey */	\
++	EMIT1(0xb9);		\
++	EMIT(randkey, 4);	\
++	/* cmp ecx, randkey */	\
++	EMIT2(0x81, 0xf9);	\
++	EMIT(randkey, 4);	\
++	/* jz after 8 int 3s */ \
++	EMIT2(0x74, 0x08);	\
++	EMIT(0xcccccccc, 4);	\
++	EMIT(0xcccccccc, 4);	\
++} while (0)
++#else
++#define APPEND_FLOW_VERIFY() do { } while (0)
++#endif
++
+ #define EMIT_COND_JMP(op, offset)				\
+ do {								\
+ 	if (is_near(offset))					\
+@@ -98,6 +193,7 @@ do {								\
+ 	else {							\
+ 		EMIT2(0x0f, op + 0x10);				\
+ 		EMIT(offset, 4); /* jxx .+off32 */		\
++		APPEND_FLOW_VERIFY();				\
+ 	}							\
+ } while (0)
+ 
+@@ -145,55 +241,54 @@ static int pkt_type_offset(void)
+ 	return -1;
+ }
+ 
+-struct bpf_binary_header {
+-	unsigned int	pages;
+-	/* Note : for security reasons, bpf code will follow a randomly
+-	 * sized amount of int3 instructions
+-	 */
+-	u8		image[];
+-};
+-
+-static struct bpf_binary_header *bpf_alloc_binary(unsigned int proglen,
++/* Note : for security reasons, bpf code will follow a randomly
++ * sized amount of int3 instructions
++ */
++static u8 *bpf_alloc_binary(unsigned int proglen,
+ 						  u8 **image_ptr)
+ {
+ 	unsigned int sz, hole;
+-	struct bpf_binary_header *header;
++	u8 *header;
+ 
+ 	/* Most of BPF filters are really small,
+ 	 * but if some of them fill a page, allow at least
+ 	 * 128 extra bytes to insert a random section of int3
+ 	 */
+-	sz = round_up(proglen + sizeof(*header) + 128, PAGE_SIZE);
+-	header = module_alloc(sz);
++	sz = round_up(proglen + 128, PAGE_SIZE);
++	header = module_alloc_exec(sz);
+ 	if (!header)
+ 		return NULL;
+ 
++	pax_open_kernel();
+ 	memset(header, 0xcc, sz); /* fill whole space with int3 instructions */
++	pax_close_kernel();
+ 
+-	header->pages = sz / PAGE_SIZE;
+-	hole = sz - (proglen + sizeof(*header));
++	hole = PAGE_SIZE - (proglen & ~PAGE_MASK);
+ 
+ 	/* insert a random number of int3 instructions before BPF code */
+-	*image_ptr = &header->image[prandom_u32() % hole];
++	*image_ptr = &header[prandom_u32() % hole];
+ 	return header;
+ }
+ 
+ void bpf_jit_compile(struct sk_filter *fp)
+ {
+-	u8 temp[64];
++	u8 temp[MAX_INSTR_CODE_SIZE];
+ 	u8 *prog;
+ 	unsigned int proglen, oldproglen = 0;
+ 	int ilen, i;
+ 	int t_offset, f_offset;
+ 	u8 t_op, f_op, seen = 0, pass;
+ 	u8 *image = NULL;
+-	struct bpf_binary_header *header = NULL;
++	u8 *header = NULL;
+ 	u8 *func;
+ 	int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
+ 	unsigned int cleanup_addr; /* epilogue code offset */
+ 	unsigned int *addrs;
+ 	const struct sock_filter *filter = fp->insns;
+ 	int flen = fp->len;
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++	unsigned int randkey;
++#endif
+ 
+ 	if (!bpf_jit_enable)
+ 		return;
+@@ -202,11 +297,15 @@ void bpf_jit_compile(struct sk_filter *fp)
+ 	if (addrs == NULL)
+ 		return;
+ 
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++	randkey = get_random_int();
++#endif
++
+ 	/* Before first pass, make a rough estimation of addrs[]
+-	 * each bpf instruction is translated to less than 64 bytes
++	 * each bpf instruction is translated to less than MAX_INSTR_CODE_SIZE bytes
+ 	 */
+ 	for (proglen = 0, i = 0; i < flen; i++) {
+-		proglen += 64;
++		proglen += MAX_INSTR_CODE_SIZE;
+ 		addrs[i] = proglen;
+ 	}
+ 	cleanup_addr = proglen; /* epilogue address */
+@@ -317,10 +416,8 @@ void bpf_jit_compile(struct sk_filter *fp)
+ 			case BPF_S_ALU_MUL_K: /* A *= K */
+ 				if (is_imm8(K))
+ 					EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */
+-				else {
+-					EMIT2(0x69, 0xc0);		/* imul imm32,%eax */
+-					EMIT(K, 4);
+-				}
++				else
++					EMIT2_off32(0x69, 0xc0, K); /* imul imm32,%eax */
+ 				break;
+ 			case BPF_S_ALU_DIV_X: /* A /= X; */
+ 				seen |= SEEN_XREG;
+@@ -360,13 +457,23 @@ void bpf_jit_compile(struct sk_filter *fp)
+ 				break;
+ 			case BPF_S_ALU_MOD_K: /* A %= K; */
+ 				EMIT2(0x31, 0xd2);	/* xor %edx,%edx */
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++				DILUTE_CONST_SEQUENCE(K, randkey);
++#else
+ 				EMIT1(0xb9);EMIT(K, 4);	/* mov imm32,%ecx */
++#endif
+ 				EMIT2(0xf7, 0xf1);	/* div %ecx */
+ 				EMIT2(0x89, 0xd0);	/* mov %edx,%eax */
+ 				break;
+ 			case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
++#ifdef CONFIG_GRKERNSEC_JIT_HARDEN
++				DILUTE_CONST_SEQUENCE(K, randkey);
++				// imul rax, rcx
++				EMIT4(0x48, 0x0f, 0xaf, 0xc1);
++#else
+ 				EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
+ 				EMIT(K, 4);
++#endif
+ 				EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+ 				break;
+ 			case BPF_S_ALU_AND_X:
+@@ -637,8 +744,7 @@ common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
+ 					if (is_imm8(K)) {
+ 						EMIT3(0x8d, 0x73, K); /* lea imm8(%rbx), %esi */
+ 					} else {
+-						EMIT2(0x8d, 0xb3); /* lea imm32(%rbx),%esi */
+-						EMIT(K, 4);
++						EMIT2_off32(0x8d, 0xb3, K); /* lea imm32(%rbx),%esi */
+ 					}
+ 				} else {
+ 					EMIT2(0x89,0xde); /* mov %ebx,%esi */
+@@ -728,10 +834,12 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
+ 				if (unlikely(proglen + ilen > oldproglen)) {
+ 					pr_err("bpb_jit_compile fatal error\n");
+ 					kfree(addrs);
+-					module_free(NULL, header);
++					module_free_exec(NULL, image);
+ 					return;
+ 				}
++				pax_open_kernel();
+ 				memcpy(image + proglen, temp, ilen);
++				pax_close_kernel();
+ 			}
+ 			proglen += ilen;
+ 			addrs[i] = proglen;
+@@ -764,7 +872,6 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
+ 
+ 	if (image) {
+ 		bpf_flush_icache(header, image + proglen);
+-		set_memory_ro((unsigned long)header, header->pages);
+ 		fp->bpf_func = (void *)image;
+ 	}
+ out:
+@@ -776,9 +883,7 @@ void bpf_jit_free(struct sk_filter *fp)
+ {
+ 	if (fp->bpf_func != sk_run_filter) {
+ 		unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK;
+-		struct bpf_binary_header *header = (void *)addr;
+-
+-		set_memory_rw(addr, header->pages);
+-		module_free(NULL, header);
++		set_memory_rw(addr, 1);
++		module_free_exec(NULL, (void *)addr);
+ 	}
+ }
+diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
+index d6aa6e8..266395a 100644
+--- a/arch/x86/oprofile/backtrace.c
++++ b/arch/x86/oprofile/backtrace.c
+@@ -46,11 +46,11 @@ dump_user_backtrace_32(struct stack_frame_ia32 *head)
+ 	struct stack_frame_ia32 *fp;
+ 	unsigned long bytes;
+ 
+-	bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
++	bytes = copy_from_user_nmi(bufhead, (const char __force_user *)head, \
sizeof(bufhead)); + 	if (bytes != sizeof(bufhead))
+ 		return NULL;
+ 
+-	fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
++	fp = (struct stack_frame_ia32 __force_kernel *) compat_ptr(bufhead[0].next_frame);
+ 
+ 	oprofile_add_trace(bufhead[0].return_address);
+ 
+@@ -92,7 +92,7 @@ static struct stack_frame *dump_user_backtrace(struct stack_frame \
*head) + 	struct stack_frame bufhead[2];
+ 	unsigned long bytes;
+ 
+-	bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
++	bytes = copy_from_user_nmi(bufhead, (const char __force_user *)head, \
sizeof(bufhead)); + 	if (bytes != sizeof(bufhead))
+ 		return NULL;
+ 
+@@ -111,7 +111,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
+ {
+ 	struct stack_frame *head = (struct stack_frame *)frame_pointer(regs);
+ 
+-	if (!user_mode_vm(regs)) {
++	if (!user_mode(regs)) {
+ 		unsigned long stack = kernel_stack_pointer(regs);
+ 		if (depth)
+ 			dump_trace(NULL, regs, (unsigned long *)stack, 0,
+diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
+index 48768df..ba9143c 100644
+--- a/arch/x86/oprofile/nmi_int.c
++++ b/arch/x86/oprofile/nmi_int.c
+@@ -23,6 +23,7 @@
+ #include <asm/nmi.h>
+ #include <asm/msr.h>
+ #include <asm/apic.h>
++#include <asm/pgtable.h>
+ 
+ #include "op_counter.h"
+ #include "op_x86_model.h"
+@@ -774,8 +775,11 @@ int __init op_nmi_init(struct oprofile_operations *ops)
+ 	if (ret)
+ 		return ret;
+ 
+-	if (!model->num_virt_counters)
+-		model->num_virt_counters = model->num_counters;
++	if (!model->num_virt_counters) {
++		pax_open_kernel();
++		*(unsigned int *)&model->num_virt_counters = model->num_counters;
++		pax_close_kernel();
++	}
+ 
+ 	mux_init(ops);
+ 
+diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
+index b2b9443..be58856 100644
+--- a/arch/x86/oprofile/op_model_amd.c
++++ b/arch/x86/oprofile/op_model_amd.c
+@@ -519,9 +519,11 @@ static int op_amd_init(struct oprofile_operations *ops)
+ 		num_counters = AMD64_NUM_COUNTERS;
+ 	}
+ 
+-	op_amd_spec.num_counters = num_counters;
+-	op_amd_spec.num_controls = num_counters;
+-	op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS);
++	pax_open_kernel();
++	*(unsigned int *)&op_amd_spec.num_counters = num_counters;
++	*(unsigned int *)&op_amd_spec.num_controls = num_counters;
++	*(unsigned int *)&op_amd_spec.num_virt_counters = max(num_counters, \
NUM_VIRT_COUNTERS); ++	pax_close_kernel();
+ 
+ 	return 0;
+ }
+diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
+index d90528e..0127e2b 100644
+--- a/arch/x86/oprofile/op_model_ppro.c
++++ b/arch/x86/oprofile/op_model_ppro.c
+@@ -19,6 +19,7 @@
+ #include <asm/msr.h>
+ #include <asm/apic.h>
+ #include <asm/nmi.h>
++#include <asm/pgtable.h>
+ 
+ #include "op_x86_model.h"
+ #include "op_counter.h"
+@@ -221,8 +222,10 @@ static void arch_perfmon_setup_counters(void)
+ 
+ 	num_counters = min((int)eax.split.num_counters, OP_MAX_COUNTER);
+ 
+-	op_arch_perfmon_spec.num_counters = num_counters;
+-	op_arch_perfmon_spec.num_controls = num_counters;
++	pax_open_kernel();
++	*(unsigned int *)&op_arch_perfmon_spec.num_counters = num_counters;
++	*(unsigned int *)&op_arch_perfmon_spec.num_controls = num_counters;
++	pax_close_kernel();
+ }
+ 
+ static int arch_perfmon_init(struct oprofile_operations *ignore)
+diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
+index 71e8a67..6a313bb 100644
+--- a/arch/x86/oprofile/op_x86_model.h
++++ b/arch/x86/oprofile/op_x86_model.h
+@@ -52,7 +52,7 @@ struct op_x86_model_spec {
+ 	void		(*switch_ctrl)(struct op_x86_model_spec const *model,
+ 				       struct op_msrs const * const msrs);
+ #endif
+-};
++} __do_const;
+ 
+ struct op_counter_config;
+ 
+diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
+index 372e9b8..e775a6c 100644
+--- a/arch/x86/pci/irq.c
++++ b/arch/x86/pci/irq.c
+@@ -50,7 +50,7 @@ struct irq_router {
+ struct irq_router_handler {
+ 	u16 vendor;
+ 	int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
+-};
++} __do_const;
+ 
+ int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
+ void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
+@@ -794,7 +794,7 @@ static __init int pico_router_probe(struct irq_router *r, struct \
pci_dev *router + 	return 0;
+ }
+ 
+-static __initdata struct irq_router_handler pirq_routers[] = {
++static __initconst const struct irq_router_handler pirq_routers[] = {
+ 	{ PCI_VENDOR_ID_INTEL, intel_router_probe },
+ 	{ PCI_VENDOR_ID_AL, ali_router_probe },
+ 	{ PCI_VENDOR_ID_ITE, ite_router_probe },
+@@ -821,7 +821,7 @@ static struct pci_dev *pirq_router_dev;
+ static void __init pirq_find_router(struct irq_router *r)
+ {
+ 	struct irq_routing_table *rt = pirq_table;
+-	struct irq_router_handler *h;
++	const struct irq_router_handler *h;
+ 
+ #ifdef CONFIG_PCI_BIOS
+ 	if (!rt->signature) {
+@@ -1094,7 +1094,7 @@ static int __init fix_acer_tm360_irqrouting(const struct \
dmi_system_id *d) + 	return 0;
+ }
+ 
+-static struct dmi_system_id __initdata pciirq_dmi_table[] = {
++static const struct dmi_system_id __initconst pciirq_dmi_table[] = {
+ 	{
+ 		.callback = fix_broken_hp_bios_irq9,
+ 		.ident = "HP Pavilion N5400 Series Laptop",
+diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c
+index 6eb18c4..20d83de 100644
+--- a/arch/x86/pci/mrst.c
++++ b/arch/x86/pci/mrst.c
+@@ -238,7 +238,9 @@ int __init pci_mrst_init(void)
+ 	printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n");
+ 	pci_mmcfg_late_init();
+ 	pcibios_enable_irq = mrst_pci_irq_enable;
+-	pci_root_ops = pci_mrst_ops;
++	pax_open_kernel();
++	memcpy((void *)&pci_root_ops, &pci_mrst_ops, sizeof(pci_mrst_ops));
++	pax_close_kernel();
+ 	pci_soc_mode = 1;
+ 	/* Continue with standard init */
+ 	return 1;
+diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
+index c77b24a..c979855 100644
+--- a/arch/x86/pci/pcbios.c
++++ b/arch/x86/pci/pcbios.c
+@@ -79,7 +79,7 @@ union bios32 {
+ static struct {
+ 	unsigned long address;
+ 	unsigned short segment;
+-} bios32_indirect = { 0, __KERNEL_CS };
++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
+ 
+ /*
+  * Returns the entry point for the given service, NULL on error
+@@ -92,37 +92,80 @@ static unsigned long bios32_service(unsigned long service)
+ 	unsigned long length;		/* %ecx */
+ 	unsigned long entry;		/* %edx */
+ 	unsigned long flags;
++	struct desc_struct d, *gdt;
+ 
+ 	local_irq_save(flags);
+-	__asm__("lcall *(%%edi); cld"
++
++	gdt = get_cpu_gdt_table(smp_processor_id());
++
++	pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
++	write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
++	pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
++	write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
++
++	__asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
+ 		: "=a" (return_code),
+ 		  "=b" (address),
+ 		  "=c" (length),
+ 		  "=d" (entry)
+ 		: "0" (service),
+ 		  "1" (0),
+-		  "D" (&bios32_indirect));
++		  "D" (&bios32_indirect),
++		  "r"(__PCIBIOS_DS)
++		: "memory");
++
++	pax_open_kernel();
++	gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
++	gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
++	gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
++	gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
++	pax_close_kernel();
++
+ 	local_irq_restore(flags);
+ 
+ 	switch (return_code) {
+-		case 0:
+-			return address + entry;
+-		case 0x80:	/* Not present */
+-			printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
+-			return 0;
+-		default: /* Shouldn't happen */
+-			printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
+-				service, return_code);
++	case 0: {
++		int cpu;
++		unsigned char flags;
++
++		printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", \
address, length, entry); ++		if (address >= 0xFFFF0 || length > 0x100000 - address || \
length <= entry) { ++			printk(KERN_WARNING "bios32_service: not valid\n");
+ 			return 0;
++		}
++		address = address + PAGE_OFFSET;
++		length += 16UL; /* some BIOSs underreport this... */
++		flags = 4;
++		if (length >= 64*1024*1024) {
++			length >>= PAGE_SHIFT;
++			flags |= 8;
++		}
++
++		for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
++			gdt = get_cpu_gdt_table(cpu);
++			pack_descriptor(&d, address, length, 0x9b, flags);
++			write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
++			pack_descriptor(&d, address, length, 0x93, flags);
++			write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
++		}
++		return entry;
++	}
++	case 0x80:	/* Not present */
++		printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
++		return 0;
++	default: /* Shouldn't happen */
++		printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
++			service, return_code);
++		return 0;
+ 	}
+ }
+ 
+ static struct {
+ 	unsigned long address;
+ 	unsigned short segment;
+-} pci_indirect = { 0, __KERNEL_CS };
++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
+ 
+-static int pci_bios_present;
++static int pci_bios_present __read_only;
+ 
+ static int check_pcibios(void)
+ {
+@@ -131,11 +174,13 @@ static int check_pcibios(void)
+ 	unsigned long flags, pcibios_entry;
+ 
+ 	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
+-		pci_indirect.address = pcibios_entry + PAGE_OFFSET;
++		pci_indirect.address = pcibios_entry;
+ 
+ 		local_irq_save(flags);
+-		__asm__(
+-			"lcall *(%%edi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%edi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -144,7 +189,8 @@ static int check_pcibios(void)
+ 			  "=b" (ebx),
+ 			  "=c" (ecx)
+ 			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
+-			  "D" (&pci_indirect)
++			  "D" (&pci_indirect),
++			  "r" (__PCIBIOS_DS)
+ 			: "memory");
+ 		local_irq_restore(flags);
+ 
+@@ -189,7 +235,10 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 
+ 	switch (len) {
+ 	case 1:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -198,7 +247,8 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 			: "1" (PCIBIOS_READ_CONFIG_BYTE),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		/*
+ 		 * Zero-extend the result beyond 8 bits, do not trust the
+ 		 * BIOS having done it:
+@@ -206,7 +256,10 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 		*value &= 0xff;
+ 		break;
+ 	case 2:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -215,7 +268,8 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 			: "1" (PCIBIOS_READ_CONFIG_WORD),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		/*
+ 		 * Zero-extend the result beyond 16 bits, do not trust the
+ 		 * BIOS having done it:
+@@ -223,7 +277,10 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 		*value &= 0xffff;
+ 		break;
+ 	case 4:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -232,7 +289,8 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
+ 			: "1" (PCIBIOS_READ_CONFIG_DWORD),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		break;
+ 	}
+ 
+@@ -256,7 +314,10 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
+ 
+ 	switch (len) {
+ 	case 1:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -265,10 +326,14 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
+ 			  "c" (value),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		break;
+ 	case 2:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -277,10 +342,14 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
+ 			  "c" (value),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		break;
+ 	case 4:
+-		__asm__("lcall *(%%esi); cld\n\t"
++		__asm__("movw %w6, %%ds\n\t"
++			"lcall *%%ss:(%%esi); cld\n\t"
++			"push %%ss\n\t"
++			"pop %%ds\n\t"
+ 			"jc 1f\n\t"
+ 			"xor %%ah, %%ah\n"
+ 			"1:"
+@@ -289,7 +358,8 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
+ 			  "c" (value),
+ 			  "b" (bx),
+ 			  "D" ((long)reg),
+-			  "S" (&pci_indirect));
++			  "S" (&pci_indirect),
++			  "r" (__PCIBIOS_DS));
+ 		break;
+ 	}
+ 
+@@ -394,10 +464,13 @@ struct irq_routing_table * pcibios_get_irq_routing_table(void)
+ 
+ 	DBG("PCI: Fetching IRQ routing table... ");
+ 	__asm__("push %%es\n\t"
++		"movw %w8, %%ds\n\t"
+ 		"push %%ds\n\t"
+ 		"pop  %%es\n\t"
+-		"lcall *(%%esi); cld\n\t"
++		"lcall *%%ss:(%%esi); cld\n\t"
+ 		"pop %%es\n\t"
++		"push %%ss\n\t"
++		"pop %%ds\n"
+ 		"jc 1f\n\t"
+ 		"xor %%ah, %%ah\n"
+ 		"1:"
+@@ -408,7 +481,8 @@ struct irq_routing_table * pcibios_get_irq_routing_table(void)
+ 		  "1" (0),
+ 		  "D" ((long) &opt),
+ 		  "S" (&pci_indirect),
+-		  "m" (opt)
++		  "m" (opt),
++		  "r" (__PCIBIOS_DS)
+ 		: "memory");
+ 	DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
+ 	if (ret & 0xff00)
+@@ -432,7 +506,10 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int \
irq) + {
+ 	int ret;
+ 
+-	__asm__("lcall *(%%esi); cld\n\t"
++	__asm__("movw %w5, %%ds\n\t"
++		"lcall *%%ss:(%%esi); cld\n\t"
++		"push %%ss\n\t"
++		"pop %%ds\n"
+ 		"jc 1f\n\t"
+ 		"xor %%ah, %%ah\n"
+ 		"1:"
+@@ -440,7 +517,8 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int \
irq) + 		: "0" (PCIBIOS_SET_PCI_HW_INT),
+ 		  "b" ((dev->bus->number << 8) | dev->devfn),
+ 		  "c" ((irq << 8) | (pin + 10)),
+-		  "S" (&pci_indirect));
++		  "S" (&pci_indirect),
++		  "r" (__PCIBIOS_DS));
+ 	return !(ret & 0xff00);
+ }
+ EXPORT_SYMBOL(pcibios_set_irq_routing);
+diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
+index 40e4469..d915bf9 100644
+--- a/arch/x86/platform/efi/efi_32.c
++++ b/arch/x86/platform/efi/efi_32.c
+@@ -44,11 +44,22 @@ void efi_call_phys_prelog(void)
+ {
+ 	struct desc_ptr gdt_descr;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	struct desc_struct d;
++#endif
++
+ 	local_irq_save(efi_rt_eflags);
+ 
+ 	load_cr3(initial_page_table);
+ 	__flush_tlb_all();
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	pack_descriptor(&d, 0, 0xFFFFF, 0x9B, 0xC);
++	write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_CS, &d, DESCTYPE_S);
++	pack_descriptor(&d, 0, 0xFFFFF, 0x93, 0xC);
++	write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_DS, &d, DESCTYPE_S);
++#endif
++
+ 	gdt_descr.address = __pa(get_cpu_gdt_table(0));
+ 	gdt_descr.size = GDT_SIZE - 1;
+ 	load_gdt(&gdt_descr);
+@@ -58,11 +69,24 @@ void efi_call_phys_epilog(void)
+ {
+ 	struct desc_ptr gdt_descr;
+ 
++#ifdef CONFIG_PAX_KERNEXEC
++	struct desc_struct d;
++
++	memset(&d, 0, sizeof d);
++	write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_CS, &d, DESCTYPE_S);
++	write_gdt_entry(get_cpu_gdt_table(0), GDT_ENTRY_KERNEXEC_EFI_DS, &d, DESCTYPE_S);
++#endif
++
+ 	gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
+ 	gdt_descr.size = GDT_SIZE - 1;
+ 	load_gdt(&gdt_descr);
+ 
++#ifdef CONFIG_PAX_PER_CPU_PGD
++	load_cr3(get_cpu_pgd(smp_processor_id(), kernel));
++#else
+ 	load_cr3(swapper_pg_dir);
++#endif
++
+ 	__flush_tlb_all();
+ 
+ 	local_irq_restore(efi_rt_eflags);
+diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
+index 39a0e7f1..872396e 100644
+--- a/arch/x86/platform/efi/efi_64.c
++++ b/arch/x86/platform/efi/efi_64.c
+@@ -76,6 +76,11 @@ void __init efi_call_phys_prelog(void)
+ 		vaddress = (unsigned long)__va(pgd * PGDIR_SIZE


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic