- forward port to 3.8.13

diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/include/asm/atomic.h linux-3.8.13-pax/arch/alpha/include/asm/atomic.h
--- linux-3.8.13/arch/alpha/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/include/asm/atomic.h	2013-02-19 01:14:42.837772685 +0100
@@ -250,6 +250,16 @@ static __inline__ int atomic64_add_unles
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/include/asm/elf.h linux-3.8.13-pax/arch/alpha/include/asm/elf.h
--- linux-3.8.13/arch/alpha/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/include/asm/elf.h	2013-02-19 01:14:42.909772689 +0100
@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/include/asm/pgalloc.h linux-3.8.13-pax/arch/alpha/include/asm/pgalloc.h
--- linux-3.8.13/arch/alpha/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/include/asm/pgalloc.h	2013-02-19 01:14:42.909772689 +0100
@@ -29,6 +29,12 @@ pgd_populate(struct mm_struct *mm, pgd_t
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/include/asm/pgtable.h linux-3.8.13-pax/arch/alpha/include/asm/pgtable.h
--- linux-3.8.13/arch/alpha/include/asm/pgtable.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/include/asm/pgtable.h	2013-02-19 01:14:42.909772689 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/kernel/module.c linux-3.8.13-pax/arch/alpha/kernel/module.c
--- linux-3.8.13/arch/alpha/kernel/module.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/kernel/module.c	2013-02-19 01:14:42.909772689 +0100
@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
 
 	/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/kernel/osf_sys.c linux-3.8.13-pax/arch/alpha/kernel/osf_sys.c
--- linux-3.8.13/arch/alpha/kernel/osf_sys.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/kernel/osf_sys.c	2013-02-19 01:14:42.909772689 +0100
@@ -1304,7 +1304,7 @@ arch_get_unmapped_area_1(unsigned long a
 		/* At this point:  (!vma || addr < vma->vm_end). */
 		if (limit - len < addr)
 			return -ENOMEM;
-		if (!vma || addr + len <= vma->vm_start)
+		if (check_heap_stack_gap(vma, addr, len))
 			return addr;
 		addr = vma->vm_end;
 		vma = vma->vm_next;
@@ -1340,6 +1340,10 @@ arch_get_unmapped_area(struct file *filp
 	   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);
 		if (addr != (unsigned long) -ENOMEM)
@@ -1347,8 +1351,8 @@ arch_get_unmapped_area(struct file *filp
 	}
 
 	/* 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 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
+
 	if (addr != (unsigned long) -ENOMEM)
 		return addr;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/alpha/mm/fault.c linux-3.8.13-pax/arch/alpha/mm/fault.c
--- linux-3.8.13/arch/alpha/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/alpha/mm/fault.c	2013-02-19 01:14:42.909772689 +0100
@@ -53,6 +53,124 @@ __load_new_mm_context(struct mm_struct *
 	__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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/common/gic.c linux-3.8.13-pax/arch/arm/common/gic.c
--- linux-3.8.13/arch/arm/common/gic.c	2013-02-19 01:12:35.493765769 +0100
+++ linux-3.8.13-pax/arch/arm/common/gic.c	2013-03-08 13:36:43.994320827 +0100
@@ -81,7 +81,7 @@ static u8 gic_cpu_map[NR_GIC_CPU_IF] __r
  * Supported arch specific GIC irq extension.
  * Default make them NULL.
  */
-struct irq_chip gic_arch_extn = {
+irq_chip_no_const gic_arch_extn __read_only = {
 	.irq_eoi	= NULL,
 	.irq_mask	= NULL,
 	.irq_unmask	= NULL,
@@ -329,7 +329,7 @@ static void gic_handle_cascade_irq(unsig
 	chained_irq_exit(chip, desc);
 }
 
-static struct irq_chip gic_chip = {
+static irq_chip_no_const gic_chip __read_only = {
 	.name			= "GIC",
 	.irq_mask		= gic_mask_irq,
 	.irq_unmask		= gic_unmask_irq,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/atomic.h linux-3.8.13-pax/arch/arm/include/asm/atomic.h
--- linux-3.8.13/arch/arm/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/atomic.h	2013-02-19 01:14:42.913772690 +0100
@@ -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, ato
 	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
 	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, ato
 	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
 	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_
 	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
 
 	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
 	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_
 	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(uns
 #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(at
 }
 
 #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) }
 
 static inline u64 atomic64_read(const atomic64_t *v)
@@ -256,6 +451,19 @@ static inline u64 atomic64_read(const at
 	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;
@@ -270,6 +478,20 @@ static inline void atomic64_set(atomic64
 	: "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");
+}
+
 static inline void atomic64_add(u64 i, atomic64_t *v)
 {
 	u64 result;
@@ -278,6 +500,36 @@ static inline void atomic64_add(u64 i, a
 	__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"
@@ -289,12 +541,49 @@ static inline void atomic64_add(u64 i, a
 
 static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
 {
+	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\n"
+	__asm__ __volatile__("@ atomic64_add_return_unchecked\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
 "	adds	%0, %0, %4\n"
 "	adc	%H0, %H0, %H4\n"
@@ -318,23 +607,34 @@ static inline void atomic64_sub(u64 i, a
 	__asm__ __volatile__("@ atomic64_sub\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
 "	subs	%0, %0, %4\n"
-"	sbc	%H0, %H0, %H4\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 u64 atomic64_sub_return(u64 i, atomic64_t *v)
+static inline void atomic64_sub_unchecked(u64 i, atomic64_unchecked_t *v)
 {
 	u64 result;
 	unsigned long tmp;
 
-	smp_mb();
-
-	__asm__ __volatile__("@ atomic64_sub_return\n"
+	__asm__ __volatile__("@ atomic64_sub_unchecked\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
 "	subs	%0, %0, %4\n"
 "	sbc	%H0, %H0, %H4\n"
@@ -344,6 +644,39 @@ static inline u64 atomic64_sub_return(u6
 	: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 	: "r" (&v->counter), "r" (i)
 	: "cc");
+}
+
+static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+{
+	u64 result, tmp;
+
+	smp_mb();
+
+	__asm__ __volatile__("@ atomic64_sub_return\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");
 
 	smp_mb();
 
@@ -374,6 +707,30 @@ static inline u64 atomic64_cmpxchg(atomi
 	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;
@@ -397,21 +754,34 @@ static inline u64 atomic64_xchg(atomic64
 
 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");
@@ -434,13 +804,25 @@ static inline int atomic64_add_unless(at
 "	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");
@@ -453,10 +835,13 @@ static inline int atomic64_add_unless(at
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/cacheflush.h linux-3.8.13-pax/arch/arm/include/asm/cacheflush.h
--- linux-3.8.13/arch/arm/include/asm/cacheflush.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/cacheflush.h	2013-02-19 01:14:42.913772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/cache.h linux-3.8.13-pax/arch/arm/include/asm/cache.h
--- linux-3.8.13/arch/arm/include/asm/cache.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/cache.h	2013-03-11 15:56:35.477106648 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/checksum.h linux-3.8.13-pax/arch/arm/include/asm/checksum.h
--- linux-3.8.13/arch/arm/include/asm/checksum.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/checksum.h	2013-02-19 01:14:42.913772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/cmpxchg.h linux-3.8.13-pax/arch/arm/include/asm/cmpxchg.h
--- linux-3.8.13/arch/arm/include/asm/cmpxchg.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/cmpxchg.h	2013-02-19 01:14:42.913772690 +0100
@@ -102,6 +102,8 @@ static inline unsigned long __xchg(unsig
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/domain.h linux-3.8.13-pax/arch/arm/include/asm/domain.h
--- linux-3.8.13/arch/arm/include/asm/domain.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/domain.h	2013-02-23 16:59:04.351130684 +0100
@@ -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 v
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/elf.h linux-3.8.13-pax/arch/arm/include/asm/elf.h
--- linux-3.8.13/arch/arm/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/elf.h	2013-02-19 01:14:42.917772690 +0100
@@ -116,7 +116,14 @@ int dump_task_regs(struct task_struct *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	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,8 +133,4 @@ int dump_task_regs(struct task_struct *t
 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
-
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/fncpy.h linux-3.8.13-pax/arch/arm/include/asm/fncpy.h
--- linux-3.8.13/arch/arm/include/asm/fncpy.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/fncpy.h	2013-02-19 01:14:42.917772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/futex.h linux-3.8.13-pax/arch/arm/include/asm/futex.h
--- linux-3.8.13/arch/arm/include/asm/futex.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/futex.h	2013-02-19 01:14:42.917772690 +0100
@@ -50,6 +50,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
 	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,
 	: "cc", "memory");
 	smp_mb();
 
+	pax_close_userland();
+
 	*uval = val;
 	return ret;
 }
@@ -95,6 +99,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
 	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,
 	: "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,
 		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,
 		ret = -ENOSYS;
 	}
 
+	pax_close_userland();
 	pagefault_enable();	/* subsumes preempt_enable() */
 
 	if (!ret) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/hardware/gic.h linux-3.8.13-pax/arch/arm/include/asm/hardware/gic.h
--- linux-3.8.13/arch/arm/include/asm/hardware/gic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/hardware/gic.h	2013-03-08 15:56:17.674347176 +0100
@@ -34,9 +34,10 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/irqdomain.h>
+#include <linux/irq.h>
 struct device_node;
 
-extern struct irq_chip gic_arch_extn;
+extern irq_chip_no_const gic_arch_extn;
 
 void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
 		    u32 offset, struct device_node *);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/kmap_types.h linux-3.8.13-pax/arch/arm/include/asm/kmap_types.h
--- linux-3.8.13/arch/arm/include/asm/kmap_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/kmap_types.h	2013-02-19 01:14:42.917772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/mach/dma.h linux-3.8.13-pax/arch/arm/include/asm/mach/dma.h
--- linux-3.8.13/arch/arm/include/asm/mach/dma.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/mach/dma.h	2013-02-19 01:14:42.917772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/mach/map.h linux-3.8.13-pax/arch/arm/include/asm/mach/map.h
--- linux-3.8.13/arch/arm/include/asm/mach/map.h	2013-02-19 01:12:35.705765781 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/mach/map.h	2013-02-19 01:14:42.917772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/outercache.h linux-3.8.13-pax/arch/arm/include/asm/outercache.h
--- linux-3.8.13/arch/arm/include/asm/outercache.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/outercache.h	2013-02-19 01:14:42.917772690 +0100
@@ -35,7 +35,7 @@ struct outer_cache_fns {
 #endif
 	void (*set_debug)(unsigned long);
 	void (*resume)(void);
-};
+} __no_const;
 
 #ifdef CONFIG_OUTER_CACHE
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/page.h linux-3.8.13-pax/arch/arm/include/asm/page.h
--- linux-3.8.13/arch/arm/include/asm/page.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/page.h	2013-02-19 01:14:42.917772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgalloc.h linux-3.8.13-pax/arch/arm/include/asm/pgalloc.h
--- linux-3.8.13/arch/arm/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/pgalloc.h	2013-02-19 01:14:42.921772690 +0100
@@ -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 m
 	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 m
 #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_st
 	__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
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgtable-2level.h linux-3.8.13-pax/arch/arm/include/asm/pgtable-2level.h
--- linux-3.8.13/arch/arm/include/asm/pgtable-2level.h	2013-02-19 01:12:35.725765782 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/pgtable-2level.h	2013-02-19 01:14:42.921772690 +0100
@@ -125,6 +125,7 @@
 #define L_PTE_XN		(_AT(pteval_t, 1) << 9)
 #define L_PTE_SHARED		(_AT(pteval_t, 1) << 10)	/* shared(v6), coherent(xsc3) */
 #define L_PTE_NONE		(_AT(pteval_t, 1) << 11)
+#define L_PTE_PXN		(_AT(pteval_t, 1) << 12)	/* v7*/
 
 /*
  * These are the memory types, defined to be compatible with
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgtable-2level-hwdef.h linux-3.8.13-pax/arch/arm/include/asm/pgtable-2level-hwdef.h
--- linux-3.8.13/arch/arm/include/asm/pgtable-2level-hwdef.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/pgtable-2level-hwdef.h	2013-02-19 01:14:42.921772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgtable-3level.h linux-3.8.13-pax/arch/arm/include/asm/pgtable-3level.h
--- linux-3.8.13/arch/arm/include/asm/pgtable-3level.h	2013-02-19 01:12:35.725765782 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/pgtable-3level.h	2013-02-19 01:14:42.921772690 +0100
@@ -74,6 +74,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 */
@@ -82,6 +83,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgtable-3level-hwdef.h linux-3.8.13-pax/arch/arm/include/asm/pgtable-3level-hwdef.h
--- linux-3.8.13/arch/arm/include/asm/pgtable-3level-hwdef.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/pgtable-3level-hwdef.h	2013-02-19 01:14:42.921772690 +0100
@@ -32,15 +32,18 @@
 #define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
 #define PMD_BIT4		(_AT(pmdval_t, 0))
 #define PMD_DOMAIN(x)		(_AT(pmdval_t, 0))
+#define PMD_PXNTABLE		(_AT(pmdval_t, 1) << 59) /* PXNTable */
 
 /*
  *   - section
  */
 #define PMD_SECT_BUFFERABLE	(_AT(pmdval_t, 1) << 2)
 #define PMD_SECT_CACHEABLE	(_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)
 #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
 #define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
 #define PMD_SECT_nG		(_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_PXN		(_AT(pmdval_t, 1) << 53)
 #define PMD_SECT_XN		(_AT(pmdval_t, 1) << 54)
 #define PMD_SECT_AP_WRITE	(_AT(pmdval_t, 0))
 #define PMD_SECT_AP_READ	(_AT(pmdval_t, 0))
@@ -66,6 +69,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/pgtable.h linux-3.8.13-pax/arch/arm/include/asm/pgtable.h
--- linux-3.8.13/arch/arm/include/asm/pgtable.h	2013-05-13 02:47:05.361794904 +0200
+++ linux-3.8.13-pax/arch/arm/include/asm/pgtable.h	2013-05-13 02:48:40.057789848 +0200
@@ -30,6 +30,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
@@ -45,6 +48,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);
@@ -53,6 +59,50 @@ extern void __pgd_error(const char *file
 #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
+
+#ifdef CONFIG_PAX_KERNEXEC
+#include <asm/domain.h>
+#include <linux/thread_info.h>
+#include <linux/preempt.h>
+#endif
+
+#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+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
@@ -72,8 +122,8 @@ extern void __pgd_error(const char *file
 /*
  * 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
 
@@ -250,7 +300,7 @@ static inline pte_t pte_mkspecial(pte_t
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/processor.h linux-3.8.13-pax/arch/arm/include/asm/processor.h
--- linux-3.8.13/arch/arm/include/asm/processor.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/processor.h	2013-02-19 01:14:42.921772690 +0100
@@ -65,9 +65,8 @@ struct thread_struct {
 	regs->ARM_cpsr |= PSR_ENDSTATE;					\
 	regs->ARM_pc = pc & ~1;		/* pc */			\
 	regs->ARM_sp = sp;		/* sp */			\
-	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
-	regs->ARM_r1 = stack[1];	/* r1 (argv) */			\
-	regs->ARM_r0 = stack[0];	/* r0 (argc) */			\
+	/* r2 (envp), r1 (argv), r0 (argc) */				\
+	(void)copy_from_user(&regs->ARM_r0, (const char __user *)stack, 3 * sizeof(unsigned long)); \
 	nommu_start_thread(regs);					\
 })
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/proc-fns.h linux-3.8.13-pax/arch/arm/include/asm/proc-fns.h
--- linux-3.8.13/arch/arm/include/asm/proc-fns.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/proc-fns.h	2013-02-19 01:14:42.921772690 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/smp.h linux-3.8.13-pax/arch/arm/include/asm/smp.h
--- linux-3.8.13/arch/arm/include/asm/smp.h	2013-02-19 01:12:35.733765782 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/smp.h	2013-02-19 01:14:42.925772690 +0100
@@ -107,7 +107,7 @@ struct smp_operations {
 	int  (*cpu_disable)(unsigned int cpu);
 #endif
 #endif
-};
+} __no_const;
 
 /*
  * set platform specific SMP operations
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/thread_info.h linux-3.8.13-pax/arch/arm/include/asm/thread_info.h
--- linux-3.8.13/arch/arm/include/asm/thread_info.h	2013-02-19 01:12:35.745765783 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/thread_info.h	2013-02-19 01:14:42.925772690 +0100
@@ -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,			\
 	},								\
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/asm/uaccess.h linux-3.8.13-pax/arch/arm/include/asm/uaccess.h
--- linux-3.8.13/arch/arm/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/asm/uaccess.h	2013-02-19 01:14:42.925772690 +0100
@@ -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
@@ -60,10 +61,34 @@ extern int __put_user_bad(void);
 #define USER_DS		TASK_SIZE
 #define get_fs()	(current_thread_info()->addr_limit)
 
+static inline void pax_open_userland(void)
+{
+
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+	if (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 (get_fs() == USER_DS) {
+		BUG_ON(test_domain(DOMAIN_USER, DOMAIN_NOACCESS));
+		modify_domain(DOMAIN_USER, DOMAIN_NOACCESS);
+	}
+#endif
+
+}
+
 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))
@@ -143,8 +168,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 +217,12 @@ extern int __put_user_8(void *, unsigned
 
 #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 +263,17 @@ static inline void set_fs(mm_segment_t f
 #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 +349,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 +459,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 +505,9 @@ extern unsigned long __must_check __clea
 
 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 +517,9 @@ static inline unsigned long __must_check
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/include/uapi/asm/ptrace.h linux-3.8.13-pax/arch/arm/include/uapi/asm/ptrace.h
--- linux-3.8.13/arch/arm/include/uapi/asm/ptrace.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/include/uapi/asm/ptrace.h	2013-02-19 01:14:42.925772690 +0100
@@ -73,7 +73,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/Kconfig linux-3.8.13-pax/arch/arm/Kconfig
--- linux-3.8.13/arch/arm/Kconfig	2013-02-19 01:12:35.229765755 +0100
+++ linux-3.8.13-pax/arch/arm/Kconfig	2013-02-19 01:14:42.925772690 +0100
@@ -1813,7 +1813,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/armksyms.c linux-3.8.13-pax/arch/arm/kernel/armksyms.c
--- linux-3.8.13/arch/arm/kernel/armksyms.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/armksyms.c	2013-03-03 21:20:31.417241578 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/entry-armv.S linux-3.8.13-pax/arch/arm/kernel/entry-armv.S
--- linux-3.8.13/arch/arm/kernel/entry-armv.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/entry-armv.S	2013-03-19 02:30:17.923163507 +0100
@@ -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
@@ -359,6 +453,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}	)
@@ -456,7 +553,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
@@ -491,10 +590,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
@@ -733,7 +836,7 @@ ENTRY(__switch_to)
  THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
  THUMB(	str	sp, [ip], #4		   )
  THUMB(	str	lr, [ip], #4		   )
-#ifdef CONFIG_CPU_USE_DOMAINS
+#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC)
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
 	set_tls	r3, r4, r5
@@ -742,7 +845,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)
 	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
 #endif
 	mov	r5, r0
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/entry-common.S linux-3.8.13-pax/arch/arm/kernel/entry-common.S
--- linux-3.8.13/arch/arm/kernel/entry-common.S	2013-02-19 01:12:35.817765787 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/entry-common.S	2013-02-19 01:14:42.929772690 +0100
@@ -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
@@ -339,6 +367,7 @@ ENDPROC(ftrace_stub)
 
 	.align	5
 ENTRY(vector_swi)
+
 	sub	sp, sp, #S_FRAME_SIZE
 	stmia	sp, {r0 - r12}			@ Calling r0 - r12
  ARM(	add	r8, sp, #S_PC		)
@@ -388,6 +417,12 @@ ENTRY(vector_swi)
 	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
+
 #ifdef CONFIG_ALIGNMENT_TRAP
 	ldr	ip, __cr_alignment
 	ldr	ip, [ip]
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/entry-header.S linux-3.8.13-pax/arch/arm/kernel/entry-header.S
--- linux-3.8.13/arch/arm/kernel/entry-header.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/entry-header.S	2013-02-19 01:14:42.929772690 +0100
@@ -73,9 +73,66 @@
 	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
 	msr	spsr_cxsf, \rpsr
+
+	pax_exit_kernel
+
 #if defined(CONFIG_CPU_V6)
 	ldr	r0, [sp]
 	strex	r1, r2, [sp]			@ clear the exclusive monitor
@@ -121,6 +178,9 @@
 	.endm
 #else	/* CONFIG_THUMB2_KERNEL */
 	.macro	svc_exit, rpsr
+
+	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/fiq.c linux-3.8.13-pax/arch/arm/kernel/fiq.c
--- linux-3.8.13/arch/arm/kernel/fiq.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/fiq.c	2013-02-19 01:14:42.929772690 +0100
@@ -82,7 +82,9 @@ void set_fiq_handler(void *start, unsign
 #if defined(CONFIG_CPU_USE_DOMAINS)
 	memcpy((void *)0xffff001c, start, length);
 #else
+	pax_open_kernel();
 	memcpy(vectors_page + 0x1c, start, length);
+	pax_close_kernel();
 #endif
 	flush_icache_range(0xffff001c, 0xffff001c + length);
 	if (!vectors_high())
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/head.S linux-3.8.13-pax/arch/arm/kernel/head.S
--- linux-3.8.13/arch/arm/kernel/head.S	2013-03-19 01:53:21.023281873 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/head.S	2013-03-19 01:53:31.187281330 +0100
@@ -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
 
 /*
@@ -434,7 +436,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/hw_breakpoint.c linux-3.8.13-pax/arch/arm/kernel/hw_breakpoint.c
--- linux-3.8.13/arch/arm/kernel/hw_breakpoint.c	2013-02-19 01:12:35.821765787 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/hw_breakpoint.c	2013-02-20 01:05:11.278072418 +0100
@@ -1011,7 +1011,7 @@ static int __cpuinit dbg_reset_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata dbg_reset_nb = {
+static struct notifier_block dbg_reset_nb = {
 	.notifier_call = dbg_reset_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/module.c linux-3.8.13-pax/arch/arm/kernel/module.c
--- linux-3.8.13/arch/arm/kernel/module.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/module.c	2013-02-19 01:14:42.929772690 +0100
@@ -37,12 +37,37 @@
 #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);
+}
+
+void *module_alloc_exec(unsigned long size)
+{
+	return __module_alloc(size, PAGE_KERNEL_EXEC);
+}
+#endif
 #endif
 
 int
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/patch.c linux-3.8.13-pax/arch/arm/kernel/patch.c
--- linux-3.8.13/arch/arm/kernel/patch.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/patch.c	2013-03-09 13:38:31.501578527 +0100
@@ -18,6 +18,7 @@ void __kprobes __patch_text(void *addr,
 	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,
 		*(u32 *)addr = insn;
 		size = sizeof(u32);
 	}
+	pax_close_kernel();
 
 	flush_icache_range((uintptr_t)(addr),
 			   (uintptr_t)(addr) + size);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/perf_event_cpu.c linux-3.8.13-pax/arch/arm/kernel/perf_event_cpu.c
--- linux-3.8.13/arch/arm/kernel/perf_event_cpu.c	2013-02-19 01:12:35.841765788 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/perf_event_cpu.c	2013-02-20 01:05:14.886072225 +0100
@@ -171,7 +171,7 @@ static int __cpuinit cpu_pmu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cpu_pmu_hotplug_notifier = {
+static struct notifier_block cpu_pmu_hotplug_notifier = {
 	.notifier_call = cpu_pmu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/process.c linux-3.8.13-pax/arch/arm/kernel/process.c
--- linux-3.8.13/arch/arm/kernel/process.c	2013-02-19 01:12:35.873765790 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/process.c	2013-03-18 23:35:05.287724800 +0100
@@ -28,7 +28,6 @@
 #include <linux/tick.h>
 #include <linux/utsname.h>
 #include <linux/uaccess.h>
-#include <linux/random.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/cpuidle.h>
 #include <linux/leds.h>
@@ -256,9 +255,10 @@ void machine_power_off(void)
 	machine_shutdown();
 	if (pm_power_off)
 		pm_power_off();
+	BUG();
 }
 
-void machine_restart(char *cmd)
+__noreturn void machine_restart(char *cmd)
 {
 	machine_shutdown();
 
@@ -452,12 +452,6 @@ unsigned long get_wchan(struct task_stru
 	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
 /*
  * The vectors page is always readable from user space for the
@@ -470,9 +464,8 @@ static int __init gate_vma_init(void)
 {
 	gate_vma.vm_start	= 0xffff0000;
 	gate_vma.vm_end		= 0xffff0000 + PAGE_SIZE;
-	gate_vma.vm_page_prot	= PAGE_READONLY_EXEC;
-	gate_vma.vm_flags	= VM_READ | VM_EXEC |
-				  VM_MAYREAD | VM_MAYEXEC;
+	gate_vma.vm_flags	= VM_NONE;
+	gate_vma.vm_page_prot	= vm_get_page_prot(gate_vma.vm_flags);
 	return 0;
 }
 arch_initcall(gate_vma_init);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/setup.c linux-3.8.13-pax/arch/arm/kernel/setup.c
--- linux-3.8.13/arch/arm/kernel/setup.c	2013-02-19 01:12:35.877765790 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/setup.c	2013-02-19 01:14:42.933772691 +0100
@@ -97,21 +97,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
 
@@ -236,9 +238,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
@@ -462,7 +468,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/signal.c linux-3.8.13-pax/arch/arm/kernel/signal.c
--- linux-3.8.13/arch/arm/kernel/signal.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/signal.c	2013-03-18 23:34:30.899726637 +0100
@@ -433,22 +433,14 @@ setup_return(struct pt_regs *regs, struc
 		    __put_user(sigreturn_codes[idx+1], rc+1))
 			return 1;
 
-		if (cpsr & MODE32_BIT) {
-			/*
-			 * 32-bit code can use the new high-page
-			 * signal return code support.
-			 */
-			retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
-		} else {
-			/*
-			 * Ensure that the instruction cache sees
-			 * the return code written onto the stack.
-			 */
-			flush_icache_range((unsigned long)rc,
-					   (unsigned long)(rc + 2));
+		/*
+		 * Ensure that the instruction cache sees
+		 * the return code written onto the stack.
+		 */
+		flush_icache_range((unsigned long)rc,
+				   (unsigned long)(rc + 2));
 
-			retcode = ((unsigned long)rc) + thumb;
-		}
+		retcode = ((unsigned long)rc) + thumb;
 	}
 
 	regs->ARM_r0 = usig;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/smp.c linux-3.8.13-pax/arch/arm/kernel/smp.c
--- linux-3.8.13/arch/arm/kernel/smp.c	2013-03-19 01:53:21.023281873 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/smp.c	2013-04-16 19:27:39.320201589 +0200
@@ -70,7 +70,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/traps.c linux-3.8.13-pax/arch/arm/kernel/traps.c
--- linux-3.8.13/arch/arm/kernel/traps.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/traps.c	2013-03-19 02:31:37.087159280 +0100
@@ -601,7 +601,9 @@ asmlinkage int arm_syscall(int no, struc
 			 * 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;
 
@@ -841,13 +843,10 @@ void __init early_trap_init(void *vector
 	 */
 	kuser_get_tls_init(vectors);
 
-	/*
-	 * Copy signal return handlers into the vector page, and
-	 * set sigreturn to be a pointer to these.
-	 */
-	memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
-	       sigreturn_codes, sizeof(sigreturn_codes));
-
 	flush_icache_range(vectors, vectors + PAGE_SIZE);
-	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+
+#ifndef CONFIG_PAX_MEMORY_UDEREF
+	modify_domain(DOMAIN_USER, DOMAIN_USERCLIENT);
+#endif
+
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/kernel/vmlinux.lds.S linux-3.8.13-pax/arch/arm/kernel/vmlinux.lds.S
--- linux-3.8.13/arch/arm/kernel/vmlinux.lds.S	2013-02-19 01:12:35.893765791 +0100
+++ linux-3.8.13-pax/arch/arm/kernel/vmlinux.lds.S	2013-05-01 23:21:25.581177795 +0200
@@ -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) = .;				\
@@ -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);
@@ -203,6 +216,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/clear_user.S linux-3.8.13-pax/arch/arm/lib/clear_user.S
--- linux-3.8.13/arch/arm/lib/clear_user.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/clear_user.S	2013-02-19 01:14:42.933772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/copy_from_user.S linux-3.8.13-pax/arch/arm/lib/copy_from_user.S
--- linux-3.8.13/arch/arm/lib/copy_from_user.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/copy_from_user.S	2013-02-19 01:14:42.933772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/copy_page.S linux-3.8.13-pax/arch/arm/lib/copy_page.S
--- linux-3.8.13/arch/arm/lib/copy_page.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/copy_page.S	2013-02-19 01:14:42.933772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/copy_to_user.S linux-3.8.13-pax/arch/arm/lib/copy_to_user.S
--- linux-3.8.13/arch/arm/lib/copy_to_user.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/copy_to_user.S	2013-02-19 01:14:42.937772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/csumpartialcopyuser.S linux-3.8.13-pax/arch/arm/lib/csumpartialcopyuser.S
--- linux-3.8.13/arch/arm/lib/csumpartialcopyuser.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/csumpartialcopyuser.S	2013-02-19 01:14:42.937772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/delay.c linux-3.8.13-pax/arch/arm/lib/delay.c
--- linux-3.8.13/arch/arm/lib/delay.c	2013-03-19 01:53:21.023281873 +0100
+++ linux-3.8.13-pax/arch/arm/lib/delay.c	2013-04-16 19:27:32.432201957 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/lib/uaccess_with_memcpy.c linux-3.8.13-pax/arch/arm/lib/uaccess_with_memcpy.c
--- linux-3.8.13/arch/arm/lib/uaccess_with_memcpy.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/lib/uaccess_with_memcpy.c	2013-02-19 01:14:42.937772691 +0100
@@ -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
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-kirkwood/common.c linux-3.8.13-pax/arch/arm/mach-kirkwood/common.c
--- linux-3.8.13/arch/arm/mach-kirkwood/common.c	2013-02-19 01:12:36.641765831 +0100
+++ linux-3.8.13-pax/arch/arm/mach-kirkwood/common.c	2013-02-19 01:14:42.937772691 +0100
@@ -150,7 +150,16 @@ static void clk_gate_fn_disable(struct c
 	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_g
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/board-n8x0.c linux-3.8.13-pax/arch/arm/mach-omap2/board-n8x0.c
--- linux-3.8.13/arch/arm/mach-omap2/board-n8x0.c	2013-02-19 01:12:37.013765852 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/board-n8x0.c	2013-02-19 01:14:42.937772691 +0100
@@ -631,7 +631,7 @@ static int n8x0_menelaus_late_init(struc
 }
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/gpmc.c linux-3.8.13-pax/arch/arm/mach-omap2/gpmc.c
--- linux-3.8.13/arch/arm/mach-omap2/gpmc.c	2013-02-19 01:12:37.229765863 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/gpmc.c	2013-03-11 14:59:17.829290192 +0100
@@ -139,7 +139,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;
@@ -700,6 +699,18 @@ static void gpmc_irq_noop(struct irq_dat
 
 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;
@@ -714,15 +725,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/omap_device.c linux-3.8.13-pax/arch/arm/mach-omap2/omap_device.c
--- linux-3.8.13/arch/arm/mach-omap2/omap_device.c	2013-02-19 01:12:37.301765867 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/omap_device.c	2013-03-11 15:17:11.261232879 +0100
@@ -686,7 +686,7 @@ void omap_device_delete(struct omap_devi
  * passes along the return value of omap_device_build_ss().
  */
 struct platform_device __init *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 omap_device_pm_latency *pm_lats,
 				      int pm_lats_cnt, int is_early_device)
@@ -720,7 +720,7 @@ struct platform_device __init *omap_devi
  */
 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 pdata_len,
+					 const void *pdata, int pdata_len,
 					 struct omap_device_pm_latency *pm_lats,
 					 int pm_lats_cnt, int is_early_device)
 {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/omap_device.h linux-3.8.13-pax/arch/arm/mach-omap2/omap_device.h
--- linux-3.8.13/arch/arm/mach-omap2/omap_device.h	2013-02-19 01:12:37.301765867 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/omap_device.h	2013-03-11 15:17:43.277231169 +0100
@@ -91,14 +91,14 @@ int omap_device_shutdown(struct platform
 /* 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 omap_device_pm_latency *pm_lats,
 				      int pm_lats_cnt, int is_early_device);
 
 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_pm_latency *pm_lats,
 					 int pm_lats_cnt, int is_early_device);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/omap_hwmod.c linux-3.8.13-pax/arch/arm/mach-omap2/omap_hwmod.c
--- linux-3.8.13/arch/arm/mach-omap2/omap_hwmod.c	2013-02-19 01:12:37.305765868 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/omap_hwmod.c	2013-02-19 01:14:42.941772691 +0100
@@ -189,10 +189,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/omap-wakeupgen.c linux-3.8.13-pax/arch/arm/mach-omap2/omap-wakeupgen.c
--- linux-3.8.13/arch/arm/mach-omap2/omap-wakeupgen.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/omap-wakeupgen.c	2013-02-20 01:04:21.910075054 +0100
@@ -340,7 +340,7 @@ static int __cpuinit irq_cpu_hotplug_not
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-omap2/wd_timer.c linux-3.8.13-pax/arch/arm/mach-omap2/wd_timer.c
--- linux-3.8.13/arch/arm/mach-omap2/wd_timer.c	2013-02-19 01:12:37.505765878 +0100
+++ linux-3.8.13-pax/arch/arm/mach-omap2/wd_timer.c	2013-03-01 15:26:43.403402946 +0100
@@ -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),
 				 NULL, 0, 0);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mach-ux500/include/mach/setup.h linux-3.8.13-pax/arch/arm/mach-ux500/include/mach/setup.h
--- linux-3.8.13/arch/arm/mach-ux500/include/mach/setup.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/mach-ux500/include/mach/setup.h	2013-02-19 01:14:42.941772691 +0100
@@ -38,13 +38,6 @@ extern struct sys_timer ux500_timer;
 	.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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/alignment.c linux-3.8.13-pax/arch/arm/mm/alignment.c
--- linux-3.8.13/arch/arm/mm/alignment.c	2013-03-19 01:53:21.023281873 +0100
+++ linux-3.8.13-pax/arch/arm/mm/alignment.c	2013-03-19 01:53:31.187281330 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/fault.c linux-3.8.13-pax/arch/arm/mm/fault.c
--- linux-3.8.13/arch/arm/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/mm/fault.c	2013-03-19 00:44:58.547500913 +0100
@@ -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,16 @@ __do_kernel_fault(struct mm_struct *mm,
 	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)))
+	{
+		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 +185,13 @@ __do_user_fault(struct task_struct *tsk,
 	}
 #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 +416,33 @@ do_page_fault(unsigned long addr, unsign
 }
 #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
  *
@@ -543,9 +588,18 @@ do_DataAbort(unsigned long addr, unsigne
 	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)) {
+		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);
 
@@ -575,9 +629,46 @@ do_PrefetchAbort(unsigned long addr, uns
 	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
 	struct siginfo info;
 
+	if (user_mode(regs)) {
+		if (addr == 0xffff0fe0UL) {
+			/*
+			 * PaX: __kuser_get_tls emulation
+			 */
+			regs->ARM_r0 = current_thread_info()->tp_value;
+			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)) {
+		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()),
+				addr >= TASK_SIZE ? "non-executable kernel" : "userland", addr);
+		goto die;
+	}
+#endif
+
+#ifdef CONFIG_PAX_REFCOUNT
+	if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) {
+		unsigned int bkpt;
+
+		if (!probe_kernel_address((unsigned int *)addr, bkpt) && 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/fault.h linux-3.8.13-pax/arch/arm/mm/fault.h
--- linux-3.8.13/arch/arm/mm/fault.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/mm/fault.h	2013-02-19 01:14:42.941772691 +0100
@@ -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 fs
 }
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/init.c linux-3.8.13-pax/arch/arm/mm/init.c
--- linux-3.8.13/arch/arm/mm/init.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/mm/init.c	2013-02-19 01:14:42.941772691 +0100
@@ -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>
@@ -736,7 +738,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);
 	totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)),
 				    __phys_to_pfn(__pa(&__tcm_end)),
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/ioremap.c linux-3.8.13-pax/arch/arm/mm/ioremap.c
--- linux-3.8.13/arch/arm/mm/ioremap.c	2013-02-19 01:12:38.149765913 +0100
+++ linux-3.8.13-pax/arch/arm/mm/ioremap.c	2013-02-19 01:14:42.941772691 +0100
@@ -335,9 +335,9 @@ __arm_ioremap_exec(unsigned long phys_ad
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/Kconfig linux-3.8.13-pax/arch/arm/mm/Kconfig
--- linux-3.8.13/arch/arm/mm/Kconfig	2013-02-19 01:12:38.125765912 +0100
+++ linux-3.8.13-pax/arch/arm/mm/Kconfig	2013-02-19 01:14:42.945772691 +0100
@@ -425,7 +425,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
 	select TLS_REG_EMUL if !CPU_32v6K && !MMU
 
 config CPU_32v6K
@@ -577,6 +577,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.
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/mmap.c linux-3.8.13-pax/arch/arm/mm/mmap.c
--- linux-3.8.13/arch/arm/mm/mmap.c	2013-02-19 01:12:38.149765913 +0100
+++ linux-3.8.13-pax/arch/arm/mm/mmap.c	2013-02-19 01:14:42.945772691 +0100
@@ -81,6 +81,10 @@ arch_get_unmapped_area(struct file *filp
 	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 +92,7 @@ arch_get_unmapped_area(struct file *filp
 			addr = PAGE_ALIGN(addr);
 
 		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
-		    (!vma || addr + len <= vma->vm_start))
+		if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len))
 			return addr;
 	}
 
@@ -132,6 +135,10 @@ arch_get_unmapped_area_topdown(struct fi
 		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 +146,7 @@ arch_get_unmapped_area_topdown(struct fi
 		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))
 			return addr;
 	}
 
@@ -162,6 +168,12 @@ arch_get_unmapped_area_topdown(struct fi
 		VM_BUG_ON(addr != -ENOMEM);
 		info.flags = 0;
 		info.low_limit = mm->mmap_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);
 	}
@@ -173,6 +185,10 @@ void arch_pick_mmap_layout(struct mm_str
 {
 	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,10 +196,22 @@ void arch_pick_mmap_layout(struct mm_str
 
 	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;
 		mm->unmap_area = arch_unmap_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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/mmu.c linux-3.8.13-pax/arch/arm/mm/mmu.c
--- linux-3.8.13/arch/arm/mm/mmu.c	2013-02-19 01:12:38.149765913 +0100
+++ linux-3.8.13-pax/arch/arm/mm/mmu.c	2013-03-18 23:37:08.451718224 +0100
@@ -35,6 +35,23 @@
 
 #include "mm.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.
@@ -195,10 +212,18 @@ void adjust_cr(unsigned long mask, unsig
 }
 #endif
 
-#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,
@@ -227,16 +252,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
@@ -244,36 +269,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,
+			     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] = {
@@ -283,10 +326,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] = {
@@ -371,9 +414,35 @@ static void __init build_mem_type_table(
 			 * 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)) {
 			/*
@@ -432,6 +501,9 @@ static void __init build_mem_type_table(
 		 * 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
@@ -448,11 +520,17 @@ static void __init build_mem_type_table(
 			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;
 		}
 	}
 
@@ -463,15 +541,20 @@ static void __init build_mem_type_table(
 	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
@@ -487,6 +570,8 @@ static void __init build_mem_type_table(
 	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);
@@ -501,10 +586,15 @@ static void __init build_mem_type_table(
 
 	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) {
@@ -1105,18 +1195,15 @@ void __init arm_mm_memblock_reserve(void
  * called function.  This means you can't use any function or debugging
  * method which may touch any device, otherwise the kernel _will_ crash.
  */
+
+static char vectors[PAGE_SIZE] __read_only __aligned(PAGE_SIZE);
+
 static 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);
 
-	early_trap_init(vectors);
+	early_trap_init(&vectors);
 
 	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
 		pmd_clear(pmd_off_k(addr));
@@ -1156,7 +1243,7 @@ static void __init devicemaps_init(struc
 	 * 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;
 	map.type = MT_HIGH_VECTORS;
@@ -1214,8 +1301,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/mm/proc-v7-2level.S linux-3.8.13-pax/arch/arm/mm/proc-v7-2level.S
--- linux-3.8.13/arch/arm/mm/proc-v7-2level.S	2013-02-19 01:12:38.165765914 +0100
+++ linux-3.8.13-pax/arch/arm/mm/proc-v7-2level.S	2013-02-19 01:14:42.945772691 +0100
@@ -99,6 +99,9 @@ ENTRY(cpu_v7_set_pte_ext)
 	tst	r1, #L_PTE_XN
 	orrne	r3, r3, #PTE_EXT_XN
 
+	tst	r1, #L_PTE_PXN
+	orrne	r3, r3, #PTE_EXT_PXN
+
 	tst	r1, #L_PTE_YOUNG
 	tstne	r1, #L_PTE_VALID
 #ifndef CONFIG_CPU_USE_DOMAINS
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/plat-omap/sram.c linux-3.8.13-pax/arch/arm/plat-omap/sram.c
--- linux-3.8.13/arch/arm/plat-omap/sram.c	2013-02-19 01:12:38.497765932 +0100
+++ linux-3.8.13-pax/arch/arm/plat-omap/sram.c	2013-02-19 01:14:42.945772691 +0100
@@ -93,6 +93,8 @@ void __init omap_map_sram(unsigned long
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm/plat-samsung/include/plat/dma-ops.h linux-3.8.13-pax/arch/arm/plat-samsung/include/plat/dma-ops.h
--- linux-3.8.13/arch/arm/plat-samsung/include/plat/dma-ops.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm/plat-samsung/include/plat/dma-ops.h	2013-02-19 01:14:42.945772691 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm64/kernel/debug-monitors.c linux-3.8.13-pax/arch/arm64/kernel/debug-monitors.c
--- linux-3.8.13/arch/arm64/kernel/debug-monitors.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm64/kernel/debug-monitors.c	2013-02-20 01:05:22.162071837 +0100
@@ -151,7 +151,7 @@ static int __cpuinit os_lock_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata os_lock_nb = {
+static struct notifier_block os_lock_nb = {
 	.notifier_call = os_lock_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/arm64/kernel/hw_breakpoint.c linux-3.8.13-pax/arch/arm64/kernel/hw_breakpoint.c
--- linux-3.8.13/arch/arm64/kernel/hw_breakpoint.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/arm64/kernel/hw_breakpoint.c	2013-02-20 01:05:18.130072052 +0100
@@ -831,7 +831,7 @@ static int __cpuinit hw_breakpoint_reset
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata hw_breakpoint_reset_nb = {
+static struct notifier_block hw_breakpoint_reset_nb = {
 	.notifier_call = hw_breakpoint_reset_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/avr32/include/asm/elf.h linux-3.8.13-pax/arch/avr32/include/asm/elf.h
--- linux-3.8.13/arch/avr32/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/avr32/include/asm/elf.h	2013-02-19 01:14:42.949772692 +0100
@@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpreg
    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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/avr32/include/asm/kmap_types.h linux-3.8.13-pax/arch/avr32/include/asm/kmap_types.h
--- linux-3.8.13/arch/avr32/include/asm/kmap_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/avr32/include/asm/kmap_types.h	2013-02-19 01:14:42.949772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/avr32/mm/fault.c linux-3.8.13-pax/arch/avr32/mm/fault.c
--- linux-3.8.13/arch/avr32/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/avr32/mm/fault.c	2013-02-19 01:14:42.949772692 +0100
@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/frv/include/asm/atomic.h linux-3.8.13-pax/arch/frv/include/asm/atomic.h
--- linux-3.8.13/arch/frv/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/frv/include/asm/atomic.h	2013-02-19 01:14:42.949772692 +0100
@@ -186,6 +186,16 @@ static inline void atomic64_dec(atomic64
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/frv/include/asm/kmap_types.h linux-3.8.13-pax/arch/frv/include/asm/kmap_types.h
--- linux-3.8.13/arch/frv/include/asm/kmap_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/frv/include/asm/kmap_types.h	2013-02-19 01:14:42.949772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/frv/mm/elf-fdpic.c linux-3.8.13-pax/arch/frv/mm/elf-fdpic.c
--- linux-3.8.13/arch/frv/mm/elf-fdpic.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/frv/mm/elf-fdpic.c	2013-02-19 01:14:42.949772692 +0100
@@ -73,8 +73,7 @@ unsigned long arch_get_unmapped_area(str
 	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))
 			goto success;
 	}
 
@@ -89,7 +88,7 @@ unsigned long arch_get_unmapped_area(str
 			for (; vma; vma = vma->vm_next) {
 				if (addr > limit)
 					break;
-				if (addr + len <= vma->vm_start)
+				if (check_heap_stack_gap(vma, addr, len))
 					goto success;
 				addr = vma->vm_end;
 			}
@@ -104,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
 		for (; vma; vma = vma->vm_next) {
 			if (addr > limit)
 				break;
-			if (addr + len <= vma->vm_start)
+			if (check_heap_stack_gap(vma, addr, len))
 				goto success;
 			addr = vma->vm_end;
 		}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/atomic.h linux-3.8.13-pax/arch/ia64/include/asm/atomic.h
--- linux-3.8.13/arch/ia64/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/atomic.h	2013-02-19 01:14:42.949772692 +0100
@@ -208,6 +208,16 @@ atomic64_add_negative (__s64 i, atomic64
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/elf.h linux-3.8.13-pax/arch/ia64/include/asm/elf.h
--- linux-3.8.13/arch/ia64/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/elf.h	2013-02-19 01:14:42.949772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/pgalloc.h linux-3.8.13-pax/arch/ia64/include/asm/pgalloc.h
--- linux-3.8.13/arch/ia64/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/pgalloc.h	2013-02-19 01:14:42.953772692 +0100
@@ -39,6 +39,12 @@ pgd_populate(struct mm_struct *mm, pgd_t
 	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_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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/pgtable.h linux-3.8.13-pax/arch/ia64/include/asm/pgtable.h
--- linux-3.8.13/arch/ia64/include/asm/pgtable.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/pgtable.h	2013-02-19 01:14:42.953772692 +0100
@@ -12,7 +12,7 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-
+#include <linux/const.h>
 #include <asm/mman.h>
 #include <asm/page.h>
 #include <asm/processor.h>
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/spinlock.h linux-3.8.13-pax/arch/ia64/include/asm/spinlock.h
--- linux-3.8.13/arch/ia64/include/asm/spinlock.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/spinlock.h	2013-02-19 01:14:42.953772692 +0100
@@ -71,7 +71,7 @@ static __always_inline void __ticket_spi
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/include/asm/uaccess.h linux-3.8.13-pax/arch/ia64/include/asm/uaccess.h
--- linux-3.8.13/arch/ia64/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/include/asm/uaccess.h	2013-04-07 15:04:49.931304005 +0200
@@ -240,12 +240,24 @@ extern unsigned long __must_check __copy
 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 _
 ({											\
 	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 _
 ({											\
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/err_inject.c linux-3.8.13-pax/arch/ia64/kernel/err_inject.c
--- linux-3.8.13/arch/ia64/kernel/err_inject.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/err_inject.c	2013-02-20 01:06:10.762069242 +0100
@@ -256,7 +256,7 @@ static int __cpuinit err_inject_cpu_call
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata err_inject_cpu_notifier =
+static struct notifier_block err_inject_cpu_notifier =
 {
 	.notifier_call = err_inject_cpu_callback,
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/mca.c linux-3.8.13-pax/arch/ia64/kernel/mca.c
--- linux-3.8.13/arch/ia64/kernel/mca.c	2013-05-13 02:47:05.429794900 +0200
+++ linux-3.8.13-pax/arch/ia64/kernel/mca.c	2013-05-13 02:47:30.577793558 +0200
@@ -1922,7 +1922,7 @@ static int __cpuinit mca_cpu_callback(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block mca_cpu_notifier __cpuinitdata = {
+static struct notifier_block mca_cpu_notifier = {
 	.notifier_call = mca_cpu_callback
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/module.c linux-3.8.13-pax/arch/ia64/kernel/module.c
--- linux-3.8.13/arch/ia64/kernel/module.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/module.c	2013-02-19 01:14:42.953772692 +0100
@@ -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 *ehd
 }
 
 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_
 		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,
 		 *     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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/palinfo.c linux-3.8.13-pax/arch/ia64/kernel/palinfo.c
--- linux-3.8.13/arch/ia64/kernel/palinfo.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/palinfo.c	2013-02-20 01:06:07.398069421 +0100
@@ -1045,7 +1045,7 @@ static int __cpuinit palinfo_cpu_callbac
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/salinfo.c linux-3.8.13-pax/arch/ia64/kernel/salinfo.c
--- linux-3.8.13/arch/ia64/kernel/salinfo.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/salinfo.c	2013-02-20 01:05:58.166069914 +0100
@@ -616,7 +616,7 @@ salinfo_cpu_callback(struct notifier_blo
 	return NOTIFY_OK;
 }
 
-static struct notifier_block salinfo_cpu_notifier __cpuinitdata =
+static struct notifier_block salinfo_cpu_notifier =
 {
 	.notifier_call = salinfo_cpu_callback,
 	.priority = 0,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/sys_ia64.c linux-3.8.13-pax/arch/ia64/kernel/sys_ia64.c
--- linux-3.8.13/arch/ia64/kernel/sys_ia64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/sys_ia64.c	2013-02-19 01:14:42.953772692 +0100
@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
 	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 = mm->free_area_cache;
 
@@ -61,14 +68,14 @@ arch_get_unmapped_area (struct file *fil
 	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
 		/* At this point:  (!vma || addr < vma->vm_end). */
 		if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
-			if (start_addr != TASK_UNMAPPED_BASE) {
+			if (start_addr != mm->mmap_base) {
 				/* Start a new search --- just in case we missed some holes.  */
-				addr = TASK_UNMAPPED_BASE;
+				addr = mm->mmap_base;
 				goto full_search;
 			}
 			return -ENOMEM;
 		}
-		if (!vma || addr + len <= vma->vm_start) {
+		if (check_heap_stack_gap(vma, addr, len)) {
 			/* Remember the address where we stopped this search:  */
 			mm->free_area_cache = addr + len;
 			return addr;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/topology.c linux-3.8.13-pax/arch/ia64/kernel/topology.c
--- linux-3.8.13/arch/ia64/kernel/topology.c	2013-02-19 01:12:39.717765999 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/topology.c	2013-02-19 01:14:42.953772692 +0100
@@ -445,7 +445,7 @@ static int __cpuinit cache_cpu_callback(
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cache_cpu_notifier =
+static struct notifier_block cache_cpu_notifier =
 {
 	.notifier_call = cache_cpu_callback
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/kernel/vmlinux.lds.S linux-3.8.13-pax/arch/ia64/kernel/vmlinux.lds.S
--- linux-3.8.13/arch/ia64/kernel/vmlinux.lds.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/kernel/vmlinux.lds.S	2013-02-19 01:14:42.957772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/mm/fault.c linux-3.8.13-pax/arch/ia64/mm/fault.c
--- linux-3.8.13/arch/ia64/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/mm/fault.c	2013-02-19 01:14:42.957772692 +0100
@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/mm/hugetlbpage.c linux-3.8.13-pax/arch/ia64/mm/hugetlbpage.c
--- linux-3.8.13/arch/ia64/mm/hugetlbpage.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/ia64/mm/hugetlbpage.c	2013-02-19 01:14:42.957772692 +0100
@@ -171,7 +171,7 @@ unsigned long hugetlb_get_unmapped_area(
 		/* At this point:  (!vmm || addr < vmm->vm_end). */
 		if (REGION_OFFSET(addr) + len > RGN_MAP_LIMIT)
 			return -ENOMEM;
-		if (!vmm || (addr + len) <= vmm->vm_start)
+		if (check_heap_stack_gap(vmm, addr, len))
 			return addr;
 		addr = ALIGN(vmm->vm_end, HPAGE_SIZE);
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/ia64/mm/init.c linux-3.8.13-pax/arch/ia64/mm/init.c
--- linux-3.8.13/arch/ia64/mm/init.c	2013-02-19 01:12:39.725765999 +0100
+++ linux-3.8.13-pax/arch/ia64/mm/init.c	2013-02-19 01:14:42.957772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/m32r/lib/usercopy.c linux-3.8.13-pax/arch/m32r/lib/usercopy.c
--- linux-3.8.13/arch/m32r/lib/usercopy.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/m32r/lib/usercopy.c	2013-02-19 01:14:42.957772692 +0100
@@ -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,
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/include/asm/atomic.h linux-3.8.13-pax/arch/mips/include/asm/atomic.h
--- linux-3.8.13/arch/mips/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/include/asm/atomic.h	2013-02-19 01:14:42.957772692 +0100
@@ -21,6 +21,10 @@
 #include <asm/cmpxchg.h>
 #include <asm/war.h>
 
+#ifdef CONFIG_GENERIC_ATOMIC64
+#include <asm-generic/atomic64.h>
+#endif
+
 #define ATOMIC_INIT(i)    { (i) }
 
 /*
@@ -759,6 +763,16 @@ static __inline__ int atomic64_add_unles
  */
 #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
 
+#define atomic64_read_unchecked(v)		atomic64_read(v)
+#define atomic64_set_unchecked(v, i)		atomic64_set((v), (i))
+#define atomic64_add_unchecked(a, v)		atomic64_add((a), (v))
+#define atomic64_add_return_unchecked(a, v)	atomic64_add_return((a), (v))
+#define atomic64_sub_unchecked(a, v)		atomic64_sub((a), (v))
+#define atomic64_inc_unchecked(v)		atomic64_inc(v)
+#define atomic64_inc_return_unchecked(v)	atomic64_inc_return(v)
+#define atomic64_dec_unchecked(v)		atomic64_dec(v)
+#define atomic64_cmpxchg_unchecked(v, o, n)	atomic64_cmpxchg((v), (o), (n))
+
 #endif /* CONFIG_64BIT */
 
 /*
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/include/asm/elf.h linux-3.8.13-pax/arch/mips/include/asm/elf.h
--- linux-3.8.13/arch/mips/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/include/asm/elf.h	2013-02-19 01:14:42.961772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/include/asm/exec.h linux-3.8.13-pax/arch/mips/include/asm/exec.h
--- linux-3.8.13/arch/mips/include/asm/exec.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/include/asm/exec.h	2013-02-19 01:14:42.961772692 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/include/asm/page.h linux-3.8.13-pax/arch/mips/include/asm/page.h
--- linux-3.8.13/arch/mips/include/asm/page.h	2013-04-30 00:04:57.119843287 +0200
+++ linux-3.8.13-pax/arch/mips/include/asm/page.h	2013-04-30 00:05:40.667840962 +0200
@@ -96,7 +96,7 @@ extern void copy_user_highpage(struct pa
   #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/include/asm/pgalloc.h linux-3.8.13-pax/arch/mips/include/asm/pgalloc.h
--- linux-3.8.13/arch/mips/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/include/asm/pgalloc.h	2013-02-19 01:14:42.961772692 +0100
@@ -37,6 +37,11 @@ static inline void pud_populate(struct m
 {
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/kernel/binfmt_elfn32.c linux-3.8.13-pax/arch/mips/kernel/binfmt_elfn32.c
--- linux-3.8.13/arch/mips/kernel/binfmt_elfn32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/kernel/binfmt_elfn32.c	2013-02-19 01:14:42.961772692 +0100
@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/kernel/binfmt_elfo32.c linux-3.8.13-pax/arch/mips/kernel/binfmt_elfo32.c
--- linux-3.8.13/arch/mips/kernel/binfmt_elfo32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/kernel/binfmt_elfo32.c	2013-02-19 01:14:42.961772692 +0100
@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/kernel/process.c linux-3.8.13-pax/arch/mips/kernel/process.c
--- linux-3.8.13/arch/mips/kernel/process.c	2013-02-19 01:12:42.069766126 +0100
+++ linux-3.8.13-pax/arch/mips/kernel/process.c	2013-02-19 01:14:42.961772692 +0100
@@ -460,15 +460,3 @@ unsigned long get_wchan(struct task_stru
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/mm/fault.c linux-3.8.13-pax/arch/mips/mm/fault.c
--- linux-3.8.13/arch/mips/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/mips/mm/fault.c	2013-02-19 01:14:42.961772692 +0100
@@ -27,6 +27,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
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/mips/mm/mmap.c linux-3.8.13-pax/arch/mips/mm/mmap.c
--- linux-3.8.13/arch/mips/mm/mmap.c	2013-02-19 01:12:42.217766134 +0100
+++ linux-3.8.13-pax/arch/mips/mm/mmap.c	2013-02-19 01:14:42.965772692 +0100
@@ -84,6 +84,11 @@ static unsigned long arch_get_unmapped_a
 		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,8 +96,7 @@ static unsigned long arch_get_unmapped_a
 			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))
 			return addr;
 	}
 
@@ -146,6 +150,10 @@ void arch_pick_mmap_layout(struct mm_str
 {
 	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,42 +165,27 @@ void arch_pick_mmap_layout(struct mm_str
 
 	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;
 		mm->unmap_area = arch_unmap_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;
 		mm->unmap_area = arch_unmap_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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/include/asm/atomic.h linux-3.8.13-pax/arch/parisc/include/asm/atomic.h
--- linux-3.8.13/arch/parisc/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/include/asm/atomic.h	2013-02-19 01:14:42.965772692 +0100
@@ -229,6 +229,16 @@ static __inline__ int atomic64_add_unles
 
 #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
 
+#define atomic64_read_unchecked(v)		atomic64_read(v)
+#define atomic64_set_unchecked(v, i)		atomic64_set((v), (i))
+#define atomic64_add_unchecked(a, v)		atomic64_add((a), (v))
+#define atomic64_add_return_unchecked(a, v)	atomic64_add_return((a), (v))
+#define atomic64_sub_unchecked(a, v)		atomic64_sub((a), (v))
+#define atomic64_inc_unchecked(v)		atomic64_inc(v)
+#define atomic64_inc_return_unchecked(v)	atomic64_inc_return(v)
+#define atomic64_dec_unchecked(v)		atomic64_dec(v)
+#define atomic64_cmpxchg_unchecked(v, o, n)	atomic64_cmpxchg((v), (o), (n))
+
 #endif /* !CONFIG_64BIT */
 
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/include/asm/elf.h linux-3.8.13-pax/arch/parisc/include/asm/elf.h
--- linux-3.8.13/arch/parisc/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/include/asm/elf.h	2013-02-19 01:14:42.969772693 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/include/asm/pgalloc.h linux-3.8.13-pax/arch/parisc/include/asm/pgalloc.h
--- linux-3.8.13/arch/parisc/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/include/asm/pgalloc.h	2013-02-19 01:14:42.969772693 +0100
@@ -61,6 +61,11 @@ static inline void pgd_populate(struct m
 		        (__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_st
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/include/asm/pgtable.h linux-3.8.13-pax/arch/parisc/include/asm/pgtable.h
--- linux-3.8.13/arch/parisc/include/asm/pgtable.h	2013-03-07 04:10:19.539802313 +0100
+++ linux-3.8.13-pax/arch/parisc/include/asm/pgtable.h	2013-03-07 04:10:37.723801342 +0100
@@ -218,6 +218,17 @@ extern void purge_tlb_entries(struct mm_
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/include/asm/uaccess.h linux-3.8.13-pax/arch/parisc/include/asm/uaccess.h
--- linux-3.8.13/arch/parisc/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/include/asm/uaccess.h	2013-02-19 01:14:42.973772693 +0100
@@ -251,10 +251,10 @@ static inline unsigned long __must_check
                                           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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/kernel/module.c linux-3.8.13-pax/arch/parisc/kernel/module.c
--- linux-3.8.13/arch/parisc/kernel/module.c	2013-02-19 01:12:42.677766159 +0100
+++ linux-3.8.13-pax/arch/parisc/kernel/module.c	2013-02-19 01:14:42.973772693 +0100
@@ -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_
 	}
 
 	/* 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 = 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.got_offset = me->core_size_rw;
+	me->core_size_rw += gots * sizeof(struct got_entry);
+
+	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
 
 	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
 #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
 
 	/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/kernel/sys_parisc.c linux-3.8.13-pax/arch/parisc/kernel/sys_parisc.c
--- linux-3.8.13/arch/parisc/kernel/sys_parisc.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/kernel/sys_parisc.c	2013-02-19 01:14:42.973772693 +0100
@@ -43,7 +43,7 @@ static unsigned long get_unshared_area(u
 		/* At this point:  (!vma || addr < vma->vm_end). */
 		if (TASK_SIZE - len < addr)
 			return -ENOMEM;
-		if (!vma || addr + len <= vma->vm_start)
+		if (check_heap_stack_gap(vma, addr, len))
 			return addr;
 		addr = vma->vm_end;
 	}
@@ -81,7 +81,7 @@ static unsigned long get_shared_area(str
 		/* At this point:  (!vma || addr < vma->vm_end). */
 		if (TASK_SIZE - len < addr)
 			return -ENOMEM;
-		if (!vma || addr + len <= vma->vm_start)
+		if (check_heap_stack_gap(vma, addr, len))
 			return addr;
 		addr = DCACHE_ALIGN(vma->vm_end - offset) + offset;
 		if (addr < vma->vm_end) /* handle wraparound */
@@ -100,7 +100,7 @@ unsigned long arch_get_unmapped_area(str
 	if (flags & MAP_FIXED)
 		return addr;
 	if (!addr)
-		addr = TASK_UNMAPPED_BASE;
+		addr = current->mm->mmap_base;
 
 	if (filp) {
 		addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/kernel/traps.c linux-3.8.13-pax/arch/parisc/kernel/traps.c
--- linux-3.8.13/arch/parisc/kernel/traps.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/kernel/traps.c	2013-02-19 01:14:42.973772693 +0100
@@ -732,9 +732,7 @@ void notrace handle_interruption(int cod
 
 			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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/parisc/mm/fault.c linux-3.8.13-pax/arch/parisc/mm/fault.c
--- linux-3.8.13/arch/parisc/mm/fault.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/parisc/mm/fault.c	2013-02-19 01:14:42.973772693 +0100
@@ -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, ex
 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, unsign
 			}
 #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;
@@ -192,8 +303,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/atomic.h linux-3.8.13-pax/arch/powerpc/include/asm/atomic.h
--- linux-3.8.13/arch/powerpc/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/atomic.h	2013-02-19 01:14:42.977772693 +0100
@@ -523,6 +523,16 @@ static __inline__ long atomic64_inc_not_
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/elf.h linux-3.8.13-pax/arch/powerpc/include/asm/elf.h
--- linux-3.8.13/arch/powerpc/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/elf.h	2013-02-19 01:14:42.977772693 +0100
@@ -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
@@ -124,10 +135,6 @@ extern int arch_setup_additional_pages(s
 	(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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/exec.h linux-3.8.13-pax/arch/powerpc/include/asm/exec.h
--- linux-3.8.13/arch/powerpc/include/asm/exec.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/exec.h	2013-02-19 01:14:42.977772693 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/kmap_types.h linux-3.8.13-pax/arch/powerpc/include/asm/kmap_types.h
--- linux-3.8.13/arch/powerpc/include/asm/kmap_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/kmap_types.h	2013-02-19 01:14:42.977772693 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/mman.h linux-3.8.13-pax/arch/powerpc/include/asm/mman.h
--- linux-3.8.13/arch/powerpc/include/asm/mman.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/mman.h	2013-02-19 01:14:42.977772693 +0100
@@ -24,7 +24,7 @@ static inline unsigned long arch_calc_vm
 }
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/page_64.h linux-3.8.13-pax/arch/powerpc/include/asm/page_64.h
--- linux-3.8.13/arch/powerpc/include/asm/page_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/page_64.h	2013-02-19 01:14:42.977772693 +0100
@@ -154,15 +154,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/page.h linux-3.8.13-pax/arch/powerpc/include/asm/page.h
--- linux-3.8.13/arch/powerpc/include/asm/page.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/page.h	2013-02-19 01:14:42.977772693 +0100
@@ -220,8 +220,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)
@@ -249,6 +250,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)
+
 /*
  * Use the top bit of the higher-level page table entries to indicate whether
  * the entries we point to contain hugepages.  This works because we know that
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/pgalloc-64.h linux-3.8.13-pax/arch/powerpc/include/asm/pgalloc-64.h
--- linux-3.8.13/arch/powerpc/include/asm/pgalloc-64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/pgalloc-64.h	2013-02-19 01:14:42.977772693 +0100
@@ -50,6 +50,7 @@ static inline void pgd_free(struct mm_st
 #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)
 {
@@ -67,6 +68,11 @@ static inline void pud_populate(struct m
 	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))
@@ -76,6 +82,7 @@ static inline void pud_populate(struct m
 #else /* CONFIG_PPC_64K_PAGES */
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/pgtable.h linux-3.8.13-pax/arch/powerpc/include/asm/pgtable.h
--- linux-3.8.13/arch/powerpc/include/asm/pgtable.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/pgtable.h	2013-02-19 01:14:42.977772693 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/pte-hash32.h linux-3.8.13-pax/arch/powerpc/include/asm/pte-hash32.h
--- linux-3.8.13/arch/powerpc/include/asm/pte-hash32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/pte-hash32.h	2013-02-19 01:14:42.981772693 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/reg.h linux-3.8.13-pax/arch/powerpc/include/asm/reg.h
--- linux-3.8.13/arch/powerpc/include/asm/reg.h	2013-02-19 01:12:42.889766171 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/reg.h	2013-02-19 01:14:42.981772693 +0100
@@ -215,6 +215,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/smp.h linux-3.8.13-pax/arch/powerpc/include/asm/smp.h
--- linux-3.8.13/arch/powerpc/include/asm/smp.h	2013-02-19 01:12:42.905766172 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/smp.h	2013-04-14 01:20:09.418970575 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/include/asm/uaccess.h linux-3.8.13-pax/arch/powerpc/include/asm/uaccess.h
--- linux-3.8.13/arch/powerpc/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/include/asm/uaccess.h	2013-04-07 15:04:49.931304005 +0200
@@ -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_
 		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_us
 		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_us
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/exceptions-64e.S linux-3.8.13-pax/arch/powerpc/kernel/exceptions-64e.S
--- linux-3.8.13/arch/powerpc/kernel/exceptions-64e.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/exceptions-64e.S	2013-02-19 01:14:42.989772694 +0100
@@ -715,6 +715,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)
@@ -723,8 +724,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/exceptions-64s.S linux-3.8.13-pax/arch/powerpc/kernel/exceptions-64s.S
--- linux-3.8.13/arch/powerpc/kernel/exceptions-64s.S	2013-05-13 02:47:05.445794900 +0200
+++ linux-3.8.13-pax/arch/powerpc/kernel/exceptions-64s.S	2013-05-13 02:47:30.577793558 +0200
@@ -1206,10 +1206,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/module_32.c linux-3.8.13-pax/arch/powerpc/kernel/module_32.c
--- linux-3.8.13/arch/powerpc/kernel/module_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/module_32.c	2013-02-19 01:14:42.993772694 +0100
@@ -162,7 +162,7 @@ int module_frob_arch_sections(Elf32_Ehdr
 			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 *locati
 
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/process.c linux-3.8.13-pax/arch/powerpc/kernel/process.c
--- linux-3.8.13/arch/powerpc/kernel/process.c	2013-02-19 01:12:43.077766181 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/process.c	2013-02-19 01:14:42.997772694 +0100
@@ -1194,58 +1194,3 @@ void __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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/signal_32.c linux-3.8.13-pax/arch/powerpc/kernel/signal_32.c
--- linux-3.8.13/arch/powerpc/kernel/signal_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/signal_32.c	2013-02-19 01:14:43.001772694 +0100
@@ -851,7 +851,7 @@ int handle_rt_signal32(unsigned long sig
 	/* 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) {
 		if (save_user_regs(regs, frame, 0, 1))
 			goto badframe;
 		regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/signal_64.c linux-3.8.13-pax/arch/powerpc/kernel/signal_64.c
--- linux-3.8.13/arch/powerpc/kernel/signal_64.c	2013-02-19 01:12:43.125766184 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/signal_64.c	2013-02-19 01:14:43.001772694 +0100
@@ -430,7 +430,7 @@ int handle_rt_signal64(int signr, struct
 	current->thread.fpscr.val = 0;
 
 	/* Set up to return from userspace. */
-	if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
+	if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
 		regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
 	} else {
 		err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/sysfs.c linux-3.8.13-pax/arch/powerpc/kernel/sysfs.c
--- linux-3.8.13/arch/powerpc/kernel/sysfs.c	2013-02-19 01:12:43.197766188 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/sysfs.c	2013-02-20 01:04:08.214075785 +0100
@@ -522,7 +522,7 @@ static int __cpuinit sysfs_cpu_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+static struct notifier_block sysfs_cpu_nb = {
 	.notifier_call	= sysfs_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/kernel/vdso.c linux-3.8.13-pax/arch/powerpc/kernel/vdso.c
--- linux-3.8.13/arch/powerpc/kernel/vdso.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/kernel/vdso.c	2013-02-19 01:14:43.005772695 +0100
@@ -34,6 +34,7 @@
 #include <asm/firmware.h>
 #include <asm/vdso.h>
 #include <asm/vdso_datapage.h>
+#include <asm/mman.h>
 
 #include "setup.h"
 
@@ -218,7 +219,7 @@ int arch_setup_additional_pages(struct l
 	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
@@ -238,7 +239,7 @@ int arch_setup_additional_pages(struct l
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/lib/usercopy_64.c linux-3.8.13-pax/arch/powerpc/lib/usercopy_64.c
--- linux-3.8.13/arch/powerpc/lib/usercopy_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/lib/usercopy_64.c	2013-02-19 01:14:43.009772695 +0100
@@ -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 *
 	return n;
 }
 
-EXPORT_SYMBOL(copy_from_user);
-EXPORT_SYMBOL(copy_to_user);
 EXPORT_SYMBOL(copy_in_user);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/mm/fault.c linux-3.8.13-pax/arch/powerpc/mm/fault.c
--- linux-3.8.13/arch/powerpc/mm/fault.c	2013-02-19 01:12:43.285766192 +0100
+++ linux-3.8.13-pax/arch/powerpc/mm/fault.c	2013-02-19 01:14:43.009772695 +0100
@@ -32,6 +32,10 @@
 #include <linux/perf_event.h>
 #include <linux/magic.h>
 #include <linux/ratelimit.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/compiler.h>
+#include <linux/unistd.h>
 
 #include <asm/firmware.h>
 #include <asm/page.h>
@@ -68,6 +72,33 @@ static inline int notify_page_fault(stru
 }
 #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.
@@ -213,7 +244,7 @@ int __kprobes do_page_fault(struct pt_re
 	 * 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
@@ -364,7 +395,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 */
@@ -379,7 +410,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 */
 
@@ -462,6 +493,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);
 		return 0;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/mm/mmap_64.c linux-3.8.13-pax/arch/powerpc/mm/mmap_64.c
--- linux-3.8.13/arch/powerpc/mm/mmap_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/mm/mmap_64.c	2013-02-19 01:14:43.009772695 +0100
@@ -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,10 +95,22 @@ void arch_pick_mmap_layout(struct mm_str
 	 */
 	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;
 		mm->unmap_area = arch_unmap_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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/mm/mmu_context_nohash.c linux-3.8.13-pax/arch/powerpc/mm/mmu_context_nohash.c
--- linux-3.8.13/arch/powerpc/mm/mmu_context_nohash.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/mm/mmu_context_nohash.c	2013-02-20 01:04:17.002075316 +0100
@@ -363,7 +363,7 @@ static int __cpuinit mmu_context_cpu_not
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata mmu_context_cpu_nb = {
+static struct notifier_block mmu_context_cpu_nb = {
 	.notifier_call	= mmu_context_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/mm/numa.c linux-3.8.13-pax/arch/powerpc/mm/numa.c
--- linux-3.8.13/arch/powerpc/mm/numa.c	2013-05-13 02:47:11.133794596 +0200
+++ linux-3.8.13-pax/arch/powerpc/mm/numa.c	2013-05-13 02:51:11.397781768 +0200
@@ -932,7 +932,7 @@ static void __init *careful_zallocation(
 	return ret;
 }
 
-static struct notifier_block __cpuinitdata ppc64_numa_nb = {
+static struct notifier_block ppc64_numa_nb = {
 	.notifier_call = cpu_numa_callback,
 	.priority = 1 /* Must run before sched domains notifier. */
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/mm/slice.c linux-3.8.13-pax/arch/powerpc/mm/slice.c
--- linux-3.8.13/arch/powerpc/mm/slice.c	2013-02-19 01:12:43.297766193 +0100
+++ linux-3.8.13-pax/arch/powerpc/mm/slice.c	2013-02-19 01:14:43.009772695 +0100
@@ -103,7 +103,7 @@ static int slice_area_is_free(struct mm_
 	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);
 }
 
 static int slice_low_has_vma(struct mm_struct *mm, unsigned long slice)
@@ -272,7 +272,7 @@ full_search:
 				addr = _ALIGN_UP(addr + 1,  1ul << SLICE_HIGH_SHIFT);
 			continue;
 		}
-		if (!vma || addr + len <= vma->vm_start) {
+		if (check_heap_stack_gap(vma, addr, len)) {
 			/*
 			 * Remember the place where we stopped the search:
 			 */
@@ -329,10 +329,14 @@ static unsigned long slice_find_area_top
 		}
 	}
 
-	addr = mm->mmap_base;
-	while (addr > len) {
+	if (mm->mmap_base < len)
+		addr = -ENOMEM;
+	else
+		addr = mm->mmap_base - len;
+
+	while (!IS_ERR_VALUE(addr)) {
 		/* Go down by chunk size */
-		addr = _ALIGN_DOWN(addr - len, 1ul << pshift);
+		addr = _ALIGN_DOWN(addr, 1ul << pshift);
 
 		/* Check for hit with different page size */
 		mask = slice_range_to_mask(addr, len);
@@ -352,7 +356,7 @@ static unsigned long slice_find_area_top
 		 * return with success:
 		 */
 		vma = find_vma(mm, addr);
-		if (!vma || (addr + len) <= vma->vm_start) {
+		if (check_heap_stack_gap(vma, addr, len)) {
 			/* remember the address as a hint for next time */
 			if (use_cache)
 				mm->free_area_cache = addr;
@@ -364,7 +368,7 @@ static unsigned long slice_find_area_top
 		        mm->cached_hole_size = vma->vm_start - addr;
 
 		/* try just below the current vma->vm_start */
-		addr = vma->vm_start;
+		addr = skip_heap_stack_gap(vma, len);
 	}
 
 	/*
@@ -442,6 +446,11 @@ unsigned long slice_get_unmapped_area(un
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/platforms/cell/spufs/file.c linux-3.8.13-pax/arch/powerpc/platforms/cell/spufs/file.c
--- linux-3.8.13/arch/powerpc/platforms/cell/spufs/file.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/powerpc/platforms/cell/spufs/file.c	2013-04-04 21:32:11.854489420 +0200
@@ -281,9 +281,9 @@ spufs_mem_mmap_fault(struct vm_area_stru
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/powerpc/platforms/powermac/smp.c linux-3.8.13-pax/arch/powerpc/platforms/powermac/smp.c
--- linux-3.8.13/arch/powerpc/platforms/powermac/smp.c	2013-02-19 01:12:43.501766204 +0100
+++ linux-3.8.13-pax/arch/powerpc/platforms/powermac/smp.c	2013-02-20 01:04:03.630076030 +0100
@@ -885,7 +885,7 @@ static int smp_core99_cpu_notify(struct
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+static struct notifier_block smp_core99_cpu_nb = {
 	.notifier_call	= smp_core99_cpu_notify,
 };
 #endif /* CONFIG_HOTPLUG_CPU */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/include/asm/atomic.h linux-3.8.13-pax/arch/s390/include/asm/atomic.h
--- linux-3.8.13/arch/s390/include/asm/atomic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/include/asm/atomic.h	2013-02-19 01:14:43.009772695 +0100
@@ -326,6 +326,16 @@ static inline long long atomic64_dec_if_
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/include/asm/elf.h linux-3.8.13-pax/arch/s390/include/asm/elf.h
--- linux-3.8.13/arch/s390/include/asm/elf.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/include/asm/elf.h	2013-02-19 01:14:43.009772695 +0100
@@ -160,8 +160,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. */
@@ -210,9 +216,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/include/asm/exec.h linux-3.8.13-pax/arch/s390/include/asm/exec.h
--- linux-3.8.13/arch/s390/include/asm/exec.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/include/asm/exec.h	2013-02-19 01:14:43.009772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/include/asm/uaccess.h linux-3.8.13-pax/arch/s390/include/asm/uaccess.h
--- linux-3.8.13/arch/s390/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/include/asm/uaccess.h	2013-02-19 01:14:43.013772695 +0100
@@ -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;
+
 	if (access_ok(VERIFY_WRITE, to, n))
 		n = __copy_to_user(to, from, n);
 	return n;
@@ -277,6 +281,9 @@ copy_to_user(void __user *to, const void
 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
@@ -308,10 +315,14 @@ __compiletime_warning("copy_from_user()
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/kernel/module.c linux-3.8.13-pax/arch/s390/kernel/module.c
--- linux-3.8.13/arch/s390/kernel/module.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/kernel/module.c	2013-02-19 01:14:43.013772695 +0100
@@ -171,11 +171,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
 
 	/* 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;
 }
 
@@ -252,7 +252,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 		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;
@@ -276,7 +276,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 		else if (r_type == R_390_GOTENT ||
 			 r_type == R_390_GOTPLTENT)
 			*(unsigned int *) loc =
-				(val + (Elf_Addr) me->module_core - loc) >> 1;
+				(val + (Elf_Addr) me->module_core_rw - loc) >> 1;
 		else if (r_type == R_390_GOT64 ||
 			 r_type == R_390_GOTPLT64)
 			*(unsigned long *) loc = val;
@@ -290,7 +290,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 	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 */
@@ -315,7 +315,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 			       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;
@@ -337,7 +337,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 	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)
 			*(unsigned short *) loc = val;
 		else if (r_type == R_390_GOTOFF32)
@@ -347,7 +347,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
 		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)
 			*(unsigned int *) loc = val;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/kernel/process.c linux-3.8.13-pax/arch/s390/kernel/process.c
--- linux-3.8.13/arch/s390/kernel/process.c	2013-02-19 01:12:50.785766600 +0100
+++ linux-3.8.13-pax/arch/s390/kernel/process.c	2013-02-19 01:14:43.013772695 +0100
@@ -250,39 +250,3 @@ unsigned long get_wchan(struct task_stru
 	}
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/s390/mm/mmap.c linux-3.8.13-pax/arch/s390/mm/mmap.c
--- linux-3.8.13/arch/s390/mm/mmap.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/s390/mm/mmap.c	2013-02-19 01:14:43.013772695 +0100
@@ -90,10 +90,22 @@ void arch_pick_mmap_layout(struct mm_str
 	 */
 	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;
 		mm->unmap_area = arch_unmap_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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
@@ -172,10 +184,22 @@ void arch_pick_mmap_layout(struct mm_str
 	 */
 	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;
 		mm->unmap_area = arch_unmap_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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/score/include/asm/exec.h linux-3.8.13-pax/arch/score/include/asm/exec.h
--- linux-3.8.13/arch/score/include/asm/exec.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/score/include/asm/exec.h	2013-02-19 01:14:43.013772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/score/kernel/process.c linux-3.8.13-pax/arch/score/kernel/process.c
--- linux-3.8.13/arch/score/kernel/process.c	2013-02-19 01:12:50.869766604 +0100
+++ linux-3.8.13-pax/arch/score/kernel/process.c	2013-02-19 01:14:43.013772695 +0100
@@ -134,8 +134,3 @@ unsigned long get_wchan(struct task_stru
 
 	return task_pt_regs(task)->cp0_epc;
 }
-
-unsigned long arch_align_stack(unsigned long sp)
-{
-	return sp;
-}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sh/kernel/cpu/sh4a/smp-shx3.c linux-3.8.13-pax/arch/sh/kernel/cpu/sh4a/smp-shx3.c
--- linux-3.8.13/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sh/kernel/cpu/sh4a/smp-shx3.c	2013-02-20 01:03:59.658076242 +0100
@@ -143,7 +143,7 @@ shx3_cpu_callback(struct notifier_block
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata shx3_cpu_notifier = {
+static struct notifier_block shx3_cpu_notifier = {
 	.notifier_call		= shx3_cpu_callback,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sh/mm/mmap.c linux-3.8.13-pax/arch/sh/mm/mmap.c
--- linux-3.8.13/arch/sh/mm/mmap.c	2013-02-19 01:12:51.065766615 +0100
+++ linux-3.8.13-pax/arch/sh/mm/mmap.c	2013-02-19 01:14:43.013772695 +0100
@@ -55,6 +55,10 @@ unsigned long arch_get_unmapped_area(str
 	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 +66,13 @@ unsigned long arch_get_unmapped_area(str
 			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))
 			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;
@@ -104,6 +107,10 @@ arch_get_unmapped_area_topdown(struct fi
 	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 +119,7 @@ arch_get_unmapped_area_topdown(struct fi
 			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))
 			return addr;
 	}
 
@@ -135,6 +141,12 @@ arch_get_unmapped_area_topdown(struct fi
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/atomic_64.h linux-3.8.13-pax/arch/sparc/include/asm/atomic_64.h
--- linux-3.8.13/arch/sparc/include/asm/atomic_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/atomic_64.h	2013-02-19 01:14:43.013772695 +0100
@@ -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, atomi
 #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, atomi
  * 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, atomi
 #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(at
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/cache.h linux-3.8.13-pax/arch/sparc/include/asm/cache.h
--- linux-3.8.13/arch/sparc/include/asm/cache.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/cache.h	2013-02-19 01:14:43.017772695 +0100
@@ -10,7 +10,7 @@
 #define ARCH_SLAB_MINALIGN	__alignof__(unsigned long long)
 
 #define L1_CACHE_SHIFT 5
-#define L1_CACHE_BYTES 32
+#define L1_CACHE_BYTES 32UL
 
 #ifdef CONFIG_SPARC32
 #define SMP_CACHE_BYTES_SHIFT 5
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/elf_32.h linux-3.8.13-pax/arch/sparc/include/asm/elf_32.h
--- linux-3.8.13/arch/sparc/include/asm/elf_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/elf_32.h	2013-02-19 01:14:43.017772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/elf_64.h linux-3.8.13-pax/arch/sparc/include/asm/elf_64.h
--- linux-3.8.13/arch/sparc/include/asm/elf_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/elf_64.h	2013-02-19 01:14:43.017772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/pgalloc_32.h linux-3.8.13-pax/arch/sparc/include/asm/pgalloc_32.h
--- linux-3.8.13/arch/sparc/include/asm/pgalloc_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/pgalloc_32.h	2013-02-19 01:14:43.017772695 +0100
@@ -33,6 +33,7 @@ static inline void pgd_set(pgd_t * pgdp,
 }
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/pgalloc_64.h linux-3.8.13-pax/arch/sparc/include/asm/pgalloc_64.h
--- linux-3.8.13/arch/sparc/include/asm/pgalloc_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/pgalloc_64.h	2013-02-19 01:14:43.017772695 +0100
@@ -26,6 +26,7 @@ static inline void pgd_free(struct mm_st
 }
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/pgtable_32.h linux-3.8.13-pax/arch/sparc/include/asm/pgtable_32.h
--- linux-3.8.13/arch/sparc/include/asm/pgtable_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/pgtable_32.h	2013-02-19 01:14:43.017772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/pgtsrmmu.h linux-3.8.13-pax/arch/sparc/include/asm/pgtsrmmu.h
--- linux-3.8.13/arch/sparc/include/asm/pgtsrmmu.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/pgtsrmmu.h	2013-02-19 01:14:43.017772695 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/spinlock_64.h linux-3.8.13-pax/arch/sparc/include/asm/spinlock_64.h
--- linux-3.8.13/arch/sparc/include/asm/spinlock_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/spinlock_64.h	2013-02-19 01:14:43.017772695 +0100
@@ -92,14 +92,19 @@ static inline void arch_spin_lock_flags(
 
 /* 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_r
 "	.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
 "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
 	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
 	: "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_
 	: "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(arc
 	: "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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/thread_info_32.h linux-3.8.13-pax/arch/sparc/include/asm/thread_info_32.h
--- linux-3.8.13/arch/sparc/include/asm/thread_info_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/thread_info_32.h	2013-02-19 01:14:43.017772695 +0100
@@ -49,6 +49,8 @@ struct thread_info {
 	unsigned long		w_saved;
 
 	struct restart_block	restart_block;
+
+	unsigned long		lowest_stack;
 };
 
 /*
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/thread_info_64.h linux-3.8.13-pax/arch/sparc/include/asm/thread_info_64.h
--- linux-3.8.13/arch/sparc/include/asm/thread_info_64.h	2013-02-19 01:12:51.109766617 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/thread_info_64.h	2013-02-19 01:14:43.021772695 +0100
@@ -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)));
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/uaccess_32.h linux-3.8.13-pax/arch/sparc/include/asm/uaccess_32.h
--- linux-3.8.13/arch/sparc/include/asm/uaccess_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/uaccess_32.h	2013-02-19 01:14:43.021772695 +0100
@@ -250,27 +250,46 @@ extern unsigned long __copy_user(void __
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/uaccess_64.h linux-3.8.13-pax/arch/sparc/include/asm/uaccess_64.h
--- linux-3.8.13/arch/sparc/include/asm/uaccess_64.h	2013-02-19 01:12:51.113766617 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/uaccess_64.h	2013-02-19 01:14:43.021772695 +0100
@@ -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_fixu
 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(
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/include/asm/uaccess.h linux-3.8.13-pax/arch/sparc/include/asm/uaccess.h
--- linux-3.8.13/arch/sparc/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/include/asm/uaccess.h	2013-04-07 15:04:49.935304005 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/Makefile linux-3.8.13-pax/arch/sparc/kernel/Makefile
--- linux-3.8.13/arch/sparc/kernel/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/Makefile	2013-02-19 01:14:43.021772695 +0100
@@ -3,7 +3,7 @@
 #
 
 asflags-y := -ansi
-ccflags-y := -Werror
+#ccflags-y := -Werror
 
 extra-y     := head_$(BITS).o
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/prom_common.c linux-3.8.13-pax/arch/sparc/kernel/prom_common.c
--- linux-3.8.13/arch/sparc/kernel/prom_common.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/prom_common.c	2013-04-07 15:04:49.935304005 +0200
@@ -143,7 +143,7 @@ static int __init prom_common_nextprop(p
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/sysfs.c linux-3.8.13-pax/arch/sparc/kernel/sysfs.c
--- linux-3.8.13/arch/sparc/kernel/sysfs.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/sysfs.c	2013-02-20 01:03:18.582078435 +0100
@@ -266,7 +266,7 @@ static int __cpuinit sysfs_cpu_notify(st
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+static struct notifier_block sysfs_cpu_nb = {
 	.notifier_call	= sysfs_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/sys_sparc_32.c linux-3.8.13-pax/arch/sparc/kernel/sys_sparc_32.c
--- linux-3.8.13/arch/sparc/kernel/sys_sparc_32.c	2013-02-19 01:12:51.209766623 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/sys_sparc_32.c	2013-02-19 01:14:43.021772695 +0100
@@ -52,7 +52,7 @@ unsigned long arch_get_unmapped_area(str
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/sys_sparc_64.c linux-3.8.13-pax/arch/sparc/kernel/sys_sparc_64.c
--- linux-3.8.13/arch/sparc/kernel/sys_sparc_64.c	2013-02-19 01:12:51.209766623 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/sys_sparc_64.c	2013-02-19 01:14:43.021772695 +0100
@@ -96,7 +96,7 @@ unsigned long arch_get_unmapped_area(str
 		/* 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 +111,10 @@ unsigned long arch_get_unmapped_area(str
 	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,14 +122,13 @@ unsigned long arch_get_unmapped_area(str
 			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))
 			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;
@@ -134,6 +137,12 @@ unsigned long arch_get_unmapped_area(str
 	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);
 	}
@@ -160,7 +169,7 @@ arch_get_unmapped_area_topdown(struct fi
 		/* 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 +182,10 @@ arch_get_unmapped_area_topdown(struct fi
 	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 +194,7 @@ arch_get_unmapped_area_topdown(struct fi
 			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))
 			return addr;
 	}
 
@@ -204,6 +216,12 @@ arch_get_unmapped_area_topdown(struct fi
 		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);
 	}
@@ -264,6 +282,10 @@ static unsigned long mmap_rnd(void)
 {
 	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))
@@ -289,6 +311,12 @@ void arch_pick_mmap_layout(struct mm_str
 	    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;
 		mm->unmap_area = arch_unmap_area;
 	} else {
@@ -301,6 +329,12 @@ void arch_pick_mmap_layout(struct mm_str
 			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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/traps_64.c linux-3.8.13-pax/arch/sparc/kernel/traps_64.c
--- linux-3.8.13/arch/sparc/kernel/traps_64.c	2013-02-19 01:12:51.233766624 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/traps_64.c	2013-02-19 01:14:43.025772696 +0100
@@ -96,6 +96,12 @@ void bad_trap(struct pt_regs *regs, long
 
 	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
 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);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/kernel/us3_cpufreq.c linux-3.8.13-pax/arch/sparc/kernel/us3_cpufreq.c
--- linux-3.8.13/arch/sparc/kernel/us3_cpufreq.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/kernel/us3_cpufreq.c	2013-05-10 01:15:01.023929132 +0200
@@ -18,14 +18,12 @@
 #include <asm/head.h>
 #include <asm/timer.h>
 
-static struct cpufreq_driver *cpufreq_us3_driver;
-
 struct us3_freq_percpu_info {
 	struct cpufreq_frequency_table table[4];
 };
 
 /* Indexed by cpu number. */
-static struct us3_freq_percpu_info *us3_freq_table;
+static struct us3_freq_percpu_info us3_freq_table[NR_CPUS];
 
 /* UltraSPARC-III has three dividers: 1, 2, and 32.  These are controlled
  * in the Safari config register.
@@ -191,12 +189,25 @@ static int __init us3_freq_cpu_init(stru
 
 static int us3_freq_cpu_exit(struct cpufreq_policy *policy)
 {
-	if (cpufreq_us3_driver)
-		us3_set_cpu_divider_index(policy->cpu, 0);
+	us3_set_cpu_divider_index(policy->cpu, 0);
 
 	return 0;
 }
 
+static int __init us3_freq_init(void);
+static void __exit us3_freq_exit(void);
+
+static struct cpufreq_driver cpufreq_us3_driver = {
+	.init	= us3_freq_cpu_init,
+	.verify	= us3_freq_verify,
+	.target	= us3_freq_target,
+	.get	= us3_freq_get,
+	.exit	= us3_freq_cpu_exit,
+	.owner	= THIS_MODULE,
+	.name	= "UltraSPARC-III",
+
+};
+
 static int __init us3_freq_init(void)
 {
 	unsigned long manuf, impl, ver;
@@ -213,57 +224,15 @@ static int __init us3_freq_init(void)
 	    (impl == CHEETAH_IMPL ||
 	     impl == CHEETAH_PLUS_IMPL ||
 	     impl == JAGUAR_IMPL ||
-	     impl == PANTHER_IMPL)) {
-		struct cpufreq_driver *driver;
-
-		ret = -ENOMEM;
-		driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL);
-		if (!driver)
-			goto err_out;
-
-		us3_freq_table = kzalloc(
-			(NR_CPUS * sizeof(struct us3_freq_percpu_info)),
-			GFP_KERNEL);
-		if (!us3_freq_table)
-			goto err_out;
-
-		driver->init = us3_freq_cpu_init;
-		driver->verify = us3_freq_verify;
-		driver->target = us3_freq_target;
-		driver->get = us3_freq_get;
-		driver->exit = us3_freq_cpu_exit;
-		driver->owner = THIS_MODULE,
-		strcpy(driver->name, "UltraSPARC-III");
-
-		cpufreq_us3_driver = driver;
-		ret = cpufreq_register_driver(driver);
-		if (ret)
-			goto err_out;
-
-		return 0;
-
-err_out:
-		if (driver) {
-			kfree(driver);
-			cpufreq_us3_driver = NULL;
-		}
-		kfree(us3_freq_table);
-		us3_freq_table = NULL;
-		return ret;
-	}
+	     impl == PANTHER_IMPL))
+		return cpufreq_register_driver(&cpufreq_us3_driver);
 
 	return -ENODEV;
 }
 
 static void __exit us3_freq_exit(void)
 {
-	if (cpufreq_us3_driver) {
-		cpufreq_unregister_driver(cpufreq_us3_driver);
-		kfree(cpufreq_us3_driver);
-		cpufreq_us3_driver = NULL;
-		kfree(us3_freq_table);
-		us3_freq_table = NULL;
-	}
+	cpufreq_unregister_driver(&cpufreq_us3_driver);
 }
 
 MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/lib/atomic_64.S linux-3.8.13-pax/arch/sparc/lib/atomic_64.S
--- linux-3.8.13/arch/sparc/lib/atomic_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/lib/atomic_64.S	2013-02-19 01:14:43.025772696 +0100
@@ -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, %o
 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, %o
 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
 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,
 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,
 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 = increme
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/lib/ksyms.c linux-3.8.13-pax/arch/sparc/lib/ksyms.c
--- linux-3.8.13/arch/sparc/lib/ksyms.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/lib/ksyms.c	2013-02-19 01:14:43.025772696 +0100
@@ -109,12 +109,18 @@ EXPORT_SYMBOL(__downgrade_write);
 
 /* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/lib/Makefile linux-3.8.13-pax/arch/sparc/lib/Makefile
--- linux-3.8.13/arch/sparc/lib/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/lib/Makefile	2013-02-19 01:14:43.025772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/mm/fault_32.c linux-3.8.13-pax/arch/sparc/mm/fault_32.c
--- linux-3.8.13/arch/sparc/mm/fault_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/mm/fault_32.c	2013-02-19 01:14:43.025772696 +0100
@@ -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(str
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/mm/fault_64.c linux-3.8.13-pax/arch/sparc/mm/fault_64.c
--- linux-3.8.13/arch/sparc/mm/fault_64.c	2013-03-07 04:10:19.663802306 +0100
+++ linux-3.8.13-pax/arch/sparc/mm/fault_64.c	2013-03-07 04:10:37.731801341 +0100
@@ -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>
@@ -270,6 +273,466 @@ static void noinline __kprobes bogus_32b
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/mm/hugetlbpage.c linux-3.8.13-pax/arch/sparc/mm/hugetlbpage.c
--- linux-3.8.13/arch/sparc/mm/hugetlbpage.c	2013-02-19 01:12:51.241766624 +0100
+++ linux-3.8.13-pax/arch/sparc/mm/hugetlbpage.c	2013-02-19 01:14:43.029772696 +0100
@@ -38,7 +38,7 @@ static unsigned long hugetlb_get_unmappe
 
 	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;
@@ -47,6 +47,12 @@ static unsigned long hugetlb_get_unmappe
 	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);
 	}
@@ -85,6 +91,12 @@ hugetlb_get_unmapped_area_topdown(struct
 		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);
 	}
@@ -114,11 +126,14 @@ hugetlb_get_unmapped_area(struct file *f
 		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))
 			return addr;
 	}
 	if (mm->get_unmapped_area == arch_get_unmapped_area)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/sparc/mm/Makefile linux-3.8.13-pax/arch/sparc/mm/Makefile
--- linux-3.8.13/arch/sparc/mm/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/sparc/mm/Makefile	2013-02-19 01:14:43.029772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/tile/include/asm/atomic_64.h linux-3.8.13-pax/arch/tile/include/asm/atomic_64.h
--- linux-3.8.13/arch/tile/include/asm/atomic_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/tile/include/asm/atomic_64.h	2013-02-19 01:14:43.029772696 +0100
@@ -143,6 +143,16 @@ static inline long atomic64_add_unless(a
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/tile/include/asm/uaccess.h linux-3.8.13-pax/arch/tile/include/asm/uaccess.h
--- linux-3.8.13/arch/tile/include/asm/uaccess.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/tile/include/asm/uaccess.h	2013-02-19 01:14:43.029772696 +0100
@@ -403,9 +403,9 @@ static inline unsigned long __must_check
 					  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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/um/include/asm/kmap_types.h linux-3.8.13-pax/arch/um/include/asm/kmap_types.h
--- linux-3.8.13/arch/um/include/asm/kmap_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/um/include/asm/kmap_types.h	2013-02-19 01:14:43.029772696 +0100
@@ -8,6 +8,6 @@
 
 /* No more #include "asm/arch/kmap_types.h" ! */
 
-#define KM_TYPE_NR 14
+#define KM_TYPE_NR 15
 
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/um/include/asm/page.h linux-3.8.13-pax/arch/um/include/asm/page.h
--- linux-3.8.13/arch/um/include/asm/page.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/um/include/asm/page.h	2013-02-19 01:14:43.029772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/um/include/asm/pgtable-3level.h linux-3.8.13-pax/arch/um/include/asm/pgtable-3level.h
--- linux-3.8.13/arch/um/include/asm/pgtable-3level.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/um/include/asm/pgtable-3level.h	2013-02-19 01:14:43.029772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/um/kernel/process.c linux-3.8.13-pax/arch/um/kernel/process.c
--- linux-3.8.13/arch/um/kernel/process.c	2013-02-19 01:12:51.349766630 +0100
+++ linux-3.8.13-pax/arch/um/kernel/process.c	2013-02-19 01:14:43.029772696 +0100
@@ -386,22 +386,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/um/Makefile linux-3.8.13-pax/arch/um/Makefile
--- linux-3.8.13/arch/um/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/um/Makefile	2013-02-19 01:14:43.029772696 +0100
@@ -62,6 +62,10 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINE
 	$(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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/bitops.h linux-3.8.13-pax/arch/x86/boot/bitops.h
--- linux-3.8.13/arch/x86/boot/bitops.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/bitops.h	2013-02-19 01:14:43.033772696 +0100
@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
 	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
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/boot.h linux-3.8.13-pax/arch/x86/boot/boot.h
--- linux-3.8.13/arch/x86/boot/boot.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/boot.h	2013-02-19 01:14:43.033772696 +0100
@@ -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
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/compressed/eboot.c linux-3.8.13-pax/arch/x86/boot/compressed/eboot.c
--- linux-3.8.13/arch/x86/boot/compressed/eboot.c	2013-03-07 04:10:19.703802304 +0100
+++ linux-3.8.13-pax/arch/x86/boot/compressed/eboot.c	2013-03-07 04:10:37.731801341 +0100
@@ -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 l
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/compressed/head_32.S linux-3.8.13-pax/arch/x86/boot/compressed/head_32.S
--- linux-3.8.13/arch/x86/boot/compressed/head_32.S	2013-02-19 01:12:51.425766634 +0100
+++ linux-3.8.13-pax/arch/x86/boot/compressed/head_32.S	2013-02-19 01:14:43.033772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/compressed/head_64.S linux-3.8.13-pax/arch/x86/boot/compressed/head_64.S
--- linux-3.8.13/arch/x86/boot/compressed/head_64.S	2013-02-19 01:12:51.437766635 +0100
+++ linux-3.8.13-pax/arch/x86/boot/compressed/head_64.S	2013-02-19 01:14:43.033772696 +0100
@@ -91,7 +91,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 */
@@ -273,7 +273,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 */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/compressed/Makefile linux-3.8.13-pax/arch/x86/boot/compressed/Makefile
--- linux-3.8.13/arch/x86/boot/compressed/Makefile	2013-04-13 00:55:42.303157687 +0200
+++ linux-3.8.13-pax/arch/x86/boot/compressed/Makefile	2013-04-13 00:55:48.519157355 +0200
@@ -14,6 +14,9 @@ cflags-$(CONFIG_X86_64) := -mcmodel=smal
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/compressed/misc.c linux-3.8.13-pax/arch/x86/boot/compressed/misc.c
--- linux-3.8.13/arch/x86/boot/compressed/misc.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/compressed/misc.c	2013-02-19 01:14:43.033772696 +0100
@@ -303,7 +303,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
@@ -352,7 +352,7 @@ asmlinkage void decompress_kernel(void *
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/cpucheck.c linux-3.8.13-pax/arch/x86/boot/cpucheck.c
--- linux-3.8.13/arch/x86/boot/cpucheck.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/cpucheck.c	2013-02-19 01:14:43.037772696 +0100
@@ -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 *r
 		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 *r
 		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 *r
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/header.S linux-3.8.13-pax/arch/x86/boot/header.S
--- linux-3.8.13/arch/x86/boot/header.S	2013-02-19 01:12:51.445766635 +0100
+++ linux-3.8.13-pax/arch/x86/boot/header.S	2013-02-19 01:14:43.037772696 +0100
@@ -401,10 +401,14 @@ setup_data:		.quad 0			# 64-bit physical
 						# 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/Makefile linux-3.8.13-pax/arch/x86/boot/Makefile
--- linux-3.8.13/arch/x86/boot/Makefile	2013-02-19 01:12:51.425766634 +0100
+++ linux-3.8.13-pax/arch/x86/boot/Makefile	2013-02-19 01:14:43.037772696 +0100
@@ -65,6 +65,9 @@ KBUILD_CFLAGS	:= $(USERINCLUDE) -g -Os -
 		   $(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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/memory.c linux-3.8.13-pax/arch/x86/boot/memory.c
--- linux-3.8.13/arch/x86/boot/memory.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/memory.c	2013-02-19 01:14:43.037772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/video.c linux-3.8.13-pax/arch/x86/boot/video.c
--- linux-3.8.13/arch/x86/boot/video.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/video.c	2013-02-19 01:14:43.037772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/boot/video-vesa.c linux-3.8.13-pax/arch/x86/boot/video-vesa.c
--- linux-3.8.13/arch/x86/boot/video-vesa.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/boot/video-vesa.c	2013-02-19 01:14:43.037772696 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/aesni-intel_asm.S linux-3.8.13-pax/arch/x86/crypto/aesni-intel_asm.S
--- linux-3.8.13/arch/x86/crypto/aesni-intel_asm.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/aesni-intel_asm.S	2013-02-19 01:14:43.037772696 +0100
@@ -31,6 +31,7 @@
 
 #include <linux/linkage.h>
 #include <asm/inst.h>
+#include <asm/alternative-asm.h>
 
 #ifdef __x86_64__
 .data
@@ -1436,7 +1437,9 @@ _return_T_done_decrypt:
 	pop	%r14
 	pop	%r13
 	pop	%r12
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_gcm_dec)
 
 
 /*****************************************************************************
@@ -1699,7 +1702,9 @@ _return_T_done_encrypt:
 	pop	%r14
 	pop	%r13
 	pop	%r12
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_gcm_enc)
 
 #endif
 
@@ -1714,6 +1719,7 @@ _key_expansion_256a:
 	pxor %xmm1, %xmm0
 	movaps %xmm0, (TKEYP)
 	add $0x10, TKEYP
+	pax_force_retaddr_bts
 	ret
 
 .align 4
@@ -1738,6 +1744,7 @@ _key_expansion_192a:
 	shufps $0b01001110, %xmm2, %xmm1
 	movaps %xmm1, 0x10(TKEYP)
 	add $0x20, TKEYP
+	pax_force_retaddr_bts
 	ret
 
 .align 4
@@ -1757,6 +1764,7 @@ _key_expansion_192b:
 
 	movaps %xmm0, (TKEYP)
 	add $0x10, TKEYP
+	pax_force_retaddr_bts
 	ret
 
 .align 4
@@ -1769,6 +1777,7 @@ _key_expansion_256b:
 	pxor %xmm1, %xmm2
 	movaps %xmm2, (TKEYP)
 	add $0x10, TKEYP
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -1881,7 +1890,9 @@ ENTRY(aesni_set_key)
 #ifndef __x86_64__
 	popl KEYP
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_set_key)
 
 /*
  * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
@@ -1902,7 +1913,9 @@ ENTRY(aesni_enc)
 	popl KLEN
 	popl KEYP
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_enc)
 
 /*
  * _aesni_enc1:		internal ABI
@@ -1959,6 +1972,7 @@ _aesni_enc1:
 	AESENC KEY STATE
 	movaps 0x70(TKEYP), KEY
 	AESENCLAST KEY STATE
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -2067,6 +2081,7 @@ _aesni_enc4:
 	AESENCLAST KEY STATE2
 	AESENCLAST KEY STATE3
 	AESENCLAST KEY STATE4
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -2089,7 +2104,9 @@ ENTRY(aesni_dec)
 	popl KLEN
 	popl KEYP
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_dec)
 
 /*
  * _aesni_dec1:		internal ABI
@@ -2146,6 +2163,7 @@ _aesni_dec1:
 	AESDEC KEY STATE
 	movaps 0x70(TKEYP), KEY
 	AESDECLAST KEY STATE
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -2254,6 +2272,7 @@ _aesni_dec4:
 	AESDECLAST KEY STATE2
 	AESDECLAST KEY STATE3
 	AESDECLAST KEY STATE4
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -2311,7 +2330,9 @@ ENTRY(aesni_ecb_enc)
 	popl KEYP
 	popl LEN
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_ecb_enc)
 
 /*
  * void aesni_ecb_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
@@ -2369,7 +2390,9 @@ ENTRY(aesni_ecb_dec)
 	popl KEYP
 	popl LEN
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_ecb_dec)
 
 /*
  * void aesni_cbc_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
@@ -2410,7 +2433,9 @@ ENTRY(aesni_cbc_enc)
 	popl LEN
 	popl IVP
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_cbc_enc)
 
 /*
  * void aesni_cbc_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
@@ -2500,7 +2525,9 @@ ENTRY(aesni_cbc_dec)
 	popl LEN
 	popl IVP
 #endif
+	pax_force_retaddr 0, 1
 	ret
+ENDPROC(aesni_cbc_dec)
 
 #ifdef __x86_64__
 .align 16
@@ -2526,6 +2553,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
 
 /*
@@ -2554,6 +2582,7 @@ _aesni_inc:
 .Linc_low:
 	movaps CTR, IV
 	PSHUFB_XMM BSWAP_MASK IV
+	pax_force_retaddr_bts
 	ret
 
 /*
@@ -2614,5 +2643,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)
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/aes-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/aes-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/aes-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/aes-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -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
@@ -71,6 +73,8 @@ FUNC:	movq	r1,r2;			\
 	je	B192;			\
 	leaq	32(r9),r9;
 
+#define ret	pax_force_retaddr 0, 1; ret
+
 #define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \
 	movq	r1,r2;			\
 	movq	r3,r4;			\
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/blowfish-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/blowfish-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/blowfish-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/blowfish-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -20,6 +20,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 .file "blowfish-x86_64-asm.S"
 .text
 
@@ -151,9 +153,11 @@ __blowfish_enc_blk:
 	jnz __enc_xor;
 
 	write_block();
+	pax_force_retaddr 0, 1
 	ret;
 __enc_xor:
 	xor_block();
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 8
@@ -188,6 +192,7 @@ blowfish_dec_blk:
 
 	movq %r11, %rbp;
 
+	pax_force_retaddr 0, 1
 	ret;
 
 /**********************************************************************
@@ -342,6 +347,7 @@ __blowfish_enc_blk_4way:
 
 	popq %rbx;
 	popq %rbp;
+	pax_force_retaddr 0, 1
 	ret;
 
 __enc_xor4:
@@ -349,6 +355,7 @@ __enc_xor4:
 
 	popq %rbx;
 	popq %rbp;
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 8
@@ -386,5 +393,6 @@ blowfish_dec_blk_4way:
 	popq %rbx;
 	popq %rbp;
 
+	pax_force_retaddr 0, 1
 	ret;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/camellia-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/camellia-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/camellia-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/camellia-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -20,6 +20,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 .file "camellia-x86_64-asm_64.S"
 .text
 
@@ -229,12 +231,14 @@ __enc_done:
 	enc_outunpack(mov, RT1);
 
 	movq RRBP, %rbp;
+	pax_force_retaddr 0, 1
 	ret;
 
 __enc_xor:
 	enc_outunpack(xor, RT1);
 
 	movq RRBP, %rbp;
+	pax_force_retaddr 0, 1
 	ret;
 
 .global camellia_dec_blk;
@@ -275,6 +279,7 @@ __dec_rounds16:
 	dec_outunpack();
 
 	movq RRBP, %rbp;
+	pax_force_retaddr 0, 1
 	ret;
 
 /**********************************************************************
@@ -468,6 +473,7 @@ __enc2_done:
 
 	movq RRBP, %rbp;
 	popq %rbx;
+	pax_force_retaddr 0, 1
 	ret;
 
 __enc2_xor:
@@ -475,6 +481,7 @@ __enc2_xor:
 
 	movq RRBP, %rbp;
 	popq %rbx;
+	pax_force_retaddr 0, 1
 	ret;
 
 .global camellia_dec_blk_2way;
@@ -517,4 +524,5 @@ __dec2_rounds16:
 
 	movq RRBP, %rbp;
 	movq RXOR, %rbx;
+	pax_force_retaddr 0, 1
 	ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/cast5-avx-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/cast5-avx-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/cast5-avx-x86_64-asm_64.S	2013-02-19 01:12:51.485766638 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/cast5-avx-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -23,6 +23,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 .file "cast5-avx-x86_64-asm_64.S"
 
 .extern cast_s1
@@ -281,6 +283,7 @@ __skip_enc:
 	outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
 	outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
 
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 16
@@ -353,6 +356,7 @@ __dec_tail:
 	outunpack_blocks(RR3, RL3, RTMP, RX, RKM);
 	outunpack_blocks(RR4, RL4, RTMP, RX, RKM);
 
+	pax_force_retaddr 0, 1
 	ret;
 
 __skip_dec:
@@ -392,6 +396,7 @@ cast5_ecb_enc_16way:
 	vmovdqu RR4, (6*4*4)(%r11);
 	vmovdqu RL4, (7*4*4)(%r11);
 
+	pax_force_retaddr
 	ret;
 
 .align 16
@@ -427,6 +432,7 @@ cast5_ecb_dec_16way:
 	vmovdqu RR4, (6*4*4)(%r11);
 	vmovdqu RL4, (7*4*4)(%r11);
 
+	pax_force_retaddr
 	ret;
 
 .align 16
@@ -479,6 +485,7 @@ cast5_cbc_dec_16way:
 
 	popq %r12;
 
+	pax_force_retaddr
 	ret;
 
 .align 16
@@ -555,4 +562,5 @@ cast5_ctr_16way:
 
 	popq %r12;
 
+	pax_force_retaddr
 	ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/cast6-avx-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/cast6-avx-x86_64-asm_64.S	2013-02-19 01:12:51.489766638 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/cast6-avx-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -23,6 +23,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 #include "glue_helper-asm-avx.S"
 
 .file "cast6-avx-x86_64-asm_64.S"
@@ -294,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;
 
 .align 8
@@ -340,6 +343,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;
 
 .align 8
@@ -361,6 +365,7 @@ cast6_ecb_enc_8way:
 
 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -382,6 +387,7 @@ cast6_ecb_dec_8way:
 
 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -408,6 +414,7 @@ cast6_cbc_dec_8way:
 
 	popq %r12;
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -436,4 +443,5 @@ cast6_ctr_8way:
 
 	popq %r12;
 
+	pax_force_retaddr
 	ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/salsa20-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/salsa20-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/salsa20-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/salsa20-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -1,3 +1,5 @@
+#include <asm/alternative-asm.h>
+
 # enter ECRYPT_encrypt_bytes
 .text
 .p2align 5
@@ -790,6 +792,7 @@ ECRYPT_encrypt_bytes:
 	add	%r11,%rsp
 	mov	%rdi,%rax
 	mov	%rsi,%rdx
+	pax_force_retaddr 0, 1
 	ret
 #   bytesatleast65:
 ._bytesatleast65:
@@ -891,6 +894,7 @@ ECRYPT_keysetup:
 	add	%r11,%rsp
 	mov	%rdi,%rax
 	mov	%rsi,%rdx
+	pax_force_retaddr
 	ret
 # enter ECRYPT_ivsetup
 .text
@@ -917,4 +921,5 @@ ECRYPT_ivsetup:
 	add	%r11,%rsp
 	mov	%rdi,%rax
 	mov	%rsi,%rdx
+	pax_force_retaddr
 	ret
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/serpent-avx-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/serpent-avx-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/serpent-avx-x86_64-asm_64.S	2013-02-19 01:12:51.501766639 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/serpent-avx-x86_64-asm_64.S	2013-02-19 01:14:43.041772697 +0100
@@ -24,6 +24,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 #include "glue_helper-asm-avx.S"
 
 .file "serpent-avx-x86_64-asm_64.S"
@@ -618,6 +620,7 @@ __serpent_enc_blk8_avx:
 	write_blocks(RA1, RB1, RC1, RD1, RK0, RK1, RK2);
 	write_blocks(RA2, RB2, RC2, RD2, RK0, RK1, RK2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -673,6 +676,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;
 
 .align 8
@@ -692,6 +696,7 @@ serpent_ecb_enc_8way_avx:
 
 	store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -711,6 +716,7 @@ serpent_ecb_dec_8way_avx:
 
 	store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -730,6 +736,7 @@ serpent_cbc_dec_8way_avx:
 
 	store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2);
 
+	pax_force_retaddr
 	ret;
 
 .align 8
@@ -751,4 +758,5 @@ serpent_ctr_8way_avx:
 
 	store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 
+	pax_force_retaddr
 	ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/serpent-sse2-x86_64-asm_64.S	2013-02-19 01:14:43.045772697 +0100
@@ -24,6 +24,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 .file "serpent-sse2-x86_64-asm_64.S"
 .text
 
@@ -692,12 +694,14 @@ __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;
 
 __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;
 
 .align 8
@@ -755,4 +759,5 @@ 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;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/sha1_ssse3_asm.S linux-3.8.13-pax/arch/x86/crypto/sha1_ssse3_asm.S
--- linux-3.8.13/arch/x86/crypto/sha1_ssse3_asm.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/sha1_ssse3_asm.S	2013-02-19 01:14:43.045772697 +0100
@@ -28,6 +28,8 @@
  * (at your option) any later version.
  */
 
+#include <asm/alternative-asm.h>
+
 #define CTX	%rdi	// arg1
 #define BUF	%rsi	// arg2
 #define CNT	%rdx	// arg3
@@ -104,6 +106,7 @@
 	pop	%r12
 	pop	%rbp
 	pop	%rbx
+	pax_force_retaddr 0, 1
 	ret
 
 	.size	\name, .-\name
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/twofish-avx-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/twofish-avx-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/twofish-avx-x86_64-asm_64.S	2013-02-19 01:12:51.505766639 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/twofish-avx-x86_64-asm_64.S	2013-02-19 01:14:43.045772697 +0100
@@ -23,6 +23,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 #include "glue_helper-asm-avx.S"
 
 .file "twofish-avx-x86_64-asm_64.S"
@@ -283,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;
 
 .align 8
@@ -324,6 +327,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;
 
 .align 8
@@ -345,6 +349,7 @@ twofish_ecb_enc_8way:
 
 	store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2);
 
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 8
@@ -366,6 +371,7 @@ twofish_ecb_dec_8way:
 
 	store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 8
@@ -392,6 +398,7 @@ twofish_cbc_dec_8way:
 
 	popq %r12;
 
+	pax_force_retaddr 0, 1
 	ret;
 
 .align 8
@@ -420,4 +427,5 @@ twofish_ctr_8way:
 
 	popq %r12;
 
+	pax_force_retaddr 0, 1
 	ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/twofish-x86_64-asm_64-3way.S linux-3.8.13-pax/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
--- linux-3.8.13/arch/x86/crypto/twofish-x86_64-asm_64-3way.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/twofish-x86_64-asm_64-3way.S	2013-02-19 01:14:43.045772697 +0100
@@ -20,6 +20,8 @@
  *
  */
 
+#include <asm/alternative-asm.h>
+
 .file "twofish-x86_64-asm-3way.S"
 .text
 
@@ -260,6 +262,7 @@ __twofish_enc_blk_3way:
 	popq %r13;
 	popq %r14;
 	popq %r15;
+	pax_force_retaddr 0, 1
 	ret;
 
 __enc_xor3:
@@ -271,6 +274,7 @@ __enc_xor3:
 	popq %r13;
 	popq %r14;
 	popq %r15;
+	pax_force_retaddr 0, 1
 	ret;
 
 .global twofish_dec_blk_3way
@@ -312,5 +316,6 @@ twofish_dec_blk_3way:
 	popq %r13;
 	popq %r14;
 	popq %r15;
+	pax_force_retaddr 0, 1
 	ret;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/crypto/twofish-x86_64-asm_64.S linux-3.8.13-pax/arch/x86/crypto/twofish-x86_64-asm_64.S
--- linux-3.8.13/arch/x86/crypto/twofish-x86_64-asm_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/crypto/twofish-x86_64-asm_64.S	2013-02-19 01:14:43.045772697 +0100
@@ -21,6 +21,7 @@
 .text
 
 #include <asm/asm-offsets.h>
+#include <asm/alternative-asm.h>
 
 #define a_offset	0
 #define b_offset	4
@@ -268,6 +269,7 @@ twofish_enc_blk:
 
 	popq	R1
 	movq	$1,%rax
+	pax_force_retaddr 0, 1
 	ret
 
 twofish_dec_blk:
@@ -319,4 +321,5 @@ twofish_dec_blk:
 
 	popq	R1
 	movq	$1,%rax
+	pax_force_retaddr 0, 1
 	ret
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/ia32/ia32entry.S linux-3.8.13-pax/arch/x86/ia32/ia32entry.S
--- linux-3.8.13/arch/x86/ia32/ia32entry.S	2013-02-19 01:12:51.529766640 +0100
+++ linux-3.8.13-pax/arch/x86/ia32/ia32entry.S	2013-05-06 00:17:45.964737776 +0200
@@ -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,44 @@ 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
+	mov pax_user_shadow_base,%r11
+	add %r11,%rbp
+#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)
+	GET_THREAD_INFO(%r11)
+	orl    $TS_COMPAT,TI_status(%r11)
+	testl  $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
 	CFI_REMEMBER_STATE
 	jnz  sysenter_tracesys
 	cmpq	$(IA32_NR_syscalls-1),%rax
@@ -162,12 +204,15 @@ sysenter_do_call:
 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 +238,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 +252,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 +263,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 +286,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 +298,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 +328,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 +362,19 @@ ENTRY(ia32_cstar_target)
 	/* no need to do an access_ok check here because r8 has been
 	   32bit zero extended */ 
 	/* hardware stack frame is complete now */	
+
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+	mov pax_user_shadow_base,%r11
+	add %r11,%r8
+#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)
+	GET_THREAD_INFO(%r11)
+	orl   $TS_COMPAT,TI_status(%r11)
+	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r11)
 	CFI_REMEMBER_STATE
 	jnz   cstar_tracesys
 	cmpq $IA32_NR_syscalls-1,%rax
@@ -319,12 +384,15 @@ cstar_do_call:
 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 +420,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,6 +434,9 @@ 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)
 				
@@ -407,19 +478,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 +520,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/ia32/ia32_signal.c linux-3.8.13-pax/arch/x86/ia32/ia32_signal.c
--- linux-3.8.13/arch/x86/ia32/ia32_signal.c	2013-02-19 01:12:51.525766640 +0100
+++ linux-3.8.13-pax/arch/x86/ia32/ia32_signal.c	2013-03-23 17:26:23.574765536 +0100
@@ -348,7 +348,7 @@ static void __user *get_sigframe(struct
 	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;
 }
 
@@ -406,7 +406,7 @@ int ia32_setup_frame(int sig, struct k_s
 		 * 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)
@@ -448,7 +448,7 @@ int ia32_setup_rt_frame(int sig, struct
 		0xb8,
 		__NR_ia32_rt_sigreturn,
 		0x80cd,
-		0,
+		0
 	};
 
 	frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
@@ -471,16 +471,18 @@ int ia32_setup_rt_frame(int sig, struct
 
 		if (ka->sa.sa_flags & SA_RESTORER)
 			restorer = 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, info);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/ia32/sys_ia32.c linux-3.8.13-pax/arch/x86/ia32/sys_ia32.c
--- linux-3.8.13/arch/x86/ia32/sys_ia32.c	2013-02-19 01:12:51.537766640 +0100
+++ linux-3.8.13-pax/arch/x86/ia32/sys_ia32.c	2013-02-19 01:14:43.049772697 +0100
@@ -69,8 +69,8 @@ asmlinkage long sys32_ftruncate64(unsign
  */
 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)) ||
@@ -303,7 +303,7 @@ asmlinkage long sys32_sched_rr_get_inter
 	mm_segment_t old_fs = get_fs();
 
 	set_fs(KERNEL_DS);
-	ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
+	ret = sys_sched_rr_get_interval(pid, (struct timespec __force_user *)&t);
 	set_fs(old_fs);
 	if (put_compat_timespec(&t, interval))
 		return -EFAULT;
@@ -319,7 +319,7 @@ asmlinkage long sys32_rt_sigpending(comp
 	mm_segment_t old_fs = get_fs();
 
 	set_fs(KERNEL_DS);
-	ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize);
+	ret = sys_rt_sigpending((sigset_t __force_user *)&s, sigsetsize);
 	set_fs(old_fs);
 	if (!ret) {
 		switch (_NSIG_WORDS) {
@@ -344,7 +344,7 @@ asmlinkage long sys32_rt_sigqueueinfo(in
 	if (copy_siginfo_from_user32(&info, uinfo))
 		return -EFAULT;
 	set_fs(KERNEL_DS);
-	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
+	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force_user *)&info);
 	set_fs(old_fs);
 	return ret;
 }
@@ -376,7 +376,7 @@ asmlinkage long sys32_sendfile(int out_f
 		return -EFAULT;
 
 	set_fs(KERNEL_DS);
-	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
+	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __force_user *)&of : NULL,
 			   count);
 	set_fs(old_fs);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/alternative-asm.h linux-3.8.13-pax/arch/x86/include/asm/alternative-asm.h
--- linux-3.8.13/arch/x86/include/asm/alternative-asm.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/alternative-asm.h	2013-02-19 01:14:43.049772697 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/alternative.h linux-3.8.13-pax/arch/x86/include/asm/alternative.h
--- linux-3.8.13/arch/x86/include/asm/alternative.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/alternative.h	2013-02-19 01:14:43.049772697 +0100
@@ -105,7 +105,7 @@ static inline int alternatives_text_rese
 	".pushsection .discard,\"aw\",@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_rese
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/apic.h linux-3.8.13-pax/arch/x86/include/asm/apic.h
--- linux-3.8.13/arch/x86/include/asm/apic.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/apic.h	2013-03-06 04:23:24.316090235 +0100
@@ -44,7 +44,7 @@ static inline void generic_apic_probe(vo
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/apm.h linux-3.8.13-pax/arch/x86/include/asm/apm.h
--- linux-3.8.13/arch/x86/include/asm/apm.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/apm.h	2013-02-19 01:14:43.049772697 +0100
@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
 	__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_as
 	__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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/atomic64_32.h linux-3.8.13-pax/arch/x86/include/asm/atomic64_32.h
--- linux-3.8.13/arch/x86/include/asm/atomic64_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/atomic64_32.h	2013-02-19 01:14:43.049772697 +0100
@@ -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_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
 }
 
 /**
+ * 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(co
  }
 
 /**
+ * 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_ret
 	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_ret
 	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;
@@ -179,6 +264,21 @@ static inline long long atomic64_add(lon
 			       ASM_OUTPUT2("+A" (i), "+c" (v)),
 			       ASM_NO_INPUT_CLOBBER("memory"));
 	return i;
+}
+
+/**
+ * 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;
 }
 
 /**
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/atomic64_64.h linux-3.8.13-pax/arch/x86/include/asm/atomic64_64.h
--- linux-3.8.13/arch/x86/include/asm/atomic64_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/atomic64_64.h	2013-02-19 01:14:43.053772697 +0100
@@ -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
 }
 
 /**
+ * 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
  */
 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,
  */
 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(
 {
 	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(
  */
 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
  */
 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(
 {
 	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(
 {
 	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(
 {
 	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(
  */
 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(l
 }
 
 #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(atom
 	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(atomic6
  */
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/atomic.h linux-3.8.13-pax/arch/x86/include/asm/atomic.h
--- linux-3.8.13/arch/x86/include/asm/atomic.h	2013-02-19 01:12:51.537766640 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/atomic.h	2013-02-19 01:14:43.053772697 +0100
@@ -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 *
 }
 
 /**
+ * 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 *
  */
 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, ato
  */
 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(in
 {
 	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(in
  */
 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 *
  */
 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(at
 {
 	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(at
 {
 	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(in
 {
 	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(in
  */
 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
 }
 
 #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_
 	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 *
  */
 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(at
 }
 
 /**
+ * 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(unsign
 #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")
-
-#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(unsigned int mask, atomic_t *v)
+{
+	asm volatile(LOCK_PREFIX "andl %1,%0"
+		     : "+m" (v->counter)
+		     : "r" (~(mask))
+		     : "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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/bitops.h linux-3.8.13-pax/arch/x86/include/asm/bitops.h
--- linux-3.8.13/arch/x86/include/asm/bitops.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/bitops.h	2013-03-13 00:54:18.543367712 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/boot.h linux-3.8.13-pax/arch/x86/include/asm/boot.h
--- linux-3.8.13/arch/x86/include/asm/boot.h	2013-02-19 01:12:51.541766641 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/boot.h	2013-02-19 01:14:43.053772697 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/cacheflush.h linux-3.8.13-pax/arch/x86/include/asm/cacheflush.h
--- linux-3.8.13/arch/x86/include/asm/cacheflush.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/cacheflush.h	2013-02-19 01:14:43.053772697 +0100
@@ -27,7 +27,7 @@ static inline unsigned long get_page_mem
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/cache.h linux-3.8.13-pax/arch/x86/include/asm/cache.h
--- linux-3.8.13/arch/x86/include/asm/cache.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/cache.h	2013-02-19 01:14:43.053772697 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/checksum_32.h linux-3.8.13-pax/arch/x86/include/asm/checksum_32.h
--- linux-3.8.13/arch/x86/include/asm/checksum_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/checksum_32.h	2013-02-19 01:14:43.053772697 +0100
@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
 					    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.
@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
 						 int *err_ptr)
 {
 	might_sleep();
-	return csum_partial_copy_generic((__force void *)src, dst,
+	return csum_partial_copy_generic_from_user((__force void *)src, dst,
 					 len, sum, err_ptr, NULL);
 }
 
@@ -178,7 +186,7 @@ static inline __wsum csum_and_copy_to_us
 {
 	might_sleep();
 	if (access_ok(VERIFY_WRITE, dst, len))
-		return csum_partial_copy_generic(src, (__force void *)dst,
+		return csum_partial_copy_generic_to_user(src, (__force void *)dst,
 						 len, sum, NULL, err_ptr);
 
 	if (len)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/cmpxchg.h linux-3.8.13-pax/arch/x86/include/asm/cmpxchg.h
--- linux-3.8.13/arch/x86/include/asm/cmpxchg.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/cmpxchg.h	2013-02-19 01:14:43.057772697 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/compat.h linux-3.8.13-pax/arch/x86/include/asm/compat.h
--- linux-3.8.13/arch/x86/include/asm/compat.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/compat.h	2013-03-27 01:59:46.984962889 +0100
@@ -41,7 +41,7 @@ typedef s64 __attribute__((aligned(4)))
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/cpufeature.h linux-3.8.13-pax/arch/x86/include/asm/cpufeature.h
--- linux-3.8.13/arch/x86/include/asm/cpufeature.h	2013-02-19 01:12:51.561766642 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/cpufeature.h	2013-02-19 01:14:43.057772697 +0100
@@ -206,7 +206,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 */
@@ -375,7 +375,7 @@ static __always_inline __pure bool __sta
 			     ".section .discard,\"aw\",@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"
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/desc_defs.h linux-3.8.13-pax/arch/x86/include/asm/desc_defs.h
--- linux-3.8.13/arch/x86/include/asm/desc_defs.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/desc_defs.h	2013-02-19 01:14:43.057772697 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/desc.h linux-3.8.13-pax/arch/x86/include/asm/desc.h
--- linux-3.8.13/arch/x86/include/asm/desc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/desc.h	2013-03-13 00:54:18.543367712 +0100
@@ -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_
 
 	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_
 }
 
 extern struct desc_ptr idt_descr;
-extern gate_desc idt_table[];
 extern struct desc_ptr nmi_idt_descr;
-extern gate_desc nmi_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[256];
+extern gate_desc nmi_idt_table[256];
 
+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 *
 			     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(str
 
 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_struc
 	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
 
 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(struc
 	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
 	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
 }
 
 #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;
 
@@ -320,7 +333,7 @@ static inline void set_nmi_gate(int 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;
@@ -339,7 +352,7 @@ static inline void _set_gate(int gate, u
  * 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);
@@ -369,19 +382,19 @@ static inline void alloc_intr_gate(unsig
 /*
  * 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);
@@ -390,19 +403,31 @@ static inline void set_trap_gate(unsigne
 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);
 }
 
+#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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/div64.h linux-3.8.13-pax/arch/x86/include/asm/div64.h
--- linux-3.8.13/arch/x86/include/asm/div64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/div64.h	2013-03-13 00:54:18.551367712 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/elf.h linux-3.8.13-pax/arch/x86/include/asm/elf.h
--- linux-3.8.13/arch/x86/include/asm/elf.h	2013-02-19 01:12:51.593766644 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/elf.h	2013-02-19 01:14:43.085772699 +0100
@@ -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(st
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/emergency-restart.h linux-3.8.13-pax/arch/x86/include/asm/emergency-restart.h
--- linux-3.8.13/arch/x86/include/asm/emergency-restart.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/emergency-restart.h	2013-02-19 01:14:43.089772699 +0100
@@ -13,6 +13,6 @@ enum reboot_type {
 
 extern enum reboot_type reboot_type;
 
-extern void machine_emergency_restart(void);
+extern void machine_emergency_restart(void) __noreturn;
 
 #endif /* _ASM_X86_EMERGENCY_RESTART_H */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/fpu-internal.h linux-3.8.13-pax/arch/x86/include/asm/fpu-internal.h
--- linux-3.8.13/arch/x86/include/asm/fpu-internal.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/fpu-internal.h	2013-02-19 01:14:43.089772699 +0100
@@ -126,7 +126,9 @@ static inline void sanitize_i387_state(s
 ({									\
 	int err;							\
 	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"				\
@@ -299,7 +301,7 @@ static inline int restore_fpu_checking(s
 		"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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/futex.h linux-3.8.13-pax/arch/x86/include/asm/futex.h
--- linux-3.8.13/arch/x86/include/asm/futex.h	2013-02-19 01:12:51.597766644 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/futex.h	2013-02-19 01:14:43.089772699 +0100
@@ -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)
@@ -59,10 +61,10 @@ static inline int futex_atomic_op_inuser
 
 	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:
@@ -116,14 +118,14 @@ static inline int futex_atomic_cmpxchg_i
 		return -EFAULT;
 
 	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"
 	);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/hw_irq.h linux-3.8.13-pax/arch/x86/include/asm/hw_irq.h
--- linux-3.8.13/arch/x86/include/asm/hw_irq.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/hw_irq.h	2013-02-19 01:14:43.089772699 +0100
@@ -136,8 +136,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/i8259.h linux-3.8.13-pax/arch/x86/include/asm/i8259.h
--- linux-3.8.13/arch/x86/include/asm/i8259.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/i8259.h	2013-03-06 05:20:03.043908769 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/io.h linux-3.8.13-pax/arch/x86/include/asm/io.h
--- linux-3.8.13/arch/x86/include/asm/io.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/io.h	2013-03-13 00:54:18.551367712 +0100
@@ -51,12 +51,12 @@ static inline void name(type val, volati
 "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(reso
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/irqflags.h linux-3.8.13-pax/arch/x86/include/asm/irqflags.h
--- linux-3.8.13/arch/x86/include/asm/irqflags.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/irqflags.h	2013-02-19 01:14:43.089772699 +0100
@@ -141,6 +141,11 @@ static inline notrace unsigned long arch
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/kprobes.h linux-3.8.13-pax/arch/x86/include/asm/kprobes.h
--- linux-3.8.13/arch/x86/include/asm/kprobes.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/kprobes.h	2013-02-19 01:14:43.093772699 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/local.h linux-3.8.13-pax/arch/x86/include/asm/local.h
--- linux-3.8.13/arch/x86/include/asm/local.h	2013-02-19 01:12:51.637766646 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/local.h	2013-02-19 01:14:43.093772699 +0100
@@ -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(lon
 {
 	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(loc
 {
 	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(loc
 {
 	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(lon
 {
 	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(lon
 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
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/mman.h linux-3.8.13-pax/arch/x86/include/asm/mman.h
--- linux-3.8.13/arch/x86/include/asm/mman.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/mman.h	2013-02-19 01:14:43.093772699 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/mmu_context.h linux-3.8.13-pax/arch/x86/include/asm/mmu_context.h
--- linux-3.8.13/arch/x86/include/asm/mmu_context.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/mmu_context.h	2013-02-19 01:14:43.093772699 +0100
@@ -24,6 +24,18 @@ void destroy_context(struct mm_struct *m
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
+
+#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF)
+	unsigned int i;
+	pgd_t *pgd;
+
+	pax_open_kernel();
+	pgd = get_cpu_pgd(smp_processor_id());
+	for (i = USER_PGD_PTRS; i < 2 * USER_PGD_PTRS; ++i)
+		set_pgd_batched(pgd+i, native_make_pgd(0));
+	pax_close_kernel();
+#endif
+
 #ifdef CONFIG_SMP
 	if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
 		this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
@@ -34,16 +46,30 @@ static inline void switch_mm(struct mm_s
 			     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();
+		__clone_user_pgds(get_cpu_pgd(cpu), next->pgd);
+		__shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd);
+		pax_close_kernel();
+		load_cr3(get_cpu_pgd(cpu));
+#else
 		load_cr3(next->pgd);
+#endif
 
 		/* stop flush ipis for the previous mm */
 		cpumask_clear_cpu(cpu, mm_cpumask(prev));
@@ -53,9 +79,38 @@ static inline void switch_mm(struct mm_s
 		 */
 		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();
+		__clone_user_pgds(get_cpu_pgd(cpu), next->pgd);
+		__shadow_user_pgds(get_cpu_pgd(cpu) + USER_PGD_PTRS, next->pgd);
+		pax_close_kernel();
+		load_cr3(get_cpu_pgd(cpu));
+#endif
+
+#ifdef CONFIG_SMP
 		this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
 		BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
 
@@ -64,11 +119,28 @@ static inline void switch_mm(struct mm_s
 			 * 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
+	}
 }
 
 #define activate_mm(prev, next)			\
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/mmu.h linux-3.8.13-pax/arch/x86/include/asm/mmu.h
--- linux-3.8.13/arch/x86/include/asm/mmu.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/mmu.h	2013-02-19 01:14:43.093772699 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/module.h linux-3.8.13-pax/arch/x86/include/asm/module.h
--- linux-3.8.13/arch/x86/include/asm/module.h	2013-02-19 01:12:51.657766647 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/module.h	2013-02-19 01:14:43.093772699 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/nmi.h linux-3.8.13-pax/arch/x86/include/asm/nmi.h
--- linux-3.8.13/arch/x86/include/asm/nmi.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/nmi.h	2013-03-08 14:48:52.506334447 +0100
@@ -42,11 +42,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),				\
@@ -54,7 +54,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/page_64_types.h linux-3.8.13-pax/arch/x86/include/asm/page_64_types.h
--- linux-3.8.13/arch/x86/include/asm/page_64_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/page_64_types.h	2013-02-19 01:14:43.093772699 +0100
@@ -56,7 +56,7 @@ void copy_page(void *to, void *from);
 
 /* duplicated to the one in bootmem.h */
 extern unsigned long max_pfn;
-extern unsigned long phys_base;
+extern const unsigned long phys_base;
 
 extern unsigned long __phys_addr(unsigned long);
 #define __phys_reloc_hide(x)	(x)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/paravirt.h linux-3.8.13-pax/arch/x86/include/asm/paravirt.h
--- linux-3.8.13/arch/x86/include/asm/paravirt.h	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/include/asm/paravirt.h	2013-04-30 00:05:07.711842721 +0200
@@ -564,7 +564,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;
 
@@ -630,6 +630,18 @@ static inline void set_pgd(pgd_t *pgdp,
 			    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));
@@ -714,6 +726,21 @@ static inline void __set_fixmap(unsigned
 	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)
@@ -930,7 +957,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						\
@@ -1005,6 +1032,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/paravirt_types.h linux-3.8.13-pax/arch/x86/include/asm/paravirt_types.h
--- linux-3.8.13/arch/x86/include/asm/paravirt_types.h	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/include/asm/paravirt_types.h	2013-04-30 00:05:07.711842721 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgalloc.h linux-3.8.13-pax/arch/x86/include/asm/pgalloc.h
--- linux-3.8.13/arch/x86/include/asm/pgalloc.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgalloc.h	2013-02-19 01:14:43.097772700 +0100
@@ -63,6 +63,13 @@ static inline void pmd_populate_kernel(s
 				       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
 
 #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 m
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable-2level.h linux-3.8.13-pax/arch/x86/include/asm/pgtable-2level.h
--- linux-3.8.13/arch/x86/include/asm/pgtable-2level.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable-2level.h	2013-02-19 01:14:43.097772700 +0100
@@ -18,7 +18,9 @@ static inline void native_set_pte(pte_t
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable_32.h linux-3.8.13-pax/arch/x86/include/asm/pgtable_32.h
--- linux-3.8.13/arch/x86/include/asm/pgtable_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable_32.h	2013-02-19 01:14:43.097772700 +0100
@@ -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, u
 # 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,7 +65,9 @@ extern void set_pmd_pfn(unsigned long, u
 /* 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)
 
@@ -75,6 +80,9 @@ do {						\
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable_32_types.h linux-3.8.13-pax/arch/x86/include/asm/pgtable_32_types.h
--- linux-3.8.13/arch/x86/include/asm/pgtable_32_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable_32_types.h	2013-02-19 01:14:43.097772700 +0100
@@ -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
 # 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable-3level.h linux-3.8.13-pax/arch/x86/include/asm/pgtable-3level.h
--- linux-3.8.13/arch/x86/include/asm/pgtable-3level.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable-3level.h	2013-02-19 01:14:43.101772700 +0100
@@ -92,12 +92,16 @@ static inline void native_set_pte_atomic
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable_64.h linux-3.8.13-pax/arch/x86/include/asm/pgtable_64.h
--- linux-3.8.13/arch/x86/include/asm/pgtable_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable_64.h	2013-02-19 01:14:43.101772700 +0100
@@ -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
 
 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_
 
 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_
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable_64_types.h linux-3.8.13-pax/arch/x86/include/asm/pgtable_64_types.h
--- linux-3.8.13/arch/x86/include/asm/pgtable_64_types.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable_64_types.h	2013-02-19 01:14:43.101772700 +0100
@@ -59,5 +59,10 @@ 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)
 
 #endif /* _ASM_X86_PGTABLE_64_DEFS_H */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable.h linux-3.8.13-pax/arch/x86/include/asm/pgtable.h
--- linux-3.8.13/arch/x86/include/asm/pgtable.h	2013-02-19 01:12:51.669766648 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable.h	2013-05-06 00:17:09.188739739 +0200
@@ -44,6 +44,7 @@ extern struct mm_struct *pgd_page_get_mm
 
 #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
 
 #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;
@@ -200,9 +240,29 @@ static inline pte_t pte_wrprotect(pte_t
 	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)
@@ -394,6 +454,15 @@ pte_t *populate_extra_pte(unsigned long
 #endif
 
 #ifndef __ASSEMBLY__
+
+#ifdef CONFIG_PAX_PER_CPU_PGD
+extern pgd_t cpu_pgd[NR_CPUS][PTRS_PER_PGD];
+static inline pgd_t *get_cpu_pgd(unsigned int cpu)
+{
+	return cpu_pgd[cpu];
+}
+#endif
+
 #include <linux/mm_types.h>
 
 static inline int pte_none(pte_t pte)
@@ -583,7 +652,7 @@ static inline pud_t *pud_offset(pgd_t *p
 
 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)
@@ -606,7 +675,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, address) (get_cpu_pgd(cpu) + pgd_index(address))
+#endif
+
 /*
  * a shortcut which implies the use of the kernel's pgd, instead
  * of a process's
@@ -617,6 +691,22 @@ 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;
+#endif
+#endif
+
+#endif
+
 #ifndef __ASSEMBLY__
 
 extern int direct_gbpages;
@@ -781,11 +871,23 @@ static inline void pmdp_set_wrprotect(st
  * 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
 
 #include <asm-generic/pgtable.h>
 #endif	/* __ASSEMBLY__ */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/pgtable_types.h linux-3.8.13-pax/arch/x86/include/asm/pgtable_types.h
--- linux-3.8.13/arch/x86/include/asm/pgtable_types.h	2013-02-19 01:12:51.673766648 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/pgtable_types.h	2013-02-19 01:14:43.105772700 +0100
@@ -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)
@@ -57,8 +55,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)
@@ -116,6 +116,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)
@@ -126,7 +129,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)
@@ -188,8 +191,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
 
@@ -227,7 +230,17 @@ static inline pgdval_t pgd_flags(pgd_t p
 {
 	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;
 
@@ -241,8 +254,6 @@ static inline pudval_t native_pud_val(pu
 	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);
@@ -262,8 +273,6 @@ static inline pmdval_t native_pmd_val(pm
 	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);
@@ -303,7 +312,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/processor.h linux-3.8.13-pax/arch/x86/include/asm/processor.h
--- linux-3.8.13/arch/x86/include/asm/processor.h	2013-02-19 01:12:51.677766648 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/processor.h	2013-02-19 01:14:43.105772700 +0100
@@ -287,7 +287,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
@@ -827,11 +827,18 @@ static inline void spin_lock_prefetch(co
  */
 #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,					  \
@@ -845,7 +852,7 @@ static inline void spin_lock_prefetch(co
  */
 #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,		  \
@@ -856,11 +863,7 @@ static inline void spin_lock_prefetch(co
 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.
@@ -875,7 +878,7 @@ extern unsigned long thread_saved_pc(str
 #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;                                                   \
 })
 
@@ -885,13 +888,13 @@ extern unsigned long thread_saved_pc(str
 /*
  * 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)
@@ -902,11 +905,11 @@ extern unsigned long thread_saved_pc(str
 #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 \
 }
 
 /*
@@ -934,6 +937,10 @@ extern void start_thread(struct pt_regs
  */
 #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 */
@@ -994,12 +1001,12 @@ extern bool cpu_has_amd_erratum(const in
 #define cpu_has_amd_erratum(x)	(false)
 #endif /* CONFIG_CPU_SUP_AMD */
 
-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);
 bool set_pm_idle_to_default(void);
 
-void stop_this_cpu(void *dummy);
+void stop_this_cpu(void *dummy) __noreturn;
 
 #endif /* _ASM_X86_PROCESSOR_H */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/ptrace.h linux-3.8.13-pax/arch/x86/include/asm/ptrace.h
--- linux-3.8.13/arch/x86/include/asm/ptrace.h	2013-02-19 01:12:51.681766648 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/ptrace.h	2013-02-19 01:14:43.105772700 +0100
@@ -85,28 +85,29 @@ static inline unsigned long regs_return_
 }
 
 /*
- * 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_r
 #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_reg
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/realmode.h linux-3.8.13-pax/arch/x86/include/asm/realmode.h
--- linux-3.8.13/arch/x86/include/asm/realmode.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/realmode.h	2013-02-19 01:14:43.105772700 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/reboot.h linux-3.8.13-pax/arch/x86/include/asm/reboot.h
--- linux-3.8.13/arch/x86/include/asm/reboot.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/reboot.h	2013-02-19 01:14:43.105772700 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/rwsem.h linux-3.8.13-pax/arch/x86/include/asm/rwsem.h
--- linux-3.8.13/arch/x86/include/asm/rwsem.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/rwsem.h	2013-02-19 01:14:43.109772700 +0100
@@ -64,6 +64,14 @@ static inline void __down_read(struct rw
 {
 	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(st
 		     "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(s
 	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      %1,%1\n\t"
 		     /* was the count 0 before? */
@@ -141,6 +165,14 @@ static inline void __up_read(struct rw_s
 	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 */
@@ -159,6 +191,14 @@ static inline void __up_write(struct rw_
 	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 */
@@ -176,6 +216,14 @@ static inline void __downgrade_write(str
 {
 	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)
@@ -194,7 +242,15 @@ static inline void __downgrade_write(str
  */
 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));
 }
@@ -204,7 +260,7 @@ static inline void rwsem_atomic_add(long
  */
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/segment.h linux-3.8.13-pax/arch/x86/include/asm/segment.h
--- linux-3.8.13/arch/x86/include/asm/segment.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/segment.h	2013-02-19 01:14:43.109772700 +0100
@@ -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
@@ -185,6 +200,7 @@
 #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 __USER_DS	(GDT_ENTRY_DEFAULT_USER_DS*8+3)
 #define __USER_CS	(GDT_ENTRY_DEFAULT_USER_CS*8+3)
@@ -265,7 +281,7 @@ static inline unsigned long get_limit(un
 {
 	unsigned long __limit;
 	asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
-	return __limit + 1;
+	return __limit;
 }
 
 #endif /* !__ASSEMBLY__ */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/smp.h linux-3.8.13-pax/arch/x86/include/asm/smp.h
--- linux-3.8.13/arch/x86/include/asm/smp.h	2013-02-19 01:12:51.697766649 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/smp.h	2013-02-19 01:14:43.109772700 +0100
@@ -36,7 +36,7 @@ DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_
 /* 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 __cpuinitd
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/spinlock.h linux-3.8.13-pax/arch/x86/include/asm/spinlock.h
--- linux-3.8.13/arch/x86/include/asm/spinlock.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/spinlock.h	2013-02-19 01:14:43.109772700 +0100
@@ -172,6 +172,14 @@ static inline int arch_write_can_lock(ar
 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_r
 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(arc
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/stackprotector.h linux-3.8.13-pax/arch/x86/include/asm/stackprotector.h
--- linux-3.8.13/arch/x86/include/asm/stackprotector.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/stackprotector.h	2013-02-19 01:14:43.109772700 +0100
@@ -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_se
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/stacktrace.h linux-3.8.13-pax/arch/x86/include/asm/stacktrace.h
--- linux-3.8.13/arch/x86/include/asm/stacktrace.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/stacktrace.h	2013-02-19 01:14:43.109772700 +0100
@@ -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);
-
-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);
+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 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/switch_to.h linux-3.8.13-pax/arch/x86/include/asm/switch_to.h
--- linux-3.8.13/arch/x86/include/asm/switch_to.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/switch_to.h	2013-02-19 01:14:43.113772700 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/thread_info.h linux-3.8.13-pax/arch/x86/include/asm/thread_info.h
--- linux-3.8.13/arch/x86/include/asm/thread_info.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/thread_info.h	2013-02-19 01:14:43.113772700 +0100
@@ -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
@@ -24,7 +25,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 */
@@ -34,19 +34,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,			\
@@ -57,7 +51,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__ */
@@ -159,6 +153,23 @@ struct thread_info {
 
 #define PREEMPT_ACTIVE		0x10000000
 
+#ifdef __ASSEMBLY__
+/* how to get the thread information struct from ASM */
+#define GET_THREAD_INFO(reg)	 \
+	mov PER_CPU_VAR(current_tinfo), reg
+
+/* use this one if reg already contains %esp */
+#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)
@@ -169,35 +180,13 @@ struct thread_info {
  */
 #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__ */
-
-/* how to get the thread information struct from ASM */
-#define GET_THREAD_INFO(reg)	 \
-	movl $-THREAD_SIZE, reg; \
-	andl %esp, reg
-
-/* use this one if reg already contains %esp */
-#define GET_THREAD_INFO_WITH_ESP(reg) \
-	andl $-THREAD_SIZE, reg
-
 #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.
@@ -205,27 +194,8 @@ static inline struct thread_info *curren
 #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 */
@@ -286,5 +256,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/uaccess_32.h linux-3.8.13-pax/arch/x86/include/asm/uaccess_32.h
--- linux-3.8.13/arch/x86/include/asm/uaccess_32.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/uaccess_32.h	2013-02-19 01:14:43.113772700 +0100
@@ -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_u
 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 __m
 __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 __c
 				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;
 
-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);
+	return __copy_from_user_ll_nocache_nozero(to, from, 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)
-{
-	int sz = __compiletime_object_size(to);
-
-	if (likely(sz == -1 || sz >= n))
-		n = _copy_from_user(to, from, n);
-	else
-		copy_from_user_overflow();
+/**
+ * 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)
+{
+	size_t sz = __compiletime_object_size(from);
+
+	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/uaccess_64.h linux-3.8.13-pax/arch/x86/include/asm/uaccess_64.h
--- linux-3.8.13/arch/x86/include/asm/uaccess_64.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/uaccess_64.h	2013-03-30 22:03:50.347071327 +0100
@@ -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 *
 			 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, con
 	}
 	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, con
 
 	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, con
 	}
 	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,72 @@ int __copy_in_user(void __user *dst, con
 		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)
+__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_sleep();
+
+	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
-__copy_from_user_inatomic_nocache(void *dst, const void __user *src,
-				  unsigned size)
+static inline unsigned long __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
+				  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);
+extern unsigned long
+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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/uaccess.h linux-3.8.13-pax/arch/x86/include/asm/uaccess.h
--- linux-3.8.13/arch/x86/include/asm/uaccess.h	2013-02-19 01:12:51.733766651 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/uaccess.h	2013-05-06 09:59:06.685055829 +0200
@@ -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
@@ -189,13 +220,21 @@ extern int __get_user_bad(void);
 	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"				\
@@ -208,8 +247,8 @@ extern int __get_user_bad(void);
 
 #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)				\
@@ -259,7 +298,7 @@ extern void __put_user_8(void);
 	__typeof__(*(ptr)) __pu_val;				\
 	__chk_user_ptr(ptr);					\
 	might_fault();						\
-	__pu_val = x;						\
+	__pu_val = (x);						\
 	switch (sizeof(*(ptr))) {				\
 	case 1:							\
 		__put_user_x(1, __pu_val, ptr, __ret_pu);	\
@@ -358,7 +397,7 @@ do {									\
 
 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
 	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"				\
@@ -366,7 +405,7 @@ do {									\
 		     "	jmp 2b\n"					\
 		     ".previous\n"					\
 		     _ASM_EXTABLE(1b, 3b)				\
-		     : "=r" (err), ltype(x)				\
+		     : "=r" (err), ltype (x)				\
 		     : "m" (__m(addr)), "i" (errret), "0" (err))
 
 #define __get_user_size_ex(x, ptr, size)				\
@@ -391,7 +430,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)))
@@ -408,13 +447,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
@@ -423,7 +473,7 @@ struct __large_struct { unsigned long bu
  */
 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\
 	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"				\
@@ -431,10 +481,10 @@ struct __large_struct { unsigned long bu
 		     ".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))
 
 #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)))
@@ -473,8 +523,12 @@ struct __large_struct { unsigned long bu
  * 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.
@@ -496,8 +550,12 @@ struct __large_struct { unsigned long bu
  * 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
@@ -515,7 +573,7 @@ struct __large_struct { unsigned long bu
 #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
@@ -532,8 +590,8 @@ strncpy_from_user(char *dst, const char
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/word-at-a-time.h linux-3.8.13-pax/arch/x86/include/asm/word-at-a-time.h
--- linux-3.8.13/arch/x86/include/asm/word-at-a-time.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/word-at-a-time.h	2013-02-19 01:14:43.113772700 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/x86_init.h linux-3.8.13-pax/arch/x86/include/asm/x86_init.h
--- linux-3.8.13/arch/x86/include/asm/x86_init.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/x86_init.h	2013-02-19 01:14:43.117772701 +0100
@@ -141,7 +141,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
@@ -152,7 +152,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 x86_platform_ops - platform specific runtime functions
@@ -178,7 +178,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;
 
@@ -187,14 +187,14 @@ struct x86_msi_ops {
 	void (*teardown_msi_irq)(unsigned int irq);
 	void (*teardown_msi_irqs)(struct pci_dev *dev);
 	void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
-};
+} __no_const;
 
 struct x86_io_apic_ops {
 	void		(*init)  (void);
 	unsigned int	(*read)  (unsigned int apic, unsigned int reg);
 	void		(*write) (unsigned int apic, unsigned int reg, unsigned int value);
 	void		(*modify)(unsigned int apic, unsigned int reg, unsigned int value);
-};
+} __no_const;
 
 extern struct x86_init_ops x86_init;
 extern struct x86_cpuinit_ops x86_cpuinit;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/asm/xsave.h linux-3.8.13-pax/arch/x86/include/asm/xsave.h
--- linux-3.8.13/arch/x86/include/asm/xsave.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/include/asm/xsave.h	2013-02-19 01:14:43.117772701 +0100
@@ -71,7 +71,9 @@ static inline int xsave_user(struct xsav
 		return -EFAULT;
 
 	__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"
@@ -87,12 +89,14 @@ static inline int xsave_user(struct xsav
 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;
 
 	__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"
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/include/uapi/asm/e820.h linux-3.8.13-pax/arch/x86/include/uapi/asm/e820.h
--- linux-3.8.13/arch/x86/include/uapi/asm/e820.h	2013-02-19 01:12:51.761766653 +0100
+++ linux-3.8.13-pax/arch/x86/include/uapi/asm/e820.h	2013-02-19 01:14:43.117772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/Kconfig linux-3.8.13-pax/arch/x86/Kconfig
--- linux-3.8.13/arch/x86/Kconfig	2013-03-07 04:10:19.703802304 +0100
+++ linux-3.8.13-pax/arch/x86/Kconfig	2013-04-15 03:05:47.640879936 +0200
@@ -238,7 +238,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
@@ -1145,7 +1145,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
@@ -1542,6 +1542,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
@@ -1662,6 +1663,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
@@ -1737,9 +1740,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/Kconfig.cpu linux-3.8.13-pax/arch/x86/Kconfig.cpu
--- linux-3.8.13/arch/x86/Kconfig.cpu	2013-02-19 01:12:51.421766634 +0100
+++ linux-3.8.13-pax/arch/x86/Kconfig.cpu	2013-02-19 01:14:43.117772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/Kconfig.debug linux-3.8.13-pax/arch/x86/Kconfig.debug
--- linux-3.8.13/arch/x86/Kconfig.debug	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/Kconfig.debug	2013-02-19 01:14:43.117772701 +0100
@@ -84,7 +84,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
@@ -102,7 +102,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
@@ -294,7 +294,7 @@ config OPTIMIZE_INLINING
 
 config DEBUG_STRICT_USER_COPY_CHECKS
 	bool "Strict copy size checks"
-	depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING
+	depends on DEBUG_KERNEL && !TRACE_BRANCH_PROFILING && BROKEN
 	---help---
 	  Enabling this option turns a certain set of sanity checks for user
 	  copy operations into compile time failures.
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/acpi/boot.c linux-3.8.13-pax/arch/x86/kernel/acpi/boot.c
--- linux-3.8.13/arch/x86/kernel/acpi/boot.c	2013-02-19 01:12:51.797766655 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/acpi/boot.c	2013-03-07 03:14:50.039980082 +0100
@@ -1358,7 +1358,7 @@ static int __init dmi_ignore_irq0_timer_
  * If your system is blacklisted here, but you find that acpi=force
  * works for you, please contact linux-acpi@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
 	 */
@@ -1433,7 +1433,7 @@ static struct dmi_system_id __initdata a
 };
 
 /* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/acpi/sleep.c linux-3.8.13-pax/arch/x86/kernel/acpi/sleep.c
--- linux-3.8.13/arch/x86/kernel/acpi/sleep.c	2013-02-19 01:12:51.809766655 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/acpi/sleep.c	2013-02-19 01:14:43.121772701 +0100
@@ -74,8 +74,12 @@ int 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/acpi/wakeup_32.S linux-3.8.13-pax/arch/x86/kernel/acpi/wakeup_32.S
--- linux-3.8.13/arch/x86/kernel/acpi/wakeup_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/acpi/wakeup_32.S	2013-02-19 01:14:43.121772701 +0100
@@ -30,13 +30,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/alternative.c linux-3.8.13-pax/arch/x86/kernel/alternative.c
--- linux-3.8.13/arch/x86/kernel/alternative.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/alternative.c	2013-02-19 01:14:43.121772701 +0100
@@ -268,6 +268,13 @@ void __init_or_module apply_alternatives
 	 */
 	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
 	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(cons
 	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(str
 
 		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(voi
 	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(voi
  * 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(v
  */
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/apic.c linux-3.8.13-pax/arch/x86/kernel/apic/apic.c
--- linux-3.8.13/arch/x86/kernel/apic/apic.c	2013-03-07 04:10:19.707802304 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/apic.c	2013-02-19 14:41:31.659174883 +0100
@@ -189,7 +189,7 @@ int first_system_vector = 0xfe;
 /*
  * Debug level, exported for io_apic.c
  */
-unsigned int apic_verbosity;
+int apic_verbosity;
 
 int pic_mode;
 
@@ -1956,7 +1956,7 @@ void smp_error_interrupt(struct pt_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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/apic_flat_64.c linux-3.8.13-pax/arch/x86/kernel/apic/apic_flat_64.c
--- linux-3.8.13/arch/x86/kernel/apic/apic_flat_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/apic_flat_64.c	2013-02-19 01:14:43.121772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/apic_noop.c linux-3.8.13-pax/arch/x86/kernel/apic/apic_noop.c
--- linux-3.8.13/arch/x86/kernel/apic/apic_noop.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/apic_noop.c	2013-03-06 04:23:30.896089883 +0100
@@ -119,7 +119,7 @@ static void noop_apic_write(u32 reg, u32
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/bigsmp_32.c linux-3.8.13-pax/arch/x86/kernel/apic/bigsmp_32.c
--- linux-3.8.13/arch/x86/kernel/apic/bigsmp_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/bigsmp_32.c	2013-02-19 01:14:43.121772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/es7000_32.c linux-3.8.13-pax/arch/x86/kernel/apic/es7000_32.c
--- linux-3.8.13/arch/x86/kernel/apic/es7000_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/es7000_32.c	2013-02-22 23:23:27.282512393 +0100
@@ -608,8 +608,7 @@ static int es7000_mps_oem_check_cluster(
 	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
 	.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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/io_apic.c linux-3.8.13-pax/arch/x86/kernel/apic/io_apic.c
--- linux-3.8.13/arch/x86/kernel/apic/io_apic.c	2013-02-19 01:12:51.829766656 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/io_apic.c	2013-03-05 22:18:20.085259751 +0100
@@ -1084,7 +1084,7 @@ int IO_APIC_get_PCI_irq_vector(int bus,
 }
 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.
@@ -1092,7 +1092,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);
 }
@@ -2399,7 +2399,7 @@ static void ack_apic_edge(struct irq_dat
 	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)
@@ -2540,7 +2540,7 @@ static void ack_apic_level(struct irq_da
 	 * at the cpu.
 	 */
 	if (!(v & (1 << (i & 0x1f)))) {
-		atomic_inc(&irq_mis_count);
+		atomic_inc_unchecked(&irq_mis_count);
 
 		eoi_ioapic_irq(irq, cfg);
 	}
@@ -2567,11 +2567,13 @@ static void ir_print_prefix(struct irq_d
 
 static void irq_remap_modify_chip_defaults(struct irq_chip *chip)
 {
-	chip->irq_print_chip = ir_print_prefix;
-	chip->irq_ack = ir_ack_apic_edge;
-	chip->irq_eoi = ir_ack_apic_level;
+	pax_open_kernel();
+	*(void **)&chip->irq_print_chip = ir_print_prefix;
+	*(void **)&chip->irq_ack = ir_ack_apic_edge;
+	*(void **)&chip->irq_eoi = ir_ack_apic_level;
 
-	chip->irq_set_affinity = set_remapped_irq_affinity;
+	*(void **)&chip->irq_set_affinity = set_remapped_irq_affinity;
+	pax_close_kernel();
 }
 #endif /* CONFIG_IRQ_REMAP */
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/numaq_32.c linux-3.8.13-pax/arch/x86/kernel/apic/numaq_32.c
--- linux-3.8.13/arch/x86/kernel/apic/numaq_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/numaq_32.c	2013-02-19 01:14:43.125772701 +0100
@@ -455,8 +455,7 @@ static void numaq_setup_portio_remap(voi
 		(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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/probe_32.c linux-3.8.13-pax/arch/x86/kernel/apic/probe_32.c
--- linux-3.8.13/arch/x86/kernel/apic/probe_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/probe_32.c	2013-02-19 01:14:43.125772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/summit_32.c linux-3.8.13-pax/arch/x86/kernel/apic/summit_32.c
--- linux-3.8.13/arch/x86/kernel/apic/summit_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/summit_32.c	2013-02-19 01:14:43.125772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/x2apic_cluster.c linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_cluster.c
--- linux-3.8.13/arch/x86/kernel/apic/x2apic_cluster.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_cluster.c	2013-02-20 01:06:27.314068358 +0100
@@ -183,7 +183,7 @@ update_clusterinfo(struct notifier_block
 	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_do
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/x2apic_phys.c linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_phys.c
--- linux-3.8.13/arch/x86/kernel/apic/x2apic_phys.c	2013-02-19 01:12:51.829766656 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_phys.c	2013-02-19 01:14:43.125772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apic/x2apic_uv_x.c linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-3.8.13/arch/x86/kernel/apic/x2apic_uv_x.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apic/x2apic_uv_x.c	2013-02-19 01:14:43.129772701 +0100
@@ -333,7 +333,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/apm_32.c linux-3.8.13-pax/arch/x86/kernel/apm_32.c
--- linux-3.8.13/arch/x86/kernel/apm_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/apm_32.c	2013-02-19 01:14:43.129772701 +0100
@@ -412,7 +412,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 */
@@ -590,7 +590,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;
@@ -599,7 +602,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;
@@ -666,7 +673,10 @@ static long __apm_bios_call_simple(void
 	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;
@@ -674,7 +684,11 @@ static long __apm_bios_call_simple(void
 					 &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;
 }
@@ -2345,12 +2359,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/asm-offsets_64.c linux-3.8.13-pax/arch/x86/kernel/asm-offsets_64.c
--- linux-3.8.13/arch/x86/kernel/asm-offsets_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/asm-offsets_64.c	2013-02-19 01:14:43.129772701 +0100
@@ -76,6 +76,7 @@ int main(void)
 	BLANK();
 #undef ENTRY
 
+	DEFINE(TSS_size, sizeof(struct tss_struct));
 	OFFSET(TSS_ist, tss_struct, x86_tss.ist);
 	BLANK();
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/asm-offsets.c linux-3.8.13-pax/arch/x86/kernel/asm-offsets.c
--- linux-3.8.13/arch/x86/kernel/asm-offsets.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/asm-offsets.c	2013-02-19 01:14:43.129772701 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/amd.c linux-3.8.13-pax/arch/x86/kernel/cpu/amd.c
--- linux-3.8.13/arch/x86/kernel/cpu/amd.c	2013-02-19 01:12:51.841766657 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/amd.c	2013-02-19 01:14:43.129772701 +0100
@@ -733,7 +733,7 @@ static unsigned int __cpuinit amd_size_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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/common.c linux-3.8.13-pax/arch/x86/kernel/cpu/common.c
--- linux-3.8.13/arch/x86/kernel/cpu/common.c	2013-02-19 01:12:51.853766658 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/common.c	2013-02-19 01:14:43.133772702 +0100
@@ -86,60 +86,6 @@ static const struct cpu_dev __cpuinitcon
 
 static const struct cpu_dev *this_cpu __cpuinitdata = &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);
@@ -389,7 +335,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 */
@@ -885,6 +831,10 @@ static void __cpuinit identify_cpu(struc
 	/* 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;
@@ -1068,10 +1018,12 @@ static __init int setup_disablecpuid(cha
 }
 __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 nmi_idt_descr = { NR_VECTORS * 16 - 1,
-				    (unsigned long) nmi_idt_table };
+struct desc_ptr nmi_idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) nmi_idt_table };
 
 DEFINE_PER_CPU_FIRST(union irq_stack_union,
 		     irq_stack_union) __aligned(PAGE_SIZE);
@@ -1085,7 +1037,7 @@ DEFINE_PER_CPU(struct task_struct *, cur
 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) =
@@ -1224,7 +1176,7 @@ void __cpuinit cpu_init(void)
 	int i;
 
 	cpu = stack_smp_processor_id();
-	t = &per_cpu(init_tss, cpu);
+	t = init_tss + cpu;
 	oist = &per_cpu(orig_ist, cpu);
 
 #ifdef CONFIG_NUMA
@@ -1250,7 +1202,7 @@ void __cpuinit cpu_init(void)
 	switch_to_new_gdt(cpu);
 	loadsegment(fs, 0);
 
-	load_idt((const struct desc_ptr *)&idt_descr);
+	load_idt(&idt_descr);
 
 	memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
 	syscall_init();
@@ -1259,7 +1211,6 @@ void __cpuinit cpu_init(void)
 	wrmsrl(MSR_KERNEL_GS_BASE, 0);
 	barrier();
 
-	x86_configure_nx();
 	enable_x2apic();
 
 	/*
@@ -1311,7 +1262,7 @@ void __cpuinit 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;
 
 	if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/intel.c linux-3.8.13-pax/arch/x86/kernel/cpu/intel.c
--- linux-3.8.13/arch/x86/kernel/cpu/intel.c	2013-02-19 01:12:51.853766658 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/intel.c	2013-02-19 01:14:43.133772702 +0100
@@ -174,7 +174,7 @@ static void __cpuinit trap_init_f00f_bug
 	 * Update the IDT descriptor and reload the IDT so that
 	 * it uses the read-only mapped virtual address.
 	 */
-	idt_descr.address = fix_to_virt(FIX_F00F_IDT);
+	idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
 	load_idt(&idt_descr);
 }
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/intel_cacheinfo.c linux-3.8.13-pax/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-3.8.13/arch/x86/kernel/cpu/intel_cacheinfo.c	2013-02-19 01:12:51.869766659 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/intel_cacheinfo.c	2013-02-20 01:07:11.722065987 +0100
@@ -1017,6 +1017,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 ** __cpuinit amd_l3_attrs(void)
 {
 	static struct attribute **attrs;
@@ -1027,18 +1043,7 @@ static struct attribute ** __cpuinit amd
 
 	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;
@@ -1089,6 +1094,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,
 };
@@ -1154,20 +1166,26 @@ static int __cpuinit cache_add_dev(struc
 		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)) {
@@ -1222,7 +1240,7 @@ static int __cpuinit cacheinfo_cpu_callb
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
+static struct notifier_block cacheinfo_cpu_notifier = {
 	.notifier_call = cacheinfo_cpu_callback,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/Makefile linux-3.8.13-pax/arch/x86/kernel/cpu/Makefile
--- linux-3.8.13/arch/x86/kernel/cpu/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/Makefile	2013-02-19 01:14:43.133772702 +0100
@@ -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			+= vmware.o hypervisor.o mshyperv.o
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mcheck/mce.c linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-3.8.13/arch/x86/kernel/cpu/mcheck/mce.c	2013-02-19 01:12:51.893766660 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/mce.c	2013-02-21 04:41:26.461062143 +0100
@@ -45,6 +45,7 @@
 #include <asm/processor.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
+#include <asm/local.h>
 
 #include "mce-internal.h"
 
@@ -246,7 +247,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");
 	}
@@ -279,10 +280,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)
@@ -306,7 +307,7 @@ static void mce_panic(char *msg, struct
 		/*
 		 * 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();
 
@@ -314,7 +315,7 @@ static void mce_panic(char *msg, struct
 		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 */
@@ -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;
@@ -1662,7 +1663,7 @@ static void unexpected_machine_check(str
 }
 
 /* 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;
 
 /*
@@ -1685,7 +1686,9 @@ void __cpuinit mcheck_cpu_init(struct cp
 		return;
 	}
 
+	pax_open_kernel();
 	machine_check_vector = do_machine_check;
+	pax_close_kernel();
 
 	__mcheck_cpu_init_generic();
 	__mcheck_cpu_init_vendor(c);
@@ -1699,7 +1702,7 @@ void __cpuinit mcheck_cpu_init(struct cp
  */
 
 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)
@@ -1707,7 +1710,7 @@ static int mce_chrdev_open(struct inode
 	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;
@@ -1715,7 +1718,7 @@ static int mce_chrdev_open(struct inode
 
 	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);
 
@@ -1726,7 +1729,7 @@ static int mce_chrdev_release(struct ino
 {
 	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);
@@ -2372,7 +2375,7 @@ mce_cpu_callback(struct notifier_block *
 	return NOTIFY_OK;
 }
 
-static struct notifier_block mce_cpu_notifier __cpuinitdata = {
+static struct notifier_block mce_cpu_notifier = {
 	.notifier_call = mce_cpu_callback,
 };
 
@@ -2382,7 +2385,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;
@@ -2450,7 +2453,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mcheck/p5.c linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/p5.c
--- linux-3.8.13/arch/x86/kernel/cpu/mcheck/p5.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/p5.c	2013-02-19 01:14:43.133772702 +0100
@@ -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
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mcheck/therm_throt.c linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/therm_throt.c
--- linux-3.8.13/arch/x86/kernel/cpu/mcheck/therm_throt.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/therm_throt.c	2013-02-20 01:07:16.890065711 +0100
@@ -288,7 +288,7 @@ thermal_throttle_cpu_callback(struct not
 	return notifier_from_errno(err);
 }
 
-static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata =
+static struct notifier_block thermal_throttle_cpu_notifier =
 {
 	.notifier_call = thermal_throttle_cpu_callback,
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mcheck/winchip.c linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/winchip.c
--- linux-3.8.13/arch/x86/kernel/cpu/mcheck/winchip.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mcheck/winchip.c	2013-02-19 01:14:43.137772702 +0100
@@ -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_
 {
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mtrr/main.c linux-3.8.13-pax/arch/x86/kernel/cpu/mtrr/main.c
--- linux-3.8.13/arch/x86/kernel/cpu/mtrr/main.c	2013-02-19 01:12:51.909766661 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mtrr/main.c	2013-02-19 01:14:43.137772702 +0100
@@ -62,7 +62,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/mtrr/mtrr.h linux-3.8.13-pax/arch/x86/kernel/cpu/mtrr/mtrr.h
--- linux-3.8.13/arch/x86/kernel/cpu/mtrr/mtrr.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/mtrr/mtrr.h	2013-02-19 01:14:43.137772702 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/perf_event.c linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event.c
--- linux-3.8.13/arch/x86/kernel/cpu/perf_event.c	2013-02-19 01:12:51.909766661 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event.c	2013-03-06 00:20:04.888869731 +0100
@@ -1305,7 +1305,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,
 };
@@ -1313,7 +1313,7 @@ static struct attribute_group x86_pmu_fo
 struct perf_pmu_events_attr {
 	struct device_attribute attr;
 	u64 id;
-};
+} __do_const;
 
 /*
  * Remove all undefined events (x86_pmu.event_map(id) == 0)
@@ -1381,7 +1381,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,
 };
@@ -1880,7 +1880,7 @@ static unsigned long get_segment_base(un
 		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);
@@ -1970,7 +1970,7 @@ perf_callchain_user(struct perf_callchai
 			break;
 
 		perf_callchain_store(entry, frame.return_address);
-		fp = frame.next_frame;
+		fp = (const void __force_user *)frame.next_frame;
 	}
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel.c linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel.c	2013-04-30 00:04:57.167843284 +0200
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel.c	2013-04-30 00:05:40.671840962 +0200
@@ -1964,10 +1964,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel_uncore.c linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel_uncore.c
--- linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel_uncore.c	2013-05-13 02:47:11.137794596 +0200
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel_uncore.c	2013-05-13 02:51:11.397781768 +0200
@@ -2428,7 +2428,7 @@ static void __init uncore_types_exit(str
 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;
 
@@ -2826,7 +2826,7 @@ static int
 	return NOTIFY_OK;
 }
 
-static struct notifier_block uncore_cpu_nb __cpuinitdata = {
+static struct notifier_block uncore_cpu_nb = {
 	.notifier_call	= uncore_cpu_notifier,
 	/*
 	 * to migrate uncore events, our notifier should be executed
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel_uncore.h linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel_uncore.h
--- linux-3.8.13/arch/x86/kernel/cpu/perf_event_intel_uncore.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpu/perf_event_intel_uncore.h	2013-02-22 04:33:09.369183670 +0100
@@ -428,7 +428,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/cpuid.c linux-3.8.13-pax/arch/x86/kernel/cpuid.c
--- linux-3.8.13/arch/x86/kernel/cpuid.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/cpuid.c	2013-02-20 01:07:07.326066222 +0100
@@ -171,7 +171,7 @@ static int __cpuinit cpuid_class_cpu_cal
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/crash.c linux-3.8.13-pax/arch/x86/kernel/crash.c
--- linux-3.8.13/arch/x86/kernel/crash.c	2013-02-19 01:12:51.941766662 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/crash.c	2013-02-19 01:14:43.137772702 +0100
@@ -58,10 +58,8 @@ static void kdump_nmi_callback(int cpu,
 {
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/doublefault_32.c linux-3.8.13-pax/arch/x86/kernel/doublefault_32.c
--- linux-3.8.13/arch/x86/kernel/doublefault_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/doublefault_32.c	2013-02-19 01:14:43.137772702 +0100
@@ -11,7 +11,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)
 
@@ -21,7 +21,7 @@ static void doublefault_fn(void)
 	unsigned long gdt, tss;
 
 	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);
 
@@ -58,10 +58,10 @@ struct tss_struct doublefault_tss __cach
 		/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/dumpstack_32.c linux-3.8.13-pax/arch/x86/kernel/dumpstack_32.c
--- linux-3.8.13/arch/x86/kernel/dumpstack_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/dumpstack_32.c	2013-02-19 01:14:43.141772702 +0100
@@ -38,15 +38,13 @@ void dump_trace(struct task_struct *task
 		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();
@@ -86,7 +84,7 @@ void show_regs(struct pt_regs *regs)
 {
 	int i;
 
-	__show_regs(regs, !user_mode_vm(regs));
+	__show_regs(regs, !user_mode(regs));
 
 	pr_emerg("Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n",
 		 TASK_COMM_LEN, current->comm, task_pid_nr(current),
@@ -95,21 +93,22 @@ void show_regs(struct pt_regs *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++) {
@@ -118,7 +117,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);
@@ -131,6 +130,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))
@@ -138,3 +138,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/dumpstack_64.c linux-3.8.13-pax/arch/x86/kernel/dumpstack_64.c
--- linux-3.8.13/arch/x86/kernel/dumpstack_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/dumpstack_64.c	2013-02-19 01:14:43.141772702 +0100
@@ -119,9 +119,9 @@ void dump_trace(struct task_struct *task
 	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
 	 * 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
 			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
 			 * 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
 			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
 	/*
 	 * 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);
@@ -249,7 +253,7 @@ void show_regs(struct pt_regs *regs)
 {
 	int i;
 	unsigned long sp;
-	const int cpu = smp_processor_id();
+	const int cpu = raw_smp_processor_id();
 	struct task_struct *cur = current;
 
 	sp = regs->sp;
@@ -304,3 +308,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/dumpstack.c linux-3.8.13-pax/arch/x86/kernel/dumpstack.c
--- linux-3.8.13/arch/x86/kernel/dumpstack.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/dumpstack.c	2013-02-19 01:14:43.141772702 +0100
@@ -35,16 +35,14 @@ void printk_address(unsigned long addres
 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 +59,7 @@ print_ftrace_graph_addr(unsigned long ad
 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 +70,8 @@ print_ftrace_graph_addr(unsigned long ad
  * 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 +82,14 @@ static inline int valid_stack_ptr(struct
 }
 
 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 +101,7 @@ print_context_stack(struct thread_info *
 			} 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 +110,7 @@ print_context_stack(struct thread_info *
 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 +118,7 @@ print_context_stack_bp(struct thread_inf
 	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 +127,7 @@ print_context_stack_bp(struct thread_inf
 		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;
@@ -189,7 +185,7 @@ void dump_stack(void)
 
 	bp = stack_frame(current, NULL);
 	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
-		current->pid, current->comm, print_tainted(),
+		task_pid_nr(current), current->comm, print_tainted(),
 		init_utsname()->release,
 		(int)strcspn(init_utsname()->version, " "),
 		init_utsname()->version);
@@ -246,7 +242,7 @@ void __kprobes oops_end(unsigned long fl
 		panic("Fatal exception in interrupt");
 	if (panic_on_oops)
 		panic("Fatal exception");
-	do_exit(signr);
+	do_group_exit(signr);
 }
 
 int __kprobes __die(const char *str, struct pt_regs *regs, long err)
@@ -274,7 +270,7 @@ int __kprobes __die(const char *str, str
 	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 {
@@ -302,7 +298,7 @@ void die(const char *str, struct pt_regs
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/early_printk.c linux-3.8.13-pax/arch/x86/kernel/early_printk.c
--- linux-3.8.13/arch/x86/kernel/early_printk.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/early_printk.c	2013-02-19 01:14:43.141772702 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/entry_32.S linux-3.8.13-pax/arch/x86/kernel/entry_32.S
--- linux-3.8.13/arch/x86/kernel/entry_32.S	2013-02-19 01:12:51.941766662 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/entry_32.S	2013-02-19 01:14:43.141772702 +0100
@@ -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 $0xB4DD00D5, %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
@@ -753,8 +985,15 @@ PTREGSCALL1(vm86old)
  * 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
@@ -807,7 +1046,7 @@ vector=vector+1
   .endr
 2:	jmp common_interrupt
 .endr
-END(irq_entries_start)
+ENDPROC(irq_entries_start)
 
 .previous
 END(interrupt)
@@ -858,7 +1097,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
@@ -880,7 +1119,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
@@ -889,18 +1128,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)
@@ -910,7 +1149,7 @@ ENTRY(overflow)
 	pushl_cfi $do_overflow
 	jmp error_code
 	CFI_ENDPROC
-END(overflow)
+ENDPROC(overflow)
 
 ENTRY(bounds)
 	RING0_INT_FRAME
@@ -919,7 +1158,7 @@ ENTRY(bounds)
 	pushl_cfi $do_bounds
 	jmp error_code
 	CFI_ENDPROC
-END(bounds)
+ENDPROC(bounds)
 
 ENTRY(invalid_op)
 	RING0_INT_FRAME
@@ -928,7 +1167,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
@@ -937,7 +1176,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
@@ -945,7 +1184,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
@@ -953,7 +1192,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
@@ -961,7 +1200,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
@@ -969,7 +1208,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
@@ -978,7 +1217,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)
@@ -988,7 +1227,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)
@@ -998,7 +1237,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
  */
@@ -1101,7 +1340,7 @@ BUILD_INTERRUPT3(xen_hvm_callback_vector
 
 ENTRY(mcount)
 	ret
-END(mcount)
+ENDPROC(mcount)
 
 ENTRY(ftrace_caller)
 	cmpl $0, function_trace_stop
@@ -1134,7 +1373,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) */
@@ -1235,7 +1474,7 @@ trace:
 	popl %ecx
 	popl %eax
 	jmp ftrace_stub
-END(mcount)
+ENDPROC(mcount)
 #endif /* CONFIG_DYNAMIC_FTRACE */
 #endif /* CONFIG_FUNCTION_TRACER */
 
@@ -1253,7 +1492,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:
@@ -1309,15 +1548,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
@@ -1360,7 +1602,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
@@ -1398,6 +1640,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
 
@@ -1434,12 +1679,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
@@ -1452,14 +1700,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)
@@ -1468,7 +1716,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/entry_64.S linux-3.8.13-pax/arch/x86/kernel/entry_64.S
--- linux-3.8.13/arch/x86/kernel/entry_64.S	2013-02-19 01:12:51.953766663 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/entry_64.S	2013-04-29 23:06:26.883996589 +0200
@@ -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,282 @@ 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
+#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)
+	pushq %rdi
+
+#ifdef CONFIG_PARAVIRT
+	PV_SAVE_REGS(CLBR_RDI)
+#endif
+
+	GET_CR0_INTO_RDI
+	bts $16,%rdi
+	jnc 3f
+	mov %cs,%edi
+	cmp $__KERNEL_CS,%edi
+	jnz 2f
+1:
+
+#ifdef CONFIG_PARAVIRT
+	PV_RESTORE_REGS(CLBR_RDI)
+#endif
+
+	popq %rdi
+	pax_force_retaddr
+	retq
+
+2:	ljmpq __KERNEL_CS,1b
+3:	ljmpq __KERNEXEC_KERNEL_CS,4f
+4:	SET_RDI_INTO_CR0
+	jmp 1b
+ENDPROC(pax_enter_kernel)
+
+ENTRY(pax_exit_kernel)
+	pushq %rdi
+
+#ifdef CONFIG_PARAVIRT
+	PV_SAVE_REGS(CLBR_RDI)
+#endif
+
+	mov %cs,%rdi
+	cmp $__KERNEXEC_KERNEL_CS,%edi
+	jz 2f
+	GET_CR0_INTO_RDI
+	bts $16,%rdi
+	jnc 4f
+1:
+
+#ifdef CONFIG_PARAVIRT
+	PV_RESTORE_REGS(CLBR_RDI);
+#endif
+
+	popq %rdi
+	pax_force_retaddr
+	retq
+
+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
+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
+	call pax_randomize_kstack
+	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
+
+	GET_CR3_INTO_RDI
+	mov %rdi,%rbx
+	add $__START_KERNEL_map,%rbx
+	sub phys_base(%rip),%rbx
+
+#ifdef CONFIG_PARAVIRT
+	pushq %rdi
+	cmpl $0, pv_info+PARAVIRT_enabled
+	jz 1f
+	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
+	jmp 2f
+1:
+#endif
+
+	i = 0
+	.rept USER_PGD_PTRS
+	movb $0,i*8(%rbx)
+	i = i + 1
+	.endr
+
+#ifdef CONFIG_PARAVIRT
+2:	popq %rdi
+#endif
+	SET_RDI_INTO_CR3
+
+#ifdef CONFIG_PAX_KERNEXEC
+	GET_CR0_INTO_RDI
+	bts $16,%rdi
+	SET_RDI_INTO_CR0
+#endif
+
+#ifdef CONFIG_PARAVIRT
+	PV_RESTORE_REGS(CLBR_RDI)
+#endif
+
+	popq %rbx
+	popq %rdi
+	pax_force_retaddr
+	retq
+ENDPROC(pax_enter_kernel_user)
+
+ENTRY(pax_exit_kernel_user)
+	push %rdi
+
+#ifdef CONFIG_PARAVIRT
+	pushq %rbx
+	PV_SAVE_REGS(CLBR_RDI)
+#endif
+
+#ifdef CONFIG_PAX_KERNEXEC
+	GET_CR0_INTO_RDI
+	btr $16,%rdi
+	jnc 3f
+	SET_RDI_INTO_CR0
+#endif
+
+	GET_CR3_INTO_RDI
+	add $__START_KERNEL_map,%rdi
+	sub phys_base(%rip),%rdi
+
+#ifdef CONFIG_PARAVIRT
+	cmpl $0, pv_info+PARAVIRT_enabled
+	jz 1f
+	mov %rdi,%rbx
+	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(%rdi)
+	i = i + 1
+	.endr
+
+#ifdef CONFIG_PARAVIRT
+2:	PV_RESTORE_REGS(CLBR_RDI)
+	popq %rbx
+#endif
+
+	popq %rdi
+	pax_force_retaddr
+	retq
+3:	ud2
+	jmp 3b
+ENDPROC(pax_exit_kernel_user)
+#endif
+
+.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 $0xB4DD00D5BADBABE5, %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 +660,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 +748,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 +783,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 +815,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 +840,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 +858,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 +895,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 +908,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 +934,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 +948,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 +1006,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 +1038,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 +1046,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 +1064,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 +1085,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 +1133,7 @@ int_restore_rest:
 	TRACE_IRQS_OFF
 	jmp int_with_check
 	CFI_ENDPROC
-END(system_call)
+ENDPROC(system_call)
 
 /*
  * Certain special system calls that need to save a complete full stack frame.
@@ -842,7 +1149,7 @@ ENTRY(\label)
 	call \func
 	jmp ptregscall_common
 	CFI_ENDPROC
-END(\label)
+ENDPROC(\label)
 	.endm
 
 	.macro FORK_LIKE func
@@ -856,9 +1163,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
 
 	FORK_LIKE  clone
@@ -875,9 +1183,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
@@ -891,7 +1200,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.
@@ -909,7 +1218,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)
@@ -975,7 +1284,7 @@ vector=vector+1
 2:	jmp common_interrupt
 .endr
 	CFI_ENDPROC
-END(irq_entries_start)
+ENDPROC(irq_entries_start)
 
 .previous
 END(interrupt)
@@ -995,6 +1304,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
 
@@ -1027,7 +1346,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 */
@@ -1049,12 +1368,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:
 	 */
@@ -1137,7 +1460,7 @@ ENTRY(retint_kernel)
 #endif
 
 	CFI_ENDPROC
-END(common_interrupt)
+ENDPROC(common_interrupt)
 /*
  * End of kprobes section
  */
@@ -1155,7 +1478,7 @@ ENTRY(\sym)
 	interrupt \do_sym
 	jmp ret_from_intr
 	CFI_ENDPROC
-END(\sym)
+ENDPROC(\sym)
 .endm
 
 #ifdef CONFIG_SMP
@@ -1211,12 +1534,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
@@ -1229,15 +1562,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
@@ -1248,14 +1591,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
@@ -1267,13 +1626,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 */
@@ -1287,13 +1656,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
@@ -1323,9 +1702,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"
@@ -1353,9 +1733,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
@@ -1393,7 +1774,7 @@ ENTRY(xen_do_hypervisor_callback)   # do
 	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.
@@ -1452,7 +1833,7 @@ ENTRY(xen_failsafe_callback)
 	SAVE_ALL
 	jmp error_exit
 	CFI_ENDPROC
-END(xen_failsafe_callback)
+ENDPROC(xen_failsafe_callback)
 
 apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
 	xen_hvm_callback_vector xen_evtchn_do_upcall
@@ -1501,16 +1882,31 @@ ENTRY(paranoid_exit)
 	TRACE_IRQS_OFF_DEBUG
 	testl %ebx,%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)
@@ -1539,7 +1935,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.
@@ -1566,12 +1962,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
 
 /*
@@ -1598,7 +1995,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) */
@@ -1618,7 +2015,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.
@@ -1676,9 +2073,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.
@@ -1712,8 +2111,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
@@ -1731,6 +2129,7 @@ nested_nmi_out:
 	CFI_RESTORE rdx
 
 	/* No need to check faults here */
+	pax_force_retaddr_bts
 	INTERRUPT_RETURN
 
 	CFI_RESTORE_STATE
@@ -1847,6 +2246,17 @@ end_repeat_nmi:
 	 */
 	movq %cr2, %r12
 
+#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
+
 	/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
 	movq %rsp,%rdi
 	movq $-1,%rsi
@@ -1862,23 +2272,34 @@ end_repeat_nmi:
 	testl %ebx,%ebx				/* swapgs needed? */
 	jnz nmi_restore
 nmi_swapgs:
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+	pax_exit_kernel_user
+#else
+	pax_exit_kernel
+#endif
 	SWAPGS_UNSAFE_STACK
+	RESTORE_ALL 6*8
+	/* Clear the NMI executing stack variable */
+	movq $0, 5*8(%rsp)
+	jmp irq_return
 nmi_restore:
+	pax_exit_kernel
 	/* Pop the extra iret frame at once */
 	RESTORE_ALL 6*8
+	pax_force_retaddr_bts
 
 	/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/ftrace.c linux-3.8.13-pax/arch/x86/kernel/ftrace.c
--- linux-3.8.13/arch/x86/kernel/ftrace.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/ftrace.c	2013-02-19 01:14:43.145772702 +0100
@@ -105,6 +105,8 @@ ftrace_modify_code_direct(unsigned long
 {
 	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_fun
 	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_fun
 	/* 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
 	 * kernel identity mapping to modify code.
 	 */
 	if (within(ip, (unsigned long)_text, (unsigned long)_etext))
-		ip = (unsigned long)__va(__pa(ip));
+		ip = (unsigned long)__va(__pa(ktla_ktva(ip)));
 
 	return probe_kernel_write((void *)ip, val, size);
 }
@@ -289,7 +291,7 @@ static int add_break(unsigned long ip, c
 	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, uns
 	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
 {
 	unsigned char code[MCOUNT_INSN_SIZE];
 
+	ip = ktla_ktva(ip);
+
 	if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
 		return -EFAULT;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/head32.c linux-3.8.13-pax/arch/x86/kernel/head32.c
--- linux-3.8.13/arch/x86/kernel/head32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/head32.c	2013-02-19 01:14:43.145772702 +0100
@@ -18,6 +18,7 @@
 #include <asm/io_apic.h>
 #include <asm/bios_ebda.h>
 #include <asm/tlbflush.h>
+#include <asm/boot.h>
 
 static void __init i386_default_early_setup(void)
 {
@@ -30,8 +31,7 @@ static void __init i386_default_early_se
 
 void __init i386_start_kernel(void)
 {
-	memblock_reserve(__pa_symbol(&_text),
-			 __pa_symbol(&__bss_stop) - __pa_symbol(&_text));
+	memblock_reserve(LOAD_PHYSICAL_ADDR, __pa_symbol(&__bss_stop) - LOAD_PHYSICAL_ADDR);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* Reserve INITRD */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/head_32.S linux-3.8.13-pax/arch/x86/kernel/head_32.S
--- linux-3.8.13/arch/x86/kernel/head_32.S	2013-02-19 01:12:51.965766664 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/head_32.S	2013-02-19 01:14:43.149772702 +0100
@@ -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_P
 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...
  */
@@ -196,8 +264,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);
@@ -227,8 +298,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
@@ -242,9 +316,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)
@@ -256,10 +328,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
@@ -335,6 +407,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 6f
 
@@ -363,6 +436,9 @@ default_entry:
 	/* Make changes effective */
 	wrmsr
 
+	btsl $_PAGE_BIT_NX-32,pa(__supported_pte_mask+4)
+#endif
+
 6:
 
 /*
@@ -460,14 +536,20 @@ is386:	movl $2,%ecx		# set MP
 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
@@ -544,8 +626,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)
@@ -576,7 +661,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
 
@@ -614,8 +699,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
@@ -634,8 +719,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
@@ -644,9 +732,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)
@@ -680,29 +765,43 @@ ENTRY(setup_once_ref)
 /*
  * BSS section
  */
-__PAGE_ALIGNED_BSS
-	.align PAGE_SIZE
 #ifdef CONFIG_X86_PAE
+.section .initial_pg_pmd,"a",@progbits
 initial_pg_pmd:
 	.fill 1024*KPMDS,4,0
 #else
+.section .initial_page_table,"a",@progbits
 ENTRY(initial_page_table)
 	.fill 1024,4,0
 #endif
+.section .initial_pg_fixmap,"a",@progbits
 initial_pg_fixmap:
 	.fill 1024,4,0
+.section .empty_zero_page,"a",@progbits
 ENTRY(empty_zero_page)
 	.fill 4096,1,0
+.section .swapper_pg_dir,"a",@progbits
 ENTRY(swapper_pg_dir)
+#ifdef CONFIG_X86_PAE
+	.fill 4,8,0
+#else
 	.fill 1024,4,0
+#endif
+
+/*
+ * The IDT has to be page-aligned to simplify the Pentium
+ * F0 0F bug workaround.. We have a special link segment
+ * for this.
+ */
+.section .idt,"a",@progbits
+ENTRY(idt_table)
+	.fill 256,8,0
 
 /*
  * 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",@progbits
 ENTRY(initial_page_table)
 	.long	pa(initial_pg_pmd+PGD_IDENT_ATTR),0	/* low identity map */
 # if KPMDS == 3
@@ -721,12 +820,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 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:
@@ -754,7 +861,7 @@ fault_msg:
  * segment size, and 32-bit linear address value:
  */
 
-	.data
+.section .rodata,"a",@progbits
 .globl boot_gdt_descr
 .globl idt_descr
 
@@ -763,7 +870,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:
@@ -774,7 +881,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
@@ -783,5 +890,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/head_64.S linux-3.8.13-pax/arch/x86/kernel/head_64.S
--- linux-3.8.13/arch/x86/kernel/head_64.S	2013-02-19 01:12:51.981766665 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/head_64.S	2013-02-19 02:14:21.367964901 +0100
@@ -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
@@ -88,35 +96,23 @@ startup_64:
 	 */
 	addq	%rbp, init_level4_pgt + 0(%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_ident_pgt + 0(%rip)
+#ifndef CONFIG_XEN
+	addq	%rbp, level3_ident_pgt + 8(%rip)
+#endif
 
-	addq	%rbp, level3_kernel_pgt + (510*8)(%rip)
-	addq	%rbp, level3_kernel_pgt + (511*8)(%rip)
+	addq	%rbp, level3_vmemmap_pgt + (L3_VMEMMAP_START*8)(%rip)
 
-	addq	%rbp, level2_fixmap_pgt + (506*8)(%rip)
+	addq	%rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
+	addq	%rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
 
-	/* Add an Identity mapping if I am above 1G */
-	leaq	_text(%rip), %rdi
-	andq	$PMD_PAGE_MASK, %rdi
-
-	movq	%rdi, %rax
-	shrq	$PUD_SHIFT, %rax
-	andq	$(PTRS_PER_PUD - 1), %rax
-	jz	ident_complete
-
-	leaq	(level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx
-	leaq	level3_ident_pgt(%rip), %rbx
-	movq	%rdx, 0(%rbx, %rax, 8)
-
-	movq	%rdi, %rax
-	shrq	$PMD_SHIFT, %rax
-	andq	$(PTRS_PER_PMD - 1), %rax
-	leaq	__PAGE_KERNEL_IDENT_LARGE_EXEC(%rdi), %rdx
-	leaq	level2_spare_pgt(%rip), %rbx
-	movq	%rdx, 0(%rbx, %rax, 8)
-ident_complete:
+	addq	%rbp, level2_fixmap_pgt + (506*8)(%rip)
+	addq	%rbp, level2_fixmap_pgt + (507*8)(%rip)
 
 	/*
 	 * Fixup the kernel text+data virtual addresses. Note that
@@ -159,8 +155,8 @@ ENTRY(secondary_startup_64)
 	 * after the boot processor executes this code.
 	 */
 
-	/* Enable PAE mode and PGE */
-	movl	$(X86_CR4_PAE | X86_CR4_PGE), %eax
+	/* Enable PAE mode and PSE/PGE */
+	movl	$(X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE), %eax
 	movq	%rax, %cr4
 
 	/* Setup early boot stage 4 level pagetables. */
@@ -182,9 +178,17 @@ 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
+	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 */
@@ -246,6 +250,7 @@ ENTRY(secondary_startup_64)
 	 * jump.  In addition we need to ensure %cs is set so we make this
 	 * a far return.
 	 */
+	pax_set_fptr_mask
 	movq	initial_code(%rip),%rax
 	pushq	$0		# fake return address to stop unwinder
 	pushq	$__KERNEL_CS	# set correct cs
@@ -284,7 +289,7 @@ ENDPROC(start_cpu0)
 bad_address:
 	jmp bad_address
 
-	.section ".init.text","ax"
+	__INIT
 	.globl early_idt_handlers
 early_idt_handlers:
 	# 104(%rsp) %rflags
@@ -343,7 +348,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 */
@@ -363,11 +368,15 @@ ENTRY(early_idt_handler)
 	addq $16,%rsp		# drop vector number and error code
 	decl early_recursion_flag(%rip)
 	INTERRUPT_RETURN
+	.previous
 
+	__INITDATA
 	.balign 4
 early_recursion_flag:
 	.long 0
+	.previous
 
+	.section .rodata,"a",@progbits
 #ifdef CONFIG_EARLY_PRINTK
 early_idt_msg:
 	.asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
@@ -376,6 +385,7 @@ early_idt_ripmsg:
 #endif /* CONFIG_EARLY_PRINTK */
 	.previous
 
+	.section .rodata,"a",@progbits
 #define NEXT_PAGE(name) \
 	.balign	PAGE_SIZE; \
 ENTRY(name)
@@ -388,7 +398,6 @@ ENTRY(name)
 	i = i + 1 ;					\
 	.endr
 
-	.data
 	/*
 	 * This default setting generates an ident mapping at address 0x100000
 	 * and a mapping for the kernel that precisely maps virtual address
@@ -399,13 +408,41 @@ 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 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(level3_kernel_pgt)
 	.fill	L3_START_KERNEL,8,0
@@ -413,20 +450,23 @@ 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_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
 
-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)
+NEXT_PAGE(level2_ident_pgt)
+	PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, 2*PTRS_PER_PMD)
 
 NEXT_PAGE(level2_kernel_pgt)
 	/*
@@ -439,37 +479,59 @@ NEXT_PAGE(level2_kernel_pgt)
 	 *  If you want to increase this then increase MODULES_VADDR
 	 *  too.)
 	 */
-	PMDS(0, __PAGE_KERNEL_LARGE_EXEC,
-		KERNEL_IMAGE_SIZE/PMD_SIZE)
-
-NEXT_PAGE(level2_spare_pgt)
-	.fill   512, 8, 0
+	PMDS(0, __PAGE_KERNEL_LARGE_EXEC, KERNEL_IMAGE_SIZE/PMD_SIZE)
 
 #undef PMDS
 #undef NEXT_PAGE
 
-	.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 */
+
+	/* 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"
-	
-	.section .bss, "aw", @nobits
+
+	.section .rodata,"a",@progbits
 	.align L1_CACHE_BYTES
 ENTRY(idt_table)
-	.skip IDT_ENTRIES * 16
+	.fill 512,8,0
 
 	.align L1_CACHE_BYTES
 ENTRY(nmi_idt_table)
-	.skip IDT_ENTRIES * 16
+	.fill 512,8,0
 
 	__PAGE_ALIGNED_BSS
 	.align PAGE_SIZE
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/i386_ksyms_32.c linux-3.8.13-pax/arch/x86/kernel/i386_ksyms_32.c
--- linux-3.8.13/arch/x86/kernel/i386_ksyms_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/i386_ksyms_32.c	2013-02-19 01:14:43.153772703 +0100
@@ -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);
@@ -36,3 +40,7 @@ EXPORT_SYMBOL(strstr);
 
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(empty_zero_page);
+
+#ifdef CONFIG_PAX_KERNEXEC
+EXPORT_SYMBOL(__LOAD_PHYSICAL_ADDR);
+#endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/i387.c linux-3.8.13-pax/arch/x86/kernel/i387.c
--- linux-3.8.13/arch/x86/kernel/i387.c	2013-02-19 01:12:51.989766665 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/i387.c	2013-02-19 01:14:43.153772703 +0100
@@ -55,7 +55,7 @@ static inline bool interrupted_kernel_fp
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/i8259.c linux-3.8.13-pax/arch/x86/kernel/i8259.c
--- linux-3.8.13/arch/x86/kernel/i8259.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/i8259.c	2013-04-26 18:14:09.396932430 +0200
@@ -110,7 +110,7 @@ static int i8259A_irq_pending(unsigned i
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/io_delay.c linux-3.8.13-pax/arch/x86/kernel/io_delay.c
--- linux-3.8.13/arch/x86/kernel/io_delay.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/io_delay.c	2013-03-07 03:15:15.043978747 +0100
@@ -58,7 +58,7 @@ static int __init dmi_io_delay_0xed_port
  * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/ioport.c linux-3.8.13-pax/arch/x86/kernel/ioport.c
--- linux-3.8.13/arch/x86/kernel/ioport.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/ioport.c	2013-02-19 01:14:43.153772703 +0100
@@ -54,7 +54,7 @@ asmlinkage long sys_ioperm(unsigned long
 	 * 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);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/irq_32.c linux-3.8.13-pax/arch/x86/kernel/irq_32.c
--- linux-3.8.13/arch/x86/kernel/irq_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/irq_32.c	2013-02-19 01:14:43.153772703 +0100
@@ -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(
  * 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, vo
 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, struc
 	 * 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, struc
 		     :  "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, struc
  */
 void __cpuinit 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) = 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;
+	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));
+ 
+ 	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 __cpuinit 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_
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/irq_64.c linux-3.8.13-pax/arch/x86/kernel/irq_64.c
--- linux-3.8.13/arch/x86/kernel/irq_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/irq_64.c	2013-02-19 01:14:43.153772703 +0100
@@ -44,7 +44,7 @@ static inline void stack_overflow_check(
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/irq.c linux-3.8.13-pax/arch/x86/kernel/irq.c
--- linux-3.8.13/arch/x86/kernel/irq.c	2013-05-13 02:47:05.445794900 +0200
+++ linux-3.8.13-pax/arch/x86/kernel/irq.c	2013-05-13 02:47:56.253792187 +0200
@@ -18,7 +18,7 @@
 #include <asm/mce.h>
 #include <asm/hw_irq.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;
@@ -122,9 +122,9 @@ int arch_show_interrupts(struct seq_file
 		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;
 }
@@ -164,7 +164,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/kdebugfs.c linux-3.8.13-pax/arch/x86/kernel/kdebugfs.c
--- linux-3.8.13/arch/x86/kernel/kdebugfs.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/kdebugfs.c	2013-02-19 01:14:43.157772703 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/kgdb.c linux-3.8.13-pax/arch/x86/kernel/kgdb.c
--- linux-3.8.13/arch/x86/kernel/kgdb.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/kgdb.c	2013-02-19 01:14:43.157772703 +0100
@@ -127,11 +127,11 @@ char *dbg_get_reg(int regno, void *mem,
 #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_vec
 	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
 
 	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
 #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
 		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 k
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/kprobes.c linux-3.8.13-pax/arch/x86/kernel/kprobes.c
--- linux-3.8.13/arch/x86/kernel/kprobes.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/kprobes.c	2013-02-19 01:14:43.157772703 +0100
@@ -119,9 +119,12 @@ static void __kprobes __synthesize_relat
 		s32 raddr;
 	} __attribute__((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
 	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 *b
 	 *  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 *des
 	/* 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)) {
@@ -355,7 +360,9 @@ int __kprobes __copy_instruction(u8 *des
 		newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest;
 		BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check.  */
 		disp = (u8 *) dest + insn_offset_displacement(&insn);
+		pax_open_kernel();
 		*(s32 *) disp = (s32) newdisp;
+		pax_close_kernel();
 	}
 #endif
 	return insn.length;
@@ -485,7 +492,7 @@ setup_singlestep(struct kprobe *p, struc
 		 * 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;
 	}
@@ -502,9 +509,9 @@ setup_singlestep(struct kprobe *p, struc
 	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);
 }
 
 /*
@@ -600,7 +607,7 @@ static int __kprobes kprobe_handler(stru
 				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
@@ -651,6 +658,9 @@ static void __used __kprobes kretprobe_t
 			"	movq %rax, 152(%rsp)\n"
 			RESTORE_REGS_STRING
 			"	popfq\n"
+#ifdef KERNEXEC_PLUGIN
+			"	btsq $63,(%rsp)\n"
+#endif
 #else
 			"	pushf\n"
 			SAVE_REGS_STRING
@@ -788,7 +798,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;
 
@@ -970,7 +980,7 @@ kprobe_exceptions_notify(struct notifier
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/kprobes-opt.c linux-3.8.13-pax/arch/x86/kernel/kprobes-opt.c
--- linux-3.8.13/arch/x86/kernel/kprobes-opt.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/kprobes-opt.c	2013-04-30 10:21:51.208032259 +0200
@@ -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_arg
 	*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_kpr
 	 * 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_kpr
 	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_kpr
 			((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,
 		/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/kvm.c linux-3.8.13-pax/arch/x86/kernel/kvm.c
--- linux-3.8.13/arch/x86/kernel/kvm.c	2013-02-19 01:12:52.005766666 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/kvm.c	2013-02-20 01:07:48.910064001 +0100
@@ -452,7 +452,7 @@ static int __cpuinit kvm_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata kvm_cpu_notifier = {
+static struct notifier_block kvm_cpu_notifier = {
         .notifier_call  = kvm_cpu_notify,
 };
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/ldt.c linux-3.8.13-pax/arch/x86/kernel/ldt.c
--- linux-3.8.13/arch/x86/kernel/ldt.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/ldt.c	2013-02-19 01:14:43.173772704 +0100
@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, i
 	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
 		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
 		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, u
 		}
 	}
 
+#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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/machine_kexec_32.c linux-3.8.13-pax/arch/x86/kernel/machine_kexec_32.c
--- linux-3.8.13/arch/x86/kernel/machine_kexec_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/machine_kexec_32.c	2013-02-19 01:14:43.177772704 +0100
@@ -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
 }
 
 
-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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/Makefile linux-3.8.13-pax/arch/x86/kernel/Makefile
--- linux-3.8.13/arch/x86/kernel/Makefile	2013-02-19 01:12:51.773766653 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/Makefile	2013-02-19 01:14:43.177772704 +0100
@@ -22,7 +22,7 @@ obj-y			+= time.o ioport.o ldt.o dumpsta
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/microcode_core.c linux-3.8.13-pax/arch/x86/kernel/microcode_core.c
--- linux-3.8.13/arch/x86/kernel/microcode_core.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/microcode_core.c	2013-02-20 01:07:03.270066438 +0100
@@ -512,7 +512,7 @@ mc_cpu_callback(struct notifier_block *n
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __refdata mc_cpu_notifier = {
+static struct notifier_block mc_cpu_notifier = {
 	.notifier_call	= mc_cpu_callback,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/microcode_intel.c linux-3.8.13-pax/arch/x86/kernel/microcode_intel.c
--- linux-3.8.13/arch/x86/kernel/microcode_intel.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/microcode_intel.c	2013-02-19 01:14:43.177772704 +0100
@@ -431,13 +431,13 @@ static enum ucode_state request_microcod
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/module.c linux-3.8.13-pax/arch/x86/kernel/module.c
--- linux-3.8.13/arch/x86/kernel/module.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/module.c	2013-02-19 01:14:43.177772704 +0100
@@ -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 *sechd
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/msr.c linux-3.8.13-pax/arch/x86/kernel/msr.c
--- linux-3.8.13/arch/x86/kernel/msr.c	2013-02-19 01:12:52.005766666 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/msr.c	2013-02-20 01:06:59.818066622 +0100
@@ -234,7 +234,7 @@ static int __cpuinit msr_class_cpu_callb
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/nmi.c linux-3.8.13-pax/arch/x86/kernel/nmi.c
--- linux-3.8.13/arch/x86/kernel/nmi.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/nmi.c	2013-03-08 14:48:44.446334422 +0100
@@ -105,7 +105,7 @@ static int __kprobes nmi_handle(unsigned
 	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;
@@ -129,9 +129,9 @@ int __register_nmi_handler(unsigned int
 	 * 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;
@@ -154,7 +154,7 @@ void unregister_nmi_handler(unsigned int
 		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;
 		}
 	}
@@ -479,6 +479,17 @@ static inline void nmi_nesting_postproce
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/nmi_selftest.c linux-3.8.13-pax/arch/x86/kernel/nmi_selftest.c
--- linux-3.8.13/arch/x86/kernel/nmi_selftest.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/nmi_selftest.c	2013-03-05 23:17:09.177071325 +0100
@@ -43,7 +43,7 @@ static void __init init_nmi_testsuite(vo
 {
 	/* 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 c
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/paravirt.c linux-3.8.13-pax/arch/x86/kernel/paravirt.c
--- linux-3.8.13/arch/x86/kernel/paravirt.c	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/kernel/paravirt.c	2013-04-30 00:05:31.879841431 +0200
@@ -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,
 	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 *insn
 	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_laz
 	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,
@@ -395,21 +402,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,
@@ -459,6 +471,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 */
 
@@ -479,6 +492,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/paravirt-spinlocks.c linux-3.8.13-pax/arch/x86/kernel/paravirt-spinlocks.c
--- linux-3.8.13/arch/x86/kernel/paravirt-spinlocks.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/paravirt-spinlocks.c	2013-02-19 01:14:43.177772704 +0100
@@ -13,7 +13,7 @@ default_spin_lock_flags(arch_spinlock_t
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/pci-calgary_64.c linux-3.8.13-pax/arch/x86/kernel/pci-calgary_64.c
--- linux-3.8.13/arch/x86/kernel/pci-calgary_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/pci-calgary_64.c	2013-04-26 21:32:04.989281593 +0200
@@ -1339,7 +1339,7 @@ static void __init get_tce_space_from_ta
 			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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/pci-iommu_table.c linux-3.8.13-pax/arch/x86/kernel/pci-iommu_table.c
--- linux-3.8.13/arch/x86/kernel/pci-iommu_table.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/pci-iommu_table.c	2013-02-19 01:14:43.177772704 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/pci-swiotlb.c linux-3.8.13-pax/arch/x86/kernel/pci-swiotlb.c
--- linux-3.8.13/arch/x86/kernel/pci-swiotlb.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/pci-swiotlb.c	2013-03-07 00:08:13.824294606 +0100
@@ -32,7 +32,7 @@ static void x86_swiotlb_free_coherent(st
 				      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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/process_32.c linux-3.8.13-pax/arch/x86/kernel/process_32.c
--- linux-3.8.13/arch/x86/kernel/process_32.c	2013-02-19 01:12:52.029766667 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/process_32.c	2013-02-19 01:14:43.181772704 +0100
@@ -65,6 +65,7 @@ asmlinkage void ret_from_kernel_thread(v
 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,21 +75,20 @@ void __show_regs(struct pt_regs *regs, i
 	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);
 
 	show_regs_common();
 
 	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",
@@ -130,20 +130,21 @@ void release_thread(struct task_struct *
 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;
@@ -250,7 +251,7 @@ __switch_to(struct task_struct *prev_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 */
@@ -274,6 +275,10 @@ __switch_to(struct task_struct *prev_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.
 	 */
@@ -304,6 +309,9 @@ __switch_to(struct task_struct *prev_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)
 	 */
@@ -312,8 +320,6 @@ __switch_to(struct task_struct *prev_p,
 
 	switch_fpu_finish(next_p, fpu);
 
-	this_cpu_write(current_task, next_p);
-
 	return prev_p;
 }
 
@@ -343,4 +349,3 @@ unsigned long get_wchan(struct task_stru
 	} while (count++ < 16);
 	return 0;
 }
-
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/process_64.c linux-3.8.13-pax/arch/x86/kernel/process_64.c
--- linux-3.8.13/arch/x86/kernel/process_64.c	2013-02-19 01:12:52.029766667 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/process_64.c	2013-02-19 01:14:43.181772704 +0100
@@ -152,10 +152,11 @@ int copy_thread(unsigned long clone_flag
 	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;
@@ -274,7 +275,7 @@ __switch_to(struct task_struct *prev_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;
 
@@ -356,10 +357,9 @@ __switch_to(struct task_struct *prev_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
@@ -428,12 +428,11 @@ unsigned long get_wchan(struct task_stru
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/process.c linux-3.8.13-pax/arch/x86/kernel/process.c
--- linux-3.8.13/arch/x86/kernel/process.c	2013-02-19 01:12:52.017766667 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/process.c	2013-02-19 01:14:43.181772704 +0100
@@ -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);
@@ -136,7 +137,7 @@ void show_regs_common(void)
 	board = dmi_get_system_info(DMI_BOARD_NAME);
 
 	printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s %s%s%s\n",
-	       current->pid, current->comm, print_tainted(),
+	       task_pid_nr(current), current->comm, print_tainted(),
 	       init_utsname()->release,
 	       (int)strcspn(init_utsname()->version, " "),
 	       init_utsname()->version,
@@ -149,6 +150,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);
@@ -301,7 +305,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();
 }
@@ -404,7 +408,7 @@ bool set_pm_idle_to_default(void)
 
 	return ret;
 }
-void stop_this_cpu(void *dummy)
+__noreturn void stop_this_cpu(void *dummy)
 {
 	local_irq_disable();
 	/*
@@ -632,16 +636,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/ptrace.c linux-3.8.13-pax/arch/x86/kernel/ptrace.c
--- linux-3.8.13/arch/x86/kernel/ptrace.c	2013-02-19 01:12:52.029766667 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/ptrace.c	2013-02-19 01:14:43.181772704 +0100
@@ -184,14 +184,13 @@ unsigned long kernel_stack_pointer(struc
 {
 	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
 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++) {
@@ -856,7 +855,7 @@ long arch_ptrace(struct task_struct *chi
 		 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. */
@@ -941,14 +940,14 @@ long arch_ptrace(struct task_struct *chi
 		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
 
@@ -1326,7 +1325,7 @@ long compat_arch_ptrace(struct task_stru
 
 #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),
@@ -1367,7 +1366,7 @@ static const struct user_regset_view use
 #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),
@@ -1420,7 +1419,7 @@ static const struct user_regset_view use
  */
 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);
@@ -1455,7 +1454,7 @@ static void fill_sigtrap_info(struct tas
 	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,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/pvclock.c linux-3.8.13-pax/arch/x86/kernel/pvclock.c
--- linux-3.8.13/arch/x86/kernel/pvclock.c	2013-03-19 01:53:21.027281872 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/pvclock.c	2013-03-19 01:53:31.191281330 +0100
@@ -43,11 +43,11 @@ unsigned long pvclock_tsc_khz(struct pvc
 	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
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/reboot.c linux-3.8.13-pax/arch/x86/kernel/reboot.c
--- linux-3.8.13/arch/x86/kernel/reboot.c	2013-02-19 01:12:52.045766668 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/reboot.c	2013-02-19 01:14:43.181772704 +0100
@@ -36,7 +36,7 @@ void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 static const struct desc_ptr no_idt = {};
-static int reboot_mode;
+static unsigned short reboot_mode;
 enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
@@ -157,6 +157,11 @@ static int __init set_bios_reboot(const
 
 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();
 
 	/*
@@ -184,7 +189,29 @@ void __noreturn machine_real_restart(uns
 
 	/* 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
@@ -531,7 +558,7 @@ void __attribute__((weak)) mach_reboot_f
  * 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;
@@ -654,13 +681,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");
 
@@ -669,7 +696,7 @@ static void native_machine_restart(char
 	__machine_emergency_restart(0);
 }
 
-static void native_machine_halt(void)
+static void __noreturn native_machine_halt(void)
 {
 	/* Stop other cpus and apics */
 	machine_shutdown();
@@ -679,7 +706,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)
@@ -688,9 +715,10 @@ static void native_machine_power_off(voi
 	}
 	/* 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/relocate_kernel_64.S linux-3.8.13-pax/arch/x86/kernel/relocate_kernel_64.S
--- linux-3.8.13/arch/x86/kernel/relocate_kernel_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/relocate_kernel_64.S	2013-02-19 01:14:43.185772704 +0100
@@ -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
@@ -160,13 +161,14 @@ identity_mapped:
 	xorq    %rbp, %rbp
 	xorq	%r8,  %r8
 	xorq	%r9,  %r9
-	xorq	%r10, %r9
+	xorq	%r10, %r10
 	xorq	%r11, %r11
 	xorq	%r12, %r12
 	xorq	%r13, %r13
 	xorq	%r14, %r14
 	xorq	%r15, %r15
 
+	pax_force_retaddr 0, 1
 	ret
 
 1:
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/setup.c linux-3.8.13-pax/arch/x86/kernel/setup.c
--- linux-3.8.13/arch/x86/kernel/setup.c	2013-02-19 01:12:52.045766668 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/setup.c	2013-02-19 01:14:43.185772704 +0100
@@ -437,7 +437,7 @@ static void __init parse_setup_data(void
 
 		switch (data->type) {
 		case SETUP_E820_EXT:
-			parse_e820_ext(data);
+			parse_e820_ext((struct setup_data __force_kernel *)data);
 			break;
 		case SETUP_DTB:
 			add_dtb(pa_data);
@@ -706,7 +706,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);
 }
@@ -830,14 +830,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 = virt_to_phys(_text);
-	code_resource.end = virt_to_phys(_etext)-1;
-	data_resource.start = virt_to_phys(_etext);
+	code_resource.start = virt_to_phys(ktla_ktva(_text));
+	code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
+	data_resource.start = virt_to_phys(_sdata);
 	data_resource.end = virt_to_phys(_edata)-1;
 	bss_resource.start = virt_to_phys(&__bss_start);
 	bss_resource.end = virt_to_phys(&__bss_stop)-1;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/setup_percpu.c linux-3.8.13-pax/arch/x86/kernel/setup_percpu.c
--- linux-3.8.13/arch/x86/kernel/setup_percpu.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/setup_percpu.c	2013-03-13 00:54:18.551367712 +0100
@@ -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(
 {
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/signal.c linux-3.8.13-pax/arch/x86/kernel/signal.c
--- linux-3.8.13/arch/x86/kernel/signal.c	2013-02-19 01:12:52.045766668 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/signal.c	2013-03-25 23:07:59.478237332 +0100
@@ -196,7 +196,7 @@ static unsigned long align_sigframe(unsi
 	 * 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
@@ -304,9 +304,9 @@ __setup_frame(int sig, struct k_sigactio
 	}
 
 	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 (ka->sa.sa_flags & SA_RESTORER)
 		restorer = ka->sa.sa_restorer;
 
@@ -320,7 +320,7 @@ __setup_frame(int sig, struct k_sigactio
 	 * 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;
@@ -367,7 +367,10 @@ static int __setup_rt_frame(int sig, str
 		err |= __save_altstack(&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 (ka->sa.sa_flags & SA_RESTORER)
 			restorer = ka->sa.sa_restorer;
 		put_user_ex(restorer, &frame->pretcode);
@@ -379,7 +382,7 @@ static int __setup_rt_frame(int sig, str
 		 * 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, info);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/smpboot.c linux-3.8.13-pax/arch/x86/kernel/smpboot.c
--- linux-3.8.13/arch/x86/kernel/smpboot.c	2013-02-19 01:12:52.061766669 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/smpboot.c	2013-02-19 01:14:43.197772705 +0100
@@ -748,6 +748,7 @@ static int __cpuinit do_boot_cpu(int api
 	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 +756,13 @@ static int __cpuinit do_boot_cpu(int api
 #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 +911,12 @@ int __cpuinit native_cpu_up(unsigned int
 	/* the FPU context is blank, nobody can own it */
 	__cpu_disable_lazy_restore(cpu);
 
+#ifdef CONFIG_PAX_PER_CPU_PGD
+	clone_pgd_range(get_cpu_pgd(cpu) + KERNEL_PGD_BOUNDARY,
+			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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/smp.c linux-3.8.13-pax/arch/x86/kernel/smp.c
--- linux-3.8.13/arch/x86/kernel/smp.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/smp.c	2013-02-19 01:14:43.197772705 +0100
@@ -285,7 +285,7 @@ static int __init nonmi_ipi_setup(char *
 
 __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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/step.c linux-3.8.13-pax/arch/x86/kernel/step.c
--- linux-3.8.13/arch/x86/kernel/step.c	2013-02-19 01:12:52.061766669 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/step.c	2013-02-19 01:14:43.201772705 +0100
@@ -27,10 +27,10 @@ unsigned long convert_ip_to_linear(struc
 		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(struc
 			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 t
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/sys_i386_32.c linux-3.8.13-pax/arch/x86/kernel/sys_i386_32.c
--- linux-3.8.13/arch/x86/kernel/sys_i386_32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/sys_i386_32.c	2013-03-10 04:26:25.990734083 +0100
@@ -0,0 +1,248 @@
+/*
+ * 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/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;
+}
+
+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 start_addr, pax_task_size = 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)
+		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))
+				return addr;
+		}
+	}
+	if (len > mm->cached_hole_size) {
+		start_addr = addr = mm->free_area_cache;
+	} else {
+		start_addr = addr = mm->mmap_base;
+		mm->cached_hole_size = 0;
+	}
+
+#ifdef CONFIG_PAX_PAGEEXEC
+	if (!(__supported_pte_mask & _PAGE_NX) && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
+		start_addr = 0x00110000UL;
+
+#ifdef CONFIG_PAX_RANDMMAP
+		if (mm->pax_flags & MF_PAX_RANDMMAP)
+			start_addr += mm->delta_mmap & 0x03FFF000UL;
+#endif
+
+		if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
+			start_addr = addr = mm->mmap_base;
+		else
+			addr = start_addr;
+	}
+#endif
+
+full_search:
+	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+		/* At this point:  (!vma || addr < vma->vm_end). */
+		if (pax_task_size - len < addr) {
+			/*
+			 * Start a new search - just in case we missed
+			 * some holes.
+			 */
+			if (start_addr != mm->mmap_base) {
+				start_addr = addr = mm->mmap_base;
+				mm->cached_hole_size = 0;
+				goto full_search;
+			}
+			return -ENOMEM;
+		}
+		if (check_heap_stack_gap(vma, addr, len))
+			break;
+		if (addr + mm->cached_hole_size < vma->vm_start)
+			mm->cached_hole_size = vma->vm_start - addr;
+		addr = vma->vm_end;
+		if (mm->start_brk <= addr && addr < mm->mmap_base) {
+			start_addr = addr = mm->mmap_base;
+			mm->cached_hole_size = 0;
+			goto full_search;
+		}
+	}
+
+	/*
+	 * Remember the place where we stopped the search:
+	 */
+	mm->free_area_cache = addr + len;
+	return addr;
+}
+
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+			  const unsigned long len, const unsigned long pgoff,
+			  const unsigned long flags)
+{
+	struct vm_area_struct *vma;
+	struct mm_struct *mm = current->mm;
+	unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = 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;
+
+	/* 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))
+				return addr;
+		}
+	}
+
+	/* check if free_area_cache is useful for us */
+	if (len <= mm->cached_hole_size) {
+		mm->cached_hole_size = 0;
+		mm->free_area_cache = mm->mmap_base;
+	}
+
+	/* either no address requested or can't fit in requested address hole */
+	addr = mm->free_area_cache;
+
+	/* make sure it can fit in the remaining address space */
+	if (addr > len) {
+		vma = find_vma(mm, addr-len);
+		if (check_heap_stack_gap(vma, addr - len, len))
+			/* remember the address as a hint for next time */
+			return (mm->free_area_cache = addr-len);
+	}
+
+	if (mm->mmap_base < len)
+		goto bottomup;
+
+	addr = mm->mmap_base-len;
+
+	do {
+		/*
+		 * Lookup failure means no vma is above this address,
+		 * else if new region fits below vma->vm_start,
+		 * return with success:
+		 */
+		vma = find_vma(mm, addr);
+		if (check_heap_stack_gap(vma, addr, len))
+			/* remember the address as a hint for next time */
+			return (mm->free_area_cache = addr);
+
+		/* remember the largest hole we saw so far */
+		if (addr + mm->cached_hole_size < vma->vm_start)
+			mm->cached_hole_size = vma->vm_start - addr;
+
+		/* try just below the current vma->vm_start */
+		addr = skip_heap_stack_gap(vma, len);
+	} while (!IS_ERR_VALUE(addr));
+
+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.
+	 */
+
+#ifdef CONFIG_PAX_SEGMEXEC
+	if (mm->pax_flags & MF_PAX_SEGMEXEC)
+		mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
+	else
+#endif
+
+	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->free_area_cache = mm->mmap_base;
+	mm->cached_hole_size = ~0UL;
+	addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
+	/*
+	 * Restore the topdown base:
+	 */
+	mm->mmap_base = base;
+	mm->free_area_cache = base;
+	mm->cached_hole_size = ~0UL;
+
+	return addr;
+}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/sys_x86_64.c linux-3.8.13-pax/arch/x86/kernel/sys_x86_64.c
--- linux-3.8.13/arch/x86/kernel/sys_x86_64.c	2013-02-19 01:12:52.061766669 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/sys_x86_64.c	2013-02-19 01:14:43.201772705 +0100
@@ -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
 				*begin = new_begin;
 		}
 	} else {
-		*begin = TASK_UNMAPPED_BASE;
+		*begin = mm->mmap_base;
 		*end = TASK_SIZE;
 	}
 }
@@ -118,16 +118,19 @@ arch_get_unmapped_area(struct file *filp
 	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))
 			return addr;
 	}
 
@@ -161,6 +164,10 @@ arch_get_unmapped_area_topdown(struct fi
 	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);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/tboot.c linux-3.8.13-pax/arch/x86/kernel/tboot.c
--- linux-3.8.13/arch/x86/kernel/tboot.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/tboot.c	2013-02-20 01:07:57.206063558 +0100
@@ -220,7 +220,7 @@ static int tboot_setup_sleep(void)
 
 void tboot_shutdown(u32 shutdown_type)
 {
-	void (*shutdown)(void);
+	void (* __noreturn shutdown)(void);
 
 	if (!tboot_enabled())
 		return;
@@ -242,7 +242,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 */
@@ -300,7 +300,7 @@ static int tboot_sleep(u8 sleep_state, u
 	return 0;
 }
 
-static atomic_t ap_wfs_count;
+static atomic_unchecked_t ap_wfs_count;
 
 static int tboot_wait_for_aps(int num_aps)
 {
@@ -324,16 +324,16 @@ static int __cpuinit tboot_cpu_callback(
 {
 	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;
 	}
 	return NOTIFY_OK;
 }
 
-static struct notifier_block tboot_cpu_notifier __cpuinitdata =
+static struct notifier_block tboot_cpu_notifier =
 {
 	.notifier_call = tboot_cpu_callback,
 };
@@ -345,7 +345,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);
 
 	acpi_os_set_prepare_sleep(&tboot_sleep);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/time.c linux-3.8.13-pax/arch/x86/kernel/time.c
--- linux-3.8.13/arch/x86/kernel/time.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/time.c	2013-02-19 01:14:43.201772705 +0100
@@ -30,9 +30,9 @@ unsigned long profile_pc(struct pt_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
 		 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/tls.c linux-3.8.13-pax/arch/x86/kernel/tls.c
--- linux-3.8.13/arch/x86/kernel/tls.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/tls.c	2013-02-19 01:14:43.201772705 +0100
@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
 	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;
@@ -204,7 +209,7 @@ int regset_tls_set(struct task_struct *t
 
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/traps.c linux-3.8.13-pax/arch/x86/kernel/traps.c
--- linux-3.8.13/arch/x86/kernel/traps.c	2013-02-19 01:12:52.069766669 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/traps.c	2013-02-19 01:14:43.201772705 +0100
@@ -68,12 +68,6 @@
 #include <asm/setup.h>
 
 asmlinkage int system_call(void);
-
-/*
- * The IDT has to be page-aligned to simplify the Pentium
- * F0 0F bug workaround.
- */
-gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
 #endif
 
 DECLARE_BITMAP(used_vectors, NR_VECTORS);
@@ -106,11 +100,11 @@ static inline void preempt_conditional_c
 }
 
 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 +117,24 @@ do_trap_no_signal(struct task_struct *ts
 		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 +142,7 @@ do_trap_no_signal(struct task_struct *ts
 }
 
 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 +166,7 @@ do_trap(int trapnr, int signr, char *str
 	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");
@@ -266,7 +272,7 @@ do_general_protection(struct pt_regs *re
 	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;
@@ -274,18 +280,42 @@ do_general_protection(struct pt_regs *re
 #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;
 
@@ -440,7 +470,7 @@ dotraplinkage void __kprobes do_debug(st
 	/* 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);
@@ -455,7 +485,7 @@ dotraplinkage void __kprobes do_debug(st
 	 * 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;
@@ -487,7 +517,7 @@ void math_error(struct pt_regs *regs, in
 		return;
 	conditional_sti(regs);
 
-	if (!user_mode_vm(regs))
+	if (!user_mode(regs))
 	{
 		if (!fixup_exception(regs)) {
 			task->thread.error_code = error_code;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/uprobes.c linux-3.8.13-pax/arch/x86/kernel/uprobes.c
--- linux-3.8.13/arch/x86/kernel/uprobes.c	2013-02-19 01:12:52.077766670 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/uprobes.c	2013-02-19 01:14:43.205772705 +0100
@@ -629,7 +629,7 @@ int arch_uprobe_exception_notify(struct
 	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) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/vm86_32.c linux-3.8.13-pax/arch/x86/kernel/vm86_32.c
--- linux-3.8.13/arch/x86/kernel/vm86_32.c	2013-02-19 01:12:52.089766670 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/vm86_32.c	2013-02-19 01:14:43.205772705 +0100
@@ -150,7 +150,7 @@ struct pt_regs *save_v86_state(struct ke
 		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);
@@ -328,7 +328,7 @@ static void do_sys_vm86(struct kernel_vm
 	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;
@@ -535,7 +535,7 @@ static void do_int(struct kernel_vm86_re
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/vmlinux.lds.S linux-3.8.13-pax/arch/x86/kernel/vmlinux.lds.S
--- linux-3.8.13/arch/x86/kernel/vmlinux.lds.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/vmlinux.lds.S	2013-02-19 01:14:43.205772705 +0100
@@ -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
 #ifdef CONFIG_X86_32
 		. = ALIGN(PAGE_SIZE);
@@ -108,13 +128,48 @@ SECTIONS
 		IRQENTRY_TEXT
 		*(.fixup)
 		*(.gnu.warning)
-		/* End of text section */
-		_etext = .;
 	} :text = 0x9090
 
-	NOTES :text :note
+	. += __KERNEL_TEXT_OFFSET;
+
+#ifdef CONFIG_X86_32
+	. = ALIGN(PAGE_SIZE);
+	.module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
+
+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_MODULES)
+		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) {
+		*(.idt)
+		. = 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) :text = 0x9090
+	EXCEPTION_TABLE(16) :rodata
 
 #if defined(CONFIG_DEBUG_RODATA)
 	/* .text should occupy whole number of pages */
@@ -126,16 +181,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)
 
@@ -176,12 +235,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
@@ -190,12 +256,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 = .;
@@ -257,19 +338,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
 
@@ -288,16 +362,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) {
@@ -313,6 +381,7 @@ SECTIONS
 		__brk_base = .;
 		. += 64 * 1024;		/* 64k alignment slop space */
 		*(.brk_reservation)	/* areas brk users have reserved */
+		. = ALIGN(HPAGE_SIZE);
 		__brk_limit = .;
 	}
 
@@ -339,13 +408,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/vsyscall_64.c linux-3.8.13-pax/arch/x86/kernel/vsyscall_64.c
--- linux-3.8.13/arch/x86/kernel/vsyscall_64.c	2013-02-19 01:12:52.097766671 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/vsyscall_64.c	2013-02-19 01:14:43.205772705 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/x8664_ksyms_64.c linux-3.8.13-pax/arch/x86/kernel/x8664_ksyms_64.c
--- linux-3.8.13/arch/x86/kernel/x8664_ksyms_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/x8664_ksyms_64.c	2013-02-19 01:14:43.205772705 +0100
@@ -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);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/x86_init.c linux-3.8.13-pax/arch/x86/kernel/x86_init.c
--- linux-3.8.13/arch/x86/kernel/x86_init.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/x86_init.c	2013-02-19 01:14:43.205772705 +0100
@@ -88,7 +88,7 @@ struct x86_init_ops x86_init __initdata
 	},
 };
 
-struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
+struct x86_cpuinit_ops x86_cpuinit __cpuinitconst = {
 	.early_percpu_clock_init	= x86_init_noop,
 	.setup_percpu_clockev		= setup_secondary_APIC_clock,
 };
@@ -96,7 +96,7 @@ struct x86_cpuinit_ops x86_cpuinit __cpu
 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,
@@ -110,14 +110,14 @@ 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,
 	.teardown_msi_irq = native_teardown_msi_irq,
 	.teardown_msi_irqs = default_teardown_msi_irqs,
 	.restore_msi_irqs = default_restore_msi_irqs,
 };
 
-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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kernel/xsave.c linux-3.8.13-pax/arch/x86/kernel/xsave.c
--- linux-3.8.13/arch/x86/kernel/xsave.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/kernel/xsave.c	2013-02-19 01:14:43.205772705 +0100
@@ -199,6 +199,7 @@ static inline int save_user_xstate(struc
 {
 	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_str
  */
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/cpuid.c linux-3.8.13-pax/arch/x86/kvm/cpuid.c
--- linux-3.8.13/arch/x86/kvm/cpuid.c	2013-02-19 01:12:52.097766671 +0100
+++ linux-3.8.13-pax/arch/x86/kvm/cpuid.c	2013-02-19 01:14:43.209772706 +0100
@@ -124,15 +124,20 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm
 			      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
 			      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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/emulate.c linux-3.8.13-pax/arch/x86/kvm/emulate.c
--- linux-3.8.13/arch/x86/kvm/emulate.c	2013-05-13 02:47:05.449794899 +0200
+++ linux-3.8.13-pax/arch/x86/kvm/emulate.c	2013-05-13 02:47:30.585793557 +0200
@@ -292,6 +292,7 @@ static void invalidate_registers(struct
 
 #define ____emulate_2op(ctxt, _op, _x, _y, _suffix, _dsttype)	\
 	do {								\
+		unsigned long _tmp;					\
 		__asm__ __volatile__ (					\
 			_PRE_EFLAGS("0", "4", "2")			\
 			_op _suffix " %"_x"3,%1; "			\
@@ -306,8 +307,6 @@ static void invalidate_registers(struct
 /* Raw emulation: instruction has two explicit operands. */
 #define __emulate_2op_nobyte(ctxt,_op,_wx,_wy,_lx,_ly,_qx,_qy)		\
 	do {								\
-		unsigned long _tmp;					\
-									\
 		switch ((ctxt)->dst.bytes) {				\
 		case 2:							\
 			____emulate_2op(ctxt,_op,_wx,_wy,"w",u16);	\
@@ -323,7 +322,6 @@ static void invalidate_registers(struct
 
 #define __emulate_2op(ctxt,_op,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy)		     \
 	do {								     \
-		unsigned long _tmp;					     \
 		switch ((ctxt)->dst.bytes) {				     \
 		case 1:							     \
 			____emulate_2op(ctxt,_op,_bx,_by,"b",u8);	     \
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/lapic.c linux-3.8.13-pax/arch/x86/kvm/lapic.c
--- linux-3.8.13/arch/x86/kvm/lapic.c	2013-04-30 00:04:57.171843284 +0200
+++ linux-3.8.13-pax/arch/x86/kvm/lapic.c	2013-04-30 00:05:40.671840962 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/paging_tmpl.h linux-3.8.13-pax/arch/x86/kvm/paging_tmpl.h
--- linux-3.8.13/arch/x86/kvm/paging_tmpl.h	2013-02-19 01:12:52.145766674 +0100
+++ linux-3.8.13-pax/arch/x86/kvm/paging_tmpl.h	2013-02-19 01:14:43.209772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/svm.c linux-3.8.13-pax/arch/x86/kvm/svm.c
--- linux-3.8.13/arch/x86/kvm/svm.c	2013-02-19 01:12:52.145766674 +0100
+++ linux-3.8.13-pax/arch/x86/kvm/svm.c	2013-02-19 01:14:43.213772706 +0100
@@ -3507,7 +3507,11 @@ static void reload_tss(struct kvm_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();
 }
 
@@ -3881,6 +3885,10 @@ static void svm_vcpu_run(struct kvm_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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/vmx.c linux-3.8.13-pax/arch/x86/kvm/vmx.c
--- linux-3.8.13/arch/x86/kvm/vmx.c	2013-02-19 01:12:52.165766675 +0100
+++ linux-3.8.13-pax/arch/x86/kvm/vmx.c	2013-04-26 18:11:53.204928425 +0200
@@ -1164,12 +1164,12 @@ static void vmcs_write64(unsigned long f
 #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);
 }
@@ -1370,7 +1370,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();
 }
 
@@ -1594,6 +1598,10 @@ static void vmx_vcpu_load(struct kvm_vcp
 		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;
@@ -2738,8 +2746,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();
@@ -3782,7 +3793,10 @@ static void vmx_set_constant_host_state(
 
 	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
@@ -3803,7 +3817,7 @@ static void vmx_set_constant_host_state(
 	native_store_idt(&dt);
 	vmcs_writel(HOST_IDTR_BASE, dt.address);   /* 22.2.4 */
 
-	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);
@@ -6355,6 +6369,12 @@ static void __noclone vmx_vcpu_run(struc
 		"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"
@@ -6407,6 +6427,11 @@ static void __noclone vmx_vcpu_run(struc
 #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"
@@ -6420,7 +6445,7 @@ static void __noclone vmx_vcpu_run(struc
 	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.
@@ -6429,8 +6454,18 @@ static void __noclone vmx_vcpu_run(struc
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/kvm/x86.c linux-3.8.13-pax/arch/x86/kvm/x86.c
--- linux-3.8.13/arch/x86/kvm/x86.c	2013-04-30 00:04:57.171843284 +0200
+++ linux-3.8.13-pax/arch/x86/kvm/x86.c	2013-04-30 00:05:40.671840962 +0200
@@ -1688,8 +1688,8 @@ static int xen_hvm_config(struct kvm_vcp
 {
 	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;
@@ -2567,6 +2567,8 @@ long kvm_arch_dev_ioctl(struct file *fil
 		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;
@@ -2696,7 +2698,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
 				    struct kvm_interrupt *irq)
 {
-	if (irq->irq < 0 || irq->irq >= KVM_NR_INTERRUPTS)
+	if (irq->irq >= KVM_NR_INTERRUPTS)
 		return -EINVAL;
 	if (irqchip_in_kernel(vcpu->kvm))
 		return -ENXIO;
@@ -5209,7 +5211,7 @@ static struct notifier_block pvclock_gto
 };
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lguest/boot.c linux-3.8.13-pax/arch/x86/lguest/boot.c
--- linux-3.8.13/arch/x86/lguest/boot.c	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/lguest/boot.c	2013-04-30 00:05:07.715842721 +0200
@@ -1200,9 +1200,10 @@ static __init int early_put_chars(u32 vt
  * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/atomic64_386_32.S linux-3.8.13-pax/arch/x86/lib/atomic64_386_32.S
--- linux-3.8.13/arch/x86/lib/atomic64_386_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/atomic64_386_32.S	2013-02-19 01:14:43.217772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/atomic64_cx8_32.S linux-3.8.13-pax/arch/x86/lib/atomic64_cx8_32.S
--- linux-3.8.13/arch/x86/lib/atomic64_cx8_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/atomic64_cx8_32.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/checksum_32.S linux-3.8.13-pax/arch/x86/lib/checksum_32.S
--- linux-3.8.13/arch/x86/lib/checksum_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/checksum_32.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 (
 
 #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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/clear_page_64.S linux-3.8.13-pax/arch/x86/lib/clear_page_64.S
--- linux-3.8.13/arch/x86/lib/clear_page_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/clear_page_64.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/cmpxchg16b_emu.S linux-3.8.13-pax/arch/x86/lib/cmpxchg16b_emu.S
--- linux-3.8.13/arch/x86/lib/cmpxchg16b_emu.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/cmpxchg16b_emu.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/copy_page_64.S linux-3.8.13-pax/arch/x86/lib/copy_page_64.S
--- linux-3.8.13/arch/x86/lib/copy_page_64.S	2013-02-19 01:12:52.189766676 +0100
+++ linux-3.8.13-pax/arch/x86/lib/copy_page_64.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/copy_user_64.S linux-3.8.13-pax/arch/x86/lib/copy_user_64.S
--- linux-3.8.13/arch/x86/lib/copy_user_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/copy_user_64.S	2013-02-19 01:14:43.221772706 +0100
@@ -18,6 +18,7 @@
 #include <asm/alternative-asm.h>
 #include <asm/asm.h>
 #include <asm/smap.h>
+#include <asm/pgtable.h>
 
 /*
  * By placing feature2 after feature1 in altinstructions section, we logically
@@ -31,7 +32,7 @@
 	.byte 0xe9	/* 32bit jump */
 	.long \orig-1f	/* by default jump to orig */
 1:
-	.section .altinstr_replacement,"ax"
+	.section .altinstr_replacement,"a"
 2:	.byte 0xe9			/* near jump with 32bit immediate */
 	.long \alt1-1b /* offset */   /* or alternatively to alt1 */
 3:	.byte 0xe9			/* near jump with 32bit immediate */
@@ -70,47 +71,20 @@
 #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
+	testl %edx,%edx
+	js bad_to_user
 	movl %edx,%ecx
 	xorl %eax,%eax
 	rep
 	stosb
 bad_to_user:
 	movl %edx,%eax
+	pax_force_retaddr
 	ret
 	CFI_ENDPROC
 ENDPROC(bad_from_user)
@@ -141,19 +115,19 @@ ENTRY(copy_user_generic_unrolled)
 	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 +154,7 @@ ENTRY(copy_user_generic_unrolled)
 	jnz 21b
 23:	xor %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 
 	.section .fixup,"ax"
@@ -251,6 +226,7 @@ ENTRY(copy_user_generic_string)
 	movsb
 4:	xorl %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 
 	.section .fixup,"ax"
@@ -286,6 +262,7 @@ ENTRY(copy_user_enhanced_fast_string)
 	movsb
 2:	xorl %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 
 	.section .fixup,"ax"
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/copy_user_nocache_64.S linux-3.8.13-pax/arch/x86/lib/copy_user_nocache_64.S
--- linux-3.8.13/arch/x86/lib/copy_user_nocache_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/copy_user_nocache_64.S	2013-05-06 00:17:42.628737954 +0200
@@ -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,15 @@
  */
 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_STAC
 	cmpl $8,%edx
 	jb 20f		/* less then 8 bytes, go to byte copy loop */
@@ -59,19 +70,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
@@ -99,6 +110,7 @@ ENTRY(__copy_user_nocache)
 23:	xorl %eax,%eax
 	ASM_CLAC
 	sfence
+	pax_force_retaddr
 	ret
 
 	.section .fixup,"ax"
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/csum-copy_64.S linux-3.8.13-pax/arch/x86/lib/csum-copy_64.S
--- linux-3.8.13/arch/x86/lib/csum-copy_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/csum-copy_64.S	2013-02-19 01:14:43.221772706 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/csum-wrappers_64.c linux-3.8.13-pax/arch/x86/lib/csum-wrappers_64.c
--- linux-3.8.13/arch/x86/lib/csum-wrappers_64.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/csum-wrappers_64.c	2013-02-19 01:14:43.225772707 +0100
@@ -52,7 +52,7 @@ csum_partial_copy_from_user(const void _
 			len -= 2;
 		}
 	}
-	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);
 	if (unlikely(*errp))
 		goto out_err;
@@ -105,7 +105,7 @@ csum_partial_copy_to_user(const void *sr
 	}
 
 	*errp = 0;
-	return csum_partial_copy_generic(src, (void __force *)dst,
+	return csum_partial_copy_generic(src, (void __force_kernel *)____m(dst),
 					 len, isum, NULL, errp);
 }
 EXPORT_SYMBOL(csum_partial_copy_to_user);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/getuser.S linux-3.8.13-pax/arch/x86/lib/getuser.S
--- linux-3.8.13/arch/x86/lib/getuser.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/getuser.S	2013-05-06 00:18:18.840736020 +0200
@@ -34,17 +34,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:	movzb (%_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 movzb (%_ASM_AX),%edx
 	xor %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 	CFI_ENDPROC
 ENDPROC(__get_user_1)
@@ -52,14 +75,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)
@@ -67,14 +104,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:	mov -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 mov -3(%_ASM_AX),%edx
 	xor %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 	CFI_ENDPROC
 ENDPROC(__get_user_4)
@@ -87,10 +138,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),%_ASM_DX
 	xor %eax,%eax
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 	CFI_ENDPROC
 ENDPROC(__get_user_8)
@@ -101,6 +162,7 @@ bad_get_user:
 	xor %edx,%edx
 	mov $(-EFAULT),%_ASM_AX
 	ASM_CLAC
+	pax_force_retaddr
 	ret
 	CFI_ENDPROC
 END(bad_get_user)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/insn.c linux-3.8.13-pax/arch/x86/lib/insn.c
--- linux-3.8.13/arch/x86/lib/insn.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/insn.c	2013-02-19 01:14:43.225772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/iomap_copy_64.S linux-3.8.13-pax/arch/x86/lib/iomap_copy_64.S
--- linux-3.8.13/arch/x86/lib/iomap_copy_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/iomap_copy_64.S	2013-02-19 01:14:43.225772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/memcpy_64.S linux-3.8.13-pax/arch/x86/lib/memcpy_64.S
--- linux-3.8.13/arch/x86/lib/memcpy_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/memcpy_64.S	2013-02-19 01:14:43.225772707 +0100
@@ -33,6 +33,7 @@
 	rep movsq
 	movl %edx, %ecx
 	rep movsb
+	pax_force_retaddr
 	ret
 .Lmemcpy_e:
 	.previous
@@ -49,6 +50,7 @@
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/memmove_64.S linux-3.8.13-pax/arch/x86/lib/memmove_64.S
--- linux-3.8.13/arch/x86/lib/memmove_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/memmove_64.S	2013-02-19 01:14:43.225772707 +0100
@@ -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,6 +202,7 @@ ENTRY(memmove)
 	movb (%rsi), %r11b
 	movb %r11b, (%rdi)
 13:
+	pax_force_retaddr
 	retq
 	CFI_ENDPROC
 
@@ -210,6 +211,7 @@ ENTRY(memmove)
 	/* Forward moving data. */
 	movq %rdx, %rcx
 	rep movsb
+	pax_force_retaddr
 	retq
 .Lmemmove_end_forward_efs:
 	.previous
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/memset_64.S linux-3.8.13-pax/arch/x86/lib/memset_64.S
--- linux-3.8.13/arch/x86/lib/memset_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/memset_64.S	2013-02-19 01:14:43.225772707 +0100
@@ -30,6 +30,7 @@
 	movl %edx,%ecx
 	rep stosb
 	movq %r9,%rax
+	pax_force_retaddr
 	ret
 .Lmemset_e:
 	.previous
@@ -52,6 +53,7 @@
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/mmx_32.c linux-3.8.13-pax/arch/x86/lib/mmx_32.c
--- linux-3.8.13/arch/x86/lib/mmx_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/mmx_32.c	2013-02-19 01:14:43.229772707 +0100
@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
 {
 	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 *
 	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, voi
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/msr-reg.S linux-3.8.13-pax/arch/x86/lib/msr-reg.S
--- linux-3.8.13/arch/x86/lib/msr-reg.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/msr-reg.S	2013-02-19 01:14:43.229772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/putuser.S linux-3.8.13-pax/arch/x86/lib/putuser.S
--- linux-3.8.13/arch/x86/lib/putuser.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/putuser.S	2013-05-06 00:17:39.144738140 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/rwlock.S linux-3.8.13-pax/arch/x86/lib/rwlock.S
--- linux-3.8.13/arch/x86/lib/rwlock.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/rwlock.S	2013-02-19 01:14:43.229772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/rwsem.S linux-3.8.13-pax/arch/x86/lib/rwsem.S
--- linux-3.8.13/arch/x86/lib/rwsem.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/rwsem.S	2013-02-19 01:14:43.229772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/thunk_64.S linux-3.8.13-pax/arch/x86/lib/thunk_64.S
--- linux-3.8.13/arch/x86/lib/thunk_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/lib/thunk_64.S	2013-02-19 01:14:43.229772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/usercopy_32.c linux-3.8.13-pax/arch/x86/lib/usercopy_32.c
--- linux-3.8.13/arch/x86/lib/usercopy_32.c	2013-02-19 01:12:52.193766676 +0100
+++ linux-3.8.13-pax/arch/x86/lib/usercopy_32.c	2013-02-19 01:14:43.229772707 +0100
@@ -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
 		       "       .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
 		       "       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
 }
 
 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, cons
 		       "        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, cons
  * hyoshiok@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
 	       "        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
 	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_n
 	       "        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_n
  */
 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 __u
 {
 	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
 {
 	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,66 +743,51 @@ unsigned long __copy_from_user_ll_nocach
 	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)
+void copy_from_user_overflow(void)
 {
-	if (access_ok(VERIFY_WRITE, to, n))
-		n = __copy_to_user(to, from, n);
-	return n;
+	WARN(1, "Buffer overflow detected!\n");
 }
-EXPORT_SYMBOL(copy_to_user);
+EXPORT_SYMBOL(copy_from_user_overflow);
 
-/**
- * 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 copy_to_user_overflow(void)
 {
-	if (access_ok(VERIFY_READ, from, n))
-		n = __copy_from_user(to, from, n);
-	else
-		memset(to, 0, n);
-	return n;
+	WARN(1, "Buffer overflow detected!\n");
 }
-EXPORT_SYMBOL(_copy_from_user);
+EXPORT_SYMBOL(copy_to_user_overflow);
 
-void copy_from_user_overflow(void)
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+void __set_fs(mm_segment_t x)
 {
-	WARN(1, "Buffer overflow detected!\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();
+	}
+	return;
 }
-EXPORT_SYMBOL(copy_from_user_overflow);
+EXPORT_SYMBOL(__set_fs);
+
+void set_fs(mm_segment_t x)
+{
+	current_thread_info()->addr_limit = x;
+	__set_fs(x);
+}
+EXPORT_SYMBOL(set_fs);
+#endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/lib/usercopy_64.c linux-3.8.13-pax/arch/x86/lib/usercopy_64.c
--- linux-3.8.13/arch/x86/lib/usercopy_64.c	2013-03-29 03:21:19.091475508 +0100
+++ linux-3.8.13-pax/arch/x86/lib/usercopy_64.c	2013-03-29 03:21:30.523474897 +0100
@@ -39,7 +39,7 @@ unsigned long __clear_user(void __user *
 		_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();
 	return size;
@@ -54,12 +54,11 @@ unsigned long clear_user(void __user *to
 }
 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,7 +68,7 @@ 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;
@@ -87,3 +86,15 @@ copy_user_handle_tail(char *to, char *fr
 	clac();
 	return len;
 }
+
+void copy_from_user_overflow(void)
+{
+	WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
+
+void copy_to_user_overflow(void)
+{
+	WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_to_user_overflow);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/Makefile linux-3.8.13-pax/arch/x86/Makefile
--- linux-3.8.13/arch/x86/Makefile	2013-02-19 01:12:51.421766634 +0100
+++ linux-3.8.13-pax/arch/x86/Makefile	2013-02-19 01:14:43.233772707 +0100
@@ -50,6 +50,7 @@ else
         UTS_MACHINE := x86_64
         CHECKFLAGS += -D__x86_64__ -m64
 
+        biarch := $(call cc-option,-m64)
         KBUILD_AFLAGS += -m64
         KBUILD_CFLAGS += -m64
 
@@ -230,3 +231,12 @@ define archhelp
   echo  '                  FDARGS="..."  arguments for the booted kernel'
   echo  '                  FDINITRD=file initrd for the booted kernel'
 endef
+
+define OLD_LD
+
+*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
+*** Please upgrade your binutils to 2.18 or newer
+endef
+
+archprepare:
+	$(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/extable.c linux-3.8.13-pax/arch/x86/mm/extable.c
--- linux-3.8.13/arch/x86/mm/extable.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/extable.c	2013-02-19 01:14:43.233772707 +0100
@@ -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
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/fault.c linux-3.8.13-pax/arch/x86/mm/fault.c
--- linux-3.8.13/arch/x86/mm/fault.c	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/mm/fault.c	2013-05-06 00:18:31.432735348 +0200
@@ -13,12 +13,19 @@
 #include <linux/perf_event.h>		/* perf_sw_event		*/
 #include <linux/hugetlb.h>		/* hstate_index_to_shift	*/
 #include <linux/prefetch.h>		/* prefetchw			*/
+#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/context_tracking.h>	/* exception_enter(), ...	*/
+#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_
 	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 *re
 		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, unsign
 	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 s
 	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,22 @@ 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);
+			pmd_t *ret;
+#else
 		list_for_each_entry(page, &pgd_list, lru) {
+			pgd_t *pgd;
 			spinlock_t *pgt_lock;
 			pmd_t *ret;
 
@@ -243,8 +296,14 @@ void vmalloc_sync_all(void)
 			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 +337,11 @@ static noinline __kprobes int vmalloc_fa
 	 * an interrupt in the middle of a task switch..
 	 */
 	pgd_paddr = read_cr3();
+
+#ifdef CONFIG_PAX_PER_CPU_PGD
+	BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (pgd_paddr & PHYSICAL_PAGE_MASK));
+#endif
+
 	pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
 	if (!pmd_k)
 		return -1;
@@ -373,7 +437,14 @@ static noinline __kprobes int vmalloc_fa
 	 * happen within a race in page table update. In the later
 	 * case just flush:
 	 */
+
+#ifdef CONFIG_PAX_PER_CPU_PGD
+	BUG_ON(__pa(get_cpu_pgd(smp_processor_id())) != (read_cr3() & PHYSICAL_PAGE_MASK));
+	pgd = pgd_offset_cpu(smp_processor_id(), address);
+#else
 	pgd = pgd_offset(current->active_mm, address);
+#endif
+
 	pgd_ref = pgd_offset_k(address);
 	if (pgd_none(*pgd_ref))
 		return -1;
@@ -543,7 +614,7 @@ static int is_errata93(struct pt_regs *r
 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 +641,7 @@ static int is_f00f_bug(struct pt_regs *r
 }
 
 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 +650,21 @@ show_fault_oops(struct pt_regs *regs, un
 	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)
+		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 +827,22 @@ __bad_area_nosemaphore(struct pt_regs *r
 				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 +928,7 @@ do_sigbus(struct pt_regs *regs, unsigned
 	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 +991,99 @@ static int spurious_fault_check(unsigned
 	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.
  *
@@ -970,6 +1156,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)))
@@ -998,7 +1187,7 @@ static inline bool smap_violation(int er
 	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;
@@ -1014,19 +1203,34 @@ __do_page_fault(struct pt_regs *regs, un
 {
 	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);
 
+	/* Get the faulting address: */
+	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@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@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;
 
-	/* Get the faulting address: */
-	address = read_cr2();
-
 	/*
 	 * Detect and handle instructions that would cause a page fault for
 	 * both a tracked kernel page and a userspace page.
@@ -1086,7 +1290,7 @@ __do_page_fault(struct pt_regs *regs, un
 	 * 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 {
@@ -1148,6 +1352,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);
@@ -1159,18 +1368,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;
@@ -1234,3 +1449,292 @@ do_page_fault(struct pt_regs *regs, unsi
 	__do_page_fault(regs, error_code);
 	exception_exit(regs);
 }
+
+#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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/gup.c linux-3.8.13-pax/arch/x86/mm/gup.c
--- linux-3.8.13/arch/x86/mm/gup.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/gup.c	2013-02-19 01:14:43.233772707 +0100
@@ -255,7 +255,7 @@ int __get_user_pages_fast(unsigned long
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/highmem_32.c linux-3.8.13-pax/arch/x86/mm/highmem_32.c
--- linux-3.8.13/arch/x86/mm/highmem_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/highmem_32.c	2013-02-19 01:14:43.233772707 +0100
@@ -44,7 +44,11 @@ void *kmap_atomic_prot(struct page *page
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/hugetlbpage.c linux-3.8.13-pax/arch/x86/mm/hugetlbpage.c
--- linux-3.8.13/arch/x86/mm/hugetlbpage.c	2013-02-19 01:12:52.245766679 +0100
+++ linux-3.8.13-pax/arch/x86/mm/hugetlbpage.c	2013-02-19 01:50:57.441890794 +0100
@@ -279,6 +279,12 @@ static unsigned long hugetlb_get_unmappe
 	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;
@@ -311,6 +317,12 @@ static unsigned long hugetlb_get_unmappe
 		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);
 	}
@@ -325,10 +337,19 @@ hugetlb_get_unmapped_area(struct file *f
 	struct hstate *h = hstate_file(file);
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
+	unsigned long pax_task_size = TASK_SIZE;
 
 	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) {
@@ -337,11 +358,14 @@ hugetlb_get_unmapped_area(struct file *f
 		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))
 			return addr;
 	}
 	if (mm->get_unmapped_area == arch_get_unmapped_area)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/init_32.c linux-3.8.13-pax/arch/x86/mm/init_32.c
--- linux-3.8.13/arch/x86/mm/init_32.c	2013-02-19 01:12:52.245766679 +0100
+++ linux-3.8.13-pax/arch/x86/mm/init_32.c	2013-02-19 01:14:43.237772707 +0100
@@ -73,36 +73,6 @@ static __init void *alloc_low_page(void)
 }
 
 /*
- * 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)) {
-		if (after_bootmem)
-			pmd_table = (pmd_t *)alloc_bootmem_pages(PAGE_SIZE);
-		else
-			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:
  */
@@ -122,13 +92,28 @@ static pte_t * __init one_page_table_ini
 			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);
@@ -202,6 +187,7 @@ page_table_range_init(unsigned long star
 	int pgd_idx, pmd_idx;
 	unsigned long vaddr;
 	pgd_t *pgd;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte = NULL;
 
@@ -211,8 +197,13 @@ page_table_range_init(unsigned long star
 	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),
@@ -224,11 +215,20 @@ page_table_range_init(unsigned long star
 	}
 }
 
-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;
 }
 
 /*
@@ -245,9 +245,10 @@ kernel_physical_mapping_init(unsigned lo
 	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;
@@ -280,8 +281,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;
@@ -293,14 +299,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
@@ -310,11 +315,7 @@ repeat:
 					__pgprot(PTE_IDENT_ATTR |
 						 _PAGE_PSE);
 
-				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++;
@@ -331,7 +332,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
@@ -339,7 +340,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++;
@@ -465,7 +466,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) || pmd_huge(*pmd))
 			break;
 
 		pte = pte_offset_kernel(pmd, va);
@@ -514,12 +515,10 @@ void __init early_ioremap_page_table_ran
 
 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 */
@@ -728,6 +727,12 @@ void __init mem_init(void)
 
 	pci_iommu_alloc();
 
+#ifdef CONFIG_PAX_PER_CPU_PGD
+	clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			KERNEL_PGD_PTRS);
+#endif
+
 #ifdef CONFIG_FLATMEM
 	BUG_ON(!mem_map);
 #endif
@@ -754,7 +759,7 @@ void __init mem_init(void)
 			reservedpages++;
 
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
-	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_sdata;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
 	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
@@ -795,10 +800,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);
 
 	/*
@@ -876,6 +881,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);
 
@@ -890,6 +896,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);
 
@@ -918,6 +925,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/init_64.c linux-3.8.13-pax/arch/x86/mm/init_64.c
--- linux-3.8.13/arch/x86/mm/init_64.c	2013-02-19 01:12:52.245766679 +0100
+++ linux-3.8.13-pax/arch/x86/mm/init_64.c	2013-02-19 01:14:43.237772707 +0100
@@ -74,7 +74,7 @@ early_param("gbpages", parse_direct_gbpa
  * 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;
@@ -107,12 +107,22 @@ void sync_global_pgds(unsigned long star
 
 	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, address);
+#else
 		list_for_each_entry(page, &pgd_list, lru) {
 			pgd_t *pgd;
 			spinlock_t *pgt_lock;
@@ -121,6 +131,7 @@ void sync_global_pgds(unsigned long star
 			/* 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);
@@ -128,7 +139,10 @@ void sync_global_pgds(unsigned long star
 				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);
 	}
@@ -161,7 +175,7 @@ static pud_t *fill_pud(pgd_t *pgd, unsig
 {
 	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));
@@ -173,7 +187,7 @@ static pmd_t *fill_pmd(pud_t *pud, unsig
 {
 	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));
@@ -202,7 +216,9 @@ void set_pte_vaddr_pud(pud_t *pud_page,
 	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.
@@ -261,14 +277,12 @@ static void __init __init_extra_mapping(
 		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));
@@ -329,7 +343,7 @@ static __ref void *alloc_low_page(unsign
 	if (pfn >= pgt_buf_top)
 		panic("alloc_low_page: ran out of memory");
 
-	adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
+	adr = (void __force_kernel *)early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
 	clear_page(adr);
 	*phys  = pfn * PAGE_SIZE;
 	return adr;
@@ -345,7 +359,7 @@ static __ref void *map_low_page(void *vi
 
 	phys = __pa(virt);
 	left = phys & (PAGE_SIZE - 1);
-	adr = early_memremap(phys & PAGE_MASK, PAGE_SIZE);
+	adr = (void __force_kernel *)early_memremap(phys & PAGE_MASK, PAGE_SIZE);
 	adr = (void *)(((unsigned long)adr) | left);
 
 	return adr;
@@ -553,7 +567,7 @@ phys_pud_init(pud_t *pud_page, unsigned
 		unmap_low_page(pmd);
 
 		spin_lock(&init_mm.page_table_lock);
-		pud_populate(&init_mm, pud, __va(pmd_phys));
+		pud_populate_kernel(&init_mm, pud, __va(pmd_phys));
 		spin_unlock(&init_mm.page_table_lock);
 	}
 	__flush_tlb_all();
@@ -599,7 +613,7 @@ kernel_physical_mapping_init(unsigned lo
 		unmap_low_page(pud);
 
 		spin_lock(&init_mm.page_table_lock);
-		pgd_populate(&init_mm, pgd, __va(pud_phys));
+		pgd_populate_kernel(&init_mm, pgd, __va(pud_phys));
 		spin_unlock(&init_mm.page_table_lock);
 		pgd_changed = true;
 	}
@@ -693,6 +707,12 @@ void __init mem_init(void)
 
 	pci_iommu_alloc();
 
+#ifdef CONFIG_PAX_PER_CPU_PGD
+	clone_pgd_range(get_cpu_pgd(0) + KERNEL_PGD_BOUNDARY,
+			swapper_pg_dir + KERNEL_PGD_BOUNDARY,
+			KERNEL_PGD_PTRS);
+#endif
+
 	/* clear_bss() already clear the empty_zero_page */
 
 	reservedpages = 0;
@@ -856,8 +876,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)
@@ -891,7 +911,7 @@ int in_gate_area_no_mm(unsigned long add
 
 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/init.c linux-3.8.13-pax/arch/x86/mm/init.c
--- linux-3.8.13/arch/x86/mm/init.c	2013-05-13 02:47:11.137794596 +0200
+++ linux-3.8.13-pax/arch/x86/mm/init.c	2013-05-13 02:51:50.285779691 +0200
@@ -16,6 +16,7 @@
 #include <asm/tlb.h>
 #include <asm/proto.h>
 #include <asm/dma.h>		/* for MAX_DMA_PFN */
+#include <asm/desc.h>
 
 unsigned long __initdata pgt_buf_start;
 unsigned long __meminitdata pgt_buf_end;
@@ -44,7 +45,7 @@ static void __init find_early_table_spac
 {
 	int i;
 	unsigned long puds = 0, pmds = 0, ptes = 0, tables;
-	unsigned long start = 0, good_end;
+	unsigned long start = 0x100000, good_end;
 	unsigned long pgd_extra = 0;
 	phys_addr_t base;
 
@@ -328,7 +329,13 @@ unsigned long __init_refok init_memory_m
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-	if (pagenr < 256)
+	if (!pagenr)
+		return 1;
+#ifdef CONFIG_VM86
+	if (pagenr < (ISA_START_ADDRESS >> PAGE_SHIFT))
+		return 1;
+#endif
+	if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
 		return 1;
 	if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
 		return 0;
@@ -388,6 +395,87 @@ void free_init_pages(char *what, unsigne
 
 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;
+
+	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
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	unsigned long addr, end;
+
+	/* 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 memory",
 			(unsigned long)(&__init_begin),
 			(unsigned long)(&__init_end));
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/iomap_32.c linux-3.8.13-pax/arch/x86/mm/iomap_32.c
--- linux-3.8.13/arch/x86/mm/iomap_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/iomap_32.c	2013-02-19 01:14:43.237772707 +0100
@@ -64,7 +64,11 @@ void *kmap_atomic_prot_pfn(unsigned long
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/ioremap.c linux-3.8.13-pax/arch/x86/mm/ioremap.c
--- linux-3.8.13/arch/x86/mm/ioremap.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/ioremap.c	2013-03-25 23:39:50.558135295 +0100
@@ -97,7 +97,7 @@ static void __iomem *__ioremap_caller(re
 	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;
 
@@ -315,6 +315,9 @@ void *xlate_dev_mem_ptr(unsigned long ph
 
 	/* 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);
@@ -327,6 +330,9 @@ void *xlate_dev_mem_ptr(unsigned long ph
 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));
@@ -344,7 +350,7 @@ static int __init early_ioremap_debug_se
 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)
 {
@@ -381,8 +387,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/kmemcheck/kmemcheck.c linux-3.8.13-pax/arch/x86/mm/kmemcheck/kmemcheck.c
--- linux-3.8.13/arch/x86/mm/kmemcheck/kmemcheck.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/kmemcheck/kmemcheck.c	2013-02-19 01:14:43.237772707 +0100
@@ -622,9 +622,9 @@ bool kmemcheck_fault(struct pt_regs *reg
 	 * 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/mmap.c linux-3.8.13-pax/arch/x86/mm/mmap.c
--- linux-3.8.13/arch/x86/mm/mmap.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/mmap.c	2013-02-19 01:14:43.241772707 +0100
@@ -52,7 +52,7 @@ static unsigned int stack_maxrandom_size
  * 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();
 }
 
@@ -113,11 +126,23 @@ static unsigned long mmap_legacy_base(vo
 void arch_pick_mmap_layout(struct mm_struct *mm)
 {
 	if (mmap_is_legacy()) {
-		mm->mmap_base = mmap_legacy_base();
+		mm->mmap_base = mmap_legacy_base(mm);
+
+#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;
 		mm->unmap_area = arch_unmap_area;
 	} else {
-		mm->mmap_base = mmap_base();
+		mm->mmap_base = mmap_base(mm);
+
+#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;
 		mm->unmap_area = arch_unmap_area_topdown;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/mmio-mod.c linux-3.8.13-pax/arch/x86/mm/mmio-mod.c
--- linux-3.8.13/arch/x86/mm/mmio-mod.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/mmio-mod.c	2013-02-19 01:14:43.241772707 +0100
@@ -194,7 +194,7 @@ static void pre(struct kmmio_probe *p, s
 		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,
 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_
 			.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 o
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/numa.c linux-3.8.13-pax/arch/x86/mm/numa.c
--- linux-3.8.13/arch/x86/mm/numa.c	2013-03-07 04:10:19.719802303 +0100
+++ linux-3.8.13-pax/arch/x86/mm/numa.c	2013-03-13 00:54:18.555367711 +0100
@@ -478,7 +478,7 @@ static bool __init numa_meminfo_cover_me
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pageattr.c linux-3.8.13-pax/arch/x86/mm/pageattr.c
--- linux-3.8.13/arch/x86/mm/pageattr.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/pageattr.c	2013-02-19 01:14:43.241772707 +0100
@@ -261,7 +261,7 @@ static inline pgprot_t static_protection
 	 */
 #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_protection
 	 * 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_protection
 	if (within(pfn, __pa((unsigned long)__start_rodata) >> PAGE_SHIFT,
 		   __pa((unsigned long)__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_protection
 	}
 #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;
@@ -369,23 +378,37 @@ EXPORT_SYMBOL_GPL(lookup_address);
 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);
+#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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pageattr-test.c linux-3.8.13-pax/arch/x86/mm/pageattr-test.c
--- linux-3.8.13/arch/x86/mm/pageattr-test.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/pageattr-test.c	2013-02-19 01:14:43.241772707 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pat.c linux-3.8.13-pax/arch/x86/mm/pat.c
--- linux-3.8.13/arch/x86/mm/pat.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/pat.c	2013-02-19 01:14:43.241772707 +0100
@@ -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(unsig
 
 	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;
@@ -570,7 +570,7 @@ int kernel_map_sync_memtype(u64 base, un
 	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;
@@ -605,7 +605,7 @@ static int reserve_pfn_range(u64 paddr,
 		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),
@@ -627,7 +627,7 @@ static int reserve_pfn_range(u64 paddr,
 			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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pf_in.c linux-3.8.13-pax/arch/x86/mm/pf_in.c
--- linux-3.8.13/arch/x86/mm/pf_in.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/pf_in.c	2013-02-19 01:14:43.241772707 +0100
@@ -148,7 +148,7 @@ enum reason_type get_ins_type(unsigned l
 	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(un
 	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
 	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 l
 	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 l
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pgtable_32.c linux-3.8.13-pax/arch/x86/mm/pgtable_32.c
--- linux-3.8.13/arch/x86/mm/pgtable_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/pgtable_32.c	2013-02-19 01:14:43.241772707 +0100
@@ -47,10 +47,13 @@ void set_pte_vaddr(unsigned long vaddr,
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/pgtable.c linux-3.8.13-pax/arch/x86/mm/pgtable.c
--- linux-3.8.13/arch/x86/mm/pgtable.c	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/mm/pgtable.c	2013-04-30 00:05:07.715842721 +0200
@@ -91,10 +91,64 @@ static inline void pgd_list_del(pgd_t *p
 	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;
+
+	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 +189,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 +202,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 +214,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 +232,38 @@ void pud_populate(struct mm_struct *mm,
 	 */
 	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,51 +276,55 @@ 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;
 	unsigned long addr;
 	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 (addr = i = 0; i < PREALLOCATED_PMDS;
-	     i++, pud++, addr += PUD_SIZE) {
-		pmd_t *pmd = pmds[i];
+#ifdef CONFIG_X86_64
+	pyd = pyd_offset(mm, 0L);
+#else
+	pyd = pyd_offset(pgd, 0L);
+#endif
+
+ 	for (addr = i = 0; i < PREALLOCATED_PXDS;
+	     i++, pyd++, addr += PYD_SIZE) {
+		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);
 
@@ -272,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
@@ -286,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:
@@ -302,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/physaddr.c linux-3.8.13-pax/arch/x86/mm/physaddr.c
--- linux-3.8.13/arch/x86/mm/physaddr.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/physaddr.c	2013-03-13 00:54:18.555367711 +0100
@@ -8,7 +8,7 @@
 
 #ifdef CONFIG_X86_64
 
-unsigned long __phys_addr(unsigned long x)
+unsigned long __intentional_overflow(-1) __phys_addr(unsigned long x)
 {
 	if (x >= __START_KERNEL_map) {
 		x -= __START_KERNEL_map;
@@ -45,7 +45,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)
 {
 	/* VMALLOC_* aren't constants  */
 	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/setup_nx.c linux-3.8.13-pax/arch/x86/mm/setup_nx.c
--- linux-3.8.13/arch/x86/mm/setup_nx.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/mm/setup_nx.c	2013-02-19 01:14:43.245772708 +0100
@@ -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 __cpuinitdata;
 
+#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 __cpuinit 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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/mm/tlb.c linux-3.8.13-pax/arch/x86/mm/tlb.c
--- linux-3.8.13/arch/x86/mm/tlb.c	2013-02-19 01:12:52.257766680 +0100
+++ linux-3.8.13-pax/arch/x86/mm/tlb.c	2013-04-29 22:35:06.719984371 +0200
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/net/bpf_jit_comp.c linux-3.8.13-pax/arch/x86/net/bpf_jit_comp.c
--- linux-3.8.13/arch/x86/net/bpf_jit_comp.c	2013-02-19 01:12:52.273766680 +0100
+++ linux-3.8.13-pax/arch/x86/net/bpf_jit_comp.c	2013-02-19 01:14:43.245772708 +0100
@@ -121,6 +121,11 @@ static inline void bpf_flush_icache(void
 	set_fs(old_fs);
 }
 
+struct bpf_jit_work {
+	struct work_struct work;
+	void *image;
+};
+
 #define CHOOSE_LOAD_FUNC(K, func) \
 	((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset)
 
@@ -147,6 +152,10 @@ void bpf_jit_compile(struct sk_filter *f
 	if (addrs == NULL)
 		return;
 
+	fp->work = kmalloc(sizeof(*fp->work), GFP_KERNEL);
+	if (!fp->work)
+		goto out;
+
 	/* Before first pass, make a rough estimation of addrs[]
 	 * each bpf instruction is translated to less than 64 bytes
 	 */
@@ -648,17 +657,18 @@ cond_branch:			f_offset = addrs[i + filt
 				break;
 			default:
 				/* hmm, too complex filter, give up with jit compiler */
-				goto out;
+				goto error;
 			}
 			ilen = prog - temp;
 			if (image) {
 				if (unlikely(proglen + ilen > oldproglen)) {
 					pr_err("bpb_jit_compile fatal error\n");
-					kfree(addrs);
-					module_free(NULL, image);
-					return;
+					module_free_exec(NULL, image);
+					goto error;
 				}
+				pax_open_kernel();
 				memcpy(image + proglen, temp, ilen);
+				pax_close_kernel();
 			}
 			proglen += ilen;
 			addrs[i] = proglen;
@@ -679,11 +689,9 @@ cond_branch:			f_offset = addrs[i + filt
 			break;
 		}
 		if (proglen == oldproglen) {
-			image = module_alloc(max_t(unsigned int,
-						   proglen,
-						   sizeof(struct work_struct)));
+			image = module_alloc_exec(proglen);
 			if (!image)
-				goto out;
+				goto error;
 		}
 		oldproglen = proglen;
 	}
@@ -699,7 +707,10 @@ cond_branch:			f_offset = addrs[i + filt
 		bpf_flush_icache(image, image + proglen);
 
 		fp->bpf_func = (void *)image;
-	}
+	} else
+error:
+		kfree(fp->work);
+
 out:
 	kfree(addrs);
 	return;
@@ -707,18 +718,20 @@ out:
 
 static void jit_free_defer(struct work_struct *arg)
 {
-	module_free(NULL, arg);
+	module_free_exec(NULL, ((struct bpf_jit_work *)arg)->image);
+	kfree(arg);
 }
 
 /* run from softirq, we must use a work_struct to call
- * module_free() from process context
+ * module_free_exec() from process context
  */
 void bpf_jit_free(struct sk_filter *fp)
 {
 	if (fp->bpf_func != sk_run_filter) {
-		struct work_struct *work = (struct work_struct *)fp->bpf_func;
+		struct work_struct *work = &fp->work->work;
 
 		INIT_WORK(work, jit_free_defer);
+		fp->work->image = fp->bpf_func;
 		schedule_work(work);
 	}
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/net/bpf_jit.S linux-3.8.13-pax/arch/x86/net/bpf_jit.S
--- linux-3.8.13/arch/x86/net/bpf_jit.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/net/bpf_jit.S	2013-02-19 01:14:43.245772708 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/oprofile/backtrace.c linux-3.8.13-pax/arch/x86/oprofile/backtrace.c
--- linux-3.8.13/arch/x86/oprofile/backtrace.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/oprofile/backtrace.c	2013-02-19 01:14:43.245772708 +0100
@@ -46,11 +46,11 @@ dump_user_backtrace_32(struct stack_fram
 	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_bac
 	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 reg
 {
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/oprofile/nmi_int.c linux-3.8.13-pax/arch/x86/oprofile/nmi_int.c
--- linux-3.8.13/arch/x86/oprofile/nmi_int.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/oprofile/nmi_int.c	2013-03-06 23:05:26.216495767 +0100
@@ -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_o
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/oprofile/op_model_amd.c linux-3.8.13-pax/arch/x86/oprofile/op_model_amd.c
--- linux-3.8.13/arch/x86/oprofile/op_model_amd.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/oprofile/op_model_amd.c	2013-03-06 14:56:01.626063609 +0100
@@ -519,9 +519,11 @@ static int op_amd_init(struct oprofile_o
 		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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/oprofile/op_model_ppro.c linux-3.8.13-pax/arch/x86/oprofile/op_model_ppro.c
--- linux-3.8.13/arch/x86/oprofile/op_model_ppro.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/oprofile/op_model_ppro.c	2013-03-06 23:06:56.360490954 +0100
@@ -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(
 
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/oprofile/op_x86_model.h linux-3.8.13-pax/arch/x86/oprofile/op_x86_model.h
--- linux-3.8.13/arch/x86/oprofile/op_x86_model.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/oprofile/op_x86_model.h	2013-03-06 05:48:14.015818484 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/pci/amd_bus.c linux-3.8.13-pax/arch/x86/pci/amd_bus.c
--- linux-3.8.13/arch/x86/pci/amd_bus.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/pci/amd_bus.c	2013-02-20 01:06:23.850068543 +0100
@@ -337,7 +337,7 @@ static int __cpuinit amd_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata amd_cpu_notifier = {
+static struct notifier_block amd_cpu_notifier = {
 	.notifier_call	= amd_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/pci/irq.c linux-3.8.13-pax/arch/x86/pci/irq.c
--- linux-3.8.13/arch/x86/pci/irq.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/pci/irq.c	2013-03-08 15:53:09.106346583 +0100
@@ -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(stru
 	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_irqrout
 	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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/pci/mrst.c linux-3.8.13-pax/arch/x86/pci/mrst.c
--- linux-3.8.13/arch/x86/pci/mrst.c	2013-02-19 01:12:52.289766681 +0100
+++ linux-3.8.13-pax/arch/x86/pci/mrst.c	2013-02-19 01:14:43.245772708 +0100
@@ -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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/pci/pcbios.c linux-3.8.13-pax/arch/x86/pci/pcbios.c
--- linux-3.8.13/arch/x86/pci/pcbios.c	2013-02-19 01:12:52.289766681 +0100
+++ linux-3.8.13-pax/arch/x86/pci/pcbios.c	2013-02-19 01:14:43.249772708 +0100
@@ -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(unsi
 	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 se
 
 	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 se
 			: "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 se
 		*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 se
 			: "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 se
 		*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 se
 			: "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 s
 
 	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 s
 			  "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 s
 			  "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 s
 			  "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_i
 
 	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_i
 		  "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_d
 {
 	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_d
 		: "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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/platform/efi/efi_32.c linux-3.8.13-pax/arch/x86/platform/efi/efi_32.c
--- linux-3.8.13/arch/x86/platform/efi/efi_32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/platform/efi/efi_32.c	2013-02-19 01:14:43.249772708 +0100
@@ -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,6 +69,14 @@ 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);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/platform/efi/efi_stub_32.S linux-3.8.13-pax/arch/x86/platform/efi/efi_stub_32.S
--- linux-3.8.13/arch/x86/platform/efi/efi_stub_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/platform/efi/efi_stub_32.S	2013-02-19 01:14:43.249772708 +0100
@@ -6,7 +6,9 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/page_types.h>
+#include <asm/segment.h>
 
 /*
  * efi_call_phys(void *, ...) is a function with variable parameters.
@@ -20,7 +22,7 @@
  * service functions will comply with gcc calling convention, too.
  */
 
-.text
+__INIT
 ENTRY(efi_call_phys)
 	/*
 	 * 0. The function can only be called in Linux kernel. So CS has been
@@ -36,10 +38,24 @@ ENTRY(efi_call_phys)
 	 * The mapping of lower virtual memory has been created in prelog and
 	 * epilog.
 	 */
-	movl	$1f, %edx
-	subl	$__PAGE_OFFSET, %edx
-	jmp	*%edx
+#ifdef CONFIG_PAX_KERNEXEC
+	movl	$(__KERNEXEC_EFI_DS), %edx
+	mov	%edx, %ds
+	mov	%edx, %es
+	mov	%edx, %ss
+	addl	$2f,(1f)
+	ljmp	*(1f)
+
+__INITDATA
+1:	.long __LOAD_PHYSICAL_ADDR, __KERNEXEC_EFI_CS
+.previous
+
+2:
+	subl	$2b,(1b)
+#else
+	jmp	1f-__PAGE_OFFSET
 1:
+#endif
 
 	/*
 	 * 2. Now on the top of stack is the return
@@ -47,14 +63,8 @@ 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	%edx
-	movl	%edx, saved_return_addr
-	/* get the function pointer into ECX*/
-	popl	%ecx
-	movl	%ecx, efi_rt_function_ptr
-	movl	$2f, %edx
-	subl	$__PAGE_OFFSET, %edx
-	pushl	%edx
+	popl	(saved_return_addr)
+	popl	(efi_rt_function_ptr)
 
 	/*
 	 * 3. Clear PG bit in %CR0.
@@ -73,9 +83,8 @@ ENTRY(efi_call_phys)
 	/*
 	 * 5. Call the physical function.
 	 */
-	jmp	*%ecx
+	call	*(efi_rt_function_ptr-__PAGE_OFFSET)
 
-2:
 	/*
 	 * 6. After EFI runtime service returns, control will return to
 	 * following instruction. We'd better readjust stack pointer first.
@@ -88,35 +97,36 @@ ENTRY(efi_call_phys)
 	movl	%cr0, %edx
 	orl	$0x80000000, %edx
 	movl	%edx, %cr0
-	jmp	1f
-1:
+
 	/*
 	 * 8. Now restore the virtual mode from flat mode by
 	 * adding EIP with PAGE_OFFSET.
 	 */
-	movl	$1f, %edx
-	jmp	*%edx
+#ifdef CONFIG_PAX_KERNEXEC
+	movl	$(__KERNEL_DS), %edx
+	mov	%edx, %ds
+	mov	%edx, %es
+	mov	%edx, %ss
+	ljmp	$(__KERNEL_CS),$1f
+#else
+	jmp	1f+__PAGE_OFFSET
+#endif
 1:
 
 	/*
 	 * 9. Balance the stack. And because EAX contain the return value,
 	 * we'd better not clobber it.
 	 */
-	leal	efi_rt_function_ptr, %edx
-	movl	(%edx), %ecx
-	pushl	%ecx
+	pushl	(efi_rt_function_ptr)
 
 	/*
-	 * 10. Push the saved return address onto the stack and return.
+	 * 10. Return to the saved return address.
 	 */
-	leal	saved_return_addr, %edx
-	movl	(%edx), %ecx
-	pushl	%ecx
-	ret
+	jmpl	*(saved_return_addr)
 ENDPROC(efi_call_phys)
 .previous
 
-.data
+__INITDATA
 saved_return_addr:
 	.long 0
 efi_rt_function_ptr:
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/platform/efi/efi_stub_64.S linux-3.8.13-pax/arch/x86/platform/efi/efi_stub_64.S
--- linux-3.8.13/arch/x86/platform/efi/efi_stub_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/platform/efi/efi_stub_64.S	2013-02-19 01:14:43.249772708 +0100
@@ -7,6 +7,7 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/alternative-asm.h>
 
 #define SAVE_XMM			\
 	mov %rsp, %rax;			\
@@ -40,6 +41,7 @@ ENTRY(efi_call0)
 	call *%rdi
 	addq $32, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call0)
 
@@ -50,6 +52,7 @@ ENTRY(efi_call1)
 	call *%rdi
 	addq $32, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call1)
 
@@ -60,6 +63,7 @@ ENTRY(efi_call2)
 	call *%rdi
 	addq $32, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call2)
 
@@ -71,6 +75,7 @@ ENTRY(efi_call3)
 	call *%rdi
 	addq $32, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call3)
 
@@ -83,6 +88,7 @@ ENTRY(efi_call4)
 	call *%rdi
 	addq $32, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call4)
 
@@ -96,6 +102,7 @@ ENTRY(efi_call5)
 	call *%rdi
 	addq $48, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call5)
 
@@ -112,5 +119,6 @@ ENTRY(efi_call6)
 	call *%rdi
 	addq $48, %rsp
 	RESTORE_XMM
+	pax_force_retaddr 0, 1
 	ret
 ENDPROC(efi_call6)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/platform/mrst/mrst.c linux-3.8.13-pax/arch/x86/platform/mrst/mrst.c
--- linux-3.8.13/arch/x86/platform/mrst/mrst.c	2013-02-19 01:12:52.301766682 +0100
+++ linux-3.8.13-pax/arch/x86/platform/mrst/mrst.c	2013-02-19 01:14:43.249772708 +0100
@@ -78,13 +78,15 @@ struct sfi_rtc_table_entry sfi_mrtc_arra
 EXPORT_SYMBOL_GPL(sfi_mrtc_array);
 int sfi_mrtc_num;
 
-static void mrst_power_off(void)
+static __noreturn void mrst_power_off(void)
 {
+	BUG();
 }
 
-static void mrst_reboot(void)
+static __noreturn void mrst_reboot(void)
 {
 	intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
+	BUG();
 }
 
 /* parse all the mtimer info to a static mtimer array */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/platform/olpc/olpc_dt.c linux-3.8.13-pax/arch/x86/platform/olpc/olpc_dt.c
--- linux-3.8.13/arch/x86/platform/olpc/olpc_dt.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/platform/olpc/olpc_dt.c	2013-02-19 01:14:43.249772708 +0100
@@ -156,7 +156,7 @@ void * __init prom_early_alloc(unsigned
 	return res;
 }
 
-static struct of_pdt_ops prom_olpc_ops __initdata = {
+static struct of_pdt_ops prom_olpc_ops __initconst = {
 	.nextprop = olpc_dt_nextprop,
 	.getproplen = olpc_dt_getproplen,
 	.getproperty = olpc_dt_getproperty,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/power/cpu.c linux-3.8.13-pax/arch/x86/power/cpu.c
--- linux-3.8.13/arch/x86/power/cpu.c	2013-03-22 02:55:24.362089273 +0100
+++ linux-3.8.13-pax/arch/x86/power/cpu.c	2013-03-22 02:55:35.626088671 +0100
@@ -134,7 +134,7 @@ static void do_fpu_end(void)
 static void fix_processor_context(void)
 {
 	int cpu = smp_processor_id();
-	struct tss_struct *t = &per_cpu(init_tss, cpu);
+	struct tss_struct *t = init_tss + cpu;
 
 	set_tss_desc(cpu, t);	/*
 				 * This just modifies memory; should not be
@@ -144,8 +144,6 @@ static void fix_processor_context(void)
 				 */
 
 #ifdef CONFIG_X86_64
-	get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
-
 	syscall_init();				/* This sets MSR_*STAR and related */
 #endif
 	load_TR_desc();				/* This does ltr */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/realmode/init.c linux-3.8.13-pax/arch/x86/realmode/init.c
--- linux-3.8.13/arch/x86/realmode/init.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/realmode/init.c	2013-02-19 01:14:43.249772708 +0100
@@ -62,7 +62,13 @@ void __init setup_real_mode(void)
 		__va(real_mode_header->trampoline_header);
 
 #ifdef CONFIG_X86_32
-	trampoline_header->start = __pa(startup_32_smp);
+	trampoline_header->start = __pa(ktla_ktva(startup_32_smp));
+
+#ifdef CONFIG_PAX_KERNEXEC
+	trampoline_header->start -= LOAD_PHYSICAL_ADDR;
+#endif
+
+	trampoline_header->boot_cs = __BOOT_CS;
 	trampoline_header->gdt_limit = __BOOT_DS + 7;
 	trampoline_header->gdt_base = __pa(boot_gdt);
 #else
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/realmode/rm/header.S linux-3.8.13-pax/arch/x86/realmode/rm/header.S
--- linux-3.8.13/arch/x86/realmode/rm/header.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/realmode/rm/header.S	2013-02-19 01:14:43.253772708 +0100
@@ -30,7 +30,9 @@ GLOBAL(real_mode_header)
 #endif
 	/* APM/BIOS reboot */
 	.long	pa_machine_real_restart_asm
-#ifdef CONFIG_X86_64
+#ifdef CONFIG_X86_32
+	.long	__KERNEL_CS
+#else
 	.long	__KERNEL32_CS
 #endif
 END(real_mode_header)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/realmode/rm/Makefile linux-3.8.13-pax/arch/x86/realmode/rm/Makefile
--- linux-3.8.13/arch/x86/realmode/rm/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/realmode/rm/Makefile	2013-02-19 01:14:43.253772708 +0100
@@ -78,5 +78,8 @@ KBUILD_CFLAGS	:= $(LINUXINCLUDE) -m32 -g
 			$(call cc-option, -fno-unit-at-a-time)) \
 		   $(call cc-option, -fno-stack-protector) \
 		   $(call cc-option, -mpreferred-stack-boundary=2)
+ifdef CONSTIFY_PLUGIN
+KBUILD_CFLAGS	+= -fplugin-arg-constify_plugin-no-constify
+endif
 KBUILD_AFLAGS	:= $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/realmode/rm/trampoline_32.S linux-3.8.13-pax/arch/x86/realmode/rm/trampoline_32.S
--- linux-3.8.13/arch/x86/realmode/rm/trampoline_32.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/realmode/rm/trampoline_32.S	2013-02-19 01:14:43.253772708 +0100
@@ -25,6 +25,12 @@
 #include <asm/page_types.h>
 #include "realmode.h"
 
+#ifdef CONFIG_PAX_KERNEXEC
+#define ta(X) (X)
+#else
+#define ta(X) (pa_ ## X)
+#endif
+
 	.text
 	.code16
 
@@ -39,8 +45,6 @@ ENTRY(trampoline_start)
 
 	cli			# We should be safe anyway
 
-	movl	tr_start, %eax	# where we need to go
-
 	movl	$0xA5A5A5A5, trampoline_status
 				# write marker for master knows we're running
 
@@ -56,7 +60,7 @@ ENTRY(trampoline_start)
 	movw	$1, %dx			# protected mode (PE) bit
 	lmsw	%dx			# into protected mode
 
-	ljmpl	$__BOOT_CS, $pa_startup_32
+	ljmpl *(trampoline_header)
 
 	.section ".text32","ax"
 	.code32
@@ -67,7 +71,7 @@ ENTRY(startup_32)			# note: also used fr
 	.balign 8
 GLOBAL(trampoline_header)
 	tr_start:		.space	4
-	tr_gdt_pad:		.space	2
+	tr_boot_cs:		.space	2
 	tr_gdt:			.space	6
 END(trampoline_header)
 	
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/realmode/rm/trampoline_64.S linux-3.8.13-pax/arch/x86/realmode/rm/trampoline_64.S
--- linux-3.8.13/arch/x86/realmode/rm/trampoline_64.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/realmode/rm/trampoline_64.S	2013-02-19 01:14:43.253772708 +0100
@@ -107,7 +107,7 @@ ENTRY(startup_32)
 	wrmsr
 
 	# Enable paging and in turn activate Long Mode
-	movl	$(X86_CR0_PG | X86_CR0_WP | X86_CR0_PE), %eax
+	movl	$(X86_CR0_PG | X86_CR0_PE), %eax
 	movl	%eax, %cr0
 
 	/*
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/tools/relocs.c linux-3.8.13-pax/arch/x86/tools/relocs.c
--- linux-3.8.13/arch/x86/tools/relocs.c	2013-02-19 01:12:52.333766684 +0100
+++ linux-3.8.13-pax/arch/x86/tools/relocs.c	2013-02-19 01:14:43.253772708 +0100
@@ -12,10 +12,13 @@
 #include <regex.h>
 #include <tools/le_byteshift.h>
 
+#include "../../../include/generated/autoconf.h"
+
 static void die(char *fmt, ...);
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 static Elf32_Ehdr ehdr;
+static Elf32_Phdr *phdr;
 static unsigned long reloc_count, reloc_idx;
 static unsigned long *relocs;
 static unsigned long reloc16_count, reloc16_idx;
@@ -330,9 +333,39 @@ static void read_ehdr(FILE *fp)
 	}
 }
 
+static void read_phdrs(FILE *fp)
+{
+	unsigned int i;
+
+	phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
+	if (!phdr) {
+		die("Unable to allocate %d program headers\n",
+		    ehdr.e_phnum);
+	}
+	if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
+		die("Seek to %d failed: %s\n",
+			ehdr.e_phoff, strerror(errno));
+	}
+	if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
+		die("Cannot read ELF program headers: %s\n",
+			strerror(errno));
+	}
+	for(i = 0; i < ehdr.e_phnum; i++) {
+		phdr[i].p_type      = elf32_to_cpu(phdr[i].p_type);
+		phdr[i].p_offset    = elf32_to_cpu(phdr[i].p_offset);
+		phdr[i].p_vaddr     = elf32_to_cpu(phdr[i].p_vaddr);
+		phdr[i].p_paddr     = elf32_to_cpu(phdr[i].p_paddr);
+		phdr[i].p_filesz    = elf32_to_cpu(phdr[i].p_filesz);
+		phdr[i].p_memsz     = elf32_to_cpu(phdr[i].p_memsz);
+		phdr[i].p_flags     = elf32_to_cpu(phdr[i].p_flags);
+		phdr[i].p_align     = elf32_to_cpu(phdr[i].p_align);
+	}
+
+}
+
 static void read_shdrs(FILE *fp)
 {
-	int i;
+	unsigned int i;
 	Elf32_Shdr shdr;
 
 	secs = calloc(ehdr.e_shnum, sizeof(struct section));
@@ -367,7 +400,7 @@ static void read_shdrs(FILE *fp)
 
 static void read_strtabs(FILE *fp)
 {
-	int i;
+	unsigned int i;
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		struct section *sec = &secs[i];
 		if (sec->shdr.sh_type != SHT_STRTAB) {
@@ -392,7 +425,7 @@ static void read_strtabs(FILE *fp)
 
 static void read_symtabs(FILE *fp)
 {
-	int i,j;
+	unsigned int i,j;
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		struct section *sec = &secs[i];
 		if (sec->shdr.sh_type != SHT_SYMTAB) {
@@ -423,9 +456,11 @@ static void read_symtabs(FILE *fp)
 }
 
 
-static void read_relocs(FILE *fp)
+static void read_relocs(FILE *fp, int use_real_mode)
 {
-	int i,j;
+	unsigned int i,j;
+	uint32_t base;
+
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		struct section *sec = &secs[i];
 		if (sec->shdr.sh_type != SHT_REL) {
@@ -445,9 +480,22 @@ static void read_relocs(FILE *fp)
 			die("Cannot read symbol table: %s\n",
 				strerror(errno));
 		}
+		base = 0;
+
+#ifdef CONFIG_X86_32
+		for (j = 0; !use_real_mode && j < ehdr.e_phnum; j++) {
+			if (phdr[j].p_type != PT_LOAD )
+				continue;
+			if (secs[sec->shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[sec->shdr.sh_info].shdr.sh_offset >= phdr[j].p_offset + phdr[j].p_filesz)
+				continue;
+			base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
+			break;
+		}
+#endif
+
 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
 			Elf32_Rel *rel = &sec->reltab[j];
-			rel->r_offset = elf32_to_cpu(rel->r_offset);
+			rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
 			rel->r_info   = elf32_to_cpu(rel->r_info);
 		}
 	}
@@ -456,13 +504,13 @@ static void read_relocs(FILE *fp)
 
 static void print_absolute_symbols(void)
 {
-	int i;
+	unsigned int i;
 	printf("Absolute symbols\n");
 	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n");
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		struct section *sec = &secs[i];
 		char *sym_strtab;
-		int j;
+		unsigned int j;
 
 		if (sec->shdr.sh_type != SHT_SYMTAB) {
 			continue;
@@ -489,14 +537,14 @@ static void print_absolute_symbols(void)
 
 static void print_absolute_relocs(void)
 {
-	int i, printed = 0;
+	unsigned int i, printed = 0;
 
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		struct section *sec = &secs[i];
 		struct section *sec_applies, *sec_symtab;
 		char *sym_strtab;
 		Elf32_Sym *sh_symtab;
-		int j;
+		unsigned int j;
 		if (sec->shdr.sh_type != SHT_REL) {
 			continue;
 		}
@@ -558,13 +606,13 @@ static void print_absolute_relocs(void)
 static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym),
 			int use_real_mode)
 {
-	int i;
+	unsigned int i;
 	/* Walk through the relocations */
 	for (i = 0; i < ehdr.e_shnum; i++) {
 		char *sym_strtab;
 		Elf32_Sym *sh_symtab;
 		struct section *sec_applies, *sec_symtab;
-		int j;
+		unsigned int j;
 		struct section *sec = &secs[i];
 
 		if (sec->shdr.sh_type != SHT_REL) {
@@ -588,6 +636,24 @@ static void walk_relocs(void (*visit)(El
 			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];
 			r_type = ELF32_R_TYPE(rel->r_info);
 
+			if (!use_real_mode) {
+				/* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
+				if (!strcmp(sec_name(sym->st_shndx), ".data..percpu") && strcmp(sym_name(sym_strtab, sym), "__per_cpu_load"))
+					continue;
+
+#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
+				/* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
+				if (!strcmp(sec_name(sym->st_shndx), ".text.end") && !strcmp(sym_name(sym_strtab, sym), "_etext"))
+					continue;
+				if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
+					continue;
+				if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
+					continue;
+				if (!strcmp(sec_name(sym->st_shndx), ".text") && strcmp(sym_name(sym_strtab, sym), "__LOAD_PHYSICAL_ADDR"))
+					continue;
+#endif
+			}
+
 			shn_abs = sym->st_shndx == SHN_ABS;
 
 			switch (r_type) {
@@ -681,7 +747,7 @@ static int write32(unsigned int v, FILE
 
 static void emit_relocs(int as_text, int use_real_mode)
 {
-	int i;
+	unsigned int i;
 	/* Count how many relocations I have and allocate space for them. */
 	reloc_count = 0;
 	walk_relocs(count_reloc, use_real_mode);
@@ -808,10 +874,11 @@ int main(int argc, char **argv)
 			fname, strerror(errno));
 	}
 	read_ehdr(fp);
+	read_phdrs(fp);
 	read_shdrs(fp);
 	read_strtabs(fp);
 	read_symtabs(fp);
-	read_relocs(fp);
+	read_relocs(fp, use_real_mode);
 	if (show_absolute_syms) {
 		print_absolute_symbols();
 		goto out;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/vdso/Makefile linux-3.8.13-pax/arch/x86/vdso/Makefile
--- linux-3.8.13/arch/x86/vdso/Makefile	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/vdso/Makefile	2013-02-19 01:14:43.253772708 +0100
@@ -181,7 +181,7 @@ quiet_cmd_vdso = VDSO    $@
 		       -Wl,-T,$(filter %.lds,$^) $(filter %.o,$^) && \
 		 sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@'
 
-VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+VDSO_LDFLAGS = -fPIC -shared -Wl,--no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
 GCOV_PROFILE := n
 
 #
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/vdso/vdso32-setup.c linux-3.8.13-pax/arch/x86/vdso/vdso32-setup.c
--- linux-3.8.13/arch/x86/vdso/vdso32-setup.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/vdso/vdso32-setup.c	2013-02-19 01:14:43.253772708 +0100
@@ -25,6 +25,7 @@
 #include <asm/tlbflush.h>
 #include <asm/vdso.h>
 #include <asm/proto.h>
+#include <asm/mman.h>
 
 enum {
 	VDSO_DISABLED = 0,
@@ -226,7 +227,7 @@ static inline void map_compat_vdso(int m
 void enable_sep_cpu(void)
 {
 	int cpu = get_cpu();
-	struct tss_struct *tss = &per_cpu(init_tss, cpu);
+	struct tss_struct *tss = init_tss + cpu;
 
 	if (!boot_cpu_has(X86_FEATURE_SEP)) {
 		put_cpu();
@@ -249,7 +250,7 @@ static int __init gate_vma_init(void)
 	gate_vma.vm_start = FIXADDR_USER_START;
 	gate_vma.vm_end = FIXADDR_USER_END;
 	gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
-	gate_vma.vm_page_prot = __P101;
+	gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
 
 	return 0;
 }
@@ -330,14 +331,14 @@ int arch_setup_additional_pages(struct l
 	if (compat)
 		addr = VDSO_HIGH_BASE;
 	else {
-		addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
+		addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
 		if (IS_ERR_VALUE(addr)) {
 			ret = addr;
 			goto up_fail;
 		}
 	}
 
-	current->mm->context.vdso = (void *)addr;
+	current->mm->context.vdso = addr;
 
 	if (compat_uses_vma || !compat) {
 		/*
@@ -353,11 +354,11 @@ int arch_setup_additional_pages(struct l
 	}
 
 	current_thread_info()->sysenter_return =
-		VDSO32_SYMBOL(addr, SYSENTER_RETURN);
+		(__force void __user *)VDSO32_SYMBOL(addr, SYSENTER_RETURN);
 
   up_fail:
 	if (ret)
-		current->mm->context.vdso = NULL;
+		current->mm->context.vdso = 0;
 
 	up_write(&mm->mmap_sem);
 
@@ -404,8 +405,14 @@ __initcall(ia32_binfmt_init);
 
 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]";
+
+#ifdef CONFIG_PAX_SEGMEXEC
+	if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
+		return "[vdso]";
+#endif
+
 	return NULL;
 }
 
@@ -415,7 +422,7 @@ struct vm_area_struct *get_gate_vma(stru
 	 * Check to see if the corresponding task was created in compat vdso
 	 * mode.
 	 */
-	if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
+	if (mm && mm->context.vdso == VDSO_HIGH_BASE)
 		return &gate_vma;
 	return NULL;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/vdso/vma.c linux-3.8.13-pax/arch/x86/vdso/vma.c
--- linux-3.8.13/arch/x86/vdso/vma.c	2013-02-19 01:12:52.361766685 +0100
+++ linux-3.8.13-pax/arch/x86/vdso/vma.c	2013-02-19 01:14:43.253772708 +0100
@@ -16,8 +16,6 @@
 #include <asm/vdso.h>
 #include <asm/page.h>
 
-unsigned int __read_mostly vdso_enabled = 1;
-
 extern char vdso_start[], vdso_end[];
 extern unsigned short vdso_sync_cpuid;
 
@@ -141,7 +139,6 @@ static unsigned long vdso_addr(unsigned
 	 * unaligned here as a result of stack start randomization.
 	 */
 	addr = PAGE_ALIGN(addr);
-	addr = align_vdso_addr(addr);
 
 	return addr;
 }
@@ -154,30 +151,31 @@ static int setup_additional_pages(struct
 				  unsigned size)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long addr;
+	unsigned long addr = 0;
 	int ret;
 
-	if (!vdso_enabled)
-		return 0;
-
 	down_write(&mm->mmap_sem);
+
+#ifdef CONFIG_PAX_RANDMMAP
+	if (!(mm->pax_flags & MF_PAX_RANDMMAP))
+#endif
+
 	addr = vdso_addr(mm->start_stack, size);
+	addr = align_vdso_addr(addr);
 	addr = get_unmapped_area(NULL, addr, size, 0, 0);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;
 	}
 
-	current->mm->context.vdso = (void *)addr;
+	mm->context.vdso = addr;
 
 	ret = install_special_mapping(mm, addr, size,
 				      VM_READ|VM_EXEC|
 				      VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
 				      pages);
-	if (ret) {
-		current->mm->context.vdso = NULL;
-		goto up_fail;
-	}
+	if (ret)
+		mm->context.vdso = 0;
 
 up_fail:
 	up_write(&mm->mmap_sem);
@@ -197,10 +195,3 @@ int x32_setup_additional_pages(struct li
 				      vdsox32_size);
 }
 #endif
-
-static __init int vdso_setup(char *s)
-{
-	vdso_enabled = simple_strtoul(s, NULL, 0);
-	return 0;
-}
-__setup("vdso=", vdso_setup);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/enlighten.c linux-3.8.13-pax/arch/x86/xen/enlighten.c
--- linux-3.8.13/arch/x86/xen/enlighten.c	2013-05-13 02:47:05.449794899 +0200
+++ linux-3.8.13-pax/arch/x86/xen/enlighten.c	2013-05-13 02:47:30.585793557 +0200
@@ -100,8 +100,6 @@ EXPORT_SYMBOL_GPL(xen_start_info);
 
 struct shared_info xen_dummy_shared_info;
 
-void *xen_initial_gdt;
-
 RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);
 __read_mostly int xen_have_vector_callback;
 EXPORT_SYMBOL_GPL(xen_have_vector_callback);
@@ -496,8 +494,7 @@ static void xen_load_gdt(const struct de
 {
 	unsigned long va = dtr->address;
 	unsigned int size = dtr->size + 1;
-	unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
-	unsigned long frames[pages];
+	unsigned long frames[65536 / PAGE_SIZE];
 	int f;
 
 	/*
@@ -545,8 +542,7 @@ static void __init xen_load_gdt_boot(con
 {
 	unsigned long va = dtr->address;
 	unsigned int size = dtr->size + 1;
-	unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
-	unsigned long frames[pages];
+	unsigned long frames[(GDT_SIZE + PAGE_SIZE - 1) / PAGE_SIZE];
 	int f;
 
 	/*
@@ -554,7 +550,7 @@ static void __init xen_load_gdt_boot(con
 	 * 8-byte entries, or 16 4k pages..
 	 */
 
-	BUG_ON(size > 65536);
+	BUG_ON(size > GDT_SIZE);
 	BUG_ON(va & ~PAGE_MASK);
 
 	for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
@@ -939,7 +935,7 @@ static u32 xen_safe_apic_wait_icr_idle(v
         return 0;
 }
 
-static void set_xen_basic_apic_ops(void)
+static void __init set_xen_basic_apic_ops(void)
 {
 	apic->read = xen_apic_read;
 	apic->write = xen_apic_write;
@@ -1245,30 +1241,30 @@ static const struct pv_apic_ops xen_apic
 #endif
 };
 
-static void xen_reboot(int reason)
+static __noreturn void xen_reboot(int reason)
 {
 	struct sched_shutdown r = { .reason = reason };
 
-	if (HYPERVISOR_sched_op(SCHEDOP_shutdown, &r))
-		BUG();
+	HYPERVISOR_sched_op(SCHEDOP_shutdown, &r);
+	BUG();
 }
 
-static void xen_restart(char *msg)
+static __noreturn void xen_restart(char *msg)
 {
 	xen_reboot(SHUTDOWN_reboot);
 }
 
-static void xen_emergency_restart(void)
+static __noreturn void xen_emergency_restart(void)
 {
 	xen_reboot(SHUTDOWN_reboot);
 }
 
-static void xen_machine_halt(void)
+static __noreturn void xen_machine_halt(void)
 {
 	xen_reboot(SHUTDOWN_poweroff);
 }
 
-static void xen_machine_power_off(void)
+static __noreturn void xen_machine_power_off(void)
 {
 	if (pm_power_off)
 		pm_power_off();
@@ -1370,7 +1366,17 @@ asmlinkage void __init xen_start_kernel(
 	__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
 
 	/* Work out if we support NX */
-	x86_configure_nx();
+#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
+	if ((cpuid_eax(0x80000000) & 0xffff0000) == 0x80000000 &&
+	    (cpuid_edx(0x80000001) & (1U << (X86_FEATURE_NX & 31)))) {
+		unsigned l, h;
+
+		__supported_pte_mask |= _PAGE_NX;
+		rdmsr(MSR_EFER, l, h);
+		l |= EFER_NX;
+		wrmsr(MSR_EFER, l, h);
+	}
+#endif
 
 	xen_setup_features();
 
@@ -1401,13 +1407,6 @@ asmlinkage void __init xen_start_kernel(
 
 	machine_ops = xen_machine_ops;
 
-	/*
-	 * The only reliable way to retain the initial address of the
-	 * percpu gdt_page is to remember it here, so we can go and
-	 * mark it RW later, when the initial percpu area is freed.
-	 */
-	xen_initial_gdt = &per_cpu(gdt_page, 0);
-
 	xen_smp_init();
 
 #ifdef CONFIG_ACPI_NUMA
@@ -1601,7 +1600,7 @@ static int __cpuinit xen_hvm_cpu_notify(
 	return NOTIFY_OK;
 }
 
-static struct notifier_block xen_hvm_cpu_notifier __cpuinitdata = {
+static struct notifier_block xen_hvm_cpu_notifier = {
 	.notifier_call	= xen_hvm_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/mmu.c linux-3.8.13-pax/arch/x86/xen/mmu.c
--- linux-3.8.13/arch/x86/xen/mmu.c	2013-04-30 00:04:53.391843486 +0200
+++ linux-3.8.13-pax/arch/x86/xen/mmu.c	2013-04-30 00:05:07.715842721 +0200
@@ -1881,6 +1881,9 @@ void __init xen_setup_kernel_pagetable(p
 	/* L3_k[510] -> level2_kernel_pgt
 	 * L3_i[511] -> level2_fixmap_pgt */
 	convert_pfn_mfn(level3_kernel_pgt);
+	convert_pfn_mfn(level3_vmalloc_start_pgt);
+	convert_pfn_mfn(level3_vmalloc_end_pgt);
+	convert_pfn_mfn(level3_vmemmap_pgt);
 
 	/* We get [511][511] and have Xen's version of level2_kernel_pgt */
 	l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
@@ -1910,8 +1913,12 @@ void __init xen_setup_kernel_pagetable(p
 	set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
 	set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
 	set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_vmalloc_start_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_vmalloc_end_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
 	set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
 	set_page_prot(level2_ident_pgt, PAGE_KERNEL_RO);
+	set_page_prot(level2_vmemmap_pgt, PAGE_KERNEL_RO);
 	set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
 	set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
 
@@ -2097,6 +2104,7 @@ static void __init xen_post_allocator_in
 	pv_mmu_ops.set_pud = xen_set_pud;
 #if PAGETABLE_LEVELS == 4
 	pv_mmu_ops.set_pgd = xen_set_pgd;
+	pv_mmu_ops.set_pgd_batched = xen_set_pgd;
 #endif
 
 	/* This will work as long as patching hasn't happened yet
@@ -2178,6 +2186,7 @@ static const struct pv_mmu_ops xen_mmu_o
 	.pud_val = PV_CALLEE_SAVE(xen_pud_val),
 	.make_pud = PV_CALLEE_SAVE(xen_make_pud),
 	.set_pgd = xen_set_pgd_hyper,
+	.set_pgd_batched = xen_set_pgd_hyper,
 
 	.alloc_pud = xen_alloc_pmd_init,
 	.release_pud = xen_release_pmd_init,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/smp.c linux-3.8.13-pax/arch/x86/xen/smp.c
--- linux-3.8.13/arch/x86/xen/smp.c	2013-05-13 02:47:05.449794899 +0200
+++ linux-3.8.13-pax/arch/x86/xen/smp.c	2013-05-13 02:47:30.585793557 +0200
@@ -229,11 +229,6 @@ static void __init xen_smp_prepare_boot_
 {
 	BUG_ON(smp_processor_id() != 0);
 	native_smp_prepare_boot_cpu();
-
-	/* We've switched to the "real" per-cpu gdt, so make sure the
-	   old memory can be recycled */
-	make_lowmem_page_readwrite(xen_initial_gdt);
-
 	xen_filter_cpu_maps();
 	xen_setup_vcpu_info_placement();
 }
@@ -300,12 +295,12 @@ cpu_initialize_context(unsigned int cpu,
 	gdt = get_cpu_gdt_table(cpu);
 
 	ctxt->flags = VGCF_IN_KERNEL;
-	ctxt->user_regs.ds = __USER_DS;
-	ctxt->user_regs.es = __USER_DS;
+	ctxt->user_regs.ds = __KERNEL_DS;
+	ctxt->user_regs.es = __KERNEL_DS;
 	ctxt->user_regs.ss = __KERNEL_DS;
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
-	ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
+	savesegment(gs, ctxt->user_regs.gs);
 #else
 	ctxt->gs_base_kernel = per_cpu_offset(cpu);
 #endif
@@ -355,13 +350,12 @@ static int __cpuinit xen_cpu_up(unsigned
 	int rc;
 
 	per_cpu(current_task, cpu) = idle;
+	per_cpu(current_tinfo, cpu) = &idle->tinfo;
 #ifdef CONFIG_X86_32
 	irq_ctx_init(cpu);
 #else
 	clear_tsk_thread_flag(idle, TIF_FORK);
-	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
 	xen_setup_runstate_info(cpu);
 	xen_setup_timer(cpu);
@@ -630,7 +624,7 @@ static const struct smp_ops xen_smp_ops
 
 void __init xen_smp_init(void)
 {
-	smp_ops = xen_smp_ops;
+	memcpy((void *)&smp_ops, &xen_smp_ops, sizeof smp_ops);
 	xen_fill_possible_map();
 	xen_init_spinlocks();
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/xen-asm_32.S linux-3.8.13-pax/arch/x86/xen/xen-asm_32.S
--- linux-3.8.13/arch/x86/xen/xen-asm_32.S	2013-02-19 01:12:52.365766685 +0100
+++ linux-3.8.13-pax/arch/x86/xen/xen-asm_32.S	2013-02-19 01:15:38.681775719 +0100
@@ -84,14 +84,14 @@ ENTRY(xen_iret)
 	ESP_OFFSET=4	# bytes pushed onto stack
 
 	/*
-	 * Store vcpu_info pointer for easy access.  Do it this way to
-	 * avoid having to reload %fs
+	 * Store vcpu_info pointer for easy access.
 	 */
 #ifdef CONFIG_SMP
-	GET_THREAD_INFO(%eax)
-	movl %ss:TI_cpu(%eax), %eax
-	movl %ss:__per_cpu_offset(,%eax,4), %eax
-	mov %ss:xen_vcpu(%eax), %eax
+	push %fs
+	mov $(__KERNEL_PERCPU), %eax
+	mov %eax, %fs
+	mov PER_CPU_VAR(xen_vcpu), %eax
+	pop %fs
 #else
 	movl %ss:xen_vcpu, %eax
 #endif
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/xen-head.S linux-3.8.13-pax/arch/x86/xen/xen-head.S
--- linux-3.8.13/arch/x86/xen/xen-head.S	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/xen/xen-head.S	2013-02-19 01:14:43.257772708 +0100
@@ -19,6 +19,17 @@ ENTRY(startup_xen)
 #ifdef CONFIG_X86_32
 	mov %esi,xen_start_info
 	mov $init_thread_union+THREAD_SIZE,%esp
+#ifdef CONFIG_SMP
+	movl $cpu_gdt_table,%edi
+	movl $__per_cpu_load,%eax
+	movw %ax,__KERNEL_PERCPU + 2(%edi)
+	rorl $16,%eax
+	movb %al,__KERNEL_PERCPU + 4(%edi)
+	movb %ah,__KERNEL_PERCPU + 7(%edi)
+	movl $__per_cpu_end - 1,%eax
+	subl $__per_cpu_start,%eax
+	movw %ax,__KERNEL_PERCPU + 0(%edi)
+#endif
 #else
 	mov %rsi,xen_start_info
 	mov $init_thread_union+THREAD_SIZE,%rsp
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/arch/x86/xen/xen-ops.h linux-3.8.13-pax/arch/x86/xen/xen-ops.h
--- linux-3.8.13/arch/x86/xen/xen-ops.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/arch/x86/xen/xen-ops.h	2013-02-19 01:14:43.261772709 +0100
@@ -10,8 +10,6 @@
 extern const char xen_hypervisor_callback[];
 extern const char xen_failsafe_callback[];
 
-extern void *xen_initial_gdt;
-
 struct trap_info;
 void xen_copy_trap_info(struct trap_info *traps);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/blk-iopoll.c linux-3.8.13-pax/block/blk-iopoll.c
--- linux-3.8.13/block/blk-iopoll.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/blk-iopoll.c	2013-02-20 00:58:24.074094159 +0100
@@ -77,7 +77,7 @@ void blk_iopoll_complete(struct blk_iopo
 }
 EXPORT_SYMBOL(blk_iopoll_complete);
 
-static void blk_iopoll_softirq(struct softirq_action *h)
+static void blk_iopoll_softirq(void)
 {
 	struct list_head *list = &__get_cpu_var(blk_cpu_iopoll);
 	int rearm = 0, budget = blk_iopoll_budget;
@@ -209,7 +209,7 @@ static int __cpuinit blk_iopoll_cpu_noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata blk_iopoll_cpu_notifier = {
+static struct notifier_block blk_iopoll_cpu_notifier = {
 	.notifier_call	= blk_iopoll_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/blk-map.c linux-3.8.13-pax/block/blk-map.c
--- linux-3.8.13/block/blk-map.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/blk-map.c	2013-02-19 01:14:43.265772709 +0100
@@ -302,7 +302,7 @@ int blk_rq_map_kern(struct request_queue
 	if (!len || !kbuf)
 		return -EINVAL;
 
-	do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf);
+	do_copy = !blk_rq_aligned(q, addr, len) || object_starts_on_stack(kbuf);
 	if (do_copy)
 		bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading);
 	else
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/blk-softirq.c linux-3.8.13-pax/block/blk-softirq.c
--- linux-3.8.13/block/blk-softirq.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/blk-softirq.c	2013-02-20 00:58:35.554093546 +0100
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head,
  * Softirq action handler - move entries to local list and loop over them
  * while passing them to the queue registered handler.
  */
-static void blk_done_softirq(struct softirq_action *h)
+static void blk_done_softirq(void)
 {
 	struct list_head *cpu_list, local_list;
 
@@ -98,7 +98,7 @@ static int __cpuinit blk_cpu_notify(stru
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata blk_cpu_notifier = {
+static struct notifier_block blk_cpu_notifier = {
 	.notifier_call	= blk_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/bsg.c linux-3.8.13-pax/block/bsg.c
--- linux-3.8.13/block/bsg.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/bsg.c	2013-02-19 01:14:43.269772709 +0100
@@ -176,16 +176,24 @@ static int blk_fill_sgv4_hdr_rq(struct r
 				struct sg_io_v4 *hdr, struct bsg_device *bd,
 				fmode_t has_write_perm)
 {
+	unsigned char tmpcmd[sizeof(rq->__cmd)];
+	unsigned char *cmdptr;
+
 	if (hdr->request_len > BLK_MAX_CDB) {
 		rq->cmd = kzalloc(hdr->request_len, GFP_KERNEL);
 		if (!rq->cmd)
 			return -ENOMEM;
-	}
+		cmdptr = rq->cmd;
+	} else
+		cmdptr = tmpcmd;
 
-	if (copy_from_user(rq->cmd, (void __user *)(unsigned long)hdr->request,
+	if (copy_from_user(cmdptr, (void __user *)(unsigned long)hdr->request,
 			   hdr->request_len))
 		return -EFAULT;
 
+	if (cmdptr != rq->cmd)
+		memcpy(rq->cmd, cmdptr, hdr->request_len);
+
 	if (hdr->subprotocol == BSG_SUB_PROTOCOL_SCSI_CMD) {
 		if (blk_verify_command(rq->cmd, has_write_perm))
 			return -EPERM;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/compat_ioctl.c linux-3.8.13-pax/block/compat_ioctl.c
--- linux-3.8.13/block/compat_ioctl.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/compat_ioctl.c	2013-02-19 01:14:43.289772710 +0100
@@ -340,7 +340,7 @@ static int compat_fd_ioctl(struct block_
 		err |= __get_user(f->spec1, &uf->spec1);
 		err |= __get_user(f->fmt_gap, &uf->fmt_gap);
 		err |= __get_user(name, &uf->name);
-		f->name = compat_ptr(name);
+		f->name = (void __force_kernel *)compat_ptr(name);
 		if (err) {
 			err = -EFAULT;
 			goto out;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/partitions/efi.c linux-3.8.13-pax/block/partitions/efi.c
--- linux-3.8.13/block/partitions/efi.c	2013-02-19 01:12:52.677766702 +0100
+++ linux-3.8.13-pax/block/partitions/efi.c	2013-02-19 01:14:43.289772710 +0100
@@ -234,14 +234,14 @@ static gpt_entry *alloc_read_gpt_entries
 	if (!gpt)
 		return NULL;
 
-	count = le32_to_cpu(gpt->num_partition_entries) *
-                le32_to_cpu(gpt->sizeof_partition_entry);
-	if (!count)
+	if (!le32_to_cpu(gpt->num_partition_entries))
 		return NULL;
-	pte = kzalloc(count, GFP_KERNEL);
+	pte = kcalloc(le32_to_cpu(gpt->num_partition_entries), le32_to_cpu(gpt->sizeof_partition_entry), GFP_KERNEL);
 	if (!pte)
 		return NULL;
 
+	count = le32_to_cpu(gpt->num_partition_entries) *
+                le32_to_cpu(gpt->sizeof_partition_entry);
 	if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba),
                      (u8 *) pte,
 		     count) < count) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/block/scsi_ioctl.c linux-3.8.13-pax/block/scsi_ioctl.c
--- linux-3.8.13/block/scsi_ioctl.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/block/scsi_ioctl.c	2013-02-19 01:14:43.289772710 +0100
@@ -223,8 +223,20 @@ EXPORT_SYMBOL(blk_verify_command);
 static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
 			     struct sg_io_hdr *hdr, fmode_t mode)
 {
-	if (copy_from_user(rq->cmd, hdr->cmdp, hdr->cmd_len))
+	unsigned char tmpcmd[sizeof(rq->__cmd)];
+	unsigned char *cmdptr;
+
+	if (rq->cmd != rq->__cmd)
+		cmdptr = rq->cmd;
+	else
+		cmdptr = tmpcmd;
+
+	if (copy_from_user(cmdptr, hdr->cmdp, hdr->cmd_len))
 		return -EFAULT;
+
+	if (cmdptr != rq->cmd)
+		memcpy(rq->cmd, cmdptr, hdr->cmd_len);
+
 	if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
 		return -EPERM;
 
@@ -433,6 +445,8 @@ int sg_scsi_ioctl(struct request_queue *
 	int err;
 	unsigned int in_len, out_len, bytes, opcode, cmdlen;
 	char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
+	unsigned char tmpcmd[sizeof(rq->__cmd)];
+	unsigned char *cmdptr;
 
 	if (!sic)
 		return -EINVAL;
@@ -466,9 +480,18 @@ int sg_scsi_ioctl(struct request_queue *
 	 */
 	err = -EFAULT;
 	rq->cmd_len = cmdlen;
-	if (copy_from_user(rq->cmd, sic->data, cmdlen))
+
+	if (rq->cmd != rq->__cmd)
+		cmdptr = rq->cmd;
+	else
+		cmdptr = tmpcmd;
+
+	if (copy_from_user(cmdptr, sic->data, cmdlen))
 		goto error;
 
+	if (rq->cmd != cmdptr)
+		memcpy(rq->cmd, cmdptr, cmdlen);
+
 	if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
 		goto error;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/crypto/cryptd.c linux-3.8.13-pax/crypto/cryptd.c
--- linux-3.8.13/crypto/cryptd.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/crypto/cryptd.c	2013-02-19 01:14:43.289772710 +0100
@@ -63,7 +63,7 @@ struct cryptd_blkcipher_ctx {
 
 struct cryptd_blkcipher_request_ctx {
 	crypto_completion_t complete;
-};
+} __no_const;
 
 struct cryptd_hash_ctx {
 	struct crypto_shash *child;
@@ -80,7 +80,7 @@ struct cryptd_aead_ctx {
 
 struct cryptd_aead_request_ctx {
 	crypto_completion_t complete;
-};
+} __no_const;
 
 static void cryptd_queue_worker(struct work_struct *work);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/Documentation/dontdiff linux-3.8.13-pax/Documentation/dontdiff
--- linux-3.8.13/Documentation/dontdiff	2013-02-19 01:12:34.605765721 +0100
+++ linux-3.8.13-pax/Documentation/dontdiff	2013-02-26 20:07:05.536689086 +0100
@@ -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,6 +75,7 @@ Image
 Module.markers
 Module.symvers
 PENDING
+PERF*
 SCCS
 System.map*
 TAGS
@@ -80,6 +87,7 @@ aic7*seq.h*
 aicasm
 aicdb.h*
 altivec*.c
+ashldi3.S
 asm-offsets.h
 asm_offsets.h
 autoconf.h*
@@ -92,19 +100,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 +128,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 +140,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 +163,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 +180,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 +204,8 @@ oui.c*
 page-types
 parse.c
 parse.h
+parse-events*
+pasyms.h
 patches*
 pca200e.bin
 pca200e_ecd.bin2
@@ -194,6 +215,7 @@ perf-archive
 piggyback
 piggy.gzip
 piggy.S
+pmu-*
 pnmtologo
 ppc_defs.h*
 pss_boot.h
@@ -203,7 +225,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 +238,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 +253,7 @@ tftpboot.img
 timeconst.h
 times.h*
 trix_boot.h
+user_constants.h
 utsrelease.h*
 vdso-syms.lds
 vdso.lds
@@ -235,13 +265,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 +283,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 -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/Documentation/kernel-parameters.txt linux-3.8.13-pax/Documentation/kernel-parameters.txt
--- linux-3.8.13/Documentation/kernel-parameters.txt	2013-03-07 04:10:19.371802322 +0100
+++ linux-3.8.13-pax/Documentation/kernel-parameters.txt	2013-03-10 02:37:24.919083325 +0100
@@ -2121,6 +2121,18 @@ bytes respectively. Such letter suffixes
 			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_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.
+
 	pcbit=		[HW,ISDN]
 
 	pcd.		[PARIDE]
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/apei/apei-internal.h linux-3.8.13-pax/drivers/acpi/apei/apei-internal.h
--- linux-3.8.13/drivers/acpi/apei/apei-internal.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/acpi/apei/apei-internal.h	2013-03-06 05:33:52.979864457 +0100
@@ -20,7 +20,7 @@ typedef int (*apei_exec_ins_func_t)(stru
 struct apei_exec_ins_type {
 	u32 flags;
 	apei_exec_ins_func_t run;
-};
+} __do_const;
 
 struct apei_exec_context {
 	u32 ip;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/apei/cper.c linux-3.8.13-pax/drivers/acpi/apei/cper.c
--- linux-3.8.13/drivers/acpi/apei/cper.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/acpi/apei/cper.c	2013-02-19 01:14:43.309772711 +0100
@@ -38,12 +38,12 @@
  */
 u64 cper_next_record_id(void)
 {
-	static atomic64_t seq;
+	static atomic64_unchecked_t seq;
 
-	if (!atomic64_read(&seq))
-		atomic64_set(&seq, ((u64)get_seconds()) << 32);
+	if (!atomic64_read_unchecked(&seq))
+		atomic64_set_unchecked(&seq, ((u64)get_seconds()) << 32);
 
-	return atomic64_inc_return(&seq);
+	return atomic64_inc_return_unchecked(&seq);
 }
 EXPORT_SYMBOL_GPL(cper_next_record_id);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/bgrt.c linux-3.8.13-pax/drivers/acpi/bgrt.c
--- linux-3.8.13/drivers/acpi/bgrt.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/acpi/bgrt.c	2013-03-05 17:41:53.338145355 +0100
@@ -87,8 +87,10 @@ static int __init bgrt_init(void)
 		return -ENODEV;
 
 	sysfs_bin_attr_init(&image_attr);
-	image_attr.private = bgrt_image;
-	image_attr.size = bgrt_image_size;
+	pax_open_kernel();
+	*(void **)&image_attr.private = bgrt_image;
+	*(size_t *)&image_attr.size = bgrt_image_size;
+	pax_close_kernel();
 
 	bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
 	if (!bgrt_kobj)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/blacklist.c linux-3.8.13-pax/drivers/acpi/blacklist.c
--- linux-3.8.13/drivers/acpi/blacklist.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/acpi/blacklist.c	2013-03-09 17:49:31.068774463 +0100
@@ -52,7 +52,7 @@ struct acpi_blacklist_item {
 	u32 is_critical_error;
 };
 
-static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
+static const struct dmi_system_id acpi_osi_dmi_table[] __initconst;
 
 /*
  * POLICY: If *anything* doesn't work, put it on the blacklist.
@@ -193,7 +193,7 @@ static int __init dmi_disable_osi_win7(c
 	return 0;
 }
 
-static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
+static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = {
 	{
 	.callback = dmi_disable_osi_vista,
 	.ident = "Fujitsu Siemens",
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/ec_sys.c linux-3.8.13-pax/drivers/acpi/ec_sys.c
--- linux-3.8.13/drivers/acpi/ec_sys.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/acpi/ec_sys.c	2013-02-19 01:14:43.309772711 +0100
@@ -12,6 +12,7 @@
 #include <linux/acpi.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,7 @@ static ssize_t acpi_ec_read_io(struct fi
 	 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
 	 */
 	unsigned int size = EC_SPACE_SIZE;
-	u8 *data = (u8 *) buf;
+	u8 data;
 	loff_t init_off = *off;
 	int err = 0;
 
@@ -47,9 +48,11 @@ static ssize_t acpi_ec_read_io(struct fi
 		size = count;
 
 	while (size) {
-		err = ec_read(*off, &data[*off - init_off]);
+		err = ec_read(*off, &data);
 		if (err)
 			return err;
+		if (put_user(data, &buf[*off - init_off]))
+			return -EFAULT;
 		*off += 1;
 		size--;
 	}
@@ -65,7 +68,6 @@ static ssize_t acpi_ec_write_io(struct f
 
 	unsigned int size = count;
 	loff_t init_off = *off;
-	u8 *data = (u8 *) buf;
 	int err = 0;
 
 	if (*off >= EC_SPACE_SIZE)
@@ -76,7 +78,9 @@ static ssize_t acpi_ec_write_io(struct f
 	}
 
 	while (size) {
-		u8 byte_write = data[*off - init_off];
+		u8 byte_write;
+		if (get_user(byte_write, &buf[*off - init_off]))
+			return -EFAULT;
 		err = ec_write(*off, byte_write);
 		if (err)
 			return err;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/processor_driver.c linux-3.8.13-pax/drivers/acpi/processor_driver.c
--- linux-3.8.13/drivers/acpi/processor_driver.c	2013-02-19 01:12:53.161766729 +0100
+++ linux-3.8.13-pax/drivers/acpi/processor_driver.c	2013-02-19 01:14:43.309772711 +0100
@@ -558,7 +558,7 @@ static int __cpuinit acpi_processor_add(
 		return 0;
 #endif
 
-	BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+	BUG_ON(pr->id >= nr_cpu_ids);
 
 	/*
 	 * Buggy BIOS check
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/processor_idle.c linux-3.8.13-pax/drivers/acpi/processor_idle.c
--- linux-3.8.13/drivers/acpi/processor_idle.c	2013-02-19 01:12:53.161766729 +0100
+++ linux-3.8.13-pax/drivers/acpi/processor_idle.c	2013-03-06 03:08:47.300329273 +0100
@@ -1005,7 +1005,7 @@ static int acpi_processor_setup_cpuidle_
 {
 	int i, count = CPUIDLE_DRIVER_STATE_START;
 	struct acpi_processor_cx *cx;
-	struct cpuidle_state *state;
+	cpuidle_state_no_const *state;
 	struct cpuidle_driver *drv = &acpi_idle_driver;
 
 	if (!pr->flags.power_setup_done)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/acpi/sysfs.c linux-3.8.13-pax/drivers/acpi/sysfs.c
--- linux-3.8.13/drivers/acpi/sysfs.c	2013-02-19 01:12:53.173766729 +0100
+++ linux-3.8.13-pax/drivers/acpi/sysfs.c	2013-02-21 04:46:42.213045285 +0100
@@ -420,11 +420,11 @@ static u32 num_counters;
 static struct attribute **all_attrs;
 static u32 acpi_gpe_count;
 
-static struct attribute_group interrupt_stats_attr_group = {
+static attribute_group_no_const interrupt_stats_attr_group = {
 	.name = "interrupts",
 };
 
-static struct kobj_attribute *counter_attrs;
+static kobj_attribute_no_const *counter_attrs;
 
 static void delete_gpe_attr_array(void)
 {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/ata/libahci.c linux-3.8.13-pax/drivers/ata/libahci.c
--- linux-3.8.13/drivers/ata/libahci.c	2013-02-19 01:12:53.197766731 +0100
+++ linux-3.8.13-pax/drivers/ata/libahci.c	2013-03-13 00:54:18.555367711 +0100
@@ -1230,7 +1230,7 @@ int ahci_kick_engine(struct ata_port *ap
 }
 EXPORT_SYMBOL_GPL(ahci_kick_engine);
 
-static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
+static int __intentional_overflow(-1) ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
 				struct ata_taskfile *tf, int is_cmd, u16 flags,
 				unsigned long timeout_msec)
 {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/ata/libata-core.c linux-3.8.13-pax/drivers/ata/libata-core.c
--- linux-3.8.13/drivers/ata/libata-core.c	2013-04-13 00:55:42.599157671 +0200
+++ linux-3.8.13-pax/drivers/ata/libata-core.c	2013-04-13 00:55:48.619157350 +0200
@@ -4784,7 +4784,7 @@ void ata_qc_free(struct ata_queued_cmd *
 	struct ata_port *ap;
 	unsigned int tag;
 
-	WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
+	BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
 	ap = qc->ap;
 
 	qc->flags = 0;
@@ -4800,7 +4800,7 @@ void __ata_qc_complete(struct ata_queued
 	struct ata_port *ap;
 	struct ata_link *link;
 
-	WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
+	BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
 	WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
 	ap = qc->ap;
 	link = qc->dev->link;
@@ -5896,6 +5896,7 @@ static void ata_finalize_port_ops(struct
 		return;
 
 	spin_lock(&lock);
+	pax_open_kernel();
 
 	for (cur = ops->inherits; cur; cur = cur->inherits) {
 		void **inherit = (void **)cur;
@@ -5909,8 +5910,9 @@ static void ata_finalize_port_ops(struct
 		if (IS_ERR(*pp))
 			*pp = NULL;
 
-	ops->inherits = NULL;
+	*(struct ata_port_operations **)&ops->inherits = NULL;
 
+	pax_close_kernel();
 	spin_unlock(&lock);
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/ata/pata_arasan_cf.c linux-3.8.13-pax/drivers/ata/pata_arasan_cf.c
--- linux-3.8.13/drivers/ata/pata_arasan_cf.c	2013-02-19 01:12:53.209766731 +0100
+++ linux-3.8.13-pax/drivers/ata/pata_arasan_cf.c	2013-02-19 01:14:43.333772712 +0100
@@ -864,7 +864,9 @@ static int arasan_cf_probe(struct platfo
 	/* Handle platform specific quirks */
 	if (pdata->quirk) {
 		if (pdata->quirk & CF_BROKEN_PIO) {
-			ap->ops->set_piomode = NULL;
+			pax_open_kernel();
+			*(void **)&ap->ops->set_piomode = NULL;
+			pax_close_kernel();
 			ap->pio_mask = 0;
 		}
 		if (pdata->quirk & CF_BROKEN_MWDMA)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/adummy.c linux-3.8.13-pax/drivers/atm/adummy.c
--- linux-3.8.13/drivers/atm/adummy.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/atm/adummy.c	2013-02-19 01:14:43.333772712 +0100
@@ -114,7 +114,7 @@ adummy_send(struct atm_vcc *vcc, struct
 		vcc->pop(vcc, skb);
 	else
 		dev_kfree_skb_any(skb);
-	atomic_inc(&vcc->stats->tx);
+	atomic_inc_unchecked(&vcc->stats->tx);
 
 	return 0;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/ambassador.c linux-3.8.13-pax/drivers/atm/ambassador.c
--- linux-3.8.13/drivers/atm/ambassador.c	2013-02-19 01:12:53.341766738 +0100
+++ linux-3.8.13-pax/drivers/atm/ambassador.c	2013-02-19 01:14:43.337772713 +0100
@@ -454,7 +454,7 @@ static void tx_complete (amb_dev * dev,
   PRINTD (DBG_FLOW|DBG_TX, "tx_complete %p %p", dev, tx);
   
   // VC layer stats
-  atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
+  atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
   
   // free the descriptor
   kfree (tx_descr);
@@ -495,7 +495,7 @@ static void rx_complete (amb_dev * dev,
 	  dump_skb ("<<<", vc, skb);
 	  
 	  // VC layer stats
-	  atomic_inc(&atm_vcc->stats->rx);
+	  atomic_inc_unchecked(&atm_vcc->stats->rx);
 	  __net_timestamp(skb);
 	  // end of our responsibility
 	  atm_vcc->push (atm_vcc, skb);
@@ -510,7 +510,7 @@ static void rx_complete (amb_dev * dev,
       } else {
       	PRINTK (KERN_INFO, "dropped over-size frame");
 	// should we count this?
-	atomic_inc(&atm_vcc->stats->rx_drop);
+	atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
       }
       
     } else {
@@ -1338,7 +1338,7 @@ static int amb_send (struct atm_vcc * at
   }
   
   if (check_area (skb->data, skb->len)) {
-    atomic_inc(&atm_vcc->stats->tx_err);
+    atomic_inc_unchecked(&atm_vcc->stats->tx_err);
     return -ENOMEM; // ?
   }
   
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/atmtcp.c linux-3.8.13-pax/drivers/atm/atmtcp.c
--- linux-3.8.13/drivers/atm/atmtcp.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/atm/atmtcp.c	2013-02-19 01:14:43.341772713 +0100
@@ -207,7 +207,7 @@ static int atmtcp_v_send(struct atm_vcc
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
 		if (dev_data) return 0;
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		return -ENOLINK;
 	}
 	size = skb->len+sizeof(struct atmtcp_hdr);
@@ -215,7 +215,7 @@ static int atmtcp_v_send(struct atm_vcc
 	if (!new_skb) {
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		return -ENOBUFS;
 	}
 	hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
@@ -226,8 +226,8 @@ static int atmtcp_v_send(struct atm_vcc
 	if (vcc->pop) vcc->pop(vcc,skb);
 	else dev_kfree_skb(skb);
 	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
+	atomic_inc_unchecked(&vcc->stats->tx);
+	atomic_inc_unchecked(&out_vcc->stats->rx);
 	return 0;
 }
 
@@ -301,7 +301,7 @@ static int atmtcp_c_send(struct atm_vcc
 	out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
 	read_unlock(&vcc_sklist_lock);
 	if (!out_vcc) {
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		goto done;
 	}
 	skb_pull(skb,sizeof(struct atmtcp_hdr));
@@ -313,8 +313,8 @@ static int atmtcp_c_send(struct atm_vcc
 	__net_timestamp(new_skb);
 	skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
 	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
+	atomic_inc_unchecked(&vcc->stats->tx);
+	atomic_inc_unchecked(&out_vcc->stats->rx);
 done:
 	if (vcc->pop) vcc->pop(vcc,skb);
 	else dev_kfree_skb(skb);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/eni.c linux-3.8.13-pax/drivers/atm/eni.c
--- linux-3.8.13/drivers/atm/eni.c	2013-02-19 01:12:53.353766739 +0100
+++ linux-3.8.13-pax/drivers/atm/eni.c	2013-02-19 01:14:43.345772713 +0100
@@ -522,7 +522,7 @@ static int rx_aal0(struct atm_vcc *vcc)
 		DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
 		    vcc->dev->number);
 		length = 0;
-		atomic_inc(&vcc->stats->rx_err);
+		atomic_inc_unchecked(&vcc->stats->rx_err);
 	}
 	else {
 		length = ATM_CELL_SIZE-1; /* no HEC */
@@ -577,7 +577,7 @@ static int rx_aal5(struct atm_vcc *vcc)
 			    size);
 		}
 		eff = length = 0;
-		atomic_inc(&vcc->stats->rx_err);
+		atomic_inc_unchecked(&vcc->stats->rx_err);
 	}
 	else {
 		size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
@@ -594,7 +594,7 @@ static int rx_aal5(struct atm_vcc *vcc)
 			    "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
 			    vcc->dev->number,vcc->vci,length,size << 2,descr);
 			length = eff = 0;
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 		}
 	}
 	skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
@@ -767,7 +767,7 @@ rx_dequeued++;
 			vcc->push(vcc,skb);
 			pushed++;
 		}
-		atomic_inc(&vcc->stats->rx);
+		atomic_inc_unchecked(&vcc->stats->rx);
 	}
 	wake_up(&eni_dev->rx_wait);
 }
@@ -1227,7 +1227,7 @@ static void dequeue_tx(struct atm_dev *d
 		    PCI_DMA_TODEVICE);
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb_irq(skb);
-		atomic_inc(&vcc->stats->tx);
+		atomic_inc_unchecked(&vcc->stats->tx);
 		wake_up(&eni_dev->tx_wait);
 dma_complete++;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/firestream.c linux-3.8.13-pax/drivers/atm/firestream.c
--- linux-3.8.13/drivers/atm/firestream.c	2013-02-19 01:12:53.353766739 +0100
+++ linux-3.8.13-pax/drivers/atm/firestream.c	2013-02-19 01:14:43.345772713 +0100
@@ -749,7 +749,7 @@ static void process_txdone_queue (struct
 				}
 			}
 
-			atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
+			atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
 
 			fs_dprintk (FS_DEBUG_TXMEM, "i");
 			fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
@@ -816,7 +816,7 @@ static void process_incoming (struct fs_
 #endif
 				skb_put (skb, qe->p1 & 0xffff); 
 				ATM_SKB(skb)->vcc = atm_vcc;
-				atomic_inc(&atm_vcc->stats->rx);
+				atomic_inc_unchecked(&atm_vcc->stats->rx);
 				__net_timestamp(skb);
 				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
 				atm_vcc->push (atm_vcc, skb);
@@ -837,12 +837,12 @@ static void process_incoming (struct fs_
 				kfree (pe);
 			}
 			if (atm_vcc)
-				atomic_inc(&atm_vcc->stats->rx_drop);
+				atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
 			break;
 		case 0x1f: /*  Reassembly abort: no buffers. */
 			/* Silently increment error counter. */
 			if (atm_vcc)
-				atomic_inc(&atm_vcc->stats->rx_drop);
+				atomic_inc_unchecked(&atm_vcc->stats->rx_drop);
 			break;
 		default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
 			printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n", 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/fore200e.c linux-3.8.13-pax/drivers/atm/fore200e.c
--- linux-3.8.13/drivers/atm/fore200e.c	2013-02-19 01:12:53.353766739 +0100
+++ linux-3.8.13-pax/drivers/atm/fore200e.c	2013-02-19 01:14:43.345772713 +0100
@@ -931,9 +931,9 @@ fore200e_tx_irq(struct fore200e* fore200
 #endif
 		/* check error condition */
 		if (*entry->status & STATUS_ERROR)
-		    atomic_inc(&vcc->stats->tx_err);
+		    atomic_inc_unchecked(&vcc->stats->tx_err);
 		else
-		    atomic_inc(&vcc->stats->tx);
+		    atomic_inc_unchecked(&vcc->stats->tx);
 	    }
 	}
 
@@ -1082,7 +1082,7 @@ fore200e_push_rpd(struct fore200e* fore2
     if (skb == NULL) {
 	DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
 
-	atomic_inc(&vcc->stats->rx_drop);
+	atomic_inc_unchecked(&vcc->stats->rx_drop);
 	return -ENOMEM;
     } 
 
@@ -1125,14 +1125,14 @@ fore200e_push_rpd(struct fore200e* fore2
 
 	dev_kfree_skb_any(skb);
 
-	atomic_inc(&vcc->stats->rx_drop);
+	atomic_inc_unchecked(&vcc->stats->rx_drop);
 	return -ENOMEM;
     }
 
     ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
 
     vcc->push(vcc, skb);
-    atomic_inc(&vcc->stats->rx);
+    atomic_inc_unchecked(&vcc->stats->rx);
 
     ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
 
@@ -1210,7 +1210,7 @@ fore200e_rx_irq(struct fore200e* fore200
 		DPRINTK(2, "damaged PDU on %d.%d.%d\n",
 			fore200e->atm_dev->number,
 			entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-		atomic_inc(&vcc->stats->rx_err);
+		atomic_inc_unchecked(&vcc->stats->rx_err);
 	    }
 	}
 
@@ -1655,7 +1655,7 @@ fore200e_send(struct atm_vcc *vcc, struc
 		goto retry_here;
 	    }
 
-	    atomic_inc(&vcc->stats->tx_err);
+	    atomic_inc_unchecked(&vcc->stats->tx_err);
 
 	    fore200e->tx_sat++;
 	    DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/he.c linux-3.8.13-pax/drivers/atm/he.c
--- linux-3.8.13/drivers/atm/he.c	2013-02-19 01:12:53.361766740 +0100
+++ linux-3.8.13-pax/drivers/atm/he.c	2013-02-19 01:14:43.349772713 +0100
@@ -1699,7 +1699,7 @@ he_service_rbrq(struct he_dev *he_dev, i
 
 		if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
 			hprintk("HBUF_ERR!  (cid 0x%x)\n", cid);
-				atomic_inc(&vcc->stats->rx_drop);
+				atomic_inc_unchecked(&vcc->stats->rx_drop);
 			goto return_host_buffers;
 		}
 
@@ -1726,7 +1726,7 @@ he_service_rbrq(struct he_dev *he_dev, i
 				RBRQ_LEN_ERR(he_dev->rbrq_head)
 							? "LEN_ERR" : "",
 							vcc->vpi, vcc->vci);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			goto return_host_buffers;
 		}
 
@@ -1778,7 +1778,7 @@ he_service_rbrq(struct he_dev *he_dev, i
 		vcc->push(vcc, skb);
 		spin_lock(&he_dev->global_lock);
 
-		atomic_inc(&vcc->stats->rx);
+		atomic_inc_unchecked(&vcc->stats->rx);
 
 return_host_buffers:
 		++pdus_assembled;
@@ -2104,7 +2104,7 @@ __enqueue_tpd(struct he_dev *he_dev, str
 					tpd->vcc->pop(tpd->vcc, tpd->skb);
 				else
 					dev_kfree_skb_any(tpd->skb);
-				atomic_inc(&tpd->vcc->stats->tx_err);
+				atomic_inc_unchecked(&tpd->vcc->stats->tx_err);
 			}
 			pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
 			return;
@@ -2516,7 +2516,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		return -EINVAL;
 	}
 
@@ -2527,7 +2527,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		return -EINVAL;
 	}
 #endif
@@ -2539,7 +2539,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
 			vcc->pop(vcc, skb);
 		else
 			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		spin_unlock_irqrestore(&he_dev->global_lock, flags);
 		return -ENOMEM;
 	}
@@ -2581,7 +2581,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
 					vcc->pop(vcc, skb);
 				else
 					dev_kfree_skb_any(skb);
-				atomic_inc(&vcc->stats->tx_err);
+				atomic_inc_unchecked(&vcc->stats->tx_err);
 				spin_unlock_irqrestore(&he_dev->global_lock, flags);
 				return -ENOMEM;
 			}
@@ -2612,7 +2612,7 @@ he_send(struct atm_vcc *vcc, struct sk_b
 	__enqueue_tpd(he_dev, tpd, cid);
 	spin_unlock_irqrestore(&he_dev->global_lock, flags);
 
-	atomic_inc(&vcc->stats->tx);
+	atomic_inc_unchecked(&vcc->stats->tx);
 
 	return 0;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/horizon.c linux-3.8.13-pax/drivers/atm/horizon.c
--- linux-3.8.13/drivers/atm/horizon.c	2013-02-19 01:12:53.365766740 +0100
+++ linux-3.8.13-pax/drivers/atm/horizon.c	2013-02-19 01:14:43.349772713 +0100
@@ -1034,7 +1034,7 @@ static void rx_schedule (hrz_dev * dev,
 	{
 	  struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
 	  // VC layer stats
-	  atomic_inc(&vcc->stats->rx);
+	  atomic_inc_unchecked(&vcc->stats->rx);
 	  __net_timestamp(skb);
 	  // end of our responsibility
 	  vcc->push (vcc, skb);
@@ -1186,7 +1186,7 @@ static void tx_schedule (hrz_dev * const
 	dev->tx_iovec = NULL;
 	
 	// VC layer stats
-	atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
+	atomic_inc_unchecked(&ATM_SKB(skb)->vcc->stats->tx);
 	
 	// free the skb
 	hrz_kfree_skb (skb);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/idt77252.c linux-3.8.13-pax/drivers/atm/idt77252.c
--- linux-3.8.13/drivers/atm/idt77252.c	2013-02-19 01:12:53.369766740 +0100
+++ linux-3.8.13-pax/drivers/atm/idt77252.c	2013-02-19 01:14:43.349772713 +0100
@@ -812,7 +812,7 @@ drain_scq(struct idt77252_dev *card, str
 		else
 			dev_kfree_skb(skb);
 
-		atomic_inc(&vcc->stats->tx);
+		atomic_inc_unchecked(&vcc->stats->tx);
 	}
 
 	atomic_dec(&scq->used);
@@ -1075,13 +1075,13 @@ dequeue_rx(struct idt77252_dev *card, st
 			if ((sb = dev_alloc_skb(64)) == NULL) {
 				printk("%s: Can't allocate buffers for aal0.\n",
 				       card->name);
-				atomic_add(i, &vcc->stats->rx_drop);
+				atomic_add_unchecked(i, &vcc->stats->rx_drop);
 				break;
 			}
 			if (!atm_charge(vcc, sb->truesize)) {
 				RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
 					 card->name);
-				atomic_add(i - 1, &vcc->stats->rx_drop);
+				atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);
 				dev_kfree_skb(sb);
 				break;
 			}
@@ -1098,7 +1098,7 @@ dequeue_rx(struct idt77252_dev *card, st
 			ATM_SKB(sb)->vcc = vcc;
 			__net_timestamp(sb);
 			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
+			atomic_inc_unchecked(&vcc->stats->rx);
 
 			cell += ATM_CELL_PAYLOAD;
 		}
@@ -1135,13 +1135,13 @@ dequeue_rx(struct idt77252_dev *card, st
 			         "(CDC: %08x)\n",
 			         card->name, len, rpp->len, readl(SAR_REG_CDC));
 			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			return;
 		}
 		if (stat & SAR_RSQE_CRC) {
 			RXPRINTK("%s: AAL5 CRC error.\n", card->name);
 			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			return;
 		}
 		if (skb_queue_len(&rpp->queue) > 1) {
@@ -1152,7 +1152,7 @@ dequeue_rx(struct idt77252_dev *card, st
 				RXPRINTK("%s: Can't alloc RX skb.\n",
 					 card->name);
 				recycle_rx_pool_skb(card, rpp);
-				atomic_inc(&vcc->stats->rx_err);
+				atomic_inc_unchecked(&vcc->stats->rx_err);
 				return;
 			}
 			if (!atm_charge(vcc, skb->truesize)) {
@@ -1171,7 +1171,7 @@ dequeue_rx(struct idt77252_dev *card, st
 			__net_timestamp(skb);
 
 			vcc->push(vcc, skb);
-			atomic_inc(&vcc->stats->rx);
+			atomic_inc_unchecked(&vcc->stats->rx);
 
 			return;
 		}
@@ -1193,7 +1193,7 @@ dequeue_rx(struct idt77252_dev *card, st
 		__net_timestamp(skb);
 
 		vcc->push(vcc, skb);
-		atomic_inc(&vcc->stats->rx);
+		atomic_inc_unchecked(&vcc->stats->rx);
 
 		if (skb->truesize > SAR_FB_SIZE_3)
 			add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
@@ -1304,14 +1304,14 @@ idt77252_rx_raw(struct idt77252_dev *car
 		if (vcc->qos.aal != ATM_AAL0) {
 			RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
 				card->name, vpi, vci);
-			atomic_inc(&vcc->stats->rx_drop);
+			atomic_inc_unchecked(&vcc->stats->rx_drop);
 			goto drop;
 		}
 	
 		if ((sb = dev_alloc_skb(64)) == NULL) {
 			printk("%s: Can't allocate buffers for AAL0.\n",
 			       card->name);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			goto drop;
 		}
 
@@ -1330,7 +1330,7 @@ idt77252_rx_raw(struct idt77252_dev *car
 		ATM_SKB(sb)->vcc = vcc;
 		__net_timestamp(sb);
 		vcc->push(vcc, sb);
-		atomic_inc(&vcc->stats->rx);
+		atomic_inc_unchecked(&vcc->stats->rx);
 
 drop:
 		skb_pull(queue, 64);
@@ -1955,13 +1955,13 @@ idt77252_send_skb(struct atm_vcc *vcc, s
 
 	if (vc == NULL) {
 		printk("%s: NULL connection in send().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
 	if (!test_bit(VCF_TX, &vc->flags)) {
 		printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -1973,14 +1973,14 @@ idt77252_send_skb(struct atm_vcc *vcc, s
 		break;
 	default:
 		printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
 
 	if (skb_shinfo(skb)->nr_frags != 0) {
 		printk("%s: No scatter-gather yet.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
 		return -EINVAL;
 	}
@@ -1988,7 +1988,7 @@ idt77252_send_skb(struct atm_vcc *vcc, s
 
 	err = queue_skb(card, vc, skb, oam);
 	if (err) {
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb(skb);
 		return err;
 	}
@@ -2011,7 +2011,7 @@ idt77252_send_oam(struct atm_vcc *vcc, v
 	skb = dev_alloc_skb(64);
 	if (!skb) {
 		printk("%s: Out of memory in send_oam().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		return -ENOMEM;
 	}
 	atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/iphase.c linux-3.8.13-pax/drivers/atm/iphase.c
--- linux-3.8.13/drivers/atm/iphase.c	2013-02-19 01:12:53.369766740 +0100
+++ linux-3.8.13-pax/drivers/atm/iphase.c	2013-02-19 01:14:43.353772714 +0100
@@ -1145,7 +1145,7 @@ static int rx_pkt(struct atm_dev *dev)
 	status = (u_short) (buf_desc_ptr->desc_mode);  
 	if (status & (RX_CER | RX_PTE | RX_OFL))  
 	{  
-                atomic_inc(&vcc->stats->rx_err);
+                atomic_inc_unchecked(&vcc->stats->rx_err);
 		IF_ERR(printk("IA: bad packet, dropping it");)  
                 if (status & RX_CER) { 
                     IF_ERR(printk(" cause: packet CRC error\n");)
@@ -1168,7 +1168,7 @@ static int rx_pkt(struct atm_dev *dev)
 	len = dma_addr - buf_addr;  
         if (len > iadev->rx_buf_sz) {
            printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
-           atomic_inc(&vcc->stats->rx_err);
+           atomic_inc_unchecked(&vcc->stats->rx_err);
 	   goto out_free_desc;
         }
 		  
@@ -1318,7 +1318,7 @@ static void rx_dle_intr(struct atm_dev *
           ia_vcc = INPH_IA_VCC(vcc);
           if (ia_vcc == NULL)
           {
-             atomic_inc(&vcc->stats->rx_err);
+             atomic_inc_unchecked(&vcc->stats->rx_err);
              atm_return(vcc, skb->truesize);
              dev_kfree_skb_any(skb);
              goto INCR_DLE;
@@ -1330,7 +1330,7 @@ static void rx_dle_intr(struct atm_dev *
           if ((length > iadev->rx_buf_sz) || (length > 
                               (skb->len - sizeof(struct cpcs_trailer))))
           {
-             atomic_inc(&vcc->stats->rx_err);
+             atomic_inc_unchecked(&vcc->stats->rx_err);
              IF_ERR(printk("rx_dle_intr: Bad  AAL5 trailer %d (skb len %d)", 
                                                             length, skb->len);)
              atm_return(vcc, skb->truesize);
@@ -1346,7 +1346,7 @@ static void rx_dle_intr(struct atm_dev *
 
 	  IF_RX(printk("rx_dle_intr: skb push");)  
 	  vcc->push(vcc,skb);  
-	  atomic_inc(&vcc->stats->rx);
+	  atomic_inc_unchecked(&vcc->stats->rx);
           iadev->rx_pkt_cnt++;
       }  
 INCR_DLE:
@@ -2826,15 +2826,15 @@ static int ia_ioctl(struct atm_dev *dev,
          {
              struct k_sonet_stats *stats;
              stats = &PRIV(_ia_dev[board])->sonet_stats;
-             printk("section_bip: %d\n", atomic_read(&stats->section_bip));
-             printk("line_bip   : %d\n", atomic_read(&stats->line_bip));
-             printk("path_bip   : %d\n", atomic_read(&stats->path_bip));
-             printk("line_febe  : %d\n", atomic_read(&stats->line_febe));
-             printk("path_febe  : %d\n", atomic_read(&stats->path_febe));
-             printk("corr_hcs   : %d\n", atomic_read(&stats->corr_hcs));
-             printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
-             printk("tx_cells   : %d\n", atomic_read(&stats->tx_cells));
-             printk("rx_cells   : %d\n", atomic_read(&stats->rx_cells));
+             printk("section_bip: %d\n", atomic_read_unchecked(&stats->section_bip));
+             printk("line_bip   : %d\n", atomic_read_unchecked(&stats->line_bip));
+             printk("path_bip   : %d\n", atomic_read_unchecked(&stats->path_bip));
+             printk("line_febe  : %d\n", atomic_read_unchecked(&stats->line_febe));
+             printk("path_febe  : %d\n", atomic_read_unchecked(&stats->path_febe));
+             printk("corr_hcs   : %d\n", atomic_read_unchecked(&stats->corr_hcs));
+             printk("uncorr_hcs : %d\n", atomic_read_unchecked(&stats->uncorr_hcs));
+             printk("tx_cells   : %d\n", atomic_read_unchecked(&stats->tx_cells));
+             printk("rx_cells   : %d\n", atomic_read_unchecked(&stats->rx_cells));
          }
             ia_cmds.status = 0;
             break;
@@ -2939,7 +2939,7 @@ static int ia_pkt_tx (struct atm_vcc *vc
 	if ((desc == 0) || (desc > iadev->num_tx_desc))  
 	{  
 		IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) 
-                atomic_inc(&vcc->stats->tx);
+                atomic_inc_unchecked(&vcc->stats->tx);
 		if (vcc->pop)   
 		    vcc->pop(vcc, skb);   
 		else  
@@ -3044,14 +3044,14 @@ static int ia_pkt_tx (struct atm_vcc *vc
         ATM_DESC(skb) = vcc->vci;
         skb_queue_tail(&iadev->tx_dma_q, skb);
 
-        atomic_inc(&vcc->stats->tx);
+        atomic_inc_unchecked(&vcc->stats->tx);
         iadev->tx_pkt_cnt++;
 	/* Increment transaction counter */  
 	writel(2, iadev->dma+IPHASE5575_TX_COUNTER);  
         
 #if 0        
         /* add flow control logic */ 
-        if (atomic_read(&vcc->stats->tx) % 20 == 0) {
+        if (atomic_read_unchecked(&vcc->stats->tx) % 20 == 0) {
           if (iavcc->vc_desc_cnt > 10) {
              vcc->tx_quota =  vcc->tx_quota * 3 / 4;
             printk("Tx1:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/lanai.c linux-3.8.13-pax/drivers/atm/lanai.c
--- linux-3.8.13/drivers/atm/lanai.c	2013-02-19 01:12:53.373766740 +0100
+++ linux-3.8.13-pax/drivers/atm/lanai.c	2013-02-19 01:14:43.353772714 +0100
@@ -1303,7 +1303,7 @@ static void lanai_send_one_aal5(struct l
 	vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
 	lanai_endtx(lanai, lvcc);
 	lanai_free_skb(lvcc->tx.atmvcc, skb);
-	atomic_inc(&lvcc->tx.atmvcc->stats->tx);
+	atomic_inc_unchecked(&lvcc->tx.atmvcc->stats->tx);
 }
 
 /* Try to fill the buffer - don't call unless there is backlog */
@@ -1426,7 +1426,7 @@ static void vcc_rx_aal5(struct lanai_vcc
 	ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
 	__net_timestamp(skb);
 	lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx);
+	atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx);
     out:
 	lvcc->rx.buf.ptr = end;
 	cardvcc_write(lvcc, endptr, vcc_rxreadptr);
@@ -1667,7 +1667,7 @@ static int handle_service(struct lanai_d
 		DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
 		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
 		lanai->stats.service_rxnotaal5++;
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
+		atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
 		return 0;
 	}
 	if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
@@ -1679,7 +1679,7 @@ static int handle_service(struct lanai_d
 		int bytes;
 		read_unlock(&vcc_sklist_lock);
 		DPRINTK("got trashed rx pdu on vci %d\n", vci);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
+		atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
 		lvcc->stats.x.aal5.service_trash++;
 		bytes = (SERVICE_GET_END(s) * 16) -
 		    (((unsigned long) lvcc->rx.buf.ptr) -
@@ -1691,7 +1691,7 @@ static int handle_service(struct lanai_d
 	}
 	if (s & SERVICE_STREAM) {
 		read_unlock(&vcc_sklist_lock);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
+		atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
 		lvcc->stats.x.aal5.service_stream++;
 		printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
 		    "PDU on VCI %d!\n", lanai->number, vci);
@@ -1699,7 +1699,7 @@ static int handle_service(struct lanai_d
 		return 0;
 	}
 	DPRINTK("got rx crc error on vci %d\n", vci);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
+	atomic_inc_unchecked(&lvcc->rx.atmvcc->stats->rx_err);
 	lvcc->stats.x.aal5.service_rxcrc++;
 	lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
 	cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/nicstar.c linux-3.8.13-pax/drivers/atm/nicstar.c
--- linux-3.8.13/drivers/atm/nicstar.c	2013-02-19 01:12:53.397766742 +0100
+++ linux-3.8.13-pax/drivers/atm/nicstar.c	2013-02-19 01:14:43.353772714 +0100
@@ -1654,7 +1654,7 @@ static int ns_send(struct atm_vcc *vcc,
 	if ((vc = (vc_map *) vcc->dev_data) == NULL) {
 		printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",
 		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb_any(skb);
 		return -EINVAL;
 	}
@@ -1662,7 +1662,7 @@ static int ns_send(struct atm_vcc *vcc,
 	if (!vc->tx) {
 		printk("nicstar%d: Trying to transmit on a non-tx VC.\n",
 		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb_any(skb);
 		return -EINVAL;
 	}
@@ -1670,14 +1670,14 @@ static int ns_send(struct atm_vcc *vcc,
 	if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
 		printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",
 		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb_any(skb);
 		return -EINVAL;
 	}
 
 	if (skb_shinfo(skb)->nr_frags != 0) {
 		printk("nicstar%d: No scatter-gather yet.\n", card->index);
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb_any(skb);
 		return -EINVAL;
 	}
@@ -1725,11 +1725,11 @@ static int ns_send(struct atm_vcc *vcc,
 	}
 
 	if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
-		atomic_inc(&vcc->stats->tx_err);
+		atomic_inc_unchecked(&vcc->stats->tx_err);
 		dev_kfree_skb_any(skb);
 		return -EIO;
 	}
-	atomic_inc(&vcc->stats->tx);
+	atomic_inc_unchecked(&vcc->stats->tx);
 
 	return 0;
 }
@@ -2046,14 +2046,14 @@ static void dequeue_rx(ns_dev * card, ns
 				printk
 				    ("nicstar%d: Can't allocate buffers for aal0.\n",
 				     card->index);
-				atomic_add(i, &vcc->stats->rx_drop);
+				atomic_add_unchecked(i, &vcc->stats->rx_drop);
 				break;
 			}
 			if (!atm_charge(vcc, sb->truesize)) {
 				RXPRINTK
 				    ("nicstar%d: atm_charge() dropped aal0 packets.\n",
 				     card->index);
-				atomic_add(i - 1, &vcc->stats->rx_drop);	/* already increased by 1 */
+				atomic_add_unchecked(i - 1, &vcc->stats->rx_drop);	/* already increased by 1 */
 				dev_kfree_skb_any(sb);
 				break;
 			}
@@ -2068,7 +2068,7 @@ static void dequeue_rx(ns_dev * card, ns
 			ATM_SKB(sb)->vcc = vcc;
 			__net_timestamp(sb);
 			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
+			atomic_inc_unchecked(&vcc->stats->rx);
 			cell += ATM_CELL_PAYLOAD;
 		}
 
@@ -2085,7 +2085,7 @@ static void dequeue_rx(ns_dev * card, ns
 			if (iovb == NULL) {
 				printk("nicstar%d: Out of iovec buffers.\n",
 				       card->index);
-				atomic_inc(&vcc->stats->rx_drop);
+				atomic_inc_unchecked(&vcc->stats->rx_drop);
 				recycle_rx_buf(card, skb);
 				return;
 			}
@@ -2109,7 +2109,7 @@ static void dequeue_rx(ns_dev * card, ns
 		   small or large buffer itself. */
 	} else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
 		printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
-		atomic_inc(&vcc->stats->rx_err);
+		atomic_inc_unchecked(&vcc->stats->rx_err);
 		recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
 				      NS_MAX_IOVECS);
 		NS_PRV_IOVCNT(iovb) = 0;
@@ -2129,7 +2129,7 @@ static void dequeue_rx(ns_dev * card, ns
 			    ("nicstar%d: Expected a small buffer, and this is not one.\n",
 			     card->index);
 			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			recycle_rx_buf(card, skb);
 			vc->rx_iov = NULL;
 			recycle_iov_buf(card, iovb);
@@ -2142,7 +2142,7 @@ static void dequeue_rx(ns_dev * card, ns
 			    ("nicstar%d: Expected a large buffer, and this is not one.\n",
 			     card->index);
 			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
 					      NS_PRV_IOVCNT(iovb));
 			vc->rx_iov = NULL;
@@ -2165,7 +2165,7 @@ static void dequeue_rx(ns_dev * card, ns
 				printk(" - PDU size mismatch.\n");
 			else
 				printk(".\n");
-			atomic_inc(&vcc->stats->rx_err);
+			atomic_inc_unchecked(&vcc->stats->rx_err);
 			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
 					      NS_PRV_IOVCNT(iovb));
 			vc->rx_iov = NULL;
@@ -2179,7 +2179,7 @@ static void dequeue_rx(ns_dev * card, ns
 			/* skb points to a small buffer */
 			if (!atm_charge(vcc, skb->truesize)) {
 				push_rxbufs(card, skb);
-				atomic_inc(&vcc->stats->rx_drop);
+				atomic_inc_unchecked(&vcc->stats->rx_drop);
 			} else {
 				skb_put(skb, len);
 				dequeue_sm_buf(card, skb);
@@ -2189,7 +2189,7 @@ static void dequeue_rx(ns_dev * card, ns
 				ATM_SKB(skb)->vcc = vcc;
 				__net_timestamp(skb);
 				vcc->push(vcc, skb);
-				atomic_inc(&vcc->stats->rx);
+				atomic_inc_unchecked(&vcc->stats->rx);
 			}
 		} else if (NS_PRV_IOVCNT(iovb) == 2) {	/* One small plus one large buffer */
 			struct sk_buff *sb;
@@ -2200,7 +2200,7 @@ static void dequeue_rx(ns_dev * card, ns
 			if (len <= NS_SMBUFSIZE) {
 				if (!atm_charge(vcc, sb->truesize)) {
 					push_rxbufs(card, sb);
-					atomic_inc(&vcc->stats->rx_drop);
+					atomic_inc_unchecked(&vcc->stats->rx_drop);
 				} else {
 					skb_put(sb, len);
 					dequeue_sm_buf(card, sb);
@@ -2210,7 +2210,7 @@ static void dequeue_rx(ns_dev * card, ns
 					ATM_SKB(sb)->vcc = vcc;
 					__net_timestamp(sb);
 					vcc->push(vcc, sb);
-					atomic_inc(&vcc->stats->rx);
+					atomic_inc_unchecked(&vcc->stats->rx);
 				}
 
 				push_rxbufs(card, skb);
@@ -2219,7 +2219,7 @@ static void dequeue_rx(ns_dev * card, ns
 
 				if (!atm_charge(vcc, skb->truesize)) {
 					push_rxbufs(card, skb);
-					atomic_inc(&vcc->stats->rx_drop);
+					atomic_inc_unchecked(&vcc->stats->rx_drop);
 				} else {
 					dequeue_lg_buf(card, skb);
 #ifdef NS_USE_DESTRUCTORS
@@ -2232,7 +2232,7 @@ static void dequeue_rx(ns_dev * card, ns
 					ATM_SKB(skb)->vcc = vcc;
 					__net_timestamp(skb);
 					vcc->push(vcc, skb);
-					atomic_inc(&vcc->stats->rx);
+					atomic_inc_unchecked(&vcc->stats->rx);
 				}
 
 				push_rxbufs(card, sb);
@@ -2253,7 +2253,7 @@ static void dequeue_rx(ns_dev * card, ns
 					printk
 					    ("nicstar%d: Out of huge buffers.\n",
 					     card->index);
-					atomic_inc(&vcc->stats->rx_drop);
+					atomic_inc_unchecked(&vcc->stats->rx_drop);
 					recycle_iovec_rx_bufs(card,
 							      (struct iovec *)
 							      iovb->data,
@@ -2304,7 +2304,7 @@ static void dequeue_rx(ns_dev * card, ns
 					card->hbpool.count++;
 				} else
 					dev_kfree_skb_any(hb);
-				atomic_inc(&vcc->stats->rx_drop);
+				atomic_inc_unchecked(&vcc->stats->rx_drop);
 			} else {
 				/* Copy the small buffer to the huge buffer */
 				sb = (struct sk_buff *)iov->iov_base;
@@ -2341,7 +2341,7 @@ static void dequeue_rx(ns_dev * card, ns
 #endif /* NS_USE_DESTRUCTORS */
 				__net_timestamp(hb);
 				vcc->push(vcc, hb);
-				atomic_inc(&vcc->stats->rx);
+				atomic_inc_unchecked(&vcc->stats->rx);
 			}
 		}
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/solos-pci.c linux-3.8.13-pax/drivers/atm/solos-pci.c
--- linux-3.8.13/drivers/atm/solos-pci.c	2013-02-19 01:12:53.397766742 +0100
+++ linux-3.8.13-pax/drivers/atm/solos-pci.c	2013-02-19 01:14:43.357772714 +0100
@@ -838,7 +838,7 @@ void solos_bh(unsigned long card_arg)
 				}
 				atm_charge(vcc, skb->truesize);
 				vcc->push(vcc, skb);
-				atomic_inc(&vcc->stats->rx);
+				atomic_inc_unchecked(&vcc->stats->rx);
 				break;
 
 			case PKT_STATUS:
@@ -1117,7 +1117,7 @@ static uint32_t fpga_tx(struct solos_car
 			vcc = SKB_CB(oldskb)->vcc;
 
 			if (vcc) {
-				atomic_inc(&vcc->stats->tx);
+				atomic_inc_unchecked(&vcc->stats->tx);
 				solos_pop(vcc, oldskb);
 			} else {
 				dev_kfree_skb_irq(oldskb);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/suni.c linux-3.8.13-pax/drivers/atm/suni.c
--- linux-3.8.13/drivers/atm/suni.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/atm/suni.c	2013-02-19 01:14:43.357772714 +0100
@@ -49,8 +49,8 @@ static DEFINE_SPINLOCK(sunis_lock);
 
 
 #define ADD_LIMITED(s,v) \
-    atomic_add((v),&stats->s); \
-    if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
+    atomic_add_unchecked((v),&stats->s); \
+    if (atomic_read_unchecked(&stats->s) < 0) atomic_set_unchecked(&stats->s,INT_MAX);
 
 
 static void suni_hz(unsigned long from_timer)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/uPD98402.c linux-3.8.13-pax/drivers/atm/uPD98402.c
--- linux-3.8.13/drivers/atm/uPD98402.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/atm/uPD98402.c	2013-02-19 01:14:43.357772714 +0100
@@ -42,7 +42,7 @@ static int fetch_stats(struct atm_dev *d
 	struct sonet_stats tmp;
  	int error = 0;
 
-	atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
+	atomic_add_unchecked(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
 	sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
 	if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
 	if (zero && !error) {
@@ -161,9 +161,9 @@ static int uPD98402_ioctl(struct atm_dev
 
 
 #define ADD_LIMITED(s,v) \
-    { atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
-    if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
-	atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
+    { atomic_add_unchecked(GET(v),&PRIV(dev)->sonet_stats.s); \
+    if (atomic_read_unchecked(&PRIV(dev)->sonet_stats.s) < 0) \
+	atomic_set_unchecked(&PRIV(dev)->sonet_stats.s,INT_MAX); }
 
 
 static void stat_event(struct atm_dev *dev)
@@ -194,7 +194,7 @@ static void uPD98402_int(struct atm_dev
 		if (reason & uPD98402_INT_PFM) stat_event(dev);
 		if (reason & uPD98402_INT_PCO) {
 			(void) GET(PCOCR); /* clear interrupt cause */
-			atomic_add(GET(HECCT),
+			atomic_add_unchecked(GET(HECCT),
 			    &PRIV(dev)->sonet_stats.uncorr_hcs);
 		}
 		if ((reason & uPD98402_INT_RFO) && 
@@ -222,9 +222,9 @@ static int uPD98402_start(struct atm_dev
 	PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
 	  uPD98402_INT_LOS),PIMR); /* enable them */
 	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
-	atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
-	atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
-	atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
+	atomic_set_unchecked(&PRIV(dev)->sonet_stats.corr_hcs,-1);
+	atomic_set_unchecked(&PRIV(dev)->sonet_stats.tx_cells,-1);
+	atomic_set_unchecked(&PRIV(dev)->sonet_stats.rx_cells,-1);
 	return 0;
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/atm/zatm.c linux-3.8.13-pax/drivers/atm/zatm.c
--- linux-3.8.13/drivers/atm/zatm.c	2013-02-19 01:12:53.401766742 +0100
+++ linux-3.8.13-pax/drivers/atm/zatm.c	2013-02-19 01:14:43.357772714 +0100
@@ -459,7 +459,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
 		}
 		if (!size) {
 			dev_kfree_skb_irq(skb);
-			if (vcc) atomic_inc(&vcc->stats->rx_err);
+			if (vcc) atomic_inc_unchecked(&vcc->stats->rx_err);
 			continue;
 		}
 		if (!atm_charge(vcc,skb->truesize)) {
@@ -469,7 +469,7 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy
 		skb->len = size;
 		ATM_SKB(skb)->vcc = vcc;
 		vcc->push(vcc,skb);
-		atomic_inc(&vcc->stats->rx);
+		atomic_inc_unchecked(&vcc->stats->rx);
 	}
 	zout(pos & 0xffff,MTA(mbx));
 #if 0 /* probably a stupid idea */
@@ -733,7 +733,7 @@ if (*ZATM_PRV_DSC(skb) != (uPD98401_TXPD
 			skb_queue_head(&zatm_vcc->backlog,skb);
 			break;
 		}
-	atomic_inc(&vcc->stats->tx);
+	atomic_inc_unchecked(&vcc->stats->tx);
 	wake_up(&zatm_vcc->tx_wait);
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/bus.c linux-3.8.13-pax/drivers/base/bus.c
--- linux-3.8.13/drivers/base/bus.c	2013-03-07 04:10:19.751802301 +0100
+++ linux-3.8.13-pax/drivers/base/bus.c	2013-03-07 04:10:37.739801341 +0100
@@ -1163,7 +1163,7 @@ int subsys_interface_register(struct sub
 		return -EINVAL;
 
 	mutex_lock(&subsys->p->mutex);
-	list_add_tail(&sif->node, &subsys->p->interfaces);
+	pax_list_add_tail((struct list_head *)&sif->node, &subsys->p->interfaces);
 	if (sif->add_dev) {
 		subsys_dev_iter_init(&iter, subsys, NULL, NULL);
 		while ((dev = subsys_dev_iter_next(&iter)))
@@ -1188,7 +1188,7 @@ void subsys_interface_unregister(struct
 	subsys = sif->subsys;
 
 	mutex_lock(&subsys->p->mutex);
-	list_del_init(&sif->node);
+	pax_list_del_init((struct list_head *)&sif->node);
 	if (sif->remove_dev) {
 		subsys_dev_iter_init(&iter, subsys, NULL, NULL);
 		while ((dev = subsys_dev_iter_next(&iter)))
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/devtmpfs.c linux-3.8.13-pax/drivers/base/devtmpfs.c
--- linux-3.8.13/drivers/base/devtmpfs.c	2013-02-19 01:12:53.441766744 +0100
+++ linux-3.8.13-pax/drivers/base/devtmpfs.c	2013-02-19 01:14:43.357772714 +0100
@@ -347,7 +347,7 @@ int devtmpfs_mount(const char *mntdir)
 	if (!thread)
 		return 0;
 
-	err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
+	err = sys_mount((char __force_user *)"devtmpfs", (char __force_user *)mntdir, (char __force_user *)"devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/node.c linux-3.8.13-pax/drivers/base/node.c
--- linux-3.8.13/drivers/base/node.c	2013-02-19 01:12:53.465766745 +0100
+++ linux-3.8.13-pax/drivers/base/node.c	2013-03-06 02:11:52.108511617 +0100
@@ -625,7 +625,7 @@ static ssize_t print_nodes_state(enum no
 struct node_attr {
 	struct device_attribute attr;
 	enum node_states state;
-};
+} __do_const;
 
 static ssize_t show_node_state(struct device *dev,
 			       struct device_attribute *attr, char *buf)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/power/domain.c linux-3.8.13-pax/drivers/base/power/domain.c
--- linux-3.8.13/drivers/base/power/domain.c	2013-02-19 01:12:53.473766746 +0100
+++ linux-3.8.13-pax/drivers/base/power/domain.c	2013-03-08 17:07:45.410360669 +0100
@@ -1851,7 +1851,7 @@ int pm_genpd_attach_cpuidle(struct gener
 {
 	struct cpuidle_driver *cpuidle_drv;
 	struct gpd_cpu_data *cpu_data;
-	struct cpuidle_state *idle_state;
+	cpuidle_state_no_const *idle_state;
 	int ret = 0;
 
 	if (IS_ERR_OR_NULL(genpd) || state < 0)
@@ -1919,7 +1919,7 @@ int pm_genpd_name_attach_cpuidle(const c
 int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
 {
 	struct gpd_cpu_data *cpu_data;
-	struct cpuidle_state *idle_state;
+	cpuidle_state_no_const *idle_state;
 	int ret = 0;
 
 	if (IS_ERR_OR_NULL(genpd))
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/power/wakeup.c linux-3.8.13-pax/drivers/base/power/wakeup.c
--- linux-3.8.13/drivers/base/power/wakeup.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/base/power/wakeup.c	2013-02-19 01:14:43.357772714 +0100
@@ -29,14 +29,14 @@ bool events_check_enabled __read_mostly;
  * They need to be modified together atomically, so it's better to use one
  * atomic variable to hold them both.
  */
-static atomic_t combined_event_count = ATOMIC_INIT(0);
+static atomic_unchecked_t combined_event_count = ATOMIC_INIT(0);
 
 #define IN_PROGRESS_BITS	(sizeof(int) * 4)
 #define MAX_IN_PROGRESS		((1 << IN_PROGRESS_BITS) - 1)
 
 static void split_counters(unsigned int *cnt, unsigned int *inpr)
 {
-	unsigned int comb = atomic_read(&combined_event_count);
+	unsigned int comb = atomic_read_unchecked(&combined_event_count);
 
 	*cnt = (comb >> IN_PROGRESS_BITS);
 	*inpr = comb & MAX_IN_PROGRESS;
@@ -389,7 +389,7 @@ static void wakeup_source_activate(struc
 		ws->start_prevent_time = ws->last_time;
 
 	/* Increment the counter of events in progress. */
-	cec = atomic_inc_return(&combined_event_count);
+	cec = atomic_inc_return_unchecked(&combined_event_count);
 
 	trace_wakeup_source_activate(ws->name, cec);
 }
@@ -515,7 +515,7 @@ static void wakeup_source_deactivate(str
 	 * Increment the counter of registered wakeup events and decrement the
 	 * couter of wakeup events in progress simultaneously.
 	 */
-	cec = atomic_add_return(MAX_IN_PROGRESS, &combined_event_count);
+	cec = atomic_add_return_unchecked(MAX_IN_PROGRESS, &combined_event_count);
 	trace_wakeup_source_deactivate(ws->name, cec);
 
 	split_counters(&cnt, &inpr);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/base/syscore.c linux-3.8.13-pax/drivers/base/syscore.c
--- linux-3.8.13/drivers/base/syscore.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/base/syscore.c	2013-02-22 04:38:50.361165463 +0100
@@ -21,7 +21,7 @@ static DEFINE_MUTEX(syscore_ops_lock);
 void register_syscore_ops(struct syscore_ops *ops)
 {
 	mutex_lock(&syscore_ops_lock);
-	list_add_tail(&ops->node, &syscore_ops_list);
+	pax_list_add_tail((struct list_head *)&ops->node, &syscore_ops_list);
 	mutex_unlock(&syscore_ops_lock);
 }
 EXPORT_SYMBOL_GPL(register_syscore_ops);
@@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(register_syscore_ops);
 void unregister_syscore_ops(struct syscore_ops *ops)
 {
 	mutex_lock(&syscore_ops_lock);
-	list_del(&ops->node);
+	pax_list_del((struct list_head *)&ops->node);
 	mutex_unlock(&syscore_ops_lock);
 }
 EXPORT_SYMBOL_GPL(unregister_syscore_ops);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/cciss.c linux-3.8.13-pax/drivers/block/cciss.c
--- linux-3.8.13/drivers/block/cciss.c	2013-02-19 01:12:53.565766751 +0100
+++ linux-3.8.13-pax/drivers/block/cciss.c	2013-02-19 01:14:43.361772714 +0100
@@ -3005,7 +3005,7 @@ static void start_io(ctlr_info_t *h)
 	while (!list_empty(&h->reqQ)) {
 		c = list_entry(h->reqQ.next, CommandList_struct, list);
 		/* can't do anything if fifo is full */
-		if ((h->access.fifo_full(h))) {
+		if ((h->access->fifo_full(h))) {
 			dev_warn(&h->pdev->dev, "fifo full\n");
 			break;
 		}
@@ -3015,7 +3015,7 @@ static void start_io(ctlr_info_t *h)
 		h->Qdepth--;
 
 		/* Tell the controller execute command */
-		h->access.submit_command(h, c);
+		h->access->submit_command(h, c);
 
 		/* Put job onto the completed Q */
 		addQ(&h->cmpQ, c);
@@ -3441,17 +3441,17 @@ startio:
 
 static inline unsigned long get_next_completion(ctlr_info_t *h)
 {
-	return h->access.command_completed(h);
+	return h->access->command_completed(h);
 }
 
 static inline int interrupt_pending(ctlr_info_t *h)
 {
-	return h->access.intr_pending(h);
+	return h->access->intr_pending(h);
 }
 
 static inline long interrupt_not_for_us(ctlr_info_t *h)
 {
-	return ((h->access.intr_pending(h) == 0) ||
+	return ((h->access->intr_pending(h) == 0) ||
 		(h->interrupts_enabled == 0));
 }
 
@@ -3484,7 +3484,7 @@ static inline u32 next_command(ctlr_info
 	u32 a;
 
 	if (unlikely(!(h->transMethod & CFGTBL_Trans_Performant)))
-		return h->access.command_completed(h);
+		return h->access->command_completed(h);
 
 	if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
 		a = *(h->reply_pool_head); /* Next cmd in ring buffer */
@@ -4041,7 +4041,7 @@ static void cciss_put_controller_into_pe
 		trans_support & CFGTBL_Trans_use_short_tags);
 
 	/* Change the access methods to the performant access methods */
-	h->access = SA5_performant_access;
+	h->access = &SA5_performant_access;
 	h->transMethod = CFGTBL_Trans_Performant;
 
 	return;
@@ -4310,7 +4310,7 @@ static int cciss_pci_init(ctlr_info_t *h
 	if (prod_index < 0)
 		return -ENODEV;
 	h->product_name = products[prod_index].product_name;
-	h->access = *(products[prod_index].access);
+	h->access = products[prod_index].access;
 
 	if (cciss_board_disabled(h)) {
 		dev_warn(&h->pdev->dev, "controller appears to be disabled\n");
@@ -5032,7 +5032,7 @@ reinit_after_soft_reset:
 	}
 
 	/* make sure the board interrupts are off */
-	h->access.set_intr_mask(h, CCISS_INTR_OFF);
+	h->access->set_intr_mask(h, CCISS_INTR_OFF);
 	rc = cciss_request_irq(h, do_cciss_msix_intr, do_cciss_intx);
 	if (rc)
 		goto clean2;
@@ -5082,7 +5082,7 @@ reinit_after_soft_reset:
 		 * fake ones to scoop up any residual completions.
 		 */
 		spin_lock_irqsave(&h->lock, flags);
-		h->access.set_intr_mask(h, CCISS_INTR_OFF);
+		h->access->set_intr_mask(h, CCISS_INTR_OFF);
 		spin_unlock_irqrestore(&h->lock, flags);
 		free_irq(h->intr[h->intr_mode], h);
 		rc = cciss_request_irq(h, cciss_msix_discard_completions,
@@ -5102,9 +5102,9 @@ reinit_after_soft_reset:
 		dev_info(&h->pdev->dev, "Board READY.\n");
 		dev_info(&h->pdev->dev,
 			"Waiting for stale completions to drain.\n");
-		h->access.set_intr_mask(h, CCISS_INTR_ON);
+		h->access->set_intr_mask(h, CCISS_INTR_ON);
 		msleep(10000);
-		h->access.set_intr_mask(h, CCISS_INTR_OFF);
+		h->access->set_intr_mask(h, CCISS_INTR_OFF);
 
 		rc = controller_reset_failed(h->cfgtable);
 		if (rc)
@@ -5127,7 +5127,7 @@ reinit_after_soft_reset:
 	cciss_scsi_setup(h);
 
 	/* Turn the interrupts on so we can service requests */
-	h->access.set_intr_mask(h, CCISS_INTR_ON);
+	h->access->set_intr_mask(h, CCISS_INTR_ON);
 
 	/* Get the firmware version */
 	inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL);
@@ -5199,7 +5199,7 @@ static void cciss_shutdown(struct pci_de
 	kfree(flush_buf);
 	if (return_code != IO_OK)
 		dev_warn(&h->pdev->dev, "Error flushing cache\n");
-	h->access.set_intr_mask(h, CCISS_INTR_OFF);
+	h->access->set_intr_mask(h, CCISS_INTR_OFF);
 	free_irq(h->intr[h->intr_mode], h);
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/cciss.h linux-3.8.13-pax/drivers/block/cciss.h
--- linux-3.8.13/drivers/block/cciss.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/block/cciss.h	2013-02-19 01:14:43.361772714 +0100
@@ -101,7 +101,7 @@ struct ctlr_info
 	/* information about each logical volume */
 	drive_info_struct *drv[CISS_MAX_LUN];
 
-	struct access_method access;
+	struct access_method *access;
 
 	/* queue and queue Info */ 
 	struct list_head reqQ;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/cpqarray.c linux-3.8.13-pax/drivers/block/cpqarray.c
--- linux-3.8.13/drivers/block/cpqarray.c	2013-02-19 01:12:53.573766751 +0100
+++ linux-3.8.13-pax/drivers/block/cpqarray.c	2013-02-19 01:14:43.361772714 +0100
@@ -404,7 +404,7 @@ static int cpqarray_register_ctlr(int i,
 	if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) {
 		goto Enomem4;
 	}
-	hba[i]->access.set_intr_mask(hba[i], 0);
+	hba[i]->access->set_intr_mask(hba[i], 0);
 	if (request_irq(hba[i]->intr, do_ida_intr,
 		IRQF_DISABLED|IRQF_SHARED, hba[i]->devname, hba[i]))
 	{
@@ -459,7 +459,7 @@ static int cpqarray_register_ctlr(int i,
 	add_timer(&hba[i]->timer);
 
 	/* Enable IRQ now that spinlock and rate limit timer are set up */
-	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
+	hba[i]->access->set_intr_mask(hba[i], FIFO_NOT_EMPTY);
 
 	for(j=0; j<NWD; j++) {
 		struct gendisk *disk = ida_gendisk[i][j];
@@ -694,7 +694,7 @@ DBGINFO(
 	for(i=0; i<NR_PRODUCTS; i++) {
 		if (board_id == products[i].board_id) {
 			c->product_name = products[i].product_name;
-			c->access = *(products[i].access);
+			c->access = products[i].access;
 			break;
 		}
 	}
@@ -792,7 +792,7 @@ static int cpqarray_eisa_detect(void)
 		hba[ctlr]->intr = intr;
 		sprintf(hba[ctlr]->devname, "ida%d", nr_ctlr);
 		hba[ctlr]->product_name = products[j].product_name;
-		hba[ctlr]->access = *(products[j].access);
+		hba[ctlr]->access = products[j].access;
 		hba[ctlr]->ctlr = ctlr;
 		hba[ctlr]->board_id = board_id;
 		hba[ctlr]->pci_dev = NULL; /* not PCI */
@@ -980,7 +980,7 @@ static void start_io(ctlr_info_t *h)
 
 	while((c = h->reqQ) != NULL) {
 		/* Can't do anything if we're busy */
-		if (h->access.fifo_full(h) == 0)
+		if (h->access->fifo_full(h) == 0)
 			return;
 
 		/* Get the first entry from the request Q */
@@ -988,7 +988,7 @@ static void start_io(ctlr_info_t *h)
 		h->Qdepth--;
 	
 		/* Tell the controller to do our bidding */
-		h->access.submit_command(h, c);
+		h->access->submit_command(h, c);
 
 		/* Get onto the completion Q */
 		addQ(&h->cmpQ, c);
@@ -1050,7 +1050,7 @@ static irqreturn_t do_ida_intr(int irq,
 	unsigned long flags;
 	__u32 a,a1;
 
-	istat = h->access.intr_pending(h);
+	istat = h->access->intr_pending(h);
 	/* Is this interrupt for us? */
 	if (istat == 0)
 		return IRQ_NONE;
@@ -1061,7 +1061,7 @@ static irqreturn_t do_ida_intr(int irq,
 	 */
 	spin_lock_irqsave(IDA_LOCK(h->ctlr), flags);
 	if (istat & FIFO_NOT_EMPTY) {
-		while((a = h->access.command_completed(h))) {
+		while((a = h->access->command_completed(h))) {
 			a1 = a; a &= ~3;
 			if ((c = h->cmpQ) == NULL)
 			{  
@@ -1449,11 +1449,11 @@ static int sendcmd(
 	/*
 	 * Disable interrupt
 	 */
-	info_p->access.set_intr_mask(info_p, 0);
+	info_p->access->set_intr_mask(info_p, 0);
 	/* Make sure there is room in the command FIFO */
 	/* Actually it should be completely empty at this time. */
 	for (i = 200000; i > 0; i--) {
-		temp = info_p->access.fifo_full(info_p);
+		temp = info_p->access->fifo_full(info_p);
 		if (temp != 0) {
 			break;
 		}
@@ -1466,7 +1466,7 @@ DBG(
 	/*
 	 * Send the cmd
 	 */
-	info_p->access.submit_command(info_p, c);
+	info_p->access->submit_command(info_p, c);
 	complete = pollcomplete(ctlr);
 	
 	pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr, 
@@ -1549,9 +1549,9 @@ static int revalidate_allvol(ctlr_info_t
 	 * we check the new geometry.  Then turn interrupts back on when
 	 * we're done.
 	 */
-	host->access.set_intr_mask(host, 0);
+	host->access->set_intr_mask(host, 0);
 	getgeometry(ctlr);
-	host->access.set_intr_mask(host, FIFO_NOT_EMPTY);
+	host->access->set_intr_mask(host, FIFO_NOT_EMPTY);
 
 	for(i=0; i<NWD; i++) {
 		struct gendisk *disk = ida_gendisk[ctlr][i];
@@ -1591,7 +1591,7 @@ static int pollcomplete(int ctlr)
 	/* Wait (up to 2 seconds) for a command to complete */
 
 	for (i = 200000; i > 0; i--) {
-		done = hba[ctlr]->access.command_completed(hba[ctlr]);
+		done = hba[ctlr]->access->command_completed(hba[ctlr]);
 		if (done == 0) {
 			udelay(10);	/* a short fixed delay */
 		} else
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/cpqarray.h linux-3.8.13-pax/drivers/block/cpqarray.h
--- linux-3.8.13/drivers/block/cpqarray.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/block/cpqarray.h	2013-02-19 01:14:43.361772714 +0100
@@ -99,7 +99,7 @@ struct ctlr_info {
 	drv_info_t	drv[NWD];
 	struct proc_dir_entry *proc;
 
-	struct access_method access;
+	struct access_method *access;
 
 	cmdlist_t *reqQ;
 	cmdlist_t *cmpQ;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/drbd/drbd_int.h linux-3.8.13-pax/drivers/block/drbd/drbd_int.h
--- linux-3.8.13/drivers/block/drbd/drbd_int.h	2013-02-19 01:12:53.589766752 +0100
+++ linux-3.8.13-pax/drivers/block/drbd/drbd_int.h	2013-02-19 01:14:43.365772714 +0100
@@ -582,7 +582,7 @@ struct drbd_epoch {
 	struct drbd_tconn *tconn;
 	struct list_head list;
 	unsigned int barrier_nr;
-	atomic_t epoch_size; /* increased on every request added. */
+	atomic_unchecked_t epoch_size; /* increased on every request added. */
 	atomic_t active;     /* increased on every req. added, and dec on every finished. */
 	unsigned long flags;
 };
@@ -1011,7 +1011,7 @@ struct drbd_conf {
 	int al_tr_cycle;
 	int al_tr_pos;   /* position of the next transaction in the journal */
 	wait_queue_head_t seq_wait;
-	atomic_t packet_seq;
+	atomic_unchecked_t packet_seq;
 	unsigned int peer_seq;
 	spinlock_t peer_seq_lock;
 	unsigned int minor;
@@ -1527,7 +1527,7 @@ static inline int drbd_setsockopt(struct
 	char __user *uoptval;
 	int err;
 
-	uoptval = (char __user __force *)optval;
+	uoptval = (char __force_user *)optval;
 
 	set_fs(KERNEL_DS);
 	if (level == SOL_SOCKET)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/drbd/drbd_main.c linux-3.8.13-pax/drivers/block/drbd/drbd_main.c
--- linux-3.8.13/drivers/block/drbd/drbd_main.c	2013-02-19 01:12:53.621766754 +0100
+++ linux-3.8.13-pax/drivers/block/drbd/drbd_main.c	2013-02-19 01:14:43.365772714 +0100
@@ -1317,7 +1317,7 @@ static int _drbd_send_ack(struct drbd_co
 	p->sector = sector;
 	p->block_id = block_id;
 	p->blksize = blksize;
-	p->seq_num = cpu_to_be32(atomic_inc_return(&mdev->packet_seq));
+	p->seq_num = cpu_to_be32(atomic_inc_return_unchecked(&mdev->packet_seq));
 	return drbd_send_command(mdev, sock, cmd, sizeof(*p), NULL, 0);
 }
 
@@ -1619,7 +1619,7 @@ int drbd_send_dblock(struct drbd_conf *m
 		return -EIO;
 	p->sector = cpu_to_be64(req->i.sector);
 	p->block_id = (unsigned long)req;
-	p->seq_num = cpu_to_be32(atomic_inc_return(&mdev->packet_seq));
+	p->seq_num = cpu_to_be32(atomic_inc_return_unchecked(&mdev->packet_seq));
 	dp_flags = bio_flags_to_wire(mdev, req->master_bio->bi_rw);
 	if (mdev->state.conn >= C_SYNC_SOURCE &&
 	    mdev->state.conn <= C_PAUSED_SYNC_T)
@@ -2574,8 +2574,8 @@ void conn_destroy(struct kref *kref)
 {
 	struct drbd_tconn *tconn = container_of(kref, struct drbd_tconn, kref);
 
-	if (atomic_read(&tconn->current_epoch->epoch_size) !=  0)
-		conn_err(tconn, "epoch_size:%d\n", atomic_read(&tconn->current_epoch->epoch_size));
+	if (atomic_read_unchecked(&tconn->current_epoch->epoch_size) !=  0)
+		conn_err(tconn, "epoch_size:%d\n", atomic_read_unchecked(&tconn->current_epoch->epoch_size));
 	kfree(tconn->current_epoch);
 
 	idr_destroy(&tconn->volumes);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/drbd/drbd_receiver.c linux-3.8.13-pax/drivers/block/drbd/drbd_receiver.c
--- linux-3.8.13/drivers/block/drbd/drbd_receiver.c	2013-02-19 01:12:53.633766754 +0100
+++ linux-3.8.13-pax/drivers/block/drbd/drbd_receiver.c	2013-03-06 02:08:32.864522255 +0100
@@ -833,7 +833,7 @@ int drbd_connected(struct drbd_conf *mde
 {
 	int err;
 
-	atomic_set(&mdev->packet_seq, 0);
+	atomic_set_unchecked(&mdev->packet_seq, 0);
 	mdev->peer_seq = 0;
 
 	mdev->state_mutex = mdev->tconn->agreed_pro_version < 100 ?
@@ -1191,7 +1191,7 @@ static enum finish_epoch drbd_may_finish
 	do {
 		next_epoch = NULL;
 
-		epoch_size = atomic_read(&epoch->epoch_size);
+		epoch_size = atomic_read_unchecked(&epoch->epoch_size);
 
 		switch (ev & ~EV_CLEANUP) {
 		case EV_PUT:
@@ -1231,7 +1231,7 @@ static enum finish_epoch drbd_may_finish
 					rv = FE_DESTROYED;
 			} else {
 				epoch->flags = 0;
-				atomic_set(&epoch->epoch_size, 0);
+				atomic_set_unchecked(&epoch->epoch_size, 0);
 				/* atomic_set(&epoch->active, 0); is already zero */
 				if (rv == FE_STILL_LIVE)
 					rv = FE_RECYCLED;
@@ -1449,7 +1449,7 @@ static int receive_Barrier(struct drbd_t
 		conn_wait_active_ee_empty(tconn);
 		drbd_flush(tconn);
 
-		if (atomic_read(&tconn->current_epoch->epoch_size)) {
+		if (atomic_read_unchecked(&tconn->current_epoch->epoch_size)) {
 			epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO);
 			if (epoch)
 				break;
@@ -1462,11 +1462,11 @@ static int receive_Barrier(struct drbd_t
 	}
 
 	epoch->flags = 0;
-	atomic_set(&epoch->epoch_size, 0);
+	atomic_set_unchecked(&epoch->epoch_size, 0);
 	atomic_set(&epoch->active, 0);
 
 	spin_lock(&tconn->epoch_lock);
-	if (atomic_read(&tconn->current_epoch->epoch_size)) {
+	if (atomic_read_unchecked(&tconn->current_epoch->epoch_size)) {
 		list_add(&epoch->list, &tconn->current_epoch->list);
 		tconn->current_epoch = epoch;
 		tconn->epochs++;
@@ -2170,7 +2170,7 @@ static int receive_Data(struct drbd_tcon
 
 		err = wait_for_and_update_peer_seq(mdev, peer_seq);
 		drbd_send_ack_dp(mdev, P_NEG_ACK, p, pi->size);
-		atomic_inc(&tconn->current_epoch->epoch_size);
+		atomic_inc_unchecked(&tconn->current_epoch->epoch_size);
 		err2 = drbd_drain_block(mdev, pi->size);
 		if (!err)
 			err = err2;
@@ -2204,7 +2204,7 @@ static int receive_Data(struct drbd_tcon
 
 	spin_lock(&tconn->epoch_lock);
 	peer_req->epoch = tconn->current_epoch;
-	atomic_inc(&peer_req->epoch->epoch_size);
+	atomic_inc_unchecked(&peer_req->epoch->epoch_size);
 	atomic_inc(&peer_req->epoch->active);
 	spin_unlock(&tconn->epoch_lock);
 
@@ -4346,7 +4346,7 @@ struct data_cmd {
 	int expect_payload;
 	size_t pkt_size;
 	int (*fn)(struct drbd_tconn *, struct packet_info *);
-};
+} __do_const;
 
 static struct data_cmd drbd_cmd_handler[] = {
 	[P_DATA]	    = { 1, sizeof(struct p_data), receive_Data },
@@ -4466,7 +4466,7 @@ static void conn_disconnect(struct drbd_
 	if (!list_empty(&tconn->current_epoch->list))
 		conn_err(tconn, "ASSERTION FAILED: tconn->current_epoch->list not empty\n");
 	/* ok, no more ee's on the fly, it is safe to reset the epoch_size */
-	atomic_set(&tconn->current_epoch->epoch_size, 0);
+	atomic_set_unchecked(&tconn->current_epoch->epoch_size, 0);
 	tconn->send.seen_any_write_yet = false;
 
 	conn_info(tconn, "Connection closed\n");
@@ -5222,7 +5222,7 @@ static int tconn_finish_peer_reqs(struct
 struct asender_cmd {
 	size_t pkt_size;
 	int (*fn)(struct drbd_tconn *tconn, struct packet_info *);
-};
+} __do_const;
 
 static struct asender_cmd asender_tbl[] = {
 	[P_PING]	    = { 0, got_Ping },
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/loop.c linux-3.8.13-pax/drivers/block/loop.c
--- linux-3.8.13/drivers/block/loop.c	2013-04-05 19:44:22.544879381 +0200
+++ linux-3.8.13-pax/drivers/block/loop.c	2013-04-05 19:44:28.748879564 +0200
@@ -226,7 +226,7 @@ static int __do_lo_send_write(struct fil
 	mm_segment_t old_fs = get_fs();
 
 	set_fs(get_ds());
-	bw = file->f_op->write(file, buf, len, &pos);
+	bw = file->f_op->write(file, (const char __force_user *)buf, len, &pos);
 	set_fs(old_fs);
 	if (likely(bw == len))
 		return 0;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/block/pktcdvd.c linux-3.8.13-pax/drivers/block/pktcdvd.c
--- linux-3.8.13/drivers/block/pktcdvd.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/block/pktcdvd.c	2013-04-26 22:49:51.949418810 +0200
@@ -83,7 +83,7 @@
 
 #define MAX_SPEED 0xffff
 
-#define ZONE(sector, pd) (((sector) + (pd)->offset) & ~((pd)->settings.size - 1))
+#define ZONE(sector, pd) (((sector) + (pd)->offset) & ~((pd)->settings.size - 1UL))
 
 static DEFINE_MUTEX(pktcdvd_mutex);
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cdrom/cdrom.c linux-3.8.13-pax/drivers/cdrom/cdrom.c
--- linux-3.8.13/drivers/cdrom/cdrom.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/cdrom/cdrom.c	2013-02-19 01:14:43.377772715 +0100
@@ -416,7 +416,6 @@ int register_cdrom(struct cdrom_device_i
 	ENSURE(reset, CDC_RESET);
 	ENSURE(generic_packet, CDC_GENERIC_PACKET);
 	cdi->mc_flags = 0;
-	cdo->n_minors = 0;
         cdi->options = CDO_USE_FFLAGS;
 	
 	if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
@@ -436,8 +435,11 @@ int register_cdrom(struct cdrom_device_i
 	else
 		cdi->cdda_method = CDDA_OLD;
 
-	if (!cdo->generic_packet)
-		cdo->generic_packet = cdrom_dummy_generic_packet;
+	if (!cdo->generic_packet) {
+		pax_open_kernel();
+		*(void **)&cdo->generic_packet = cdrom_dummy_generic_packet;
+		pax_close_kernel();
+	}
 
 	cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
 	mutex_lock(&cdrom_mutex);
@@ -458,7 +460,6 @@ void unregister_cdrom(struct cdrom_devic
 	if (cdi->exit)
 		cdi->exit(cdi);
 
-	cdi->ops->n_minors--;
 	cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cdrom/gdrom.c linux-3.8.13-pax/drivers/cdrom/gdrom.c
--- linux-3.8.13/drivers/cdrom/gdrom.c	2013-02-19 01:12:53.793766763 +0100
+++ linux-3.8.13-pax/drivers/cdrom/gdrom.c	2013-02-19 01:14:43.381772715 +0100
@@ -491,7 +491,6 @@ static struct cdrom_device_ops gdrom_ops
 	.audio_ioctl		= gdrom_audio_ioctl,
 	.capability		= CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
 				  CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R,
-	.n_minors		= 1,
 };
 
 static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/agp/frontend.c linux-3.8.13-pax/drivers/char/agp/frontend.c
--- linux-3.8.13/drivers/char/agp/frontend.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/char/agp/frontend.c	2013-02-19 01:14:43.381772715 +0100
@@ -817,7 +817,7 @@ static int agpioc_reserve_wrap(struct ag
 	if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
 		return -EFAULT;
 
-	if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
+	if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
 		return -EFAULT;
 
 	client = agp_find_client_by_pid(reserve.pid);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/hpet.c linux-3.8.13-pax/drivers/char/hpet.c
--- linux-3.8.13/drivers/char/hpet.c	2013-04-30 00:04:57.171843284 +0200
+++ linux-3.8.13-pax/drivers/char/hpet.c	2013-04-30 00:05:40.671840962 +0200
@@ -559,7 +559,7 @@ static inline unsigned long hpet_time_di
 }
 
 static int
-hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg,
+hpet_ioctl_common(struct hpet_dev *devp, unsigned int cmd, unsigned long arg,
 		  struct hpet_info *info)
 {
 	struct hpet_timer __iomem *timer;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/ipmi/ipmi_msghandler.c linux-3.8.13-pax/drivers/char/ipmi/ipmi_msghandler.c
--- linux-3.8.13/drivers/char/ipmi/ipmi_msghandler.c	2013-02-19 01:12:53.905766769 +0100
+++ linux-3.8.13-pax/drivers/char/ipmi/ipmi_msghandler.c	2013-02-19 01:14:43.381772715 +0100
@@ -420,7 +420,7 @@ struct ipmi_smi {
 	struct proc_dir_entry *proc_dir;
 	char                  proc_dir_name[10];
 
-	atomic_t stats[IPMI_NUM_STATS];
+	atomic_unchecked_t stats[IPMI_NUM_STATS];
 
 	/*
 	 * run_to_completion duplicate of smb_info, smi_info
@@ -453,9 +453,9 @@ static DEFINE_MUTEX(smi_watchers_mutex);
 
 
 #define ipmi_inc_stat(intf, stat) \
-	atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
+	atomic_inc_unchecked(&(intf)->stats[IPMI_STAT_ ## stat])
 #define ipmi_get_stat(intf, stat) \
-	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))
+	((unsigned int) atomic_read_unchecked(&(intf)->stats[IPMI_STAT_ ## stat]))
 
 static int is_lan_addr(struct ipmi_addr *addr)
 {
@@ -2884,7 +2884,7 @@ int ipmi_register_smi(struct ipmi_smi_ha
 	INIT_LIST_HEAD(&intf->cmd_rcvrs);
 	init_waitqueue_head(&intf->waitq);
 	for (i = 0; i < IPMI_NUM_STATS; i++)
-		atomic_set(&intf->stats[i], 0);
+		atomic_set_unchecked(&intf->stats[i], 0);
 
 	intf->proc_dir = NULL;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/ipmi/ipmi_si_intf.c linux-3.8.13-pax/drivers/char/ipmi/ipmi_si_intf.c
--- linux-3.8.13/drivers/char/ipmi/ipmi_si_intf.c	2013-02-19 01:12:53.905766769 +0100
+++ linux-3.8.13-pax/drivers/char/ipmi/ipmi_si_intf.c	2013-02-19 01:14:43.385772715 +0100
@@ -275,7 +275,7 @@ struct smi_info {
 	unsigned char slave_addr;
 
 	/* Counters and things for the proc filesystem. */
-	atomic_t stats[SI_NUM_STATS];
+	atomic_unchecked_t stats[SI_NUM_STATS];
 
 	struct task_struct *thread;
 
@@ -284,9 +284,9 @@ struct smi_info {
 };
 
 #define smi_inc_stat(smi, stat) \
-	atomic_inc(&(smi)->stats[SI_STAT_ ## stat])
+	atomic_inc_unchecked(&(smi)->stats[SI_STAT_ ## stat])
 #define smi_get_stat(smi, stat) \
-	((unsigned int) atomic_read(&(smi)->stats[SI_STAT_ ## stat]))
+	((unsigned int) atomic_read_unchecked(&(smi)->stats[SI_STAT_ ## stat]))
 
 #define SI_MAX_PARMS 4
 
@@ -3225,7 +3225,7 @@ static int try_smi_init(struct smi_info
 	atomic_set(&new_smi->req_events, 0);
 	new_smi->run_to_completion = 0;
 	for (i = 0; i < SI_NUM_STATS; i++)
-		atomic_set(&new_smi->stats[i], 0);
+		atomic_set_unchecked(&new_smi->stats[i], 0);
 
 	new_smi->interrupt_disabled = 1;
 	atomic_set(&new_smi->stop_operation, 0);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/mem.c linux-3.8.13-pax/drivers/char/mem.c
--- linux-3.8.13/drivers/char/mem.c	2013-02-19 01:12:53.913766770 +0100
+++ linux-3.8.13-pax/drivers/char/mem.c	2013-02-19 01:14:43.389772715 +0100
@@ -120,6 +120,7 @@ static ssize_t read_mem(struct file *fil
 
 	while (count > 0) {
 		unsigned long remaining;
+		char *temp;
 
 		sz = size_inside_page(p, count);
 
@@ -135,7 +136,23 @@ static ssize_t read_mem(struct file *fil
 		if (!ptr)
 			return -EFAULT;
 
-		remaining = copy_to_user(buf, ptr, sz);
+#ifdef CONFIG_PAX_USERCOPY
+		temp = kmalloc(sz, GFP_KERNEL|GFP_USERCOPY);
+		if (!temp) {
+			unxlate_dev_mem_ptr(p, ptr);
+			return -ENOMEM;
+		}
+		memcpy(temp, ptr, sz);
+#else
+		temp = ptr;
+#endif
+
+		remaining = copy_to_user(buf, temp, sz);
+
+#ifdef CONFIG_PAX_USERCOPY
+		kfree(temp);
+#endif
+
 		unxlate_dev_mem_ptr(p, ptr);
 		if (remaining)
 			return -EFAULT;
@@ -398,9 +415,8 @@ static ssize_t read_kmem(struct file *fi
 			 size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	ssize_t low_count, read, sz;
+	ssize_t low_count, read, sz, err = 0;
 	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
-	int err = 0;
 
 	read = 0;
 	if (p < (unsigned long) high_memory) {
@@ -422,6 +438,8 @@ static ssize_t read_kmem(struct file *fi
 		}
 #endif
 		while (low_count > 0) {
+			char *temp;
+
 			sz = size_inside_page(p, low_count);
 
 			/*
@@ -431,7 +449,22 @@ static ssize_t read_kmem(struct file *fi
 			 */
 			kbuf = xlate_dev_kmem_ptr((char *)p);
 
-			if (copy_to_user(buf, kbuf, sz))
+#ifdef CONFIG_PAX_USERCOPY
+			temp = kmalloc(sz, GFP_KERNEL|GFP_USERCOPY);
+			if (!temp)
+				return -ENOMEM;
+			memcpy(temp, kbuf, sz);
+#else
+			temp = kbuf;
+#endif
+
+			err = copy_to_user(buf, temp, sz);
+
+#ifdef CONFIG_PAX_USERCOPY
+			kfree(temp);
+#endif
+
+			if (err)
 				return -EFAULT;
 			buf += sz;
 			p += sz;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/nvram.c linux-3.8.13-pax/drivers/char/nvram.c
--- linux-3.8.13/drivers/char/nvram.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/char/nvram.c	2013-02-19 01:14:43.389772715 +0100
@@ -247,7 +247,7 @@ static ssize_t nvram_read(struct file *f
 
 	spin_unlock_irq(&rtc_lock);
 
-	if (copy_to_user(buf, contents, tmp - contents))
+	if (tmp - contents > sizeof(contents) || copy_to_user(buf, contents, tmp - contents))
 		return -EFAULT;
 
 	*ppos = i;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/pcmcia/synclink_cs.c linux-3.8.13-pax/drivers/char/pcmcia/synclink_cs.c
--- linux-3.8.13/drivers/char/pcmcia/synclink_cs.c	2013-02-19 01:12:53.917766770 +0100
+++ linux-3.8.13-pax/drivers/char/pcmcia/synclink_cs.c	2013-02-19 01:14:43.389772715 +0100
@@ -2348,9 +2348,9 @@ static void mgslpc_close(struct tty_stru
 
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgslpc_close(%s) entry, count=%d\n",
-			 __FILE__,__LINE__, info->device_name, port->count);
+			 __FILE__,__LINE__, info->device_name, atomic_read(&port->count));
 
-	WARN_ON(!port->count);
+	WARN_ON(!atomic_read(&port->count));
 
 	if (tty_port_close_start(port, tty, filp) == 0)
 		goto cleanup;
@@ -2368,7 +2368,7 @@ static void mgslpc_close(struct tty_stru
 cleanup:
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgslpc_close(%s) exit, count=%d\n", __FILE__,__LINE__,
-			tty->driver->name, port->count);
+			tty->driver->name, atomic_read(&port->count));
 }
 
 /* Wait until the transmitter is empty.
@@ -2510,7 +2510,7 @@ static int mgslpc_open(struct tty_struct
 
 	if (debug_level >= DEBUG_LEVEL_INFO)
 		printk("%s(%d):mgslpc_open(%s), old ref count = %d\n",
-			 __FILE__,__LINE__,tty->driver->name, port->count);
+			 __FILE__,__LINE__,tty->driver->name, atomic_read(&port->count));
 
 	/* If port is closing, signal caller to try again */
 	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING){
@@ -2530,11 +2530,11 @@ static int mgslpc_open(struct tty_struct
 		goto cleanup;
 	}
 	spin_lock(&port->lock);
-	port->count++;
+	atomic_inc(&port->count);
 	spin_unlock(&port->lock);
 	spin_unlock_irqrestore(&info->netlock, flags);
 
-	if (port->count == 1) {
+	if (atomic_read(&port->count) == 1) {
 		/* 1st open on this device, init hardware */
 		retval = startup(info, tty);
 		if (retval < 0)
@@ -3889,7 +3889,7 @@ static int hdlcdev_attach(struct net_dev
 	unsigned short new_crctype;
 
 	/* return error if TTY interface open */
-	if (info->port.count)
+	if (atomic_read(&info->port.count))
 		return -EBUSY;
 
 	switch (encoding)
@@ -3992,7 +3992,7 @@ static int hdlcdev_open(struct net_devic
 
 	/* arbitrate between network and tty opens */
 	spin_lock_irqsave(&info->netlock, flags);
-	if (info->port.count != 0 || info->netcount != 0) {
+	if (atomic_read(&info->port.count) != 0 || info->netcount != 0) {
 		printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
 		spin_unlock_irqrestore(&info->netlock, flags);
 		return -EBUSY;
@@ -4081,7 +4081,7 @@ static int hdlcdev_ioctl(struct net_devi
 		printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
 
 	/* return error if TTY interface open */
-	if (info->port.count)
+	if (atomic_read(&info->port.count))
 		return -EBUSY;
 
 	if (cmd != SIOCWANDEV)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/random.c linux-3.8.13-pax/drivers/char/random.c
--- linux-3.8.13/drivers/char/random.c	2013-03-19 01:53:21.031281872 +0100
+++ linux-3.8.13-pax/drivers/char/random.c	2013-03-19 01:53:31.199281329 +0100
@@ -524,8 +524,8 @@ static void _mix_pool_bytes(struct entro
 		input_rotate += i ? 7 : 14;
 	}
 
-	ACCESS_ONCE(r->input_rotate) = input_rotate;
-	ACCESS_ONCE(r->add_ptr) = i;
+	ACCESS_ONCE_RW(r->input_rotate) = input_rotate;
+	ACCESS_ONCE_RW(r->add_ptr) = i;
 	smp_wmb();
 
 	if (out)
@@ -1024,7 +1024,7 @@ static ssize_t extract_entropy_user(stru
 
 		extract_buf(r, tmp);
 		i = min_t(int, nbytes, EXTRACT_SIZE);
-		if (copy_to_user(buf, tmp, i)) {
+		if (i > sizeof(tmp) || copy_to_user(buf, tmp, i)) {
 			ret = -EFAULT;
 			break;
 		}
@@ -1360,7 +1360,7 @@ EXPORT_SYMBOL(generate_random_uuid);
 #include <linux/sysctl.h>
 
 static int min_read_thresh = 8, min_write_thresh;
-static int max_read_thresh = INPUT_POOL_WORDS * 32;
+static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
 static int max_write_thresh = INPUT_POOL_WORDS * 32;
 static char sysctl_bootid[16];
 
@@ -1376,7 +1376,7 @@ static char sysctl_bootid[16];
 static int proc_do_uuid(ctl_table *table, int write,
 			void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-	ctl_table fake_table;
+	ctl_table_no_const fake_table;
 	unsigned char buf[64], tmp_uuid[16], *uuid;
 
 	uuid = table->data;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/sonypi.c linux-3.8.13-pax/drivers/char/sonypi.c
--- linux-3.8.13/drivers/char/sonypi.c	2013-02-19 01:12:53.933766771 +0100
+++ linux-3.8.13-pax/drivers/char/sonypi.c	2013-02-19 01:14:43.393772716 +0100
@@ -54,6 +54,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <asm/local.h>
 
 #include <linux/sonypi.h>
 
@@ -490,7 +491,7 @@ static struct sonypi_device {
 	spinlock_t fifo_lock;
 	wait_queue_head_t fifo_proc_list;
 	struct fasync_struct *fifo_async;
-	int open_count;
+	local_t open_count;
 	int model;
 	struct input_dev *input_jog_dev;
 	struct input_dev *input_key_dev;
@@ -897,7 +898,7 @@ static int sonypi_misc_fasync(int fd, st
 static int sonypi_misc_release(struct inode *inode, struct file *file)
 {
 	mutex_lock(&sonypi_device.lock);
-	sonypi_device.open_count--;
+	local_dec(&sonypi_device.open_count);
 	mutex_unlock(&sonypi_device.lock);
 	return 0;
 }
@@ -906,9 +907,9 @@ static int sonypi_misc_open(struct inode
 {
 	mutex_lock(&sonypi_device.lock);
 	/* Flush input queue on first open */
-	if (!sonypi_device.open_count)
+	if (!local_read(&sonypi_device.open_count))
 		kfifo_reset(&sonypi_device.fifo);
-	sonypi_device.open_count++;
+	local_inc(&sonypi_device.open_count);
 	mutex_unlock(&sonypi_device.lock);
 
 	return 0;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/tpm/tpm_acpi.c linux-3.8.13-pax/drivers/char/tpm/tpm_acpi.c
--- linux-3.8.13/drivers/char/tpm/tpm_acpi.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/char/tpm/tpm_acpi.c	2013-02-19 01:14:43.393772716 +0100
@@ -98,11 +98,12 @@ int read_log(struct tpm_bios_log *log)
 	virt = acpi_os_map_memory(start, len);
 	if (!virt) {
 		kfree(log->bios_event_log);
+		log->bios_event_log = NULL;
 		printk("%s: ERROR - Unable to map memory\n", __func__);
 		return -EIO;
 	}
 
-	memcpy_fromio(log->bios_event_log, virt, len);
+	memcpy_fromio(log->bios_event_log, (const char __force_kernel *)virt, len);
 
 	acpi_os_unmap_memory(virt, len);
 	return 0;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/tpm/tpm.c linux-3.8.13-pax/drivers/char/tpm/tpm.c
--- linux-3.8.13/drivers/char/tpm/tpm.c	2013-05-13 02:47:05.465794899 +0200
+++ linux-3.8.13-pax/drivers/char/tpm/tpm.c	2013-05-13 02:47:30.589793557 +0200
@@ -410,7 +410,7 @@ static ssize_t tpm_transmit(struct tpm_c
 		    chip->vendor.req_complete_val)
 			goto out_recv;
 
-		if ((status == chip->vendor.req_canceled)) {
+		if (status == chip->vendor.req_canceled) {
 			dev_err(chip->dev, "Operation Canceled\n");
 			rc = -ECANCELED;
 			goto out;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/tpm/tpm_eventlog.c linux-3.8.13-pax/drivers/char/tpm/tpm_eventlog.c
--- linux-3.8.13/drivers/char/tpm/tpm_eventlog.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/char/tpm/tpm_eventlog.c	2013-02-19 01:14:43.393772716 +0100
@@ -95,7 +95,7 @@ static void *tpm_bios_measurements_start
 	event = addr;
 
 	if ((event->event_type == 0 && event->event_size == 0) ||
-	    ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
+	    (event->event_size >= limit - addr - sizeof(struct tcpa_event)))
 		return NULL;
 
 	return addr;
@@ -120,7 +120,7 @@ static void *tpm_bios_measurements_next(
 		return NULL;
 
 	if ((event->event_type == 0 && event->event_size == 0) ||
-	    ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
+	    (event->event_size >= limit - v - sizeof(struct tcpa_event)))
 		return NULL;
 
 	(*pos)++;
@@ -213,7 +213,8 @@ static int tpm_binary_bios_measurements_
 	int i;
 
 	for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
-		seq_putc(m, data[i]);
+		if (!seq_putc(m, data[i]))
+			return -EFAULT;
 
 	return 0;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/char/virtio_console.c linux-3.8.13-pax/drivers/char/virtio_console.c
--- linux-3.8.13/drivers/char/virtio_console.c	2013-04-05 19:44:22.576879382 +0200
+++ linux-3.8.13-pax/drivers/char/virtio_console.c	2013-04-05 19:44:28.748879564 +0200
@@ -685,7 +685,7 @@ static ssize_t fill_readbuf(struct port
 	if (to_user) {
 		ssize_t ret;
 
-		ret = copy_to_user(out_buf, buf->buf + buf->offset, out_count);
+		ret = copy_to_user((char __force_user *)out_buf, buf->buf + buf->offset, out_count);
 		if (ret)
 			return -EFAULT;
 	} else {
@@ -784,7 +784,7 @@ static ssize_t port_fops_read(struct fil
 	if (!port_has_data(port) && !port->host_connected)
 		return 0;
 
-	return fill_readbuf(port, ubuf, count, true);
+	return fill_readbuf(port, (char __force_kernel *)ubuf, count, true);
 }
 
 static int wait_port_writable(struct port *port, bool nonblock)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/clocksource/arm_generic.c linux-3.8.13-pax/drivers/clocksource/arm_generic.c
--- linux-3.8.13/drivers/clocksource/arm_generic.c	2013-02-19 01:12:54.009766775 +0100
+++ linux-3.8.13-pax/drivers/clocksource/arm_generic.c	2013-02-20 01:00:26.698087612 +0100
@@ -181,7 +181,7 @@ static int __cpuinit arch_timer_cpu_noti
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata arch_timer_cpu_nb = {
+static struct notifier_block arch_timer_cpu_nb = {
 	.notifier_call = arch_timer_cpu_notify,
 };
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/acpi-cpufreq.c linux-3.8.13-pax/drivers/cpufreq/acpi-cpufreq.c
--- linux-3.8.13/drivers/cpufreq/acpi-cpufreq.c	2013-02-19 01:12:54.033766776 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/acpi-cpufreq.c	2013-03-05 19:10:30.913861437 +0100
@@ -172,7 +172,7 @@ static ssize_t show_global_boost(struct
 	return sprintf(buf, "%u\n", boost_enabled);
 }
 
-static struct global_attr global_boost = __ATTR(boost, 0644,
+static global_attr_no_const global_boost = __ATTR(boost, 0644,
 						show_global_boost,
 						store_global_boost);
 
@@ -712,8 +712,11 @@ static int acpi_cpufreq_cpu_init(struct
 	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
 	per_cpu(acfreq_data, cpu) = data;
 
-	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
-		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
+	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
+		pax_open_kernel();
+		*(u8 *)&acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
+		pax_close_kernel();
+	}
 
 	result = acpi_processor_register_performance(data->acpi_data, cpu);
 	if (result)
@@ -835,7 +838,9 @@ static int acpi_cpufreq_cpu_init(struct
 		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
 		break;
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
-		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
+		pax_open_kernel();
+		*(void **)&acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
+		pax_close_kernel();
 		policy->cur = get_cur_freq_on_cpu(cpu);
 		break;
 	default:
@@ -846,8 +851,11 @@ static int acpi_cpufreq_cpu_init(struct
 	acpi_processor_notify_smm(THIS_MODULE);
 
 	/* Check for APERF/MPERF support in hardware */
-	if (boot_cpu_has(X86_FEATURE_APERFMPERF))
-		acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
+	if (boot_cpu_has(X86_FEATURE_APERFMPERF)) {
+		pax_open_kernel();
+		*(void **)&acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
+		pax_close_kernel();
+	}
 
 	pr_debug("CPU%u - ACPI performance management activated.\n", cpu);
 	for (i = 0; i < perf->state_count; i++)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/cpufreq.c linux-3.8.13-pax/drivers/cpufreq/cpufreq.c
--- linux-3.8.13/drivers/cpufreq/cpufreq.c	2013-02-19 01:12:54.049766777 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/cpufreq.c	2013-03-05 19:10:53.717860220 +0100
@@ -1843,7 +1843,7 @@ static int __cpuinit cpufreq_cpu_callbac
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __refdata cpufreq_cpu_notifier = {
+static struct notifier_block cpufreq_cpu_notifier = {
     .notifier_call = cpufreq_cpu_callback,
 };
 
@@ -1875,8 +1875,11 @@ int cpufreq_register_driver(struct cpufr
 
 	pr_debug("trying to register driver %s\n", driver_data->name);
 
-	if (driver_data->setpolicy)
-		driver_data->flags |= CPUFREQ_CONST_LOOPS;
+	if (driver_data->setpolicy) {
+		pax_open_kernel();
+		*(u8 *)&driver_data->flags |= CPUFREQ_CONST_LOOPS;
+		pax_close_kernel();
+	}
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
 	if (cpufreq_driver) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/cpufreq_governor.c linux-3.8.13-pax/drivers/cpufreq/cpufreq_governor.c
--- linux-3.8.13/drivers/cpufreq/cpufreq_governor.c	2013-02-19 01:12:54.061766778 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/cpufreq_governor.c	2013-03-08 15:16:34.458339677 +0100
@@ -243,7 +243,7 @@ int cpufreq_governor_dbs(struct dbs_data
 		 * governor, thus we are bound to jiffes/HZ
 		 */
 		if (dbs_data->governor == GOV_CONSERVATIVE) {
-			struct cs_ops *ops = dbs_data->gov_ops;
+			const struct cs_ops *ops = dbs_data->gov_ops;
 
 			cpufreq_register_notifier(ops->notifier_block,
 					CPUFREQ_TRANSITION_NOTIFIER);
@@ -251,7 +251,7 @@ int cpufreq_governor_dbs(struct dbs_data
 			dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO *
 				jiffies_to_usecs(10);
 		} else {
-			struct od_ops *ops = dbs_data->gov_ops;
+			const struct od_ops *ops = dbs_data->gov_ops;
 
 			od_tuners->io_is_busy = ops->io_busy();
 		}
@@ -268,7 +268,7 @@ second_time:
 			cs_dbs_info->enable = 1;
 			cs_dbs_info->requested_freq = policy->cur;
 		} else {
-			struct od_ops *ops = dbs_data->gov_ops;
+			const struct od_ops *ops = dbs_data->gov_ops;
 			od_dbs_info->rate_mult = 1;
 			od_dbs_info->sample_type = OD_NORMAL_SAMPLE;
 			ops->powersave_bias_init_cpu(cpu);
@@ -289,7 +289,7 @@ second_time:
 		mutex_destroy(&cpu_cdbs->timer_mutex);
 		dbs_data->enable--;
 		if (!dbs_data->enable) {
-			struct cs_ops *ops = dbs_data->gov_ops;
+			const struct cs_ops *ops = dbs_data->gov_ops;
 
 			sysfs_remove_group(cpufreq_global_kobject,
 					dbs_data->attr_group);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/cpufreq_governor.h linux-3.8.13-pax/drivers/cpufreq/cpufreq_governor.h
--- linux-3.8.13/drivers/cpufreq/cpufreq_governor.h	2013-02-19 01:12:54.061766778 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/cpufreq_governor.h	2013-02-21 04:58:45.441006670 +0100
@@ -142,7 +142,7 @@ struct dbs_data {
 	void (*gov_check_cpu)(int cpu, unsigned int load);
 
 	/* Governor specific ops, see below */
-	void *gov_ops;
+	const void *gov_ops;
 };
 
 /* Governor specific ops, will be passed to dbs_data->gov_ops */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/cpufreq_stats.c linux-3.8.13-pax/drivers/cpufreq/cpufreq_stats.c
--- linux-3.8.13/drivers/cpufreq/cpufreq_stats.c	2013-02-19 01:12:54.073766778 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/cpufreq_stats.c	2013-02-20 01:00:02.682088894 +0100
@@ -340,7 +340,7 @@ static int __cpuinit cpufreq_stat_cpu_ca
 }
 
 /* priority=1 so this will get called before cpufreq_remove_dev */
-static struct notifier_block cpufreq_stat_cpu_notifier __refdata = {
+static struct notifier_block cpufreq_stat_cpu_notifier = {
 	.notifier_call = cpufreq_stat_cpu_callback,
 	.priority = 1,
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/p4-clockmod.c linux-3.8.13-pax/drivers/cpufreq/p4-clockmod.c
--- linux-3.8.13/drivers/cpufreq/p4-clockmod.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/p4-clockmod.c	2013-03-05 19:05:07.033878730 +0100
@@ -167,10 +167,14 @@ static unsigned int cpufreq_p4_get_frequ
 		case 0x0F: /* Core Duo */
 		case 0x16: /* Celeron Core */
 		case 0x1C: /* Atom */
-			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			pax_open_kernel();
+			*(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			pax_close_kernel();
 			return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
 		case 0x0D: /* Pentium M (Dothan) */
-			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			pax_open_kernel();
+			*(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			pax_close_kernel();
 			/* fall through */
 		case 0x09: /* Pentium M (Banias) */
 			return speedstep_get_frequency(SPEEDSTEP_CPU_PM);
@@ -182,7 +186,9 @@ static unsigned int cpufreq_p4_get_frequ
 
 	/* on P-4s, the TSC runs with constant frequency independent whether
 	 * throttling is active or not. */
-	p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+	pax_open_kernel();
+	*(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+	pax_close_kernel();
 
 	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) {
 		printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. "
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpufreq/speedstep-centrino.c linux-3.8.13-pax/drivers/cpufreq/speedstep-centrino.c
--- linux-3.8.13/drivers/cpufreq/speedstep-centrino.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/cpufreq/speedstep-centrino.c	2013-03-05 19:04:07.389881914 +0100
@@ -353,8 +353,11 @@ static int centrino_cpu_init(struct cpuf
 	    !cpu_has(cpu, X86_FEATURE_EST))
 		return -ENODEV;
 
-	if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC))
-		centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
+	if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) {
+		pax_open_kernel();
+		*(u8 *)&centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
+		pax_close_kernel();
+	}
 
 	if (policy->cpu != 0)
 		return -ENODEV;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpuidle/cpuidle.c linux-3.8.13-pax/drivers/cpuidle/cpuidle.c
--- linux-3.8.13/drivers/cpuidle/cpuidle.c	2013-02-19 01:12:54.101766780 +0100
+++ linux-3.8.13-pax/drivers/cpuidle/cpuidle.c	2013-03-06 03:10:49.448322751 +0100
@@ -279,7 +279,7 @@ static int poll_idle(struct cpuidle_devi
 
 static void poll_idle_init(struct cpuidle_driver *drv)
 {
-	struct cpuidle_state *state = &drv->states[0];
+	cpuidle_state_no_const *state = &drv->states[0];
 
 	snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
 	snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpuidle/governor.c linux-3.8.13-pax/drivers/cpuidle/governor.c
--- linux-3.8.13/drivers/cpuidle/governor.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/cpuidle/governor.c	2013-03-06 16:01:02.749855319 +0100
@@ -87,7 +87,7 @@ int cpuidle_register_governor(struct cpu
 	mutex_lock(&cpuidle_lock);
 	if (__cpuidle_find_governor(gov->name) == NULL) {
 		ret = 0;
-		list_add_tail(&gov->governor_list, &cpuidle_governors);
+		pax_list_add_tail((struct list_head *)&gov->governor_list, &cpuidle_governors);
 		if (!cpuidle_curr_governor ||
 		    cpuidle_curr_governor->rating < gov->rating)
 			cpuidle_switch_governor(gov);
@@ -135,7 +135,7 @@ void cpuidle_unregister_governor(struct
 		new_gov = cpuidle_replace_governor(gov->rating);
 		cpuidle_switch_governor(new_gov);
 	}
-	list_del(&gov->governor_list);
+	pax_list_del((struct list_head *)&gov->governor_list);
 	mutex_unlock(&cpuidle_lock);
 }
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/cpuidle/sysfs.c linux-3.8.13-pax/drivers/cpuidle/sysfs.c
--- linux-3.8.13/drivers/cpuidle/sysfs.c	2013-02-19 01:12:54.121766781 +0100
+++ linux-3.8.13-pax/drivers/cpuidle/sysfs.c	2013-02-21 04:56:12.209014851 +0100
@@ -131,7 +131,7 @@ static struct attribute *cpuidle_switch_
 	NULL
 };
 
-static struct attribute_group cpuidle_attr_group = {
+static attribute_group_no_const cpuidle_attr_group = {
 	.attrs = cpuidle_default_attrs,
 	.name = "cpuidle",
 };
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/devfreq/devfreq.c linux-3.8.13-pax/drivers/devfreq/devfreq.c
--- linux-3.8.13/drivers/devfreq/devfreq.c	2013-02-19 01:12:56.161766892 +0100
+++ linux-3.8.13-pax/drivers/devfreq/devfreq.c	2013-03-06 16:11:19.197822405 +0100
@@ -588,7 +588,7 @@ int devfreq_add_governor(struct devfreq_
 		goto err_out;
 	}
 
-	list_add(&governor->node, &devfreq_governor_list);
+	pax_list_add((struct list_head *)&governor->node, &devfreq_governor_list);
 
 	list_for_each_entry(devfreq, &devfreq_list, node) {
 		int ret = 0;
@@ -676,7 +676,7 @@ int devfreq_remove_governor(struct devfr
 		}
 	}
 
-	list_del(&governor->node);
+	pax_list_del((struct list_head *)&governor->node);
 err_out:
 	mutex_unlock(&devfreq_list_lock);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/dma/sh/shdma.c linux-3.8.13-pax/drivers/dma/sh/shdma.c
--- linux-3.8.13/drivers/dma/sh/shdma.c	2013-03-07 04:10:19.751802301 +0100
+++ linux-3.8.13-pax/drivers/dma/sh/shdma.c	2013-03-07 04:10:37.743801341 +0100
@@ -476,7 +476,7 @@ static int sh_dmae_nmi_handler(struct no
 	return ret;
 }
 
-static struct notifier_block sh_dmae_nmi_notifier __read_mostly = {
+static struct notifier_block sh_dmae_nmi_notifier = {
 	.notifier_call	= sh_dmae_nmi_handler,
 
 	/* Run before NMI debug handler and KGDB */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/edac/edac_mc_sysfs.c linux-3.8.13-pax/drivers/edac/edac_mc_sysfs.c
--- linux-3.8.13/drivers/edac/edac_mc_sysfs.c	2013-05-13 02:47:11.137794596 +0200
+++ linux-3.8.13-pax/drivers/edac/edac_mc_sysfs.c	2013-05-13 02:51:11.401781767 +0200
@@ -148,7 +148,7 @@ static const char *edac_caps[] = {
 struct dev_ch_attribute {
 	struct device_attribute attr;
 	int channel;
-};
+} __do_const;
 
 #define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
 	struct dev_ch_attribute dev_attr_legacy_##_name = \
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/edac/edac_pci_sysfs.c linux-3.8.13-pax/drivers/edac/edac_pci_sysfs.c
--- linux-3.8.13/drivers/edac/edac_pci_sysfs.c	2013-02-19 01:12:56.317766900 +0100
+++ linux-3.8.13-pax/drivers/edac/edac_pci_sysfs.c	2013-03-06 16:46:22.761710091 +0100
@@ -26,8 +26,8 @@ static int edac_pci_log_pe = 1;		/* log
 static int edac_pci_log_npe = 1;	/* log PCI non-parity error errors */
 static int edac_pci_poll_msec = 1000;	/* one second workq period */
 
-static atomic_t pci_parity_count = ATOMIC_INIT(0);
-static atomic_t pci_nonparity_count = ATOMIC_INIT(0);
+static atomic_unchecked_t pci_parity_count = ATOMIC_INIT(0);
+static atomic_unchecked_t pci_nonparity_count = ATOMIC_INIT(0);
 
 static struct kobject *edac_pci_top_main_kobj;
 static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0);
@@ -235,7 +235,7 @@ struct edac_pci_dev_attribute {
 	void *value;
 	 ssize_t(*show) (void *, char *);
 	 ssize_t(*store) (void *, const char *, size_t);
-};
+} __do_const;
 
 /* Set of show/store abstract level functions for PCI Parity object */
 static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr,
@@ -579,7 +579,7 @@ static void edac_pci_dev_parity_test(str
 			edac_printk(KERN_CRIT, EDAC_PCI,
 				"Signaled System Error on %s\n",
 				pci_name(dev));
-			atomic_inc(&pci_nonparity_count);
+			atomic_inc_unchecked(&pci_nonparity_count);
 		}
 
 		if (status & (PCI_STATUS_PARITY)) {
@@ -587,7 +587,7 @@ static void edac_pci_dev_parity_test(str
 				"Master Data Parity Error on %s\n",
 				pci_name(dev));
 
-			atomic_inc(&pci_parity_count);
+			atomic_inc_unchecked(&pci_parity_count);
 		}
 
 		if (status & (PCI_STATUS_DETECTED_PARITY)) {
@@ -595,7 +595,7 @@ static void edac_pci_dev_parity_test(str
 				"Detected Parity Error on %s\n",
 				pci_name(dev));
 
-			atomic_inc(&pci_parity_count);
+			atomic_inc_unchecked(&pci_parity_count);
 		}
 	}
 
@@ -618,7 +618,7 @@ static void edac_pci_dev_parity_test(str
 				edac_printk(KERN_CRIT, EDAC_PCI, "Bridge "
 					"Signaled System Error on %s\n",
 					pci_name(dev));
-				atomic_inc(&pci_nonparity_count);
+				atomic_inc_unchecked(&pci_nonparity_count);
 			}
 
 			if (status & (PCI_STATUS_PARITY)) {
@@ -626,7 +626,7 @@ static void edac_pci_dev_parity_test(str
 					"Master Data Parity Error on "
 					"%s\n", pci_name(dev));
 
-				atomic_inc(&pci_parity_count);
+				atomic_inc_unchecked(&pci_parity_count);
 			}
 
 			if (status & (PCI_STATUS_DETECTED_PARITY)) {
@@ -634,7 +634,7 @@ static void edac_pci_dev_parity_test(str
 					"Detected Parity Error on %s\n",
 					pci_name(dev));
 
-				atomic_inc(&pci_parity_count);
+				atomic_inc_unchecked(&pci_parity_count);
 			}
 		}
 	}
@@ -672,7 +672,7 @@ void edac_pci_do_parity_check(void)
 	if (!check_pci_errors)
 		return;
 
-	before_count = atomic_read(&pci_parity_count);
+	before_count = atomic_read_unchecked(&pci_parity_count);
 
 	/* scan all PCI devices looking for a Parity Error on devices and
 	 * bridges.
@@ -684,7 +684,7 @@ void edac_pci_do_parity_check(void)
 	/* Only if operator has selected panic on PCI Error */
 	if (edac_pci_get_panic_on_pe()) {
 		/* If the count is different 'after' from 'before' */
-		if (before_count != atomic_read(&pci_parity_count))
+		if (before_count != atomic_read_unchecked(&pci_parity_count))
 			panic("EDAC: PCI Parity Error");
 	}
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/edac/mce_amd.h linux-3.8.13-pax/drivers/edac/mce_amd.h
--- linux-3.8.13/drivers/edac/mce_amd.h	2013-02-19 01:12:56.361766902 +0100
+++ linux-3.8.13-pax/drivers/edac/mce_amd.h	2013-02-19 01:14:43.397772716 +0100
@@ -78,7 +78,7 @@ extern const char * const ii_msgs[];
 struct amd_decoder_ops {
 	bool (*mc0_mce)(u16, u8);
 	bool (*mc1_mce)(u16, u8);
-};
+} __no_const;
 
 void amd_report_gart_errors(bool);
 void amd_register_ecc_decoder(void (*f)(int, struct mce *));
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firewire/core-card.c linux-3.8.13-pax/drivers/firewire/core-card.c
--- linux-3.8.13/drivers/firewire/core-card.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firewire/core-card.c	2013-02-19 01:14:43.397772716 +0100
@@ -680,7 +680,7 @@ EXPORT_SYMBOL_GPL(fw_card_release);
 
 void fw_core_remove_card(struct fw_card *card)
 {
-	struct fw_card_driver dummy_driver = dummy_driver_template;
+	fw_card_driver_no_const dummy_driver = dummy_driver_template;
 
 	card->driver->update_phy_reg(card, 4,
 				     PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firewire/core-cdev.c linux-3.8.13-pax/drivers/firewire/core-cdev.c
--- linux-3.8.13/drivers/firewire/core-cdev.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firewire/core-cdev.c	2013-02-19 01:14:43.397772716 +0100
@@ -1365,8 +1365,7 @@ static int init_iso_resource(struct clie
 	int ret;
 
 	if ((request->channels == 0 && request->bandwidth == 0) ||
-	    request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
-	    request->bandwidth < 0)
+	    request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL)
 		return -EINVAL;
 
 	r  = kmalloc(sizeof(*r), GFP_KERNEL);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firewire/core-device.c linux-3.8.13-pax/drivers/firewire/core-device.c
--- linux-3.8.13/drivers/firewire/core-device.c	2013-03-07 04:10:19.755802301 +0100
+++ linux-3.8.13-pax/drivers/firewire/core-device.c	2013-03-07 04:10:37.743801341 +0100
@@ -232,7 +232,7 @@ EXPORT_SYMBOL(fw_device_enable_phys_dma)
 struct config_rom_attribute {
 	struct device_attribute attr;
 	u32 key;
-};
+} __do_const;
 
 static ssize_t show_immediate(struct device *dev,
 			      struct device_attribute *dattr, char *buf)
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firewire/core.h linux-3.8.13-pax/drivers/firewire/core.h
--- linux-3.8.13/drivers/firewire/core.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firewire/core.h	2013-02-19 01:14:43.397772716 +0100
@@ -111,6 +111,7 @@ struct fw_card_driver {
 
 	int (*stop_iso)(struct fw_iso_context *ctx);
 };
+typedef struct fw_card_driver __no_const fw_card_driver_no_const;
 
 void fw_card_initialize(struct fw_card *card,
 		const struct fw_card_driver *driver, struct device *device);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firewire/core-transaction.c linux-3.8.13-pax/drivers/firewire/core-transaction.c
--- linux-3.8.13/drivers/firewire/core-transaction.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firewire/core-transaction.c	2013-02-19 01:14:43.397772716 +0100
@@ -38,6 +38,7 @@
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
 
 #include <asm/byteorder.h>
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firmware/dmi-id.c linux-3.8.13-pax/drivers/firmware/dmi-id.c
--- linux-3.8.13/drivers/firmware/dmi-id.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firmware/dmi-id.c	2013-03-05 17:31:56.650177213 +0100
@@ -16,7 +16,7 @@
 struct dmi_device_attribute{
 	struct device_attribute dev_attr;
 	int field;
-};
+} __do_const;
 #define to_dmi_dev_attr(_dev_attr) \
 	container_of(_dev_attr, struct dmi_device_attribute, dev_attr)
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firmware/dmi_scan.c linux-3.8.13-pax/drivers/firmware/dmi_scan.c
--- linux-3.8.13/drivers/firmware/dmi_scan.c	2013-03-19 01:53:21.031281872 +0100
+++ linux-3.8.13-pax/drivers/firmware/dmi_scan.c	2013-03-19 01:53:31.203281329 +0100
@@ -490,11 +490,6 @@ void __init dmi_scan_machine(void)
 		}
 	}
 	else {
-		/*
-		 * no iounmap() for that ioremap(); it would be a no-op, but
-		 * it's so early in setup that sucker gets confused into doing
-		 * what it shouldn't if we actually call it.
-		 */
 		p = dmi_ioremap(0xF0000, 0x10000);
 		if (p == NULL)
 			goto error;
@@ -769,7 +764,7 @@ int dmi_walk(void (*decode)(const struct
 	if (buf == NULL)
 		return -1;
 
-	dmi_table(buf, dmi_len, dmi_num, decode, private_data);
+	dmi_table((char __force_kernel *)buf, dmi_len, dmi_num, decode, private_data);
 
 	iounmap(buf);
 	return 0;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firmware/efivars.c linux-3.8.13-pax/drivers/firmware/efivars.c
--- linux-3.8.13/drivers/firmware/efivars.c	2013-04-05 19:44:22.612879383 +0200
+++ linux-3.8.13-pax/drivers/firmware/efivars.c	2013-04-05 19:44:28.752879564 +0200
@@ -138,7 +138,7 @@ struct efivar_attribute {
 };
 
 static struct efivars __efivars;
-static struct efivar_operations ops;
+static efivar_operations_no_const ops __read_only;
 
 #define PSTORE_EFI_ATTRIBUTES \
 	(EFI_VARIABLE_NON_VOLATILE | \
@@ -1834,7 +1834,7 @@ efivar_create_sysfs_entry(struct efivars
 static int
 create_efivars_bin_attributes(struct efivars *efivars)
 {
-	struct bin_attribute *attr;
+	bin_attribute_no_const *attr;
 	int error;
 
 	/* new_var */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/firmware/google/memconsole.c linux-3.8.13-pax/drivers/firmware/google/memconsole.c
--- linux-3.8.13/drivers/firmware/google/memconsole.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/firmware/google/memconsole.c	2013-03-05 17:43:00.314141779 +0100
@@ -147,7 +147,9 @@ static int __init memconsole_init(void)
 	if (!found_memconsole())
 		return -ENODEV;
 
-	memconsole_bin_attr.size = memconsole_length;
+	pax_open_kernel();
+	*(size_t *)&memconsole_bin_attr.size = memconsole_length;
+	pax_close_kernel();
 
 	ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpio/gpio-ich.c linux-3.8.13-pax/drivers/gpio/gpio-ich.c
--- linux-3.8.13/drivers/gpio/gpio-ich.c	2013-02-19 01:12:56.481766909 +0100
+++ linux-3.8.13-pax/drivers/gpio/gpio-ich.c	2013-03-05 00:11:07.365511521 +0100
@@ -69,7 +69,7 @@ struct ichx_desc {
 	/* Some chipsets have quirks, let these use their own request/get */
 	int (*request)(struct gpio_chip *chip, unsigned offset);
 	int (*get)(struct gpio_chip *chip, unsigned offset);
-};
+} __do_const;
 
 static struct {
 	spinlock_t lock;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpio/gpio-vr41xx.c linux-3.8.13-pax/drivers/gpio/gpio-vr41xx.c
--- linux-3.8.13/drivers/gpio/gpio-vr41xx.c	2013-02-19 01:12:56.573766914 +0100
+++ linux-3.8.13-pax/drivers/gpio/gpio-vr41xx.c	2013-02-19 01:14:43.401772716 +0100
@@ -204,7 +204,7 @@ static int giu_get_irq(unsigned int irq)
 	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
 	       maskl, pendl, maskh, pendh);
 
-	atomic_inc(&irq_err_count);
+	atomic_inc_unchecked(&irq_err_count);
 
 	return -EINVAL;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_crtc_helper.c linux-3.8.13-pax/drivers/gpu/drm/drm_crtc_helper.c
--- linux-3.8.13/drivers/gpu/drm/drm_crtc_helper.c	2013-02-19 01:12:56.625766917 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_crtc_helper.c	2013-02-19 01:14:43.401772716 +0100
@@ -319,7 +319,7 @@ static bool drm_encoder_crtc_ok(struct d
 	struct drm_crtc *tmp;
 	int crtc_mask = 1;
 
-	WARN(!crtc, "checking null crtc?\n");
+	BUG_ON(!crtc);
 
 	dev = crtc->dev;
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_drv.c linux-3.8.13-pax/drivers/gpu/drm/drm_drv.c
--- linux-3.8.13/drivers/gpu/drm/drm_drv.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_drv.c	2013-03-06 02:57:25.144365694 +0100
@@ -307,7 +307,7 @@ module_exit(drm_core_exit);
 /**
  * Copy and IOCTL return string to user space
  */
-static int drm_copy_field(char *buf, size_t *buf_len, const char *value)
+static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value)
 {
 	int len;
 
@@ -377,7 +377,7 @@ long drm_ioctl(struct file *filp,
 	struct drm_file *file_priv = filp->private_data;
 	struct drm_device *dev;
 	struct drm_ioctl_desc *ioctl;
-	drm_ioctl_t *func;
+	drm_ioctl_no_const_t func;
 	unsigned int nr = DRM_IOCTL_NR(cmd);
 	int retcode = -EINVAL;
 	char stack_kdata[128];
@@ -390,7 +390,7 @@ long drm_ioctl(struct file *filp,
 		return -ENODEV;
 
 	atomic_inc(&dev->ioctl_count);
-	atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_IOCTLS]);
 	++file_priv->ioctl_count;
 
 	DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_fops.c linux-3.8.13-pax/drivers/gpu/drm/drm_fops.c
--- linux-3.8.13/drivers/gpu/drm/drm_fops.c	2013-04-13 00:55:42.723157665 +0200
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_fops.c	2013-04-13 00:56:41.575154523 +0200
@@ -71,7 +71,7 @@ static int drm_setup(struct drm_device *
 	}
 
 	for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
-		atomic_set(&dev->counts[i], 0);
+		atomic_set_unchecked(&dev->counts[i], 0);
 
 	dev->sigdata.lock = NULL;
 
@@ -135,7 +135,7 @@ int drm_open(struct inode *inode, struct
 	if (drm_device_is_unplugged(dev))
 		return -ENODEV;
 
-	if (!dev->open_count++)
+	if (local_inc_return(&dev->open_count) == 1)
 		need_setup = 1;
 	mutex_lock(&dev->struct_mutex);
 	old_imapping = inode->i_mapping;
@@ -151,7 +151,7 @@ int drm_open(struct inode *inode, struct
 	retcode = drm_open_helper(inode, filp, dev);
 	if (retcode)
 		goto err_undo;
-	atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
 	if (need_setup) {
 		retcode = drm_setup(dev);
 		if (retcode)
@@ -166,7 +166,7 @@ err_undo:
 	iput(container_of(dev->dev_mapping, struct inode, i_data));
 	dev->dev_mapping = old_mapping;
 	mutex_unlock(&dev->struct_mutex);
-	dev->open_count--;
+	local_dec(&dev->open_count);
 	return retcode;
 }
 EXPORT_SYMBOL(drm_open);
@@ -440,7 +440,7 @@ int drm_release(struct inode *inode, str
 
 	mutex_lock(&drm_global_mutex);
 
-	DRM_DEBUG("open_count = %d\n", dev->open_count);
+	DRM_DEBUG("open_count = %ld\n", local_read(&dev->open_count));
 
 	if (dev->driver->preclose)
 		dev->driver->preclose(dev, file_priv);
@@ -449,10 +449,10 @@ int drm_release(struct inode *inode, str
 	 * Begin inline drm_release
 	 */
 
-	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
+	DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %ld\n",
 		  task_pid_nr(current),
 		  (long)old_encode_dev(file_priv->minor->device),
-		  dev->open_count);
+		  local_read(&dev->open_count));
 
 	/* Release any auth tokens that might point to this file_priv,
 	   (do that under the drm_global_mutex) */
@@ -549,8 +549,8 @@ int drm_release(struct inode *inode, str
 	 * End inline drm_release
 	 */
 
-	atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
-	if (!--dev->open_count) {
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_CLOSES]);
+	if (local_dec_and_test(&dev->open_count)) {
 		if (atomic_read(&dev->ioctl_count)) {
 			DRM_ERROR("Device busy: %d\n",
 				  atomic_read(&dev->ioctl_count));
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_global.c linux-3.8.13-pax/drivers/gpu/drm/drm_global.c
--- linux-3.8.13/drivers/gpu/drm/drm_global.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_global.c	2013-02-19 01:14:43.405772716 +0100
@@ -36,7 +36,7 @@
 struct drm_global_item {
 	struct mutex mutex;
 	void *object;
-	int refcount;
+	atomic_t refcount;
 };
 
 static struct drm_global_item glob[DRM_GLOBAL_NUM];
@@ -49,7 +49,7 @@ void drm_global_init(void)
 		struct drm_global_item *item = &glob[i];
 		mutex_init(&item->mutex);
 		item->object = NULL;
-		item->refcount = 0;
+		atomic_set(&item->refcount, 0);
 	}
 }
 
@@ -59,7 +59,7 @@ void drm_global_release(void)
 	for (i = 0; i < DRM_GLOBAL_NUM; ++i) {
 		struct drm_global_item *item = &glob[i];
 		BUG_ON(item->object != NULL);
-		BUG_ON(item->refcount != 0);
+		BUG_ON(atomic_read(&item->refcount) != 0);
 	}
 }
 
@@ -70,7 +70,7 @@ int drm_global_item_ref(struct drm_globa
 	void *object;
 
 	mutex_lock(&item->mutex);
-	if (item->refcount == 0) {
+	if (atomic_read(&item->refcount) == 0) {
 		item->object = kzalloc(ref->size, GFP_KERNEL);
 		if (unlikely(item->object == NULL)) {
 			ret = -ENOMEM;
@@ -83,7 +83,7 @@ int drm_global_item_ref(struct drm_globa
 			goto out_err;
 
 	}
-	++item->refcount;
+	atomic_inc(&item->refcount);
 	ref->object = item->object;
 	object = item->object;
 	mutex_unlock(&item->mutex);
@@ -100,9 +100,9 @@ void drm_global_item_unref(struct drm_gl
 	struct drm_global_item *item = &glob[ref->global_type];
 
 	mutex_lock(&item->mutex);
-	BUG_ON(item->refcount == 0);
+	BUG_ON(atomic_read(&item->refcount) == 0);
 	BUG_ON(ref->object != item->object);
-	if (--item->refcount == 0) {
+	if (atomic_dec_and_test(&item->refcount)) {
 		ref->release(ref);
 		item->object = NULL;
 	}
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_info.c linux-3.8.13-pax/drivers/gpu/drm/drm_info.c
--- linux-3.8.13/drivers/gpu/drm/drm_info.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_info.c	2013-02-19 01:14:43.405772716 +0100
@@ -75,10 +75,14 @@ int drm_vm_info(struct seq_file *m, void
 	struct drm_local_map *map;
 	struct drm_map_list *r_list;
 
-	/* Hardcoded from _DRM_FRAME_BUFFER,
-	   _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
-	   _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
-	const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
+	static const char * const types[] = {
+		[_DRM_FRAME_BUFFER] = "FB",
+		[_DRM_REGISTERS] = "REG",
+		[_DRM_SHM] = "SHM",
+		[_DRM_AGP] = "AGP",
+		[_DRM_SCATTER_GATHER] = "SG",
+		[_DRM_CONSISTENT] = "PCI",
+		[_DRM_GEM] = "GEM" };
 	const char *type;
 	int i;
 
@@ -89,7 +93,7 @@ int drm_vm_info(struct seq_file *m, void
 		map = r_list->map;
 		if (!map)
 			continue;
-		if (map->type < 0 || map->type > 5)
+		if (map->type >= ARRAY_SIZE(types))
 			type = "??";
 		else
 			type = types[map->type];
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_ioc32.c linux-3.8.13-pax/drivers/gpu/drm/drm_ioc32.c
--- linux-3.8.13/drivers/gpu/drm/drm_ioc32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_ioc32.c	2013-03-06 02:56:54.000367357 +0100
@@ -457,7 +457,7 @@ static int compat_drm_infobufs(struct fi
 	request = compat_alloc_user_space(nbytes);
 	if (!access_ok(VERIFY_WRITE, request, nbytes))
 		return -EFAULT;
-	list = (struct drm_buf_desc *) (request + 1);
+	list = (struct drm_buf_desc __user *) (request + 1);
 
 	if (__put_user(count, &request->count)
 	    || __put_user(list, &request->list))
@@ -518,7 +518,7 @@ static int compat_drm_mapbufs(struct fil
 	request = compat_alloc_user_space(nbytes);
 	if (!access_ok(VERIFY_WRITE, request, nbytes))
 		return -EFAULT;
-	list = (struct drm_buf_pub *) (request + 1);
+	list = (struct drm_buf_pub __user *) (request + 1);
 
 	if (__put_user(count, &request->count)
 	    || __put_user(list, &request->list))
@@ -1016,7 +1016,7 @@ static int compat_drm_wait_vblank(struct
 	return 0;
 }
 
-drm_ioctl_compat_t *drm_compat_ioctls[] = {
+drm_ioctl_compat_t drm_compat_ioctls[] = {
 	[DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
 	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
 	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
@@ -1062,7 +1062,6 @@ drm_ioctl_compat_t *drm_compat_ioctls[]
 long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	unsigned int nr = DRM_IOCTL_NR(cmd);
-	drm_ioctl_compat_t *fn;
 	int ret;
 
 	/* Assume that ioctls without an explicit compat routine will just
@@ -1072,10 +1071,8 @@ long drm_compat_ioctl(struct file *filp,
 	if (nr >= ARRAY_SIZE(drm_compat_ioctls))
 		return drm_ioctl(filp, cmd, arg);
 
-	fn = drm_compat_ioctls[nr];
-
-	if (fn != NULL)
-		ret = (*fn) (filp, cmd, arg);
+	if (drm_compat_ioctls[nr] != NULL)
+		ret = (*drm_compat_ioctls[nr]) (filp, cmd, arg);
 	else
 		ret = drm_ioctl(filp, cmd, arg);
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_ioctl.c linux-3.8.13-pax/drivers/gpu/drm/drm_ioctl.c
--- linux-3.8.13/drivers/gpu/drm/drm_ioctl.c	2013-02-19 01:12:56.649766918 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_ioctl.c	2013-02-19 01:14:43.405772716 +0100
@@ -252,7 +252,7 @@ int drm_getstats(struct drm_device *dev,
 			stats->data[i].value =
 			    (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
 		else
-			stats->data[i].value = atomic_read(&dev->counts[i]);
+			stats->data[i].value = atomic_read_unchecked(&dev->counts[i]);
 		stats->data[i].type = dev->types[i];
 	}
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_lock.c linux-3.8.13-pax/drivers/gpu/drm/drm_lock.c
--- linux-3.8.13/drivers/gpu/drm/drm_lock.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_lock.c	2013-02-19 01:14:43.405772716 +0100
@@ -86,7 +86,7 @@ int drm_lock(struct drm_device *dev, voi
 		if (drm_lock_take(&master->lock, lock->context)) {
 			master->lock.file_priv = file_priv;
 			master->lock.lock_time = jiffies;
-			atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
+			atomic_inc_unchecked(&dev->counts[_DRM_STAT_LOCKS]);
 			break;	/* Got lock */
 		}
 
@@ -157,7 +157,7 @@ int drm_unlock(struct drm_device *dev, v
 		return -EINVAL;
 	}
 
-	atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_UNLOCKS]);
 
 	if (drm_lock_free(&master->lock, lock->context)) {
 		/* FIXME: Should really bail out here. */
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/drm_stub.c linux-3.8.13-pax/drivers/gpu/drm/drm_stub.c
--- linux-3.8.13/drivers/gpu/drm/drm_stub.c	2013-02-19 01:12:56.657766919 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/drm_stub.c	2013-02-19 01:14:43.405772716 +0100
@@ -516,7 +516,7 @@ void drm_unplug_dev(struct drm_device *d
 
 	drm_device_set_unplugged(dev);
 
-	if (dev->open_count == 0) {
+	if (local_read(&dev->open_count) == 0) {
 		drm_put_dev(dev);
 	}
 	mutex_unlock(&drm_global_mutex);
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i810/i810_dma.c linux-3.8.13-pax/drivers/gpu/drm/i810/i810_dma.c
--- linux-3.8.13/drivers/gpu/drm/i810/i810_dma.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i810/i810_dma.c	2013-02-19 01:14:43.405772716 +0100
@@ -945,8 +945,8 @@ static int i810_dma_vertex(struct drm_de
 				 dma->buflist[vertex->idx],
 				 vertex->discard, vertex->used);
 
-	atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
-	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
+	atomic_add_unchecked(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
 	sarea_priv->last_enqueue = dev_priv->counter - 1;
 	sarea_priv->last_dispatch = (int)hw_status[5];
 
@@ -1106,8 +1106,8 @@ static int i810_dma_mc(struct drm_device
 	i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
 			     mc->last_render);
 
-	atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
-	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
+	atomic_add_unchecked(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
+	atomic_inc_unchecked(&dev->counts[_DRM_STAT_DMA]);
 	sarea_priv->last_enqueue = dev_priv->counter - 1;
 	sarea_priv->last_dispatch = (int)hw_status[5];
 
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i810/i810_drv.h linux-3.8.13-pax/drivers/gpu/drm/i810/i810_drv.h
--- linux-3.8.13/drivers/gpu/drm/i810/i810_drv.h	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i810/i810_drv.h	2013-02-19 01:14:43.409772717 +0100
@@ -108,8 +108,8 @@ typedef struct drm_i810_private {
 	int page_flipping;
 
 	wait_queue_head_t irq_queue;
-	atomic_t irq_received;
-	atomic_t irq_emitted;
+	atomic_unchecked_t irq_received;
+	atomic_unchecked_t irq_emitted;
 
 	int front_offset;
 } drm_i810_private_t;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_debugfs.c linux-3.8.13-pax/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-3.8.13/drivers/gpu/drm/i915/i915_debugfs.c	2013-03-29 03:21:19.167475504 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_debugfs.c	2013-03-29 03:21:30.523474897 +0100
@@ -496,7 +496,7 @@ static int i915_interrupt_info(struct se
 			   I915_READ(GTIMR));
 	}
 	seq_printf(m, "Interrupts received: %d\n",
-		   atomic_read(&dev_priv->irq_received));
+		   atomic_read_unchecked(&dev_priv->irq_received));
 	for_each_ring(ring, dev_priv, i) {
 		if (IS_GEN6(dev) || IS_GEN7(dev)) {
 			seq_printf(m,
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_dma.c linux-3.8.13-pax/drivers/gpu/drm/i915/i915_dma.c
--- linux-3.8.13/drivers/gpu/drm/i915/i915_dma.c	2013-03-22 02:55:24.362089273 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_dma.c	2013-03-22 02:55:35.626088671 +0100
@@ -1253,7 +1253,7 @@ static bool i915_switcheroo_can_switch(s
 	bool can_switch;
 
 	spin_lock(&dev->count_lock);
-	can_switch = (dev->open_count == 0);
+	can_switch = (local_read(&dev->open_count) == 0);
 	spin_unlock(&dev->count_lock);
 	return can_switch;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_drv.h linux-3.8.13-pax/drivers/gpu/drm/i915/i915_drv.h
--- linux-3.8.13/drivers/gpu/drm/i915/i915_drv.h	2013-05-13 02:47:11.165794594 +0200
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_drv.h	2013-05-13 02:51:11.401781767 +0200
@@ -656,7 +656,7 @@ typedef struct drm_i915_private {
 	drm_dma_handle_t *status_page_dmah;
 	struct resource mch_res;
 
-	atomic_t irq_received;
+	atomic_unchecked_t irq_received;
 
 	/* protects the irq masks */
 	spinlock_t irq_lock;
@@ -1104,7 +1104,7 @@ struct drm_i915_gem_object {
 	 * will be page flipped away on the next vblank.  When it
 	 * reaches 0, dev_priv->pending_flip_queue will be woken up.
 	 */
-	atomic_t pending_flip;
+	atomic_unchecked_t pending_flip;
 };
 #define to_gem_object(obj) (&((struct drm_i915_gem_object *)(obj))->base)
 
@@ -1635,7 +1635,7 @@ extern struct i2c_adapter *intel_gmbus_g
 		struct drm_i915_private *dev_priv, unsigned port);
 extern void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed);
 extern void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit);
-extern inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
+static inline bool intel_gmbus_is_forced_bit(struct i2c_adapter *adapter)
 {
 	return container_of(adapter, struct intel_gmbus, adapter)->force_bit;
 }
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_gem_execbuffer.c linux-3.8.13-pax/drivers/gpu/drm/i915/i915_gem_execbuffer.c
--- linux-3.8.13/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2013-04-13 00:55:42.727157665 +0200
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2013-04-13 00:55:48.687157346 +0200
@@ -672,7 +672,7 @@ i915_gem_execbuffer_move_to_gpu(struct i
 			i915_gem_clflush_object(obj);
 
 		if (obj->base.pending_write_domain)
-			flips |= atomic_read(&obj->pending_flip);
+			flips |= atomic_read_unchecked(&obj->pending_flip);
 
 		flush_domains |= obj->base.write_domain;
 	}
@@ -703,9 +703,9 @@ i915_gem_check_execbuffer(struct drm_i91
 
 static int
 validate_exec_list(struct drm_i915_gem_exec_object2 *exec,
-		   int count)
+		   unsigned int count)
 {
-	int i;
+	unsigned int i;
 	int relocs_total = 0;
 	int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry);
 
@@ -1202,7 +1202,7 @@ i915_gem_execbuffer2(struct drm_device *
 		return -ENOMEM;
 	}
 	ret = copy_from_user(exec2_list,
-			     (struct drm_i915_relocation_entry __user *)
+			     (struct drm_i915_gem_exec_object2 __user *)
 			     (uintptr_t) args->buffers_ptr,
 			     sizeof(*exec2_list) * args->buffer_count);
 	if (ret != 0) {
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_ioc32.c linux-3.8.13-pax/drivers/gpu/drm/i915/i915_ioc32.c
--- linux-3.8.13/drivers/gpu/drm/i915/i915_ioc32.c	2012-12-11 04:30:57.000000000 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_ioc32.c	2013-03-06 02:46:29.468400702 +0100
@@ -181,7 +181,7 @@ static int compat_i915_alloc(struct file
 			 (unsigned long)request);
 }
 
-static drm_ioctl_compat_t *i915_compat_ioctls[] = {
+static drm_ioctl_compat_t i915_compat_ioctls[] = {
 	[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
 	[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
 	[DRM_I915_GETPARAM] = compat_i915_getparam,
@@ -202,18 +202,15 @@ static drm_ioctl_compat_t *i915_compat_i
 long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
 	unsigned int nr = DRM_IOCTL_NR(cmd);
-	drm_ioctl_compat_t *fn = NULL;
 	int ret;
 
 	if (nr < DRM_COMMAND_BASE)
 		return drm_compat_ioctl(filp, cmd, arg);
 
-	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
-		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
-
-	if (fn != NULL)
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) {
+		drm_ioctl_compat_t fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
 		ret = (*fn) (filp, cmd, arg);
-	else
+	} else
 		ret = drm_ioctl(filp, cmd, arg);
 
 	return ret;
diff -NurpX linux-3.8.13-pax/Documentation/dontdiff linux-3.8.13/drivers/gpu/drm/i915/i915_irq.c linux-3.8.13-pax/drivers/gpu/drm/i915/i915_irq.c
--- linux-3.8.13/drivers/gpu/drm/i915/i915_irq.c	2013-03-22 02:55:24.362089273 +0100
+++ linux-3.8.13-pax/drivers/gpu/drm/i915/i915_irq.c	2013-03-22 02:55:35.630088671 +0100
@@ -535,7 +535,7 @@ static irqreturn_t valleyview_irq_handle
 	u32 pipe_stats[I915_MAX_PIPES];
 	bool blc_event;
 
-	atomic_inc(&dev_priv->irq_received);
+	atomic_inc_unchecked(&dev_priv->irq_received);
 
 	while (true) {
 		iir = I915_READ(VLV_IIR);
@@ -688,7 +688,7 @@ static irqreturn_t ivybridge_irq_handler
 	irqreturn_t ret = IRQ_NONE;
 	int i;
 
-	atomic_inc(&dev_priv->irq_received);
+	atomic_inc_unchecked(&dev_priv->irq_received);
 
 	/* disable master interrupt before clearing iir  */
 	de_ier = I915_READ(DEIER);
@@ -760,7 +760,7 @@ static irqreturn_t ironlake_irq_handler(
 	int ret = IRQ_NONE;
 	u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
 
-	atomic_inc(&dev_priv->irq_received);
+	atomic_inc_unchecked(&dev_priv->irq_received);
 
 	/* disable master interrupt before clearing iir  */
 	de_ier = I915_READ(DEIER);
@@ -1787,7 +1787,7 @@ static void ironlake_irq_preinstall(stru
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-	atomic_set(&dev_priv->irq_received, 0);
+	atomic_set_unchecked(&dev_priv->irq_received, 0);
 
 	I915_WRITE(HWSTAM, 0xeffe);
 
@@ -1813,7 +1813,7 @@ static void valleyview_irq_preinstall(st
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int pipe;
 
-	atomic_set(&dev_priv->irq_received, 0);
+	atomic_set_unchecked(&dev_priv->irq_received, 0);
 
 	/* VLV magic */
 	I915_WRITE(VLV_IMR, 0);
@@ -2108,7 +2108,7 @@ static void i8xx_irq_preinstall(struct d
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int pipe;
 
-	atomic_set(&dev_priv->irq_received, 0);
+	atomic_set_unchecked(&dev_priv->irq_received, 0);
 
 	for_each_pipe(pipe)
 		I915_WRITE(PIPESTAT(pipe), 0);
@@ -2159,7 +2159,7 @@ static irqreturn_t i8xx_irq_handler(int
 		I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
 		I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
 
-	atomic_inc(&dev_priv->irq_received);
+	atomic_inc_unchecked(&dev_priv->irq_received);
 
 	iir = I915_READ16(IIR);
 	if (iir == 0)
@@ -2244,7 +2244,7 @@ static void i915_irq_preinstall(struct d
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int pipe;
 
-	atomic_set(&dev_priv->irq_received, 0);
+	atomic_set_unchecked(&dev_priv->irq_received, 0);
 
 	if (I915_HAS_HOTPLUG(dev)) {
 		I915_WRITE(PORT_HOTPLUG_EN, 0);
@@ -2339,7 +2339,7 @@ static irqreturn_t i915_irq_handler(int
 	};
 	int pipe, ret = IRQ_NONE;
 
-	atomic_inc(&dev_priv->irq_received);
+	atomic_inc_unchecked(&dev_priv->irq_received);
 
 	iir = I915_READ(