summaryrefslogtreecommitdiff
path: root/4.9.15
diff options
context:
space:
mode:
Diffstat (limited to '4.9.15')
-rw-r--r--4.9.15/0000_README60
-rw-r--r--4.9.15/1013_linux-4.9.14.patch6768
-rw-r--r--4.9.15/1014_linux-4.9.15.patch2838
-rw-r--r--4.9.15/4420_grsecurity-3.1-4.9.15-201703150049.patch225862
-rw-r--r--4.9.15/4425_grsec_remove_EI_PAX.patch19
-rw-r--r--4.9.15/4426_default_XATTR_PAX_FLAGS.patch36
-rw-r--r--4.9.15/4427_force_XATTR_PAX_tmpfs.patch48
-rw-r--r--4.9.15/4430_grsec-remove-localversion-grsec.patch9
-rw-r--r--4.9.15/4435_grsec-mute-warnings.patch43
-rw-r--r--4.9.15/4440_grsec-remove-protected-paths.patch20
-rw-r--r--4.9.15/4450_grsec-kconfig-default-gids.patch111
-rw-r--r--4.9.15/4465_selinux-avc_audit-log-curr_ip.patch73
-rw-r--r--4.9.15/4470_disable-compat_vdso.patch58
-rw-r--r--4.9.15/4475_emutramp_default_on.patch34
14 files changed, 235979 insertions, 0 deletions
diff --git a/4.9.15/0000_README b/4.9.15/0000_README
new file mode 100644
index 0000000..5da73c7
--- /dev/null
+++ b/4.9.15/0000_README
@@ -0,0 +1,60 @@
+README
+-----------------------------------------------------------------------------
+Individual Patch Descriptions:
+-----------------------------------------------------------------------------
+Patch: 1013_linux-4.9.14.patch
+From: http://www.kernel.org
+Desc: Linux 4.9.14
+
+Patch: 1014_linux-4.9.15.patch
+From: http://www.kernel.org
+Desc: Linux 4.9.15
+
+Patch: 4420_grsecurity-3.1-4.9.15-201703150049.patch
+From: http://www.grsecurity.net
+Desc: hardened-sources base patch from upstream grsecurity
+
+Patch: 4425_grsec_remove_EI_PAX.patch
+From: Anthony G. Basile <blueness@gentoo.org>
+Desc: Remove EI_PAX option and force off
+
+Patch: 4426_default_XATTR_PAX_FLAGS.patch
+From: Anthony G. Basile <blueness@gentoo.org>
+Desc: Defalut PT_PAX_FLAGS off and XATTR_PAX_FLAGS on
+
+Patch: 4427_force_XATTR_PAX_tmpfs.patch
+From: Anthony G. Basile <blueness@gentoo.org>
+Desc: Force XATTR_PAX on tmpfs
+
+Patch: 4430_grsec-remove-localversion-grsec.patch
+From: Kerin Millar <kerframil@gmail.com>
+Desc: Removes grsecurity's localversion-grsec file
+
+Patch: 4435_grsec-mute-warnings.patch
+From: Alexander Gabert <gaberta@fh-trier.de>
+ Gordon Malm <gengor@gentoo.org>
+Desc: Removes verbose compile warning settings from grsecurity, restores
+ mainline Linux kernel behavior
+
+Patch: 4440_grsec-remove-protected-paths.patch
+From: Anthony G. Basile <blueness@gentoo.org>
+Desc: Removes chmod statements from grsecurity/Makefile
+
+Patch: 4450_grsec-kconfig-default-gids.patch
+From: Kerin Millar <kerframil@gmail.com>
+Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
+ features
+
+Patch: 4465_selinux-avc_audit-log-curr_ip.patch
+From: Gordon Malm <gengor@gentoo.org>
+ Anthony G. Basile <blueness@gentoo.org>
+Desc: Configurable option to add src IP address to SELinux log messages
+
+Patch: 4470_disable-compat_vdso.patch
+From: Gordon Malm <gengor@gentoo.org>
+ Kerin Millar <kerframil@gmail.com>
+Desc: Disables VDSO_COMPAT operation completely
+
+Patch: 4475_emutramp_default_on.patch
+From: Anthony G. Basile <blueness@gentoo.org>
+Desc: Set PAX_EMUTRAMP default on for libffi, bugs #329499 and #457194
diff --git a/4.9.15/1013_linux-4.9.14.patch b/4.9.15/1013_linux-4.9.14.patch
new file mode 100644
index 0000000..5d8c119
--- /dev/null
+++ b/4.9.15/1013_linux-4.9.14.patch
@@ -0,0 +1,6768 @@
+diff --git a/Makefile b/Makefile
+index 14dc275..5e7706e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 13
++SUBLEVEL = 14
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+
+diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+index 0b9a59d..30fac04 100644
+--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+@@ -148,6 +148,8 @@
+ uart1: serial@f8020000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
++ atmel,use-dma-rx;
++ atmel,use-dma-tx;
+ status = "okay";
+ };
+
+diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+index ed7fce2..44d1171 100644
+--- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts
++++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts
+@@ -110,6 +110,8 @@
+ };
+
+ usart3: serial@fc00c000 {
++ atmel,use-dma-rx;
++ atmel,use-dma-tx;
+ status = "okay";
+ };
+
+diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
+index 74a44727..a58bbaa 100644
+--- a/arch/arm/include/asm/kvm_mmu.h
++++ b/arch/arm/include/asm/kvm_mmu.h
+@@ -150,18 +150,12 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
+ * and iterate over the range.
+ */
+
+- bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
+-
+ VM_BUG_ON(size & ~PAGE_MASK);
+
+- if (!need_flush && !icache_is_pipt())
+- goto vipt_cache;
+-
+ while (size) {
+ void *va = kmap_atomic_pfn(pfn);
+
+- if (need_flush)
+- kvm_flush_dcache_to_poc(va, PAGE_SIZE);
++ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ if (icache_is_pipt())
+ __cpuc_coherent_user_range((unsigned long)va,
+@@ -173,7 +167,6 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
+ kunmap_atomic(va);
+ }
+
+-vipt_cache:
+ if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
+ /* any kind of VIPT cache */
+ __flush_icache_all();
+diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
+index 6f72fe8..6d22017 100644
+--- a/arch/arm64/include/asm/kvm_mmu.h
++++ b/arch/arm64/include/asm/kvm_mmu.h
+@@ -241,8 +241,7 @@ static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu,
+ {
+ void *va = page_address(pfn_to_page(pfn));
+
+- if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached)
+- kvm_flush_dcache_to_poc(va, size);
++ kvm_flush_dcache_to_poc(va, size);
+
+ if (!icache_is_aliasing()) { /* PIPT */
+ flush_icache_range((unsigned long)va,
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index c02504e..3a129d4 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -653,15 +653,15 @@ static u64 __raw_read_system_reg(u32 sys_id)
+ case SYS_ID_ISAR2_EL1: return read_cpuid(ID_ISAR2_EL1);
+ case SYS_ID_ISAR3_EL1: return read_cpuid(ID_ISAR3_EL1);
+ case SYS_ID_ISAR4_EL1: return read_cpuid(ID_ISAR4_EL1);
+- case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR4_EL1);
++ case SYS_ID_ISAR5_EL1: return read_cpuid(ID_ISAR5_EL1);
+ case SYS_MVFR0_EL1: return read_cpuid(MVFR0_EL1);
+ case SYS_MVFR1_EL1: return read_cpuid(MVFR1_EL1);
+ case SYS_MVFR2_EL1: return read_cpuid(MVFR2_EL1);
+
+ case SYS_ID_AA64PFR0_EL1: return read_cpuid(ID_AA64PFR0_EL1);
+- case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR0_EL1);
++ case SYS_ID_AA64PFR1_EL1: return read_cpuid(ID_AA64PFR1_EL1);
+ case SYS_ID_AA64DFR0_EL1: return read_cpuid(ID_AA64DFR0_EL1);
+- case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR0_EL1);
++ case SYS_ID_AA64DFR1_EL1: return read_cpuid(ID_AA64DFR1_EL1);
+ case SYS_ID_AA64MMFR0_EL1: return read_cpuid(ID_AA64MMFR0_EL1);
+ case SYS_ID_AA64MMFR1_EL1: return read_cpuid(ID_AA64MMFR1_EL1);
+ case SYS_ID_AA64MMFR2_EL1: return read_cpuid(ID_AA64MMFR2_EL1);
+diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
+index 02265a5..b5bf46c 100644
+--- a/arch/arm64/mm/dma-mapping.c
++++ b/arch/arm64/mm/dma-mapping.c
+@@ -352,6 +352,13 @@ static int __swiotlb_dma_supported(struct device *hwdev, u64 mask)
+ return 1;
+ }
+
++static int __swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t addr)
++{
++ if (swiotlb)
++ return swiotlb_dma_mapping_error(hwdev, addr);
++ return 0;
++}
++
+ static struct dma_map_ops swiotlb_dma_ops = {
+ .alloc = __dma_alloc,
+ .free = __dma_free,
+@@ -366,7 +373,7 @@ static struct dma_map_ops swiotlb_dma_ops = {
+ .sync_sg_for_cpu = __swiotlb_sync_sg_for_cpu,
+ .sync_sg_for_device = __swiotlb_sync_sg_for_device,
+ .dma_supported = __swiotlb_dma_supported,
+- .mapping_error = swiotlb_dma_mapping_error,
++ .mapping_error = __swiotlb_dma_mapping_error,
+ };
+
+ static int __init atomic_pool_init(void)
+diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
+index 52caa75..e2f50d6 100644
+--- a/arch/mips/bcm47xx/buttons.c
++++ b/arch/mips/bcm47xx/buttons.c
+@@ -17,6 +17,12 @@
+ .active_low = 1, \
+ }
+
++#define BCM47XX_GPIO_KEY_H(_gpio, _code) \
++ { \
++ .code = _code, \
++ .gpio = _gpio, \
++ }
++
+ /* Asus */
+
+ static const struct gpio_keys_button
+@@ -79,8 +85,8 @@ bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
+
+ static const struct gpio_keys_button
+ bcm47xx_buttons_asus_wl500w[] __initconst = {
+- BCM47XX_GPIO_KEY(6, KEY_RESTART),
+- BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
++ BCM47XX_GPIO_KEY_H(6, KEY_RESTART),
++ BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON),
+ };
+
+ static const struct gpio_keys_button
+diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
+index 64e08df..8b70041 100644
+--- a/arch/mips/cavium-octeon/octeon-memcpy.S
++++ b/arch/mips/cavium-octeon/octeon-memcpy.S
+@@ -208,18 +208,18 @@ EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
+ ADD src, src, 16*NBYTES
+ EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
+ ADD dst, dst, 16*NBYTES
+-EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
+-EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
+-EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
+-EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
++EXC( LOAD t0, UNIT(-8)(src), l_exc_copy_rewind16)
++EXC( LOAD t1, UNIT(-7)(src), l_exc_copy_rewind16)
++EXC( LOAD t2, UNIT(-6)(src), l_exc_copy_rewind16)
++EXC( LOAD t3, UNIT(-5)(src), l_exc_copy_rewind16)
+ EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
+ EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
+ EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
+ EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
+-EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
+-EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
+-EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
+-EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
++EXC( LOAD t0, UNIT(-4)(src), l_exc_copy_rewind16)
++EXC( LOAD t1, UNIT(-3)(src), l_exc_copy_rewind16)
++EXC( LOAD t2, UNIT(-2)(src), l_exc_copy_rewind16)
++EXC( LOAD t3, UNIT(-1)(src), l_exc_copy_rewind16)
+ EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
+ EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
+ EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
+@@ -383,6 +383,10 @@ done:
+ nop
+ END(memcpy)
+
++l_exc_copy_rewind16:
++ /* Rewind src and dst by 16*NBYTES for l_exc_copy */
++ SUB src, src, 16*NBYTES
++ SUB dst, dst, 16*NBYTES
+ l_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
+index bce1ce5..0e23197 100644
+--- a/arch/mips/include/asm/checksum.h
++++ b/arch/mips/include/asm/checksum.h
+@@ -186,7 +186,9 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+ " daddu %0, %4 \n"
+ " dsll32 $1, %0, 0 \n"
+ " daddu %0, $1 \n"
++ " sltu $1, %0, $1 \n"
+ " dsra32 %0, %0, 0 \n"
++ " addu %0, $1 \n"
+ #endif
+ " .set pop"
+ : "=r" (sum)
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index 9514e5f..1652f36 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -195,11 +195,9 @@ struct mips_frame_info {
+ #define J_TARGET(pc,target) \
+ (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
+
+-static inline int is_ra_save_ins(union mips_instruction *ip)
++static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
+ {
+ #ifdef CONFIG_CPU_MICROMIPS
+- union mips_instruction mmi;
+-
+ /*
+ * swsp ra,offset
+ * swm16 reglist,offset(sp)
+@@ -209,29 +207,71 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
+ *
+ * microMIPS is way more fun...
+ */
+- if (mm_insn_16bit(ip->halfword[0])) {
+- mmi.word = (ip->halfword[0] << 16);
+- return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
+- mmi.mm16_r5_format.rt == 31) ||
+- (mmi.mm16_m_format.opcode == mm_pool16c_op &&
+- mmi.mm16_m_format.func == mm_swm16_op);
++ if (mm_insn_16bit(ip->halfword[1])) {
++ switch (ip->mm16_r5_format.opcode) {
++ case mm_swsp16_op:
++ if (ip->mm16_r5_format.rt != 31)
++ return 0;
++
++ *poff = ip->mm16_r5_format.simmediate;
++ *poff = (*poff << 2) / sizeof(ulong);
++ return 1;
++
++ case mm_pool16c_op:
++ switch (ip->mm16_m_format.func) {
++ case mm_swm16_op:
++ *poff = ip->mm16_m_format.imm;
++ *poff += 1 + ip->mm16_m_format.rlist;
++ *poff = (*poff << 2) / sizeof(ulong);
++ return 1;
++
++ default:
++ return 0;
++ }
++
++ default:
++ return 0;
++ }
+ }
+- else {
+- mmi.halfword[0] = ip->halfword[1];
+- mmi.halfword[1] = ip->halfword[0];
+- return (mmi.mm_m_format.opcode == mm_pool32b_op &&
+- mmi.mm_m_format.rd > 9 &&
+- mmi.mm_m_format.base == 29 &&
+- mmi.mm_m_format.func == mm_swm32_func) ||
+- (mmi.i_format.opcode == mm_sw32_op &&
+- mmi.i_format.rs == 29 &&
+- mmi.i_format.rt == 31);
++
++ switch (ip->i_format.opcode) {
++ case mm_sw32_op:
++ if (ip->i_format.rs != 29)
++ return 0;
++ if (ip->i_format.rt != 31)
++ return 0;
++
++ *poff = ip->i_format.simmediate / sizeof(ulong);
++ return 1;
++
++ case mm_pool32b_op:
++ switch (ip->mm_m_format.func) {
++ case mm_swm32_func:
++ if (ip->mm_m_format.rd < 0x10)
++ return 0;
++ if (ip->mm_m_format.base != 29)
++ return 0;
++
++ *poff = ip->mm_m_format.simmediate;
++ *poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
++ *poff /= sizeof(ulong);
++ return 1;
++ default:
++ return 0;
++ }
++
++ default:
++ return 0;
+ }
+ #else
+ /* sw / sd $ra, offset($sp) */
+- return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
+- ip->i_format.rs == 29 &&
+- ip->i_format.rt == 31;
++ if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
++ ip->i_format.rs == 29 && ip->i_format.rt == 31) {
++ *poff = ip->i_format.simmediate / sizeof(ulong);
++ return 1;
++ }
++
++ return 0;
+ #endif
+ }
+
+@@ -246,13 +286,16 @@ static inline int is_jump_ins(union mips_instruction *ip)
+ *
+ * microMIPS is kind of more fun...
+ */
+- union mips_instruction mmi;
+-
+- mmi.word = (ip->halfword[0] << 16);
++ if (mm_insn_16bit(ip->halfword[1])) {
++ if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
++ (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
++ return 1;
++ return 0;
++ }
+
+- if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
+- (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
+- ip->j_format.opcode == mm_jal32_op)
++ if (ip->j_format.opcode == mm_j32_op)
++ return 1;
++ if (ip->j_format.opcode == mm_jal32_op)
+ return 1;
+ if (ip->r_format.opcode != mm_pool32a_op ||
+ ip->r_format.func != mm_pool32axf_op)
+@@ -280,15 +323,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
+ *
+ * microMIPS is not more fun...
+ */
+- if (mm_insn_16bit(ip->halfword[0])) {
+- union mips_instruction mmi;
+-
+- mmi.word = (ip->halfword[0] << 16);
+- return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
+- mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
+- (mmi.mm16_r5_format.opcode == mm_pool16d_op &&
+- mmi.mm16_r5_format.rt == 29);
++ if (mm_insn_16bit(ip->halfword[1])) {
++ return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
++ ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
++ (ip->mm16_r5_format.opcode == mm_pool16d_op &&
++ ip->mm16_r5_format.rt == 29);
+ }
++
+ return ip->mm_i_format.opcode == mm_addiu32_op &&
+ ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
+ #else
+@@ -303,30 +344,36 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
+
+ static int get_frame_info(struct mips_frame_info *info)
+ {
+-#ifdef CONFIG_CPU_MICROMIPS
+- union mips_instruction *ip = (void *) (((char *) info->func) - 1);
+-#else
+- union mips_instruction *ip = info->func;
+-#endif
+- unsigned max_insns = info->func_size / sizeof(union mips_instruction);
+- unsigned i;
++ bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
++ union mips_instruction insn, *ip, *ip_end;
++ const unsigned int max_insns = 128;
++ unsigned int i;
+
+ info->pc_offset = -1;
+ info->frame_size = 0;
+
++ ip = (void *)msk_isa16_mode((ulong)info->func);
+ if (!ip)
+ goto err;
+
+- if (max_insns == 0)
+- max_insns = 128U; /* unknown function size */
+- max_insns = min(128U, max_insns);
++ ip_end = (void *)ip + info->func_size;
+
+- for (i = 0; i < max_insns; i++, ip++) {
++ for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
++ if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
++ insn.halfword[0] = 0;
++ insn.halfword[1] = ip->halfword[0];
++ } else if (is_mmips) {
++ insn.halfword[0] = ip->halfword[1];
++ insn.halfword[1] = ip->halfword[0];
++ } else {
++ insn.word = ip->word;
++ }
+
+- if (is_jump_ins(ip))
++ if (is_jump_ins(&insn))
+ break;
++
+ if (!info->frame_size) {
+- if (is_sp_move_ins(ip))
++ if (is_sp_move_ins(&insn))
+ {
+ #ifdef CONFIG_CPU_MICROMIPS
+ if (mm_insn_16bit(ip->halfword[0]))
+@@ -349,11 +396,9 @@ static int get_frame_info(struct mips_frame_info *info)
+ }
+ continue;
+ }
+- if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
+- info->pc_offset =
+- ip->i_format.simmediate / sizeof(long);
++ if (info->pc_offset == -1 &&
++ is_ra_save_ins(&insn, &info->pc_offset))
+ break;
+- }
+ }
+ if (info->frame_size && info->pc_offset >= 0) /* nested */
+ return 0;
+diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
+index 236193b..9a61671 100644
+--- a/arch/mips/lantiq/xway/sysctrl.c
++++ b/arch/mips/lantiq/xway/sysctrl.c
+@@ -545,7 +545,7 @@ void __init ltq_soc_init(void)
+ clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI);
+ clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI);
+ clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL);
+- clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH | PMU_PPE_DP);
++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP);
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ } else if (of_machine_is_compatible("lantiq,ar10")) {
+@@ -553,7 +553,7 @@ void __init ltq_soc_init(void)
+ ltq_ar10_fpi_hz(), ltq_ar10_pp32_hz());
+ clkdev_add_pmu("1e101000.usb", "ctl", 1, 0, PMU_USB0);
+ clkdev_add_pmu("1e106000.usb", "ctl", 1, 0, PMU_USB1);
+- clkdev_add_pmu("1e108000.eth", NULL, 1, 0, PMU_SWITCH |
++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0, PMU_SWITCH |
+ PMU_PPE_DP | PMU_PPE_TC);
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+ clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
+@@ -575,11 +575,11 @@ void __init ltq_soc_init(void)
+ clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS);
+
+ clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF);
+- clkdev_add_pmu("1e108000.eth", NULL, 1, 0,
++ clkdev_add_pmu("1e108000.eth", NULL, 0, 0,
+ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM |
+ PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
+ PMU_PPE_QSB | PMU_PPE_TOP);
+- clkdev_add_pmu("1f203000.rcu", "gphy", 1, 0, PMU_GPHY);
++ clkdev_add_pmu("1f203000.rcu", "gphy", 0, 0, PMU_GPHY);
+ clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO);
+ clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU);
+ clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
+diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c
+index 026cb59..f293a97 100644
+--- a/arch/mips/mm/sc-ip22.c
++++ b/arch/mips/mm/sc-ip22.c
+@@ -31,26 +31,40 @@ static inline void indy_sc_wipe(unsigned long first, unsigned long last)
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+- ".set\tpush\t\t\t# indy_sc_wipe\n\t"
+- ".set\tnoreorder\n\t"
+- ".set\tmips3\n\t"
+- ".set\tnoat\n\t"
+- "mfc0\t%2, $12\n\t"
+- "li\t$1, 0x80\t\t\t# Go 64 bit\n\t"
+- "mtc0\t$1, $12\n\t"
+-
+- "dli\t$1, 0x9000000080000000\n\t"
+- "or\t%0, $1\t\t\t# first line to flush\n\t"
+- "or\t%1, $1\t\t\t# last line to flush\n\t"
+- ".set\tat\n\t"
+-
+- "1:\tsw\t$0, 0(%0)\n\t"
+- "bne\t%0, %1, 1b\n\t"
+- " daddu\t%0, 32\n\t"
+-
+- "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t"
+- "nop; nop; nop; nop;\n\t"
+- ".set\tpop"
++ " .set push # indy_sc_wipe \n"
++ " .set noreorder \n"
++ " .set mips3 \n"
++ " .set noat \n"
++ " mfc0 %2, $12 \n"
++ " li $1, 0x80 # Go 64 bit \n"
++ " mtc0 $1, $12 \n"
++ " \n"
++ " # \n"
++ " # Open code a dli $1, 0x9000000080000000 \n"
++ " # \n"
++ " # Required because binutils 2.25 will happily accept \n"
++ " # 64 bit instructions in .set mips3 mode but puke on \n"
++ " # 64 bit constants when generating 32 bit ELF \n"
++ " # \n"
++ " lui $1,0x9000 \n"
++ " dsll $1,$1,0x10 \n"
++ " ori $1,$1,0x8000 \n"
++ " dsll $1,$1,0x10 \n"
++ " \n"
++ " or %0, $1 # first line to flush \n"
++ " or %1, $1 # last line to flush \n"
++ " .set at \n"
++ " \n"
++ "1: sw $0, 0(%0) \n"
++ " bne %0, %1, 1b \n"
++ " daddu %0, 32 \n"
++ " \n"
++ " mtc0 %2, $12 # Back to 32 bit \n"
++ " nop # pipeline hazard \n"
++ " nop \n"
++ " nop \n"
++ " nop \n"
++ " .set pop \n"
+ : "=r" (first), "=r" (last), "=&r" (tmp)
+ : "0" (first), "1" (last));
+ }
+diff --git a/arch/mips/pic32/pic32mzda/Makefile b/arch/mips/pic32/pic32mzda/Makefile
+index 4a4c272..c286496 100644
+--- a/arch/mips/pic32/pic32mzda/Makefile
++++ b/arch/mips/pic32/pic32mzda/Makefile
+@@ -2,8 +2,7 @@
+ # Joshua Henderson, <joshua.henderson@microchip.com>
+ # Copyright (C) 2015 Microchip Technology, Inc. All rights reserved.
+ #
+-obj-y := init.o time.o config.o
++obj-y := config.o early_clk.o init.o time.o
+
+ obj-$(CONFIG_EARLY_PRINTK) += early_console.o \
+- early_pin.o \
+- early_clk.o
++ early_pin.o
+diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
+index a244e09..5d22b0b 100644
+--- a/arch/powerpc/include/asm/mmu.h
++++ b/arch/powerpc/include/asm/mmu.h
+@@ -136,6 +136,7 @@ enum {
+ MMU_FTR_NO_SLBIE_B | MMU_FTR_16M_PAGE | MMU_FTR_TLBIEL |
+ MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_CI_LARGE_PAGE |
+ MMU_FTR_1T_SEGMENT | MMU_FTR_TLBIE_CROP_VA |
++ MMU_FTR_KERNEL_RO |
+ #ifdef CONFIG_PPC_RADIX_MMU
+ MMU_FTR_TYPE_RADIX |
+ #endif
+diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
+index 37c027c..7803756 100644
+--- a/arch/powerpc/kernel/cpu_setup_power.S
++++ b/arch/powerpc/kernel/cpu_setup_power.S
+@@ -100,6 +100,8 @@ _GLOBAL(__setup_cpu_power9)
+ mfspr r3,SPRN_LPCR
+ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
+ or r3, r3, r4
++ LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
++ andc r3, r3, r4
+ bl __init_LPCR
+ bl __init_HFSCR
+ bl __init_tlb_power9
+@@ -120,6 +122,8 @@ _GLOBAL(__restore_cpu_power9)
+ mfspr r3,SPRN_LPCR
+ LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
+ or r3, r3, r4
++ LOAD_REG_IMMEDIATE(r4, LPCR_UPRT | LPCR_HR)
++ andc r3, r3, r4
+ bl __init_LPCR
+ bl __init_HFSCR
+ bl __init_tlb_power9
+diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
+index 03d089b..469d86d 100644
+--- a/arch/powerpc/kernel/hw_breakpoint.c
++++ b/arch/powerpc/kernel/hw_breakpoint.c
+@@ -228,8 +228,10 @@ int hw_breakpoint_handler(struct die_args *args)
+ rcu_read_lock();
+
+ bp = __this_cpu_read(bp_per_reg);
+- if (!bp)
++ if (!bp) {
++ rc = NOTIFY_DONE;
+ goto out;
++ }
+ info = counter_arch_bp(bp);
+
+ /*
+diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
+index 34684ad..b3b09b9 100644
+--- a/arch/x86/include/asm/pkeys.h
++++ b/arch/x86/include/asm/pkeys.h
+@@ -46,6 +46,15 @@ extern int __arch_set_user_pkey_access(struct task_struct *tsk, int pkey,
+ static inline
+ bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey)
+ {
++ /*
++ * "Allocated" pkeys are those that have been returned
++ * from pkey_alloc(). pkey 0 is special, and never
++ * returned from pkey_alloc().
++ */
++ if (pkey <= 0)
++ return false;
++ if (pkey >= arch_max_pkey())
++ return false;
+ return mm_pkey_allocation_map(mm) & (1U << pkey);
+ }
+
+@@ -82,12 +91,6 @@ int mm_pkey_alloc(struct mm_struct *mm)
+ static inline
+ int mm_pkey_free(struct mm_struct *mm, int pkey)
+ {
+- /*
+- * pkey 0 is special, always allocated and can never
+- * be freed.
+- */
+- if (!pkey)
+- return -EINVAL;
+ if (!mm_pkey_is_allocated(mm, pkey))
+ return -EINVAL;
+
+diff --git a/crypto/testmgr.h b/crypto/testmgr.h
+index e64a4ef..9033088 100644
+--- a/crypto/testmgr.h
++++ b/crypto/testmgr.h
+@@ -22813,7 +22813,7 @@ static struct aead_testvec aes_ccm_enc_tv_template[] = {
+ "\x09\x75\x9a\x9b\x3c\x9b\x27\x39",
+ .klen = 32,
+ .iv = "\x03\xf9\xd9\x4e\x63\xb5\x3d\x9d"
+- "\x43\xf6\x1e\x50",
++ "\x43\xf6\x1e\x50\0\0\0\0",
+ .assoc = "\x57\xf5\x6b\x8b\x57\x5c\x3d\x3b"
+ "\x13\x02\x01\x0c\x83\x4c\x96\x35"
+ "\x8e\xd6\x39\xcf\x7d\x14\x9b\x94"
+diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
+index 2c1798e..3868823 100644
+--- a/drivers/bcma/main.c
++++ b/drivers/bcma/main.c
+@@ -633,8 +633,11 @@ static int bcma_device_probe(struct device *dev)
+ drv);
+ int err = 0;
+
++ get_device(dev);
+ if (adrv->probe)
+ err = adrv->probe(core);
++ if (err)
++ put_device(dev);
+
+ return err;
+ }
+@@ -647,6 +650,7 @@ static int bcma_device_remove(struct device *dev)
+
+ if (adrv->remove)
+ adrv->remove(core);
++ put_device(dev);
+
+ return 0;
+ }
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index 4af8187..24d6cef 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1097,9 +1097,12 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
+ return -EINVAL;
+
++ /* I/O need to be drained during transfer transition */
++ blk_mq_freeze_queue(lo->lo_queue);
++
+ err = loop_release_xfer(lo);
+ if (err)
+- return err;
++ goto exit;
+
+ if (info->lo_encrypt_type) {
+ unsigned int type = info->lo_encrypt_type;
+@@ -1114,12 +1117,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+
+ err = loop_init_xfer(lo, xfer, info);
+ if (err)
+- return err;
++ goto exit;
+
+ if (lo->lo_offset != info->lo_offset ||
+ lo->lo_sizelimit != info->lo_sizelimit)
+- if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit))
+- return -EFBIG;
++ if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) {
++ err = -EFBIG;
++ goto exit;
++ }
+
+ loop_config_discard(lo);
+
+@@ -1137,13 +1142,6 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ (info->lo_flags & LO_FLAGS_AUTOCLEAR))
+ lo->lo_flags ^= LO_FLAGS_AUTOCLEAR;
+
+- if ((info->lo_flags & LO_FLAGS_PARTSCAN) &&
+- !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
+- lo->lo_flags |= LO_FLAGS_PARTSCAN;
+- lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
+- loop_reread_partitions(lo, lo->lo_device);
+- }
+-
+ lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
+ lo->lo_init[0] = info->lo_init[0];
+ lo->lo_init[1] = info->lo_init[1];
+@@ -1156,7 +1154,17 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
+ /* update dio if lo_offset or transfer is changed */
+ __loop_update_dio(lo, lo->use_dio);
+
+- return 0;
++ exit:
++ blk_mq_unfreeze_queue(lo->lo_queue);
++
++ if (!err && (info->lo_flags & LO_FLAGS_PARTSCAN) &&
++ !(lo->lo_flags & LO_FLAGS_PARTSCAN)) {
++ lo->lo_flags |= LO_FLAGS_PARTSCAN;
++ lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
++ loop_reread_partitions(lo, lo->lo_device);
++ }
++
++ return err;
+ }
+
+ static int
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index eaf5730..8022bea 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -421,7 +421,7 @@ static int __init init_tis(void)
+ acpi_bus_unregister_driver(&tis_acpi_driver);
+ err_acpi:
+ #endif
+- platform_device_unregister(force_pdev);
++ platform_driver_unregister(&tis_drv);
+ err_platform:
+ if (force_pdev)
+ platform_device_unregister(force_pdev);
+diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
+index 712592c..7309c08 100644
+--- a/drivers/devfreq/devfreq.c
++++ b/drivers/devfreq/devfreq.c
+@@ -130,7 +130,7 @@ static void devfreq_set_freq_table(struct devfreq *devfreq)
+ * @devfreq: the devfreq instance
+ * @freq: the update target frequency
+ */
+-static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
++int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
+ {
+ int lev, prev_lev, ret = 0;
+ unsigned long cur_time;
+@@ -166,6 +166,7 @@ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq)
+ devfreq->last_stat_updated = cur_time;
+ return ret;
+ }
++EXPORT_SYMBOL(devfreq_update_status);
+
+ /**
+ * find_devfreq_governor() - find devfreq governor from name
+@@ -939,6 +940,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
+ if (df->governor == governor) {
+ ret = 0;
+ goto out;
++ } else if (df->governor->immutable || governor->immutable) {
++ ret = -EINVAL;
++ goto out;
+ }
+
+ if (df->governor) {
+@@ -968,13 +972,33 @@ static ssize_t available_governors_show(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+ {
+- struct devfreq_governor *tmp_governor;
++ struct devfreq *df = to_devfreq(d);
+ ssize_t count = 0;
+
+ mutex_lock(&devfreq_list_lock);
+- list_for_each_entry(tmp_governor, &devfreq_governor_list, node)
+- count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
+- "%s ", tmp_governor->name);
++
++ /*
++ * The devfreq with immutable governor (e.g., passive) shows
++ * only own governor.
++ */
++ if (df->governor->immutable) {
++ count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
++ "%s ", df->governor_name);
++ /*
++ * The devfreq device shows the registered governor except for
++ * immutable governors such as passive governor .
++ */
++ } else {
++ struct devfreq_governor *governor;
++
++ list_for_each_entry(governor, &devfreq_governor_list, node) {
++ if (governor->immutable)
++ continue;
++ count += scnprintf(&buf[count], (PAGE_SIZE - count - 2),
++ "%s ", governor->name);
++ }
++ }
++
+ mutex_unlock(&devfreq_list_lock);
+
+ /* Truncate the trailing space */
+diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h
+index fad7d63..71576b8 100644
+--- a/drivers/devfreq/governor.h
++++ b/drivers/devfreq/governor.h
+@@ -38,4 +38,6 @@ extern void devfreq_interval_update(struct devfreq *devfreq,
+ extern int devfreq_add_governor(struct devfreq_governor *governor);
+ extern int devfreq_remove_governor(struct devfreq_governor *governor);
+
++extern int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
++
+ #endif /* _GOVERNOR_H */
+diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c
+index 9ef46e2..5be96b2 100644
+--- a/drivers/devfreq/governor_passive.c
++++ b/drivers/devfreq/governor_passive.c
+@@ -112,6 +112,11 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq)
+ if (ret < 0)
+ goto out;
+
++ if (devfreq->profile->freq_table
++ && (devfreq_update_status(devfreq, freq)))
++ dev_err(&devfreq->dev,
++ "Couldn't update frequency transition information.\n");
++
+ devfreq->previous_freq = freq;
+
+ out:
+@@ -179,6 +184,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq,
+
+ static struct devfreq_governor devfreq_passive = {
+ .name = "passive",
++ .immutable = 1,
+ .get_target_freq = devfreq_passive_get_target_freq,
+ .event_handler = devfreq_passive_event_handler,
+ };
+diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
+index dd184b5..2846278 100644
+--- a/drivers/dma/ipu/ipu_irq.c
++++ b/drivers/dma/ipu/ipu_irq.c
+@@ -272,7 +272,7 @@ static void ipu_irq_handler(struct irq_desc *desc)
+ u32 status;
+ int i, line;
+
+- for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
++ for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
+ struct ipu_irq_bank *bank = irq_bank + i;
+
+ raw_spin_lock(&bank_lock);
+diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
+index 5fb4c6d..be34547 100644
+--- a/drivers/hv/channel.c
++++ b/drivers/hv/channel.c
+@@ -157,6 +157,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ }
+
+ init_completion(&open_info->waitevent);
++ open_info->waiting_channel = newchannel;
+
+ open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
+ open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
+@@ -181,7 +182,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(open_msg,
+- sizeof(struct vmbus_channel_open_channel));
++ sizeof(struct vmbus_channel_open_channel), true);
+
+ if (ret != 0) {
+ err = ret;
+@@ -194,6 +195,11 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
+ list_del(&open_info->msglistentry);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
++ if (newchannel->rescind) {
++ err = -ENODEV;
++ goto error_free_gpadl;
++ }
++
+ if (open_info->response.open_result.status) {
+ err = -EAGAIN;
+ goto error_free_gpadl;
+@@ -233,7 +239,7 @@ int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id,
+ conn_msg.guest_endpoint_id = *shv_guest_servie_id;
+ conn_msg.host_service_id = *shv_host_servie_id;
+
+- return vmbus_post_msg(&conn_msg, sizeof(conn_msg));
++ return vmbus_post_msg(&conn_msg, sizeof(conn_msg), true);
+ }
+ EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request);
+
+@@ -405,6 +411,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
+ return ret;
+
+ init_completion(&msginfo->waitevent);
++ msginfo->waiting_channel = channel;
+
+ gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
+ gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
+@@ -419,7 +426,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
+- sizeof(*msginfo));
++ sizeof(*msginfo), true);
+ if (ret != 0)
+ goto cleanup;
+
+@@ -433,14 +440,19 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
+ gpadl_body->gpadl = next_gpadl_handle;
+
+ ret = vmbus_post_msg(gpadl_body,
+- submsginfo->msgsize -
+- sizeof(*submsginfo));
++ submsginfo->msgsize - sizeof(*submsginfo),
++ true);
+ if (ret != 0)
+ goto cleanup;
+
+ }
+ wait_for_completion(&msginfo->waitevent);
+
++ if (channel->rescind) {
++ ret = -ENODEV;
++ goto cleanup;
++ }
++
+ /* At this point, we received the gpadl created msg */
+ *gpadl_handle = gpadlmsg->gpadl;
+
+@@ -474,6 +486,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
+ return -ENOMEM;
+
+ init_completion(&info->waitevent);
++ info->waiting_channel = channel;
+
+ msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
+
+@@ -485,14 +498,19 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
+ list_add_tail(&info->msglistentry,
+ &vmbus_connection.chn_msg_list);
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+- ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_gpadl_teardown));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_gpadl_teardown),
++ true);
+
+ if (ret)
+ goto post_msg_err;
+
+ wait_for_completion(&info->waitevent);
+
++ if (channel->rescind) {
++ ret = -ENODEV;
++ goto post_msg_err;
++ }
++
+ post_msg_err:
+ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+ list_del(&info->msglistentry);
+@@ -557,7 +575,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel)
+ msg->header.msgtype = CHANNELMSG_CLOSECHANNEL;
+ msg->child_relid = channel->offermsg.child_relid;
+
+- ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel),
++ true);
+
+ if (ret) {
+ pr_err("Close failed: close post msg return is %d\n", ret);
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index caf3418..cb95315 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -147,6 +147,29 @@ static const struct {
+ { HV_RDV_GUID },
+ };
+
++/*
++ * The rescinded channel may be blocked waiting for a response from the host;
++ * take care of that.
++ */
++static void vmbus_rescind_cleanup(struct vmbus_channel *channel)
++{
++ struct vmbus_channel_msginfo *msginfo;
++ unsigned long flags;
++
++
++ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
++
++ list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list,
++ msglistentry) {
++
++ if (msginfo->waiting_channel == channel) {
++ complete(&msginfo->waitevent);
++ break;
++ }
++ }
++ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
++}
++
+ static bool is_unsupported_vmbus_devs(const uuid_le *guid)
+ {
+ int i;
+@@ -321,7 +344,8 @@ static void vmbus_release_relid(u32 relid)
+ memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
+ msg.child_relid = relid;
+ msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
+- vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released));
++ vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released),
++ true);
+ }
+
+ void hv_event_tasklet_disable(struct vmbus_channel *channel)
+@@ -728,7 +752,8 @@ void vmbus_initiate_unload(bool crash)
+ init_completion(&vmbus_connection.unload_event);
+ memset(&hdr, 0, sizeof(struct vmbus_channel_message_header));
+ hdr.msgtype = CHANNELMSG_UNLOAD;
+- vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
++ vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header),
++ !crash);
+
+ /*
+ * vmbus_initiate_unload() is also called on crash and the crash can be
+@@ -823,6 +848,8 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr)
+ channel->rescind = true;
+ spin_unlock_irqrestore(&channel->lock, flags);
+
++ vmbus_rescind_cleanup(channel);
++
+ if (channel->device_obj) {
+ if (channel->chn_rescind_callback) {
+ channel->chn_rescind_callback(channel);
+@@ -1116,8 +1143,8 @@ int vmbus_request_offers(void)
+ msg->msgtype = CHANNELMSG_REQUESTOFFERS;
+
+
+- ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_message_header));
++ ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header),
++ true);
+ if (ret != 0) {
+ pr_err("Unable to request offers - %d\n", ret);
+
+diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
+index 78e6368..840b6db 100644
+--- a/drivers/hv/connection.c
++++ b/drivers/hv/connection.c
+@@ -110,7 +110,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
+ spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
+
+ ret = vmbus_post_msg(msg,
+- sizeof(struct vmbus_channel_initiate_contact));
++ sizeof(struct vmbus_channel_initiate_contact),
++ true);
+ if (ret != 0) {
+ spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
+ list_del(&msginfo->msglistentry);
+@@ -434,7 +435,7 @@ void vmbus_on_event(unsigned long data)
+ /*
+ * vmbus_post_msg - Send a msg on the vmbus's message connection
+ */
+-int vmbus_post_msg(void *buffer, size_t buflen)
++int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
+ {
+ union hv_connection_id conn_id;
+ int ret = 0;
+@@ -449,7 +450,7 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ * insufficient resources. Retry the operation a couple of
+ * times before giving up.
+ */
+- while (retries < 20) {
++ while (retries < 100) {
+ ret = hv_post_message(conn_id, 1, buffer, buflen);
+
+ switch (ret) {
+@@ -472,8 +473,14 @@ int vmbus_post_msg(void *buffer, size_t buflen)
+ }
+
+ retries++;
+- udelay(usec);
+- if (usec < 2048)
++ if (can_sleep && usec > 1000)
++ msleep(usec / 1000);
++ else if (usec < MAX_UDELAY_MS * 1000)
++ udelay(usec);
++ else
++ mdelay(usec / 1000);
++
++ if (usec < 256000)
+ usec *= 2;
+ }
+ return ret;
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 60dbd6c..6e49a4d 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -309,9 +309,10 @@ void hv_cleanup(bool crash)
+
+ hypercall_msr.as_uint64 = 0;
+ wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64);
+- if (!crash)
++ if (!crash) {
+ vfree(hv_context.tsc_page);
+- hv_context.tsc_page = NULL;
++ hv_context.tsc_page = NULL;
++ }
+ }
+ #endif
+ }
+@@ -411,7 +412,7 @@ int hv_synic_alloc(void)
+ goto err;
+ }
+
+- for_each_online_cpu(cpu) {
++ for_each_present_cpu(cpu) {
+ hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC);
+ if (hv_context.event_dpc[cpu] == NULL) {
+ pr_err("Unable to allocate event dpc\n");
+@@ -457,6 +458,8 @@ int hv_synic_alloc(void)
+ pr_err("Unable to allocate post msg page\n");
+ goto err;
+ }
++
++ INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
+ }
+
+ return 0;
+@@ -482,7 +485,7 @@ void hv_synic_free(void)
+ int cpu;
+
+ kfree(hv_context.hv_numa_map);
+- for_each_online_cpu(cpu)
++ for_each_present_cpu(cpu)
+ hv_synic_free_cpu(cpu);
+ }
+
+@@ -552,8 +555,6 @@ void hv_synic_init(void *arg)
+ rdmsrl(HV_X64_MSR_VP_INDEX, vp_index);
+ hv_context.vp_index[cpu] = (u32)vp_index;
+
+- INIT_LIST_HEAD(&hv_context.percpu_list[cpu]);
+-
+ /*
+ * Register the per-cpu clockevent source.
+ */
+diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c
+index 8b2ba98..e47d8c9 100644
+--- a/drivers/hv/hv_fcopy.c
++++ b/drivers/hv/hv_fcopy.c
+@@ -61,6 +61,7 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data);
+ static const char fcopy_devname[] = "vmbus/hv_fcopy";
+ static u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+ /*
+ * This state maintains the version number registered by the daemon.
+ */
+@@ -317,6 +318,7 @@ static void fcopy_on_reset(void)
+
+ if (cancel_delayed_work_sync(&fcopy_timeout_work))
+ fcopy_respond_to_host(HV_E_FAIL);
++ complete(&release_event);
+ }
+
+ int hv_fcopy_init(struct hv_util_service *srv)
+@@ -324,6 +326,7 @@ int hv_fcopy_init(struct hv_util_service *srv)
+ recv_buffer = srv->recv_buffer;
+ fcopy_transaction.recv_channel = srv->channel;
+
++ init_completion(&release_event);
+ /*
+ * When this driver loads, the user level daemon that
+ * processes the host requests may not yet be running.
+@@ -345,4 +348,5 @@ void hv_fcopy_deinit(void)
+ fcopy_transaction.state = HVUTIL_DEVICE_DYING;
+ cancel_delayed_work_sync(&fcopy_timeout_work);
+ hvutil_transport_destroy(hvt);
++ wait_for_completion(&release_event);
+ }
+diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
+index 5e1fdc8..3abfc59 100644
+--- a/drivers/hv/hv_kvp.c
++++ b/drivers/hv/hv_kvp.c
+@@ -88,6 +88,7 @@ static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
+ static const char kvp_devname[] = "vmbus/hv_kvp";
+ static u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+ /*
+ * Register the kernel component with the user-level daemon.
+ * As part of this registration, pass the LIC version number.
+@@ -716,6 +717,7 @@ static void kvp_on_reset(void)
+ if (cancel_delayed_work_sync(&kvp_timeout_work))
+ kvp_respond_to_host(NULL, HV_E_FAIL);
+ kvp_transaction.state = HVUTIL_DEVICE_INIT;
++ complete(&release_event);
+ }
+
+ int
+@@ -724,6 +726,7 @@ hv_kvp_init(struct hv_util_service *srv)
+ recv_buffer = srv->recv_buffer;
+ kvp_transaction.recv_channel = srv->channel;
+
++ init_completion(&release_event);
+ /*
+ * When this driver loads, the user level daemon that
+ * processes the host requests may not yet be running.
+@@ -747,4 +750,5 @@ void hv_kvp_deinit(void)
+ cancel_delayed_work_sync(&kvp_timeout_work);
+ cancel_work_sync(&kvp_sendkey_work);
+ hvutil_transport_destroy(hvt);
++ wait_for_completion(&release_event);
+ }
+diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
+index a670713..a76e3db 100644
+--- a/drivers/hv/hv_snapshot.c
++++ b/drivers/hv/hv_snapshot.c
+@@ -66,6 +66,7 @@ static int dm_reg_value;
+ static const char vss_devname[] = "vmbus/hv_vss";
+ static __u8 *recv_buffer;
+ static struct hvutil_transport *hvt;
++static struct completion release_event;
+
+ static void vss_timeout_func(struct work_struct *dummy);
+ static void vss_handle_request(struct work_struct *dummy);
+@@ -330,11 +331,13 @@ static void vss_on_reset(void)
+ if (cancel_delayed_work_sync(&vss_timeout_work))
+ vss_respond_to_host(HV_E_FAIL);
+ vss_transaction.state = HVUTIL_DEVICE_INIT;
++ complete(&release_event);
+ }
+
+ int
+ hv_vss_init(struct hv_util_service *srv)
+ {
++ init_completion(&release_event);
+ if (vmbus_proto_version < VERSION_WIN8_1) {
+ pr_warn("Integration service 'Backup (volume snapshot)'"
+ " not supported on this host version.\n");
+@@ -365,4 +368,5 @@ void hv_vss_deinit(void)
+ cancel_delayed_work_sync(&vss_timeout_work);
+ cancel_work_sync(&vss_handle_request_work);
+ hvutil_transport_destroy(hvt);
++ wait_for_completion(&release_event);
+ }
+diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
+index 2b13f2a..8d7f865 100644
+--- a/drivers/hv/hyperv_vmbus.h
++++ b/drivers/hv/hyperv_vmbus.h
+@@ -683,7 +683,7 @@ void vmbus_free_channels(void);
+ int vmbus_connect(void);
+ void vmbus_disconnect(void);
+
+-int vmbus_post_msg(void *buffer, size_t buflen);
++int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep);
+
+ void vmbus_on_event(unsigned long data);
+ void vmbus_on_msg_dpc(unsigned long data);
+diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
+index 308dbda..e94ed1c 100644
+--- a/drivers/hv/ring_buffer.c
++++ b/drivers/hv/ring_buffer.c
+@@ -298,6 +298,9 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
+ unsigned long flags = 0;
+ struct hv_ring_buffer_info *outring_info = &channel->outbound;
+
++ if (channel->rescind)
++ return -ENODEV;
++
+ for (i = 0; i < kv_count; i++)
+ totalbytes_towrite += kv_list[i].iov_len;
+
+@@ -350,6 +353,10 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
+ spin_unlock_irqrestore(&outring_info->ring_lock, flags);
+
+ hv_signal_on_write(old_write, channel, kick_q);
++
++ if (channel->rescind)
++ return -ENODEV;
++
+ return 0;
+ }
+
+diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
+index ad82cb2..4314616 100644
+--- a/drivers/hwmon/it87.c
++++ b/drivers/hwmon/it87.c
+@@ -1300,25 +1300,35 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
+ it87_write_value(data, IT87_REG_FAN_MAIN_CTRL,
+ data->fan_main_ctrl);
+ } else {
++ u8 ctrl;
++
+ /* No on/off mode, set maximum pwm value */
+ data->pwm_duty[nr] = pwm_to_reg(data, 0xff);
+ it87_write_value(data, IT87_REG_PWM_DUTY[nr],
+ data->pwm_duty[nr]);
+ /* and set manual mode */
+- data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
+- data->pwm_temp_map[nr] :
+- data->pwm_duty[nr];
+- it87_write_value(data, IT87_REG_PWM[nr],
+- data->pwm_ctrl[nr]);
++ if (has_newer_autopwm(data)) {
++ ctrl = (data->pwm_ctrl[nr] & 0x7c) |
++ data->pwm_temp_map[nr];
++ } else {
++ ctrl = data->pwm_duty[nr];
++ }
++ data->pwm_ctrl[nr] = ctrl;
++ it87_write_value(data, IT87_REG_PWM[nr], ctrl);
+ }
+ } else {
+- if (val == 1) /* Manual mode */
+- data->pwm_ctrl[nr] = has_newer_autopwm(data) ?
+- data->pwm_temp_map[nr] :
+- data->pwm_duty[nr];
+- else /* Automatic mode */
+- data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
+- it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
++ u8 ctrl;
++
++ if (has_newer_autopwm(data)) {
++ ctrl = (data->pwm_ctrl[nr] & 0x7c) |
++ data->pwm_temp_map[nr];
++ if (val != 1)
++ ctrl |= 0x80;
++ } else {
++ ctrl = (val == 1 ? data->pwm_duty[nr] : 0x80);
++ }
++ data->pwm_ctrl[nr] = ctrl;
++ it87_write_value(data, IT87_REG_PWM[nr], ctrl);
+
+ if (data->type != it8603 && nr < 3) {
+ /* set SmartGuardian mode */
+@@ -1344,6 +1354,7 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
++ it87_update_pwm_ctrl(data, nr);
+ if (has_newer_autopwm(data)) {
+ /*
+ * If we are in automatic mode, the PWM duty cycle register
+@@ -1456,13 +1467,15 @@ static ssize_t set_pwm_temp_map(struct device *dev,
+ }
+
+ mutex_lock(&data->update_lock);
++ it87_update_pwm_ctrl(data, nr);
+ data->pwm_temp_map[nr] = reg;
+ /*
+ * If we are in automatic mode, write the temp mapping immediately;
+ * otherwise, just store it for later use.
+ */
+ if (data->pwm_ctrl[nr] & 0x80) {
+- data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
++ data->pwm_ctrl[nr] = (data->pwm_ctrl[nr] & 0xfc) |
++ data->pwm_temp_map[nr];
+ it87_write_value(data, IT87_REG_PWM[nr], data->pwm_ctrl[nr]);
+ }
+ mutex_unlock(&data->update_lock);
+diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
+index 49e0f1b..8e79056 100644
+--- a/drivers/hwtracing/coresight/coresight-stm.c
++++ b/drivers/hwtracing/coresight/coresight-stm.c
+@@ -356,7 +356,7 @@ static void stm_generic_unlink(struct stm_data *stm_data,
+ if (!drvdata || !drvdata->csdev)
+ return;
+
+- stm_disable(drvdata->csdev, NULL);
++ coresight_disable(drvdata->csdev);
+ }
+
+ static phys_addr_t
+diff --git a/drivers/iio/pressure/mpl115.c b/drivers/iio/pressure/mpl115.c
+index 73f2f0c..8f2bce2 100644
+--- a/drivers/iio/pressure/mpl115.c
++++ b/drivers/iio/pressure/mpl115.c
+@@ -137,6 +137,7 @@ static const struct iio_chan_spec mpl115_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++ .info_mask_shared_by_type =
+ BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE),
+ },
+ };
+diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c
+index 6392d7b..eb87948 100644
+--- a/drivers/iio/pressure/mpl3115.c
++++ b/drivers/iio/pressure/mpl3115.c
+@@ -182,7 +182,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
+ {
+ .type = IIO_PRESSURE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+- BIT(IIO_CHAN_INFO_SCALE),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+@@ -195,7 +195,7 @@ static const struct iio_chan_spec mpl3115_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+- BIT(IIO_CHAN_INFO_SCALE),
++ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 1,
+ .scan_type = {
+ .sign = 's',
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index c25768c..f2d40c0 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -3540,6 +3540,9 @@ static int cma_accept_iw(struct rdma_id_private *id_priv,
+ struct iw_cm_conn_param iw_param;
+ int ret;
+
++ if (!conn_param)
++ return -EINVAL;
++
+ ret = cma_modify_qp_rtr(id_priv, conn_param);
+ if (ret)
+ return ret;
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index d82637a..34be95e 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -3325,13 +3325,14 @@ static int __init init_dmars(void)
+ iommu_identity_mapping |= IDENTMAP_GFX;
+ #endif
+
++ check_tylersburg_isoch();
++
+ if (iommu_identity_mapping) {
+ ret = si_domain_init(hw_pass_through);
+ if (ret)
+ goto free_iommu;
+ }
+
+- check_tylersburg_isoch();
+
+ /*
+ * If we copied translations from a previous kernel in the kdump
+diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
+index 59b2c50..c817627 100644
+--- a/drivers/md/dm-cache-target.c
++++ b/drivers/md/dm-cache-target.c
+@@ -248,7 +248,7 @@ struct cache {
+ /*
+ * Fields for converting from sectors to blocks.
+ */
+- uint32_t sectors_per_block;
++ sector_t sectors_per_block;
+ int sectors_per_block_shift;
+
+ spinlock_t lock;
+@@ -3546,11 +3546,11 @@ static void cache_status(struct dm_target *ti, status_type_t type,
+
+ residency = policy_residency(cache->policy);
+
+- DMEMIT("%u %llu/%llu %u %llu/%llu %u %u %u %u %u %u %lu ",
++ DMEMIT("%u %llu/%llu %llu %llu/%llu %u %u %u %u %u %u %lu ",
+ (unsigned)DM_CACHE_METADATA_BLOCK_SIZE,
+ (unsigned long long)(nr_blocks_metadata - nr_free_blocks_metadata),
+ (unsigned long long)nr_blocks_metadata,
+- cache->sectors_per_block,
++ (unsigned long long)cache->sectors_per_block,
+ (unsigned long long) from_cblock(residency),
+ (unsigned long long) from_cblock(cache->cache_size),
+ (unsigned) atomic_read(&cache->stats.read_hit),
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index af2d79b..15daa36 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -3621,6 +3621,8 @@ static int raid_preresume(struct dm_target *ti)
+ return r;
+ }
+
++#define RESUME_STAY_FROZEN_FLAGS (CTR_FLAG_DELTA_DISKS | CTR_FLAG_DATA_OFFSET)
++
+ static void raid_resume(struct dm_target *ti)
+ {
+ struct raid_set *rs = ti->private;
+@@ -3638,7 +3640,15 @@ static void raid_resume(struct dm_target *ti)
+ mddev->ro = 0;
+ mddev->in_sync = 0;
+
+- clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
++ /*
++ * Keep the RAID set frozen if reshape/rebuild flags are set.
++ * The RAID set is unfrozen once the next table load/resume,
++ * which clears the reshape/rebuild flags, occurs.
++ * This ensures that the constructor for the inactive table
++ * retrieves an up-to-date reshape_position.
++ */
++ if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
++ clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+
+ if (mddev->suspended)
+ mddev_resume(mddev);
+diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c
+index 6c25213..bdbb7e6 100644
+--- a/drivers/md/dm-round-robin.c
++++ b/drivers/md/dm-round-robin.c
+@@ -17,8 +17,8 @@
+ #include <linux/module.h>
+
+ #define DM_MSG_PREFIX "multipath round-robin"
+-#define RR_MIN_IO 1000
+-#define RR_VERSION "1.1.0"
++#define RR_MIN_IO 1
++#define RR_VERSION "1.2.0"
+
+ /*-----------------------------------------------------------------
+ * Path-handling code, paths are held in lists
+@@ -47,44 +47,19 @@ struct selector {
+ struct list_head valid_paths;
+ struct list_head invalid_paths;
+ spinlock_t lock;
+- struct dm_path * __percpu *current_path;
+- struct percpu_counter repeat_count;
+ };
+
+-static void set_percpu_current_path(struct selector *s, struct dm_path *path)
+-{
+- int cpu;
+-
+- for_each_possible_cpu(cpu)
+- *per_cpu_ptr(s->current_path, cpu) = path;
+-}
+-
+ static struct selector *alloc_selector(void)
+ {
+ struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL);
+
+- if (!s)
+- return NULL;
+-
+- INIT_LIST_HEAD(&s->valid_paths);
+- INIT_LIST_HEAD(&s->invalid_paths);
+- spin_lock_init(&s->lock);
+-
+- s->current_path = alloc_percpu(struct dm_path *);
+- if (!s->current_path)
+- goto out_current_path;
+- set_percpu_current_path(s, NULL);
+-
+- if (percpu_counter_init(&s->repeat_count, 0, GFP_KERNEL))
+- goto out_repeat_count;
++ if (s) {
++ INIT_LIST_HEAD(&s->valid_paths);
++ INIT_LIST_HEAD(&s->invalid_paths);
++ spin_lock_init(&s->lock);
++ }
+
+ return s;
+-
+-out_repeat_count:
+- free_percpu(s->current_path);
+-out_current_path:
+- kfree(s);
+- return NULL;;
+ }
+
+ static int rr_create(struct path_selector *ps, unsigned argc, char **argv)
+@@ -105,8 +80,6 @@ static void rr_destroy(struct path_selector *ps)
+
+ free_paths(&s->valid_paths);
+ free_paths(&s->invalid_paths);
+- free_percpu(s->current_path);
+- percpu_counter_destroy(&s->repeat_count);
+ kfree(s);
+ ps->context = NULL;
+ }
+@@ -157,6 +130,11 @@ static int rr_add_path(struct path_selector *ps, struct dm_path *path,
+ return -EINVAL;
+ }
+
++ if (repeat_count > 1) {
++ DMWARN_LIMIT("repeat_count > 1 is deprecated, using 1 instead");
++ repeat_count = 1;
++ }
++
+ /* allocate the path */
+ pi = kmalloc(sizeof(*pi), GFP_KERNEL);
+ if (!pi) {
+@@ -183,9 +161,6 @@ static void rr_fail_path(struct path_selector *ps, struct dm_path *p)
+ struct path_info *pi = p->pscontext;
+
+ spin_lock_irqsave(&s->lock, flags);
+- if (p == *this_cpu_ptr(s->current_path))
+- set_percpu_current_path(s, NULL);
+-
+ list_move(&pi->list, &s->invalid_paths);
+ spin_unlock_irqrestore(&s->lock, flags);
+ }
+@@ -208,29 +183,15 @@ static struct dm_path *rr_select_path(struct path_selector *ps, size_t nr_bytes)
+ unsigned long flags;
+ struct selector *s = ps->context;
+ struct path_info *pi = NULL;
+- struct dm_path *current_path = NULL;
+-
+- local_irq_save(flags);
+- current_path = *this_cpu_ptr(s->current_path);
+- if (current_path) {
+- percpu_counter_dec(&s->repeat_count);
+- if (percpu_counter_read_positive(&s->repeat_count) > 0) {
+- local_irq_restore(flags);
+- return current_path;
+- }
+- }
+
+- spin_lock(&s->lock);
++ spin_lock_irqsave(&s->lock, flags);
+ if (!list_empty(&s->valid_paths)) {
+ pi = list_entry(s->valid_paths.next, struct path_info, list);
+ list_move_tail(&pi->list, &s->valid_paths);
+- percpu_counter_set(&s->repeat_count, pi->repeat_count);
+- set_percpu_current_path(s, pi->path);
+- current_path = pi->path;
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+
+- return current_path;
++ return pi ? pi->path : NULL;
+ }
+
+ static struct path_selector_type rr_ps = {
+diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c
+index 38b05f2..0250e7e 100644
+--- a/drivers/md/dm-stats.c
++++ b/drivers/md/dm-stats.c
+@@ -175,6 +175,7 @@ static void dm_stat_free(struct rcu_head *head)
+ int cpu;
+ struct dm_stat *s = container_of(head, struct dm_stat, rcu_head);
+
++ kfree(s->histogram_boundaries);
+ kfree(s->program_id);
+ kfree(s->aux_data);
+ for_each_possible_cpu(cpu) {
+diff --git a/drivers/md/linear.c b/drivers/md/linear.c
+index 86f5d43..b0c0aef 100644
+--- a/drivers/md/linear.c
++++ b/drivers/md/linear.c
+@@ -52,18 +52,26 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector)
+ return conf->disks + lo;
+ }
+
++/*
++ * In linear_congested() conf->raid_disks is used as a copy of
++ * mddev->raid_disks to iterate conf->disks[], because conf->raid_disks
++ * and conf->disks[] are created in linear_conf(), they are always
++ * consitent with each other, but mddev->raid_disks does not.
++ */
+ static int linear_congested(struct mddev *mddev, int bits)
+ {
+ struct linear_conf *conf;
+ int i, ret = 0;
+
+- conf = mddev->private;
++ rcu_read_lock();
++ conf = rcu_dereference(mddev->private);
+
+- for (i = 0; i < mddev->raid_disks && !ret ; i++) {
++ for (i = 0; i < conf->raid_disks && !ret ; i++) {
+ struct request_queue *q = bdev_get_queue(conf->disks[i].rdev->bdev);
+ ret |= bdi_congested(&q->backing_dev_info, bits);
+ }
+
++ rcu_read_unlock();
+ return ret;
+ }
+
+@@ -143,6 +151,19 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks)
+ conf->disks[i-1].end_sector +
+ conf->disks[i].rdev->sectors;
+
++ /*
++ * conf->raid_disks is copy of mddev->raid_disks. The reason to
++ * keep a copy of mddev->raid_disks in struct linear_conf is,
++ * mddev->raid_disks may not be consistent with pointers number of
++ * conf->disks[] when it is updated in linear_add() and used to
++ * iterate old conf->disks[] earray in linear_congested().
++ * Here conf->raid_disks is always consitent with number of
++ * pointers in conf->disks[] array, and mddev->private is updated
++ * with rcu_assign_pointer() in linear_addr(), such race can be
++ * avoided.
++ */
++ conf->raid_disks = raid_disks;
++
+ return conf;
+
+ out:
+@@ -195,15 +216,23 @@ static int linear_add(struct mddev *mddev, struct md_rdev *rdev)
+ if (!newconf)
+ return -ENOMEM;
+
++ /* newconf->raid_disks already keeps a copy of * the increased
++ * value of mddev->raid_disks, WARN_ONCE() is just used to make
++ * sure of this. It is possible that oldconf is still referenced
++ * in linear_congested(), therefore kfree_rcu() is used to free
++ * oldconf until no one uses it anymore.
++ */
+ mddev_suspend(mddev);
+- oldconf = mddev->private;
++ oldconf = rcu_dereference(mddev->private);
+ mddev->raid_disks++;
+- mddev->private = newconf;
++ WARN_ONCE(mddev->raid_disks != newconf->raid_disks,
++ "copied raid_disks doesn't match mddev->raid_disks");
++ rcu_assign_pointer(mddev->private, newconf);
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ mddev_resume(mddev);
+ revalidate_disk(mddev->gendisk);
+- kfree(oldconf);
++ kfree_rcu(oldconf, rcu);
+ return 0;
+ }
+
+diff --git a/drivers/md/linear.h b/drivers/md/linear.h
+index b685ddd..8d392e6 100644
+--- a/drivers/md/linear.h
++++ b/drivers/md/linear.h
+@@ -10,6 +10,7 @@ struct linear_conf
+ {
+ struct rcu_head rcu;
+ sector_t array_sectors;
++ int raid_disks; /* a copy of mddev->raid_disks */
+ struct dev_info disks[0];
+ };
+ #endif
+diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c
+index 95267c6..f6ebbb4 100644
+--- a/drivers/media/dvb-frontends/cxd2820r_core.c
++++ b/drivers/media/dvb-frontends/cxd2820r_core.c
+@@ -615,6 +615,7 @@ static int cxd2820r_probe(struct i2c_client *client,
+ }
+
+ priv->client[0] = client;
++ priv->fe.demodulator_priv = priv;
+ priv->i2c = client->adapter;
+ priv->ts_mode = pdata->ts_mode;
+ priv->ts_clk_inv = pdata->ts_clk_inv;
+@@ -697,7 +698,6 @@ static int cxd2820r_probe(struct i2c_client *client,
+ memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops));
+ if (!pdata->attach_in_use)
+ priv->fe.ops.release = NULL;
+- priv->fe.demodulator_priv = priv;
+ i2c_set_clientdata(client, priv);
+
+ /* Setup callbacks */
+diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
+index 2783531..4462d8c 100644
+--- a/drivers/media/media-device.c
++++ b/drivers/media/media-device.c
+@@ -130,7 +130,7 @@ static long media_device_enum_entities(struct media_device *mdev,
+ * old range.
+ */
+ if (ent->function < MEDIA_ENT_F_OLD_BASE ||
+- ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) {
++ ent->function > MEDIA_ENT_F_TUNER) {
+ if (is_media_entity_v4l2_subdev(ent))
+ entd->type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
+ else if (ent->function != MEDIA_ENT_F_IO_V4L)
+diff --git a/drivers/media/pci/dm1105/Kconfig b/drivers/media/pci/dm1105/Kconfig
+index 173daf0..14fa7e4 100644
+--- a/drivers/media/pci/dm1105/Kconfig
++++ b/drivers/media/pci/dm1105/Kconfig
+@@ -1,6 +1,6 @@
+ config DVB_DM1105
+ tristate "SDMC DM1105 based PCI cards"
+- depends on DVB_CORE && PCI && I2C
++ depends on DVB_CORE && PCI && I2C && I2C_ALGOBIT
+ select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_STV0288 if MEDIA_SUBDRV_AUTOSELECT
+diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
+index b33b9e3..05489a4 100644
+--- a/drivers/media/platform/am437x/am437x-vpfe.c
++++ b/drivers/media/platform/am437x/am437x-vpfe.c
+@@ -1576,7 +1576,7 @@ static int vpfe_s_fmt(struct file *file, void *priv,
+ return -EBUSY;
+ }
+
+- ret = vpfe_try_fmt(file, priv, &format);
++ ret = __vpfe_get_format(vpfe, &format, &bpp);
+ if (ret)
+ return ret;
+
+diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
+index 91f9bb8..6ebe895 100644
+--- a/drivers/media/rc/lirc_dev.c
++++ b/drivers/media/rc/lirc_dev.c
+@@ -589,7 +589,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ result = put_user(ir->d.features, (__u32 __user *)arg);
+ break;
+ case LIRC_GET_REC_MODE:
+- if (LIRC_CAN_REC(ir->d.features)) {
++ if (!LIRC_CAN_REC(ir->d.features)) {
+ result = -ENOTTY;
+ break;
+ }
+@@ -599,7 +599,7 @@ long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ (__u32 __user *)arg);
+ break;
+ case LIRC_SET_REC_MODE:
+- if (LIRC_CAN_REC(ir->d.features)) {
++ if (!LIRC_CAN_REC(ir->d.features)) {
+ result = -ENOTTY;
+ break;
+ }
+diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
+index 77edd20..40e5a6b 100644
+--- a/drivers/media/usb/uvc/uvc_queue.c
++++ b/drivers/media/usb/uvc/uvc_queue.c
+@@ -412,7 +412,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
+ nextbuf = NULL;
+ spin_unlock_irqrestore(&queue->irqlock, flags);
+
+- buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
++ buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
+ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
+ vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
+
+diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
+index fa50635..41f3186 100644
+--- a/drivers/misc/mei/main.c
++++ b/drivers/misc/mei/main.c
+@@ -182,32 +182,36 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
+ goto out;
+ }
+
+- if (rets == -EBUSY &&
+- !mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, file)) {
+- rets = -ENOMEM;
+- goto out;
+- }
+
+- do {
+- mutex_unlock(&dev->device_lock);
+-
+- if (wait_event_interruptible(cl->rx_wait,
+- (!list_empty(&cl->rd_completed)) ||
+- (!mei_cl_is_connected(cl)))) {
++again:
++ mutex_unlock(&dev->device_lock);
++ if (wait_event_interruptible(cl->rx_wait,
++ !list_empty(&cl->rd_completed) ||
++ !mei_cl_is_connected(cl))) {
++ if (signal_pending(current))
++ return -EINTR;
++ return -ERESTARTSYS;
++ }
++ mutex_lock(&dev->device_lock);
+
+- if (signal_pending(current))
+- return -EINTR;
+- return -ERESTARTSYS;
+- }
++ if (!mei_cl_is_connected(cl)) {
++ rets = -ENODEV;
++ goto out;
++ }
+
+- mutex_lock(&dev->device_lock);
+- if (!mei_cl_is_connected(cl)) {
+- rets = -ENODEV;
+- goto out;
+- }
++ cb = mei_cl_read_cb(cl, file);
++ if (!cb) {
++ /*
++ * For amthif all the waiters are woken up,
++ * but only fp with matching cb->fp get the cb,
++ * the others have to return to wait on read.
++ */
++ if (cl == &dev->iamthif_cl)
++ goto again;
+
+- cb = mei_cl_read_cb(cl, file);
+- } while (!cb);
++ rets = 0;
++ goto out;
++ }
+
+ copy_buffer:
+ /* now copy the data to user space */
+diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
+index fddd0be..80918ab 100644
+--- a/drivers/mmc/host/sdhci-acpi.c
++++ b/drivers/mmc/host/sdhci-acpi.c
+@@ -466,7 +466,10 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
+ if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
+ bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
+
+- if (mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL)) {
++ err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0, NULL);
++ if (err) {
++ if (err == -EPROBE_DEFER)
++ goto err_free;
+ dev_warn(dev, "failed to setup card detect gpio\n");
+ c->use_runtime_pm = false;
+ }
+diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
+index 0a177b1..d1570f5 100644
+--- a/drivers/mtd/nand/fsl_ifc_nand.c
++++ b/drivers/mtd/nand/fsl_ifc_nand.c
+@@ -258,9 +258,15 @@ static void fsl_ifc_run_command(struct mtd_info *mtd)
+ int bufnum = nctrl->page & priv->bufnum_mask;
+ int sector = bufnum * chip->ecc.steps;
+ int sector_end = sector + chip->ecc.steps - 1;
++ __be32 *eccstat_regs;
++
++ if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
++ eccstat_regs = ifc->ifc_nand.v2_nand_eccstat;
++ else
++ eccstat_regs = ifc->ifc_nand.v1_nand_eccstat;
+
+ for (i = sector / 4; i <= sector_end / 4; i++)
+- eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
++ eccstat[i] = ifc_in32(&eccstat_regs[i]);
+
+ for (i = sector; i <= sector_end; i++) {
+ errors = check_read_ecc(mtd, ctrl, eccstat, i);
+diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c
+index 77e3cc0..a0dabd4 100644
+--- a/drivers/net/can/usb/gs_usb.c
++++ b/drivers/net/can/usb/gs_usb.c
+@@ -908,10 +908,14 @@ static int gs_usb_probe(struct usb_interface *intf,
+ struct gs_usb *dev;
+ int rc = -ENOMEM;
+ unsigned int icount, i;
+- struct gs_host_config hconf = {
+- .byte_order = 0x0000beef,
+- };
+- struct gs_device_config dconf;
++ struct gs_host_config *hconf;
++ struct gs_device_config *dconf;
++
++ hconf = kmalloc(sizeof(*hconf), GFP_KERNEL);
++ if (!hconf)
++ return -ENOMEM;
++
++ hconf->byte_order = 0x0000beef;
+
+ /* send host config */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+@@ -920,16 +924,22 @@ static int gs_usb_probe(struct usb_interface *intf,
+ USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ 1,
+ intf->altsetting[0].desc.bInterfaceNumber,
+- &hconf,
+- sizeof(hconf),
++ hconf,
++ sizeof(*hconf),
+ 1000);
+
++ kfree(hconf);
++
+ if (rc < 0) {
+ dev_err(&intf->dev, "Couldn't send data format (err=%d)\n",
+ rc);
+ return rc;
+ }
+
++ dconf = kmalloc(sizeof(*dconf), GFP_KERNEL);
++ if (!dconf)
++ return -ENOMEM;
++
+ /* read device config */
+ rc = usb_control_msg(interface_to_usbdev(intf),
+ usb_rcvctrlpipe(interface_to_usbdev(intf), 0),
+@@ -937,28 +947,33 @@ static int gs_usb_probe(struct usb_interface *intf,
+ USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
+ 1,
+ intf->altsetting[0].desc.bInterfaceNumber,
+- &dconf,
+- sizeof(dconf),
++ dconf,
++ sizeof(*dconf),
+ 1000);
+ if (rc < 0) {
+ dev_err(&intf->dev, "Couldn't get device config: (err=%d)\n",
+ rc);
++ kfree(dconf);
+ return rc;
+ }
+
+- icount = dconf.icount + 1;
++ icount = dconf->icount + 1;
+ dev_info(&intf->dev, "Configuring for %d interfaces\n", icount);
+
+ if (icount > GS_MAX_INTF) {
+ dev_err(&intf->dev,
+ "Driver cannot handle more that %d CAN interfaces\n",
+ GS_MAX_INTF);
++ kfree(dconf);
+ return -EINVAL;
+ }
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+- if (!dev)
++ if (!dev) {
++ kfree(dconf);
+ return -ENOMEM;
++ }
++
+ init_usb_anchor(&dev->rx_submitted);
+
+ atomic_set(&dev->active_channels, 0);
+@@ -967,7 +982,7 @@ static int gs_usb_probe(struct usb_interface *intf,
+ dev->udev = interface_to_usbdev(intf);
+
+ for (i = 0; i < icount; i++) {
+- dev->canch[i] = gs_make_candev(i, intf, &dconf);
++ dev->canch[i] = gs_make_candev(i, intf, dconf);
+ if (IS_ERR_OR_NULL(dev->canch[i])) {
+ /* save error code to return later */
+ rc = PTR_ERR(dev->canch[i]);
+@@ -978,12 +993,15 @@ static int gs_usb_probe(struct usb_interface *intf,
+ gs_destroy_candev(dev->canch[i]);
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
++ kfree(dconf);
+ kfree(dev);
+ return rc;
+ }
+ dev->canch[i]->parent = dev;
+ }
+
++ kfree(dconf);
++
+ return 0;
+ }
+
+diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
+index 108a30e..d000cb6 100644
+--- a/drivers/net/can/usb/usb_8dev.c
++++ b/drivers/net/can/usb/usb_8dev.c
+@@ -951,8 +951,8 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+- priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
+- GFP_KERNEL);
++ priv->cmd_msg_buffer = devm_kzalloc(&intf->dev, sizeof(struct usb_8dev_cmd_msg),
++ GFP_KERNEL);
+ if (!priv->cmd_msg_buffer)
+ goto cleanup_candev;
+
+@@ -966,7 +966,7 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ if (err) {
+ netdev_err(netdev,
+ "couldn't register CAN device: %d\n", err);
+- goto cleanup_cmd_msg_buffer;
++ goto cleanup_candev;
+ }
+
+ err = usb_8dev_cmd_version(priv, &version);
+@@ -987,9 +987,6 @@ static int usb_8dev_probe(struct usb_interface *intf,
+ cleanup_unregister_candev:
+ unregister_netdev(priv->netdev);
+
+-cleanup_cmd_msg_buffer:
+- kfree(priv->cmd_msg_buffer);
+-
+ cleanup_candev:
+ free_candev(netdev);
+
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index 0c45322..972b5e2 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -1901,7 +1901,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
+ ar->hw->wiphy->fw_version);
+
+- if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map)) {
++ if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&
++ mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ val = 0;
+ if (ath10k_peer_stats_enabled(ar))
+ val = WMI_10_4_PEER_STATS;
+@@ -1954,10 +1955,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
+ * possible to implicitly make it correct by creating a dummy vdev and
+ * then deleting it.
+ */
+- status = ath10k_core_reset_rx_filter(ar);
+- if (status) {
+- ath10k_err(ar, "failed to reset rx filter: %d\n", status);
+- goto err_hif_stop;
++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
++ status = ath10k_core_reset_rx_filter(ar);
++ if (status) {
++ ath10k_err(ar,
++ "failed to reset rx filter: %d\n", status);
++ goto err_hif_stop;
++ }
+ }
+
+ /* If firmware indicates Full Rx Reorder support it must be used in a
+diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+index dc44cfe..16e052d 100644
+--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+@@ -502,8 +502,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ break;
+ return -EOPNOTSUPP;
+ default:
+- WARN_ON(1);
+- return -EINVAL;
++ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&ah->lock);
+diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+index 107bcfb..cb37bf0 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+@@ -73,13 +73,13 @@
+ #define AR9300_OTP_BASE \
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
+ #define AR9300_OTP_STATUS \
+- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
++ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
+ #define AR9300_OTP_STATUS_TYPE 0x7
+ #define AR9300_OTP_STATUS_VALID 0x4
+ #define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+ #define AR9300_OTP_STATUS_SM_BUSY 0x1
+ #define AR9300_OTP_READ_DATA \
+- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
++ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
+
+ enum targetPowerHTRates {
+ HT_TARGET_RATE_0_8_16,
+diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
+index 26fc8ec..a731671 100644
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -959,6 +959,7 @@ struct ath_softc {
+ struct survey_info *cur_survey;
+ struct survey_info survey[ATH9K_NUM_CHANNELS];
+
++ spinlock_t intr_lock;
+ struct tasklet_struct intr_tq;
+ struct tasklet_struct bcon_tasklet;
+ struct ath_hw *sc_ah;
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index cfa3fe8..297d4bb 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -626,6 +626,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
+ common->bt_ant_diversity = 1;
+
+ spin_lock_init(&common->cc_lock);
++ spin_lock_init(&sc->intr_lock);
+ spin_lock_init(&sc->sc_serial_rw);
+ spin_lock_init(&sc->sc_pm_lock);
+ spin_lock_init(&sc->chan_lock);
+diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
+index bba85d1..d937c39 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -805,21 +805,12 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+
+-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ {
+ struct ath_common *common = ath9k_hw_common(ah);
+ u32 sync_default = AR_INTR_SYNC_DEFAULT;
+ u32 async_mask;
+
+- if (!(ah->imask & ATH9K_INT_GLOBAL))
+- return;
+-
+- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+- atomic_read(&ah->intr_ref_cnt));
+- return;
+- }
+-
+ if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+ AR_SREV_9561(ah))
+ sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+@@ -841,6 +832,39 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+ }
++
++void ath9k_hw_resume_interrupts(struct ath_hw *ah)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
++ return;
++
++ if (atomic_read(&ah->intr_ref_cnt) != 0) {
++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++ atomic_read(&ah->intr_ref_cnt));
++ return;
++ }
++
++ __ath9k_hw_enable_interrupts(ah);
++}
++EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
++
++void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++{
++ struct ath_common *common = ath9k_hw_common(ah);
++
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
++ return;
++
++ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
++ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++ atomic_read(&ah->intr_ref_cnt));
++ return;
++ }
++
++ __ath9k_hw_enable_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+
+ void ath9k_hw_set_interrupts(struct ath_hw *ah)
+diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
+index 3bab014..770fc11 100644
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah);
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_kill_interrupts(struct ath_hw *ah);
++void ath9k_hw_resume_interrupts(struct ath_hw *ah);
+
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
+
+diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
+index e9f32b5..b868f02 100644
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -373,21 +373,20 @@ void ath9k_tasklet(unsigned long data)
+ struct ath_common *common = ath9k_hw_common(ah);
+ enum ath_reset_type type;
+ unsigned long flags;
+- u32 status = sc->intrstatus;
++ u32 status;
+ u32 rxmask;
+
++ spin_lock_irqsave(&sc->intr_lock, flags);
++ status = sc->intrstatus;
++ sc->intrstatus = 0;
++ spin_unlock_irqrestore(&sc->intr_lock, flags);
++
+ ath9k_ps_wakeup(sc);
+ spin_lock(&sc->sc_pcu_lock);
+
+ if (status & ATH9K_INT_FATAL) {
+ type = RESET_TYPE_FATAL_INT;
+ ath9k_queue_reset(sc, type);
+-
+- /*
+- * Increment the ref. counter here so that
+- * interrupts are enabled in the reset routine.
+- */
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+ goto out;
+ }
+@@ -403,11 +402,6 @@ void ath9k_tasklet(unsigned long data)
+ type = RESET_TYPE_BB_WATCHDOG;
+ ath9k_queue_reset(sc, type);
+
+- /*
+- * Increment the ref. counter here so that
+- * interrupts are enabled in the reset routine.
+- */
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET,
+ "BB_WATCHDOG: Skipping interrupts\n");
+ goto out;
+@@ -420,7 +414,6 @@ void ath9k_tasklet(unsigned long data)
+ if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+ type = RESET_TYPE_TX_GTT;
+ ath9k_queue_reset(sc, type);
+- atomic_inc(&ah->intr_ref_cnt);
+ ath_dbg(common, RESET,
+ "GTT: Skipping interrupts\n");
+ goto out;
+@@ -477,7 +470,7 @@ void ath9k_tasklet(unsigned long data)
+ ath9k_btcoex_handle_interrupt(sc, status);
+
+ /* re-enable hardware interrupt */
+- ath9k_hw_enable_interrupts(ah);
++ ath9k_hw_resume_interrupts(ah);
+ out:
+ spin_unlock(&sc->sc_pcu_lock);
+ ath9k_ps_restore(sc);
+@@ -541,7 +534,9 @@ irqreturn_t ath_isr(int irq, void *dev)
+ return IRQ_NONE;
+
+ /* Cache the status */
+- sc->intrstatus = status;
++ spin_lock(&sc->intr_lock);
++ sc->intrstatus |= status;
++ spin_unlock(&sc->intr_lock);
+
+ if (status & SCHED_INTR)
+ sched = true;
+@@ -587,7 +582,7 @@ irqreturn_t ath_isr(int irq, void *dev)
+
+ if (sched) {
+ /* turn off every interrupt */
+- ath9k_hw_disable_interrupts(ah);
++ ath9k_hw_kill_interrupts(ah);
+ tasklet_schedule(&sc->intr_tq);
+ }
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.h b/drivers/net/wireless/realtek/rtlwifi/pci.h
+index b951eba..d2f4dd4 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.h
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.h
+@@ -275,10 +275,10 @@ struct mp_adapter {
+ };
+
+ struct rtl_pci_priv {
++ struct bt_coexist_info bt_coexist;
++ struct rtl_led_ctl ledctl;
+ struct rtl_pci dev;
+ struct mp_adapter ndis_adapter;
+- struct rtl_led_ctl ledctl;
+- struct bt_coexist_info bt_coexist;
+ };
+
+ #define rtl_pcipriv(hw) (((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+index ebf663e..cab4601 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+@@ -1006,7 +1006,7 @@ static void _rtl92ee_hw_configure(struct ieee80211_hw *hw)
+ rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a);
+
+ /* Note Data sheet don't define */
+- rtl_write_word(rtlpriv, 0x4C7, 0x80);
++ rtl_write_byte(rtlpriv, 0x4C7, 0x80);
+
+ rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
+
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+index 1281ebe..2cbef96 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+@@ -1128,7 +1128,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
+ }
+ if (0 == tmp) {
+ read_addr = REG_DBI_RDATA + addr % 4;
+- ret = rtl_read_word(rtlpriv, read_addr);
++ ret = rtl_read_byte(rtlpriv, read_addr);
+ }
+ return ret;
+ }
+diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.h b/drivers/net/wireless/realtek/rtlwifi/usb.h
+index 685273c..441c441 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/usb.h
++++ b/drivers/net/wireless/realtek/rtlwifi/usb.h
+@@ -150,8 +150,9 @@ struct rtl_usb {
+ };
+
+ struct rtl_usb_priv {
+- struct rtl_usb dev;
++ struct bt_coexist_info bt_coexist;
+ struct rtl_led_ctl ledctl;
++ struct rtl_usb dev;
+ };
+
+ #define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv))
+diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
+index 763ff87..61fc349 100644
+--- a/drivers/pci/host/pci-hyperv.c
++++ b/drivers/pci/host/pci-hyperv.c
+@@ -130,7 +130,8 @@ union pci_version {
+ */
+ union win_slot_encoding {
+ struct {
+- u32 func:8;
++ u32 dev:5;
++ u32 func:3;
+ u32 reserved:24;
+ } bits;
+ u32 slot;
+@@ -483,7 +484,8 @@ static u32 devfn_to_wslot(int devfn)
+ union win_slot_encoding wslot;
+
+ wslot.slot = 0;
+- wslot.bits.func = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
++ wslot.bits.dev = PCI_SLOT(devfn);
++ wslot.bits.func = PCI_FUNC(devfn);
+
+ return wslot.slot;
+ }
+@@ -501,7 +503,7 @@ static int wslot_to_devfn(u32 wslot)
+ union win_slot_encoding slot_no;
+
+ slot_no.slot = wslot;
+- return PCI_DEVFN(0, slot_no.bits.func);
++ return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func);
+ }
+
+ /*
+diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
+index b0ac4df..f2907e7 100644
+--- a/drivers/pci/host/pcie-altera.c
++++ b/drivers/pci/host/pcie-altera.c
+@@ -57,10 +57,14 @@
+ #define TLP_WRITE_TAG 0x10
+ #define RP_DEVFN 0
+ #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
+-#define TLP_CFG_DW0(pcie, bus) \
++#define TLP_CFGRD_DW0(pcie, bus) \
+ ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGRD0 \
+ : TLP_FMTTYPE_CFGRD1) << 24) | \
+ TLP_PAYLOAD_SIZE)
++#define TLP_CFGWR_DW0(pcie, bus) \
++ ((((bus == pcie->root_bus_nr) ? TLP_FMTTYPE_CFGWR0 \
++ : TLP_FMTTYPE_CFGWR1) << 24) | \
++ TLP_PAYLOAD_SIZE)
+ #define TLP_CFG_DW1(pcie, tag, be) \
+ (((TLP_REQ_ID(pcie->root_bus_nr, RP_DEVFN)) << 16) | (tag << 8) | (be))
+ #define TLP_CFG_DW2(bus, devfn, offset) \
+@@ -222,7 +226,7 @@ static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
+ {
+ u32 headers[TLP_HDR_SIZE];
+
+- headers[0] = TLP_CFG_DW0(pcie, bus);
++ headers[0] = TLP_CFGRD_DW0(pcie, bus);
+ headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
+ headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+@@ -237,7 +241,7 @@ static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
+ u32 headers[TLP_HDR_SIZE];
+ int ret;
+
+- headers[0] = TLP_CFG_DW0(pcie, bus);
++ headers[0] = TLP_CFGWR_DW0(pcie, bus);
+ headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
+ headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
+index 56efaf7..acb2be0 100644
+--- a/drivers/pci/hotplug/pnv_php.c
++++ b/drivers/pci/hotplug/pnv_php.c
+@@ -35,9 +35,11 @@ static void pnv_php_register(struct device_node *dn);
+ static void pnv_php_unregister_one(struct device_node *dn);
+ static void pnv_php_unregister(struct device_node *dn);
+
+-static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
++static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
++ bool disable_device)
+ {
+ struct pci_dev *pdev = php_slot->pdev;
++ int irq = php_slot->irq;
+ u16 ctrl;
+
+ if (php_slot->irq > 0) {
+@@ -56,10 +58,14 @@ static void pnv_php_disable_irq(struct pnv_php_slot *php_slot)
+ php_slot->wq = NULL;
+ }
+
+- if (pdev->msix_enabled)
+- pci_disable_msix(pdev);
+- else if (pdev->msi_enabled)
+- pci_disable_msi(pdev);
++ if (disable_device || irq > 0) {
++ if (pdev->msix_enabled)
++ pci_disable_msix(pdev);
++ else if (pdev->msi_enabled)
++ pci_disable_msi(pdev);
++
++ pci_disable_device(pdev);
++ }
+ }
+
+ static void pnv_php_free_slot(struct kref *kref)
+@@ -68,7 +74,7 @@ static void pnv_php_free_slot(struct kref *kref)
+ struct pnv_php_slot, kref);
+
+ WARN_ON(!list_empty(&php_slot->children));
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, false);
+ kfree(php_slot->name);
+ kfree(php_slot);
+ }
+@@ -759,7 +765,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
+ php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
+ if (!php_slot->wq) {
+ dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, true);
+ return;
+ }
+
+@@ -772,7 +778,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
+ ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
+ php_slot->name, php_slot);
+ if (ret) {
+- pnv_php_disable_irq(php_slot);
++ pnv_php_disable_irq(php_slot, true);
+ dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
+ return;
+ }
+diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
+index c74c3f6..02e46bb 100644
+--- a/drivers/power/reset/Kconfig
++++ b/drivers/power/reset/Kconfig
+@@ -32,7 +32,7 @@ config POWER_RESET_AT91_RESET
+
+ config POWER_RESET_AT91_SAMA5D2_SHDWC
+ tristate "Atmel AT91 SAMA5D2-Compatible shutdown controller driver"
+- depends on ARCH_AT91 || COMPILE_TEST
++ depends on ARCH_AT91
+ default SOC_SAMA5
+ help
+ This driver supports the alternate shutdown controller for some Atmel
+diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
+index e9e24df..2579f02 100644
+--- a/drivers/power/reset/at91-poweroff.c
++++ b/drivers/power/reset/at91-poweroff.c
+@@ -14,9 +14,12 @@
+ #include <linux/io.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_address.h>
+ #include <linux/platform_device.h>
+ #include <linux/printk.h>
+
++#include <soc/at91/at91sam9_ddrsdr.h>
++
+ #define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
+ #define AT91_SHDW_SHDW BIT(0) /* Shut Down command */
+ #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
+@@ -50,6 +53,7 @@ static const char *shdwc_wakeup_modes[] = {
+
+ static void __iomem *at91_shdwc_base;
+ static struct clk *sclk;
++static void __iomem *mpddrc_base;
+
+ static void __init at91_wakeup_status(void)
+ {
+@@ -73,6 +77,29 @@ static void at91_poweroff(void)
+ writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR);
+ }
+
++static void at91_lpddr_poweroff(void)
++{
++ asm volatile(
++ /* Align to cache lines */
++ ".balign 32\n\t"
++
++ /* Ensure AT91_SHDW_CR is in the TLB by reading it */
++ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
++
++ /* Power down SDRAM0 */
++ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
++ /* Shutdown CPU */
++ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
++
++ " b .\n\t"
++ :
++ : "r" (mpddrc_base),
++ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
++ "r" (at91_shdwc_base),
++ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
++ : "r0");
++}
++
+ static int at91_poweroff_get_wakeup_mode(struct device_node *np)
+ {
+ const char *pm;
+@@ -124,6 +151,8 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
+ static int __init at91_poweroff_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
++ struct device_node *np;
++ u32 ddr_type;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+@@ -150,12 +179,30 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
+
+ pm_power_off = at91_poweroff;
+
++ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
++ if (!np)
++ return 0;
++
++ mpddrc_base = of_iomap(np, 0);
++ of_node_put(np);
++
++ if (!mpddrc_base)
++ return 0;
++
++ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
++ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
++ (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
++ pm_power_off = at91_lpddr_poweroff;
++ else
++ iounmap(mpddrc_base);
++
+ return 0;
+ }
+
+ static int __exit at91_poweroff_remove(struct platform_device *pdev)
+ {
+- if (pm_power_off == at91_poweroff)
++ if (pm_power_off == at91_poweroff ||
++ pm_power_off == at91_lpddr_poweroff)
+ pm_power_off = NULL;
+
+ clk_disable_unprepare(sclk);
+@@ -163,6 +210,11 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++static const struct of_device_id at91_ramc_of_match[] = {
++ { .compatible = "atmel,sama5d3-ddramc", },
++ { /* sentinel */ }
++};
++
+ static const struct of_device_id at91_poweroff_of_match[] = {
+ { .compatible = "atmel,at91sam9260-shdwc", },
+ { .compatible = "atmel,at91sam9rl-shdwc", },
+diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c
+index 8a5ac97..90b0b5a 100644
+--- a/drivers/power/reset/at91-sama5d2_shdwc.c
++++ b/drivers/power/reset/at91-sama5d2_shdwc.c
+@@ -22,9 +22,12 @@
+ #include <linux/io.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
++#include <linux/of_address.h>
+ #include <linux/platform_device.h>
+ #include <linux/printk.h>
+
++#include <soc/at91/at91sam9_ddrsdr.h>
++
+ #define SLOW_CLOCK_FREQ 32768
+
+ #define AT91_SHDW_CR 0x00 /* Shut Down Control Register */
+@@ -75,6 +78,7 @@ struct shdwc {
+ */
+ static struct shdwc *at91_shdwc;
+ static struct clk *sclk;
++static void __iomem *mpddrc_base;
+
+ static const unsigned long long sdwc_dbc_period[] = {
+ 0, 3, 32, 512, 4096, 32768,
+@@ -108,6 +112,29 @@ static void at91_poweroff(void)
+ at91_shdwc->at91_shdwc_base + AT91_SHDW_CR);
+ }
+
++static void at91_lpddr_poweroff(void)
++{
++ asm volatile(
++ /* Align to cache lines */
++ ".balign 32\n\t"
++
++ /* Ensure AT91_SHDW_CR is in the TLB by reading it */
++ " ldr r6, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
++
++ /* Power down SDRAM0 */
++ " str %1, [%0, #" __stringify(AT91_DDRSDRC_LPR) "]\n\t"
++ /* Shutdown CPU */
++ " str %3, [%2, #" __stringify(AT91_SHDW_CR) "]\n\t"
++
++ " b .\n\t"
++ :
++ : "r" (mpddrc_base),
++ "r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
++ "r" (at91_shdwc->at91_shdwc_base),
++ "r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
++ : "r0");
++}
++
+ static u32 at91_shdwc_debouncer_value(struct platform_device *pdev,
+ u32 in_period_us)
+ {
+@@ -212,6 +239,8 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
+ {
+ struct resource *res;
+ const struct of_device_id *match;
++ struct device_node *np;
++ u32 ddr_type;
+ int ret;
+
+ if (!pdev->dev.of_node)
+@@ -249,6 +278,23 @@ static int __init at91_shdwc_probe(struct platform_device *pdev)
+
+ pm_power_off = at91_poweroff;
+
++ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
++ if (!np)
++ return 0;
++
++ mpddrc_base = of_iomap(np, 0);
++ of_node_put(np);
++
++ if (!mpddrc_base)
++ return 0;
++
++ ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) & AT91_DDRSDRC_MD;
++ if ((ddr_type == AT91_DDRSDRC_MD_LPDDR2) ||
++ (ddr_type == AT91_DDRSDRC_MD_LPDDR3))
++ pm_power_off = at91_lpddr_poweroff;
++ else
++ iounmap(mpddrc_base);
++
+ return 0;
+ }
+
+@@ -256,7 +302,8 @@ static int __exit at91_shdwc_remove(struct platform_device *pdev)
+ {
+ struct shdwc *shdw = platform_get_drvdata(pdev);
+
+- if (pm_power_off == at91_poweroff)
++ if (pm_power_off == at91_poweroff ||
++ pm_power_off == at91_lpddr_poweroff)
+ pm_power_off = NULL;
+
+ /* Reset values to disable wake-up features */
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index 5c1519b..9faccfc 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -4357,12 +4357,13 @@ static void regulator_summary_show_subtree(struct seq_file *s,
+ seq_puts(s, "\n");
+
+ list_for_each_entry(consumer, &rdev->consumer_list, list) {
+- if (consumer->dev->class == &regulator_class)
++ if (consumer->dev && consumer->dev->class == &regulator_class)
+ continue;
+
+ seq_printf(s, "%*s%-*s ",
+ (level + 1) * 3 + 1, "",
+- 30 - (level + 1) * 3, dev_name(consumer->dev));
++ 30 - (level + 1) * 3,
++ consumer->dev ? dev_name(consumer->dev) : "deviceless");
+
+ switch (rdev->desc->type) {
+ case REGULATOR_VOLTAGE:
+diff --git a/drivers/remoteproc/qcom_mdt_loader.c b/drivers/remoteproc/qcom_mdt_loader.c
+index 114e8e4..04db02d 100644
+--- a/drivers/remoteproc/qcom_mdt_loader.c
++++ b/drivers/remoteproc/qcom_mdt_loader.c
+@@ -115,6 +115,7 @@ int qcom_mdt_load(struct rproc *rproc,
+ const struct elf32_phdr *phdrs;
+ const struct elf32_phdr *phdr;
+ const struct elf32_hdr *ehdr;
++ const struct firmware *seg_fw;
+ size_t fw_name_len;
+ char *fw_name;
+ void *ptr;
+@@ -153,16 +154,16 @@ int qcom_mdt_load(struct rproc *rproc,
+
+ if (phdr->p_filesz) {
+ sprintf(fw_name + fw_name_len - 3, "b%02d", i);
+- ret = request_firmware(&fw, fw_name, &rproc->dev);
++ ret = request_firmware(&seg_fw, fw_name, &rproc->dev);
+ if (ret) {
+ dev_err(&rproc->dev, "failed to load %s\n",
+ fw_name);
+ break;
+ }
+
+- memcpy(ptr, fw->data, fw->size);
++ memcpy(ptr, seg_fw->data, seg_fw->size);
+
+- release_firmware(fw);
++ release_firmware(seg_fw);
+ }
+
+ if (phdr->p_memsz > phdr->p_filesz)
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index e859d14..0723c97 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -1432,7 +1432,7 @@ config RTC_DRV_SUN4V
+ based RTC on SUN4V systems.
+
+ config RTC_DRV_SUN6I
+- tristate "Allwinner A31 RTC"
++ bool "Allwinner A31 RTC"
+ default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
+ depends on ARCH_SUNXI
+ help
+diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
+index c169a2c..b0d45d2 100644
+--- a/drivers/rtc/rtc-sun6i.c
++++ b/drivers/rtc/rtc-sun6i.c
+@@ -37,9 +37,11 @@
+
+ /* Control register */
+ #define SUN6I_LOSC_CTRL 0x0000
++#define SUN6I_LOSC_CTRL_KEY (0x16aa << 16)
+ #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9)
+ #define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8)
+ #define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7)
++#define SUN6I_LOSC_CTRL_EXT_OSC BIT(0)
+ #define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7)
+
+ /* RTC */
+@@ -114,13 +116,17 @@ struct sun6i_rtc_dev {
+ void __iomem *base;
+ int irq;
+ unsigned long alarm;
++
++ spinlock_t lock;
+ };
+
+ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
+ {
+ struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id;
++ irqreturn_t ret = IRQ_NONE;
+ u32 val;
+
++ spin_lock(&chip->lock);
+ val = readl(chip->base + SUN6I_ALRM_IRQ_STA);
+
+ if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) {
+@@ -129,10 +135,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id)
+
+ rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF);
+
+- return IRQ_HANDLED;
++ ret = IRQ_HANDLED;
+ }
++ spin_unlock(&chip->lock);
+
+- return IRQ_NONE;
++ return ret;
+ }
+
+ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+@@ -140,6 +147,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+ u32 alrm_val = 0;
+ u32 alrm_irq_val = 0;
+ u32 alrm_wake_val = 0;
++ unsigned long flags;
+
+ if (to) {
+ alrm_val = SUN6I_ALRM_EN_CNT_EN;
+@@ -150,9 +158,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip)
+ chip->base + SUN6I_ALRM_IRQ_STA);
+ }
+
++ spin_lock_irqsave(&chip->lock, flags);
+ writel(alrm_val, chip->base + SUN6I_ALRM_EN);
+ writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN);
+ writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG);
++ spin_unlock_irqrestore(&chip->lock, flags);
+ }
+
+ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+@@ -191,11 +201,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+ static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+ {
+ struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
++ unsigned long flags;
+ u32 alrm_st;
+ u32 alrm_en;
+
++ spin_lock_irqsave(&chip->lock, flags);
+ alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN);
+ alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA);
++ spin_unlock_irqrestore(&chip->lock, flags);
++
+ wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN);
+ wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN);
+ rtc_time_to_tm(chip->alarm, &wkalrm->time);
+@@ -356,6 +370,7 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
+ chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
++ spin_lock_init(&chip->lock);
+
+ platform_set_drvdata(pdev, chip);
+ chip->dev = &pdev->dev;
+@@ -404,6 +419,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
+ /* disable alarm wakeup */
+ writel(0, chip->base + SUN6I_ALARM_CONFIG);
+
++ /* switch to the external, more precise, oscillator */
++ writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC,
++ chip->base + SUN6I_LOSC_CTRL);
++
+ chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev,
+ &sun6i_rtc_ops, THIS_MODULE);
+ if (IS_ERR(chip->rtc)) {
+@@ -439,9 +458,4 @@ static struct platform_driver sun6i_rtc_driver = {
+ .of_match_table = sun6i_rtc_dt_ids,
+ },
+ };
+-
+-module_platform_driver(sun6i_rtc_driver);
+-
+-MODULE_DESCRIPTION("sun6i RTC driver");
+-MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
+-MODULE_LICENSE("GPL");
++builtin_platform_driver(sun6i_rtc_driver);
+diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
+index 0c45388..7b178d7 100644
+--- a/drivers/scsi/aacraid/src.c
++++ b/drivers/scsi/aacraid/src.c
+@@ -414,16 +414,23 @@ static int aac_src_check_health(struct aac_dev *dev)
+ u32 status = src_readl(dev, MUnit.OMR);
+
+ /*
++ * Check to see if the board panic'd.
++ */
++ if (unlikely(status & KERNEL_PANIC))
++ goto err_blink;
++
++ /*
+ * Check to see if the board failed any self tests.
+ */
+ if (unlikely(status & SELF_TEST_FAILED))
+- return -1;
++ goto err_out;
+
+ /*
+- * Check to see if the board panic'd.
++ * Check to see if the board failed any self tests.
+ */
+- if (unlikely(status & KERNEL_PANIC))
+- return (status >> 16) & 0xFF;
++ if (unlikely(status & MONITOR_PANIC))
++ goto err_out;
++
+ /*
+ * Wait for the adapter to be up and running.
+ */
+@@ -433,6 +440,12 @@ static int aac_src_check_health(struct aac_dev *dev)
+ * Everything is OK
+ */
+ return 0;
++
++err_out:
++ return -1;
++
++err_blink:
++ return (status > 16) & 0xFF;
+ }
+
+ /**
+diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
+index ee802273..55faa94 100644
+--- a/drivers/scsi/lpfc/lpfc_hw4.h
++++ b/drivers/scsi/lpfc/lpfc_hw4.h
+@@ -1185,6 +1185,7 @@ struct lpfc_mbx_wq_create {
+ #define lpfc_mbx_wq_create_page_size_SHIFT 0
+ #define lpfc_mbx_wq_create_page_size_MASK 0x000000FF
+ #define lpfc_mbx_wq_create_page_size_WORD word1
++#define LPFC_WQ_PAGE_SIZE_4096 0x1
+ #define lpfc_mbx_wq_create_wqe_size_SHIFT 8
+ #define lpfc_mbx_wq_create_wqe_size_MASK 0x0000000F
+ #define lpfc_mbx_wq_create_wqe_size_WORD word1
+@@ -1256,6 +1257,7 @@ struct rq_context {
+ #define lpfc_rq_context_page_size_SHIFT 0 /* Version 1 Only */
+ #define lpfc_rq_context_page_size_MASK 0x000000FF
+ #define lpfc_rq_context_page_size_WORD word0
++#define LPFC_RQ_PAGE_SIZE_4096 0x1
+ uint32_t reserved1;
+ uint32_t word2;
+ #define lpfc_rq_context_cq_id_SHIFT 16
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index f4f77c5..49b4c79 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -13678,7 +13678,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
+ LPFC_WQ_WQE_SIZE_128);
+ bf_set(lpfc_mbx_wq_create_page_size,
+ &wq_create->u.request_1,
+- (PAGE_SIZE/SLI4_PAGE_SIZE));
++ LPFC_WQ_PAGE_SIZE_4096);
+ page = wq_create->u.request_1.page;
+ break;
+ }
+@@ -13704,8 +13704,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
+ LPFC_WQ_WQE_SIZE_128);
+ break;
+ }
+- bf_set(lpfc_mbx_wq_create_page_size, &wq_create->u.request_1,
+- (PAGE_SIZE/SLI4_PAGE_SIZE));
++ bf_set(lpfc_mbx_wq_create_page_size,
++ &wq_create->u.request_1,
++ LPFC_WQ_PAGE_SIZE_4096);
+ page = wq_create->u.request_1.page;
+ break;
+ default:
+@@ -13891,7 +13892,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
+ LPFC_RQE_SIZE_8);
+ bf_set(lpfc_rq_context_page_size,
+ &rq_create->u.request.context,
+- (PAGE_SIZE/SLI4_PAGE_SIZE));
++ LPFC_RQ_PAGE_SIZE_4096);
+ } else {
+ switch (hrq->entry_count) {
+ default:
+diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
+index b8d3b97..84addee 100644
+--- a/drivers/scsi/scsi_dh.c
++++ b/drivers/scsi/scsi_dh.c
+@@ -219,20 +219,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
+ }
+ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
+
+-static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
+-{
+- struct scsi_device *sdev;
+- unsigned long flags;
+-
+- spin_lock_irqsave(q->queue_lock, flags);
+- sdev = q->queuedata;
+- if (!sdev || !get_device(&sdev->sdev_gendev))
+- sdev = NULL;
+- spin_unlock_irqrestore(q->queue_lock, flags);
+-
+- return sdev;
+-}
+-
+ /*
+ * scsi_dh_activate - activate the path associated with the scsi_device
+ * corresponding to the given request queue.
+@@ -251,7 +237,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
+ struct scsi_device *sdev;
+ int err = SCSI_DH_NOSYS;
+
+- sdev = get_sdev_from_queue(q);
++ sdev = scsi_device_from_queue(q);
+ if (!sdev) {
+ if (fn)
+ fn(data, err);
+@@ -298,7 +284,7 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
+ struct scsi_device *sdev;
+ int err = -SCSI_DH_NOSYS;
+
+- sdev = get_sdev_from_queue(q);
++ sdev = scsi_device_from_queue(q);
+ if (!sdev)
+ return err;
+
+@@ -321,7 +307,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
+ struct scsi_device_handler *scsi_dh;
+ int err = 0;
+
+- sdev = get_sdev_from_queue(q);
++ sdev = scsi_device_from_queue(q);
+ if (!sdev)
+ return -ENODEV;
+
+@@ -359,7 +345,7 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
+ struct scsi_device *sdev;
+ const char *handler_name = NULL;
+
+- sdev = get_sdev_from_queue(q);
++ sdev = scsi_device_from_queue(q);
+ if (!sdev)
+ return NULL;
+
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index e64eae4..d8099c7 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -2127,6 +2127,29 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
+ blk_mq_free_tag_set(&shost->tag_set);
+ }
+
++/**
++ * scsi_device_from_queue - return sdev associated with a request_queue
++ * @q: The request queue to return the sdev from
++ *
++ * Return the sdev associated with a request queue or NULL if the
++ * request_queue does not reference a SCSI device.
++ */
++struct scsi_device *scsi_device_from_queue(struct request_queue *q)
++{
++ struct scsi_device *sdev = NULL;
++
++ if (q->mq_ops) {
++ if (q->mq_ops == &scsi_mq_ops)
++ sdev = q->queuedata;
++ } else if (q->request_fn == scsi_request_fn)
++ sdev = q->queuedata;
++ if (!sdev || !get_device(&sdev->sdev_gendev))
++ sdev = NULL;
++
++ return sdev;
++}
++EXPORT_SYMBOL_GPL(scsi_device_from_queue);
++
+ /*
+ * Function: scsi_block_requests()
+ *
+diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
+index 8ccfc9e..3f218f5 100644
+--- a/drivers/scsi/storvsc_drv.c
++++ b/drivers/scsi/storvsc_drv.c
+@@ -136,6 +136,8 @@ struct hv_fc_wwn_packet {
+ #define SRB_FLAGS_PORT_DRIVER_RESERVED 0x0F000000
+ #define SRB_FLAGS_CLASS_DRIVER_RESERVED 0xF0000000
+
++#define SP_UNTAGGED ((unsigned char) ~0)
++#define SRB_SIMPLE_TAG_REQUEST 0x20
+
+ /*
+ * Platform neutral description of a scsi request -
+@@ -375,6 +377,7 @@ enum storvsc_request_type {
+ #define SRB_STATUS_SUCCESS 0x01
+ #define SRB_STATUS_ABORTED 0x02
+ #define SRB_STATUS_ERROR 0x04
++#define SRB_STATUS_DATA_OVERRUN 0x12
+
+ #define SRB_STATUS(status) \
+ (status & ~(SRB_STATUS_AUTOSENSE_VALID | SRB_STATUS_QUEUE_FROZEN))
+@@ -889,6 +892,13 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb,
+ switch (SRB_STATUS(vm_srb->srb_status)) {
+ case SRB_STATUS_ERROR:
+ /*
++ * Let upper layer deal with error when
++ * sense message is present.
++ */
++
++ if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID)
++ break;
++ /*
+ * If there is an error; offline the device since all
+ * error recovery strategies would have already been
+ * deployed on the host side. However, if the command
+@@ -953,6 +963,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+ struct scsi_cmnd *scmnd = cmd_request->cmd;
+ struct scsi_sense_hdr sense_hdr;
+ struct vmscsi_request *vm_srb;
++ u32 data_transfer_length;
+ struct Scsi_Host *host;
+ u32 payload_sz = cmd_request->payload_sz;
+ void *payload = cmd_request->payload;
+@@ -960,6 +971,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+ host = stor_dev->host;
+
+ vm_srb = &cmd_request->vstor_packet.vm_srb;
++ data_transfer_length = vm_srb->data_transfer_length;
+
+ scmnd->result = vm_srb->scsi_status;
+
+@@ -973,13 +985,20 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request,
+ &sense_hdr);
+ }
+
+- if (vm_srb->srb_status != SRB_STATUS_SUCCESS)
++ if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
+ storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc,
+ sense_hdr.ascq);
++ /*
++ * The Windows driver set data_transfer_length on
++ * SRB_STATUS_DATA_OVERRUN. On other errors, this value
++ * is untouched. In these cases we set it to 0.
++ */
++ if (vm_srb->srb_status != SRB_STATUS_DATA_OVERRUN)
++ data_transfer_length = 0;
++ }
+
+ scsi_set_resid(scmnd,
+- cmd_request->payload->range.len -
+- vm_srb->data_transfer_length);
++ cmd_request->payload->range.len - data_transfer_length);
+
+ scmnd->scsi_done(scmnd);
+
+@@ -1451,6 +1470,13 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
+ vm_srb->win8_extension.srb_flags |=
+ SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
+
++ if (scmnd->device->tagged_supported) {
++ vm_srb->win8_extension.srb_flags |=
++ (SRB_FLAGS_QUEUE_ACTION_ENABLE | SRB_FLAGS_NO_QUEUE_FREEZE);
++ vm_srb->win8_extension.queue_tag = SP_UNTAGGED;
++ vm_srb->win8_extension.queue_action = SRB_SIMPLE_TAG_REQUEST;
++ }
++
+ /* Build the SRB */
+ switch (scmnd->sc_data_direction) {
+ case DMA_TO_DEVICE:
+diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
+index 3c09e94..186342b 100644
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -1003,7 +1003,7 @@ static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
+ sci->num_cs = temp;
+ }
+
+- sci->no_cs = of_property_read_bool(dev->of_node, "broken-cs");
++ sci->no_cs = of_property_read_bool(dev->of_node, "no-cs-readback");
+
+ return sci;
+ }
+diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
+index 7882306..29dc249 100644
+--- a/drivers/staging/greybus/loopback.c
++++ b/drivers/staging/greybus/loopback.c
+@@ -1051,8 +1051,13 @@ static int gb_loopback_fn(void *data)
+ gb_loopback_calculate_stats(gb, !!error);
+ }
+ gb->send_count++;
+- if (us_wait)
+- udelay(us_wait);
++
++ if (us_wait) {
++ if (us_wait < 20000)
++ usleep_range(us_wait, us_wait + 100);
++ else
++ msleep(us_wait / 1000);
++ }
+ }
+
+ gb_pm_runtime_put_autosuspend(bundle);
+diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
+index f5619d8..0256d65 100644
+--- a/drivers/staging/lustre/lnet/selftest/rpc.c
++++ b/drivers/staging/lustre/lnet/selftest/rpc.c
+@@ -252,7 +252,7 @@ srpc_service_init(struct srpc_service *svc)
+ svc->sv_shuttingdown = 0;
+
+ svc->sv_cpt_data = cfs_percpt_alloc(lnet_cpt_table(),
+- sizeof(*svc->sv_cpt_data));
++ sizeof(**svc->sv_cpt_data));
+ if (!svc->sv_cpt_data)
+ return -ENOMEM;
+
+diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
+index b87cbbb..b39fd1e 100644
+--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
++++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
+@@ -1383,6 +1383,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
+ ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+ }
+
++ if (!ptr)
++ return _FAIL;
++
+ memcpy(ptr, pattrib->dst, ETH_ALEN);
+ memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
+
+diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
+index cbd2e51..cedf25b 100644
+--- a/drivers/staging/rtl8712/rtl871x_recv.c
++++ b/drivers/staging/rtl8712/rtl871x_recv.c
+@@ -643,11 +643,16 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
+ /* append rx status for mp test packets */
+ ptr = recvframe_pull(precvframe, (rmv_len -
+ sizeof(struct ethhdr) + 2) - 24);
++ if (!ptr)
++ return _FAIL;
+ memcpy(ptr, get_rxmem(precvframe), 24);
+ ptr += 24;
+- } else
++ } else {
+ ptr = recvframe_pull(precvframe, (rmv_len -
+ sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
++ if (!ptr)
++ return _FAIL;
++ }
+
+ memcpy(ptr, pattrib->dst, ETH_ALEN);
+ memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index d2b860e..5dc6bfc 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1234,6 +1234,9 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
+ unsigned transfer_in_flight;
+ unsigned started;
+
++ if (dep->flags & DWC3_EP_STALL)
++ return 0;
++
+ if (dep->number > 1)
+ trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue);
+ else
+@@ -1258,6 +1261,8 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
+ else
+ dep->flags |= DWC3_EP_STALL;
+ } else {
++ if (!(dep->flags & DWC3_EP_STALL))
++ return 0;
+
+ ret = dwc3_send_clear_stall_ep_cmd(dep);
+ if (ret)
+diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
+index e2966f8..b0f7195 100644
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -50,12 +50,12 @@ struct f_hidg {
+
+ /* recv report */
+ struct list_head completed_out_req;
+- spinlock_t spinlock;
++ spinlock_t read_spinlock;
+ wait_queue_head_t read_queue;
+ unsigned int qlen;
+
+ /* send report */
+- struct mutex lock;
++ spinlock_t write_spinlock;
+ bool write_pending;
+ wait_queue_head_t write_queue;
+ struct usb_request *req;
+@@ -204,28 +204,35 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
+
+- spin_lock_irqsave(&hidg->spinlock, flags);
++ spin_lock_irqsave(&hidg->read_spinlock, flags);
+
+ #define READ_COND (!list_empty(&hidg->completed_out_req))
+
+ /* wait for at least one buffer to complete */
+ while (!READ_COND) {
+- spin_unlock_irqrestore(&hidg->spinlock, flags);
++ spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ if (wait_event_interruptible(hidg->read_queue, READ_COND))
+ return -ERESTARTSYS;
+
+- spin_lock_irqsave(&hidg->spinlock, flags);
++ spin_lock_irqsave(&hidg->read_spinlock, flags);
+ }
+
+ /* pick the first one */
+ list = list_first_entry(&hidg->completed_out_req,
+ struct f_hidg_req_list, list);
++
++ /*
++ * Remove this from list to protect it from beign free()
++ * while host disables our function
++ */
++ list_del(&list->list);
++
+ req = list->req;
+ count = min_t(unsigned int, count, req->actual - list->pos);
+- spin_unlock_irqrestore(&hidg->spinlock, flags);
++ spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+
+ /* copy to user outside spinlock */
+ count -= copy_to_user(buffer, req->buf + list->pos, count);
+@@ -238,15 +245,20 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+ * call, taking into account its current read position.
+ */
+ if (list->pos == req->actual) {
+- spin_lock_irqsave(&hidg->spinlock, flags);
+- list_del(&list->list);
+ kfree(list);
+- spin_unlock_irqrestore(&hidg->spinlock, flags);
+
+ req->length = hidg->report_length;
+ ret = usb_ep_queue(hidg->out_ep, req, GFP_KERNEL);
+- if (ret < 0)
++ if (ret < 0) {
++ free_ep_req(hidg->out_ep, req);
+ return ret;
++ }
++ } else {
++ spin_lock_irqsave(&hidg->read_spinlock, flags);
++ list_add(&list->list, &hidg->completed_out_req);
++ spin_unlock_irqrestore(&hidg->read_spinlock, flags);
++
++ wake_up(&hidg->read_queue);
+ }
+
+ return count;
+@@ -255,13 +267,16 @@ static ssize_t f_hidg_read(struct file *file, char __user *buffer,
+ static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+ struct f_hidg *hidg = (struct f_hidg *)ep->driver_data;
++ unsigned long flags;
+
+ if (req->status != 0) {
+ ERROR(hidg->func.config->cdev,
+ "End Point Request ERROR: %d\n", req->status);
+ }
+
++ spin_lock_irqsave(&hidg->write_spinlock, flags);
+ hidg->write_pending = 0;
++ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+ wake_up(&hidg->write_queue);
+ }
+
+@@ -269,18 +284,19 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *offp)
+ {
+ struct f_hidg *hidg = file->private_data;
++ unsigned long flags;
+ ssize_t status = -ENOMEM;
+
+ if (!access_ok(VERIFY_READ, buffer, count))
+ return -EFAULT;
+
+- mutex_lock(&hidg->lock);
++ spin_lock_irqsave(&hidg->write_spinlock, flags);
+
+ #define WRITE_COND (!hidg->write_pending)
+
+ /* write queue */
+ while (!WRITE_COND) {
+- mutex_unlock(&hidg->lock);
++ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+@@ -288,17 +304,20 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
+ hidg->write_queue, WRITE_COND))
+ return -ERESTARTSYS;
+
+- mutex_lock(&hidg->lock);
++ spin_lock_irqsave(&hidg->write_spinlock, flags);
+ }
+
++ hidg->write_pending = 1;
+ count = min_t(unsigned, count, hidg->report_length);
++
++ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
+ status = copy_from_user(hidg->req->buf, buffer, count);
+
+ if (status != 0) {
+ ERROR(hidg->func.config->cdev,
+ "copy_from_user error\n");
+- mutex_unlock(&hidg->lock);
+- return -EINVAL;
++ status = -EINVAL;
++ goto release_write_pending;
+ }
+
+ hidg->req->status = 0;
+@@ -306,19 +325,23 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
+ hidg->req->length = count;
+ hidg->req->complete = f_hidg_req_complete;
+ hidg->req->context = hidg;
+- hidg->write_pending = 1;
+
+ status = usb_ep_queue(hidg->in_ep, hidg->req, GFP_ATOMIC);
+ if (status < 0) {
+ ERROR(hidg->func.config->cdev,
+ "usb_ep_queue error on int endpoint %zd\n", status);
+- hidg->write_pending = 0;
+- wake_up(&hidg->write_queue);
++ goto release_write_pending;
+ } else {
+ status = count;
+ }
+
+- mutex_unlock(&hidg->lock);
++ return status;
++release_write_pending:
++ spin_lock_irqsave(&hidg->write_spinlock, flags);
++ hidg->write_pending = 0;
++ spin_unlock_irqrestore(&hidg->write_spinlock, flags);
++
++ wake_up(&hidg->write_queue);
+
+ return status;
+ }
+@@ -371,20 +394,36 @@ static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
+ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
+ {
+ struct f_hidg *hidg = (struct f_hidg *) req->context;
++ struct usb_composite_dev *cdev = hidg->func.config->cdev;
+ struct f_hidg_req_list *req_list;
+ unsigned long flags;
+
+- req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
+- if (!req_list)
+- return;
++ switch (req->status) {
++ case 0:
++ req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
++ if (!req_list) {
++ ERROR(cdev, "Unable to allocate mem for req_list\n");
++ goto free_req;
++ }
+
+- req_list->req = req;
++ req_list->req = req;
+
+- spin_lock_irqsave(&hidg->spinlock, flags);
+- list_add_tail(&req_list->list, &hidg->completed_out_req);
+- spin_unlock_irqrestore(&hidg->spinlock, flags);
++ spin_lock_irqsave(&hidg->read_spinlock, flags);
++ list_add_tail(&req_list->list, &hidg->completed_out_req);
++ spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+
+- wake_up(&hidg->read_queue);
++ wake_up(&hidg->read_queue);
++ break;
++ default:
++ ERROR(cdev, "Set report failed %d\n", req->status);
++ /* FALLTHROUGH */
++ case -ECONNABORTED: /* hardware forced ep reset */
++ case -ECONNRESET: /* request dequeued */
++ case -ESHUTDOWN: /* disconnect from host */
++free_req:
++ free_ep_req(ep, req);
++ return;
++ }
+ }
+
+ static int hidg_setup(struct usb_function *f,
+@@ -490,14 +529,18 @@ static void hidg_disable(struct usb_function *f)
+ {
+ struct f_hidg *hidg = func_to_hidg(f);
+ struct f_hidg_req_list *list, *next;
++ unsigned long flags;
+
+ usb_ep_disable(hidg->in_ep);
+ usb_ep_disable(hidg->out_ep);
+
++ spin_lock_irqsave(&hidg->read_spinlock, flags);
+ list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) {
++ free_ep_req(hidg->out_ep, list->req);
+ list_del(&list->list);
+ kfree(list);
+ }
++ spin_unlock_irqrestore(&hidg->read_spinlock, flags);
+ }
+
+ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+@@ -646,8 +689,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
+ if (status)
+ goto fail;
+
+- mutex_init(&hidg->lock);
+- spin_lock_init(&hidg->spinlock);
++ spin_lock_init(&hidg->write_spinlock);
++ spin_lock_init(&hidg->read_spinlock);
+ init_waitqueue_head(&hidg->write_queue);
+ init_waitqueue_head(&hidg->read_queue);
+ INIT_LIST_HEAD(&hidg->completed_out_req);
+diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
+index 0402177..d685d82 100644
+--- a/drivers/usb/gadget/udc/core.c
++++ b/drivers/usb/gadget/udc/core.c
+@@ -1080,6 +1080,24 @@ static void usb_udc_nop_release(struct device *dev)
+ dev_vdbg(dev, "%s\n", __func__);
+ }
+
++/* should be called with udc_lock held */
++static int check_pending_gadget_drivers(struct usb_udc *udc)
++{
++ struct usb_gadget_driver *driver;
++ int ret = 0;
++
++ list_for_each_entry(driver, &gadget_driver_pending_list, pending)
++ if (!driver->udc_name || strcmp(driver->udc_name,
++ dev_name(&udc->dev)) == 0) {
++ ret = udc_bind_to_driver(udc, driver);
++ if (ret != -EPROBE_DEFER)
++ list_del(&driver->pending);
++ break;
++ }
++
++ return ret;
++}
++
+ /**
+ * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
+ * @parent: the parent device to this udc. Usually the controller driver's
+@@ -1093,7 +1111,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
+ void (*release)(struct device *dev))
+ {
+ struct usb_udc *udc;
+- struct usb_gadget_driver *driver;
+ int ret = -ENOMEM;
+
+ udc = kzalloc(sizeof(*udc), GFP_KERNEL);
+@@ -1136,17 +1153,9 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
+ udc->vbus = true;
+
+ /* pick up one of pending gadget drivers */
+- list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
+- if (!driver->udc_name || strcmp(driver->udc_name,
+- dev_name(&udc->dev)) == 0) {
+- ret = udc_bind_to_driver(udc, driver);
+- if (ret != -EPROBE_DEFER)
+- list_del(&driver->pending);
+- if (ret)
+- goto err5;
+- break;
+- }
+- }
++ ret = check_pending_gadget_drivers(udc);
++ if (ret)
++ goto err5;
+
+ mutex_unlock(&udc_lock);
+
+@@ -1356,14 +1365,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ return -EINVAL;
+
+ mutex_lock(&udc_lock);
+- list_for_each_entry(udc, &udc_list, list)
++ list_for_each_entry(udc, &udc_list, list) {
+ if (udc->driver == driver) {
+ usb_gadget_remove_driver(udc);
+ usb_gadget_set_state(udc->gadget,
+- USB_STATE_NOTATTACHED);
++ USB_STATE_NOTATTACHED);
++
++ /* Maybe there is someone waiting for this UDC? */
++ check_pending_gadget_drivers(udc);
++ /*
++ * For now we ignore bind errors as probably it's
++ * not a valid reason to fail other's gadget unbind
++ */
+ ret = 0;
+ break;
+ }
++ }
+
+ if (ret) {
+ list_del(&driver->pending);
+diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c
+index aab5221..aac0ce8 100644
+--- a/drivers/usb/gadget/udc/fsl_udc_core.c
++++ b/drivers/usb/gadget/udc/fsl_udc_core.c
+@@ -1249,6 +1249,12 @@ static const struct usb_gadget_ops fsl_gadget_ops = {
+ .udc_stop = fsl_udc_stop,
+ };
+
++/*
++ * Empty complete function used by this driver to fill in the req->complete
++ * field when creating a request since the complete field is mandatory.
++ */
++static void fsl_noop_complete(struct usb_ep *ep, struct usb_request *req) { }
++
+ /* Set protocol stall on ep0, protocol stall will automatically be cleared
+ on new transaction */
+ static void ep0stall(struct fsl_udc *udc)
+@@ -1283,7 +1289,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
+ req->req.length = 0;
+ req->req.status = -EINPROGRESS;
+ req->req.actual = 0;
+- req->req.complete = NULL;
++ req->req.complete = fsl_noop_complete;
+ req->dtd_count = 0;
+
+ ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
+@@ -1366,7 +1372,7 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
+ req->req.length = 2;
+ req->req.status = -EINPROGRESS;
+ req->req.actual = 0;
+- req->req.complete = NULL;
++ req->req.complete = fsl_noop_complete;
+ req->dtd_count = 0;
+
+ ret = usb_gadget_map_request(&ep->udc->gadget, &req->req, ep_is_in(ep));
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index ed56bf9..abe3606 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -223,9 +223,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable"))
+ xhci->quirks |= XHCI_LPM_SUPPORT;
+
+- if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+- xhci->shared_hcd->can_do_streams = 1;
+-
+ hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0);
+ if (IS_ERR(hcd->usb_phy)) {
+ ret = PTR_ERR(hcd->usb_phy);
+@@ -242,6 +239,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ if (ret)
+ goto disable_usb_phy;
+
++ if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
++ xhci->shared_hcd->can_do_streams = 1;
++
+ ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+ if (ret)
+ goto dealloc_usb2_hcd;
+diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c
+index 2440f88..bacee0f 100644
+--- a/drivers/usb/musb/da8xx.c
++++ b/drivers/usb/musb/da8xx.c
+@@ -434,15 +434,11 @@ static int da8xx_musb_exit(struct musb *musb)
+ }
+
+ static const struct musb_platform_ops da8xx_ops = {
+- .quirks = MUSB_DMA_CPPI | MUSB_INDEXED_EP,
++ .quirks = MUSB_INDEXED_EP,
+ .init = da8xx_musb_init,
+ .exit = da8xx_musb_exit,
+
+ .fifo_mode = 2,
+-#ifdef CONFIG_USB_TI_CPPI_DMA
+- .dma_init = cppi_dma_controller_create,
+- .dma_exit = cppi_dma_controller_destroy,
+-#endif
+ .enable = da8xx_musb_enable,
+ .disable = da8xx_musb_disable,
+
+diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
+index 181793f..9d2738e 100644
+--- a/drivers/virtio/virtio_balloon.c
++++ b/drivers/virtio/virtio_balloon.c
+@@ -615,8 +615,12 @@ static void virtballoon_remove(struct virtio_device *vdev)
+ cancel_work_sync(&vb->update_balloon_stats_work);
+
+ remove_common(vb);
++#ifdef CONFIG_BALLOON_COMPACTION
+ if (vb->vb_dev_info.inode)
+ iput(vb->vb_dev_info.inode);
++
++ kern_unmount(balloon_mnt);
++#endif
+ kfree(vb);
+ }
+
+diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c
+index bdbadaa..0035cf7 100644
+--- a/drivers/vme/vme.c
++++ b/drivers/vme/vme.c
+@@ -1625,10 +1625,25 @@ static int vme_bus_probe(struct device *dev)
+ return retval;
+ }
+
++static int vme_bus_remove(struct device *dev)
++{
++ int retval = -ENODEV;
++ struct vme_driver *driver;
++ struct vme_dev *vdev = dev_to_vme_dev(dev);
++
++ driver = dev->platform_data;
++
++ if (driver->remove != NULL)
++ retval = driver->remove(vdev);
++
++ return retval;
++}
++
+ struct bus_type vme_bus_type = {
+ .name = "vme",
+ .match = vme_bus_match,
+ .probe = vme_bus_probe,
++ .remove = vme_bus_remove,
+ };
+ EXPORT_SYMBOL(vme_bus_type);
+
+diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
+index 049a884..59d74d1 100644
+--- a/drivers/w1/masters/ds2490.c
++++ b/drivers/w1/masters/ds2490.c
+@@ -153,6 +153,9 @@ struct ds_device
+ */
+ u16 spu_bit;
+
++ u8 st_buf[ST_SIZE];
++ u8 byte_buf;
++
+ struct w1_bus_master master;
+ };
+
+@@ -174,7 +177,6 @@ struct ds_status
+ u8 data_in_buffer_status;
+ u8 reserved1;
+ u8 reserved2;
+-
+ };
+
+ static struct usb_device_id ds_id_table [] = {
+@@ -244,28 +246,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
+ return err;
+ }
+
+-static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
+- unsigned char *buf, int size)
+-{
+- int count, err;
+-
+- memset(st, 0, sizeof(*st));
+-
+- count = 0;
+- err = usb_interrupt_msg(dev->udev, usb_rcvintpipe(dev->udev,
+- dev->ep[EP_STATUS]), buf, size, &count, 1000);
+- if (err < 0) {
+- pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
+- dev->ep[EP_STATUS], err);
+- return err;
+- }
+-
+- if (count >= sizeof(*st))
+- memcpy(st, buf, sizeof(*st));
+-
+- return count;
+-}
+-
+ static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
+ {
+ pr_info("%45s: %8x\n", str, buf[off]);
+@@ -324,6 +304,35 @@ static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+ }
+ }
+
++static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
++ bool dump)
++{
++ int count, err;
++
++ if (st)
++ memset(st, 0, sizeof(*st));
++
++ count = 0;
++ err = usb_interrupt_msg(dev->udev,
++ usb_rcvintpipe(dev->udev,
++ dev->ep[EP_STATUS]),
++ dev->st_buf, sizeof(dev->st_buf),
++ &count, 1000);
++ if (err < 0) {
++ pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
++ dev->ep[EP_STATUS], err);
++ return err;
++ }
++
++ if (dump)
++ ds_dump_status(dev, dev->st_buf, count);
++
++ if (st && count >= sizeof(*st))
++ memcpy(st, dev->st_buf, sizeof(*st));
++
++ return count;
++}
++
+ static void ds_reset_device(struct ds_device *dev)
+ {
+ ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+@@ -344,7 +353,6 @@ static void ds_reset_device(struct ds_device *dev)
+ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+ {
+ int count, err;
+- struct ds_status st;
+
+ /* Careful on size. If size is less than what is available in
+ * the input buffer, the device fails the bulk transfer and
+@@ -359,14 +367,9 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
+ err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
+ buf, size, &count, 1000);
+ if (err < 0) {
+- u8 buf[ST_SIZE];
+- int count;
+-
+ pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
+ usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
+-
+- count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
+- ds_dump_status(dev, buf, count);
++ ds_recv_status(dev, NULL, true);
+ return err;
+ }
+
+@@ -404,7 +407,6 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
+ {
+ struct ds_status st;
+ int count = 0, err = 0;
+- u8 buf[ST_SIZE];
+
+ do {
+ err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
+@@ -413,7 +415,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
+ err = ds_send_control(dev, CTL_RESUME_EXE, 0);
+ if (err)
+ break;
+- err = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
++ err = ds_recv_status(dev, &st, false);
+ if (err)
+ break;
+
+@@ -456,18 +458,17 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
+
+ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+ {
+- u8 buf[ST_SIZE];
+ int err, count = 0;
+
+ do {
+ st->status = 0;
+- err = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
++ err = ds_recv_status(dev, st, false);
+ #if 0
+ if (err >= 0) {
+ int i;
+ printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
+ for (i=0; i<err; ++i)
+- printk("%02x ", buf[i]);
++ printk("%02x ", dev->st_buf[i]);
+ printk("\n");
+ }
+ #endif
+@@ -485,7 +486,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
+ * can do something with it).
+ */
+ if (err > 16 || count >= 100 || err < 0)
+- ds_dump_status(dev, buf, err);
++ ds_dump_status(dev, dev->st_buf, err);
+
+ /* Extended data isn't an error. Well, a short is, but the dump
+ * would have already told the user that and we can't do anything
+@@ -608,7 +609,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
+ {
+ int err;
+ struct ds_status st;
+- u8 rbyte;
+
+ err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
+ if (err)
+@@ -621,11 +621,11 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
+ if (err)
+ return err;
+
+- err = ds_recv_data(dev, &rbyte, sizeof(rbyte));
++ err = ds_recv_data(dev, &dev->byte_buf, 1);
+ if (err < 0)
+ return err;
+
+- return !(byte == rbyte);
++ return !(byte == dev->byte_buf);
+ }
+
+ static int ds_read_byte(struct ds_device *dev, u8 *byte)
+@@ -712,7 +712,6 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ int err;
+ u16 value, index;
+ struct ds_status st;
+- u8 st_buf[ST_SIZE];
+ int search_limit;
+ int found = 0;
+ int i;
+@@ -724,7 +723,12 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ /* FIFO 128 bytes, bulk packet size 64, read a multiple of the
+ * packet size.
+ */
+- u64 buf[2*64/8];
++ const size_t bufsize = 2 * 64;
++ u64 *buf;
++
++ buf = kmalloc(bufsize, GFP_KERNEL);
++ if (!buf)
++ return;
+
+ mutex_lock(&master->bus_mutex);
+
+@@ -745,10 +749,9 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ do {
+ schedule_timeout(jtime);
+
+- if (ds_recv_status_nodump(dev, &st, st_buf, sizeof(st_buf)) <
+- sizeof(st)) {
++ err = ds_recv_status(dev, &st, false);
++ if (err < 0 || err < sizeof(st))
+ break;
+- }
+
+ if (st.data_in_buffer_status) {
+ /* Bulk in can receive partial ids, but when it does
+@@ -758,7 +761,7 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ * bulk without first checking if status says there
+ * is data to read.
+ */
+- err = ds_recv_data(dev, (u8 *)buf, sizeof(buf));
++ err = ds_recv_data(dev, (u8 *)buf, bufsize);
+ if (err < 0)
+ break;
+ for (i = 0; i < err/8; ++i) {
+@@ -794,9 +797,14 @@ static void ds9490r_search(void *data, struct w1_master *master,
+ }
+ search_out:
+ mutex_unlock(&master->bus_mutex);
++ kfree(buf);
+ }
+
+ #if 0
++/*
++ * FIXME: if this disabled code is ever used in the future all ds_send_data()
++ * calls must be changed to use a DMAable buffer.
++ */
+ static int ds_match_access(struct ds_device *dev, u64 init)
+ {
+ int err;
+@@ -845,13 +853,12 @@ static int ds_set_path(struct ds_device *dev, u64 init)
+
+ static u8 ds9490r_touch_bit(void *data, u8 bit)
+ {
+- u8 ret;
+ struct ds_device *dev = data;
+
+- if (ds_touch_bit(dev, bit, &ret))
++ if (ds_touch_bit(dev, bit, &dev->byte_buf))
+ return 0;
+
+- return ret;
++ return dev->byte_buf;
+ }
+
+ #if 0
+@@ -866,13 +873,12 @@ static u8 ds9490r_read_bit(void *data)
+ {
+ struct ds_device *dev = data;
+ int err;
+- u8 bit = 0;
+
+- err = ds_touch_bit(dev, 1, &bit);
++ err = ds_touch_bit(dev, 1, &dev->byte_buf);
+ if (err)
+ return 0;
+
+- return bit & 1;
++ return dev->byte_buf & 1;
+ }
+ #endif
+
+@@ -887,32 +893,52 @@ static u8 ds9490r_read_byte(void *data)
+ {
+ struct ds_device *dev = data;
+ int err;
+- u8 byte = 0;
+
+- err = ds_read_byte(dev, &byte);
++ err = ds_read_byte(dev, &dev->byte_buf);
+ if (err)
+ return 0;
+
+- return byte;
++ return dev->byte_buf;
+ }
+
+ static void ds9490r_write_block(void *data, const u8 *buf, int len)
+ {
+ struct ds_device *dev = data;
++ u8 *tbuf;
++
++ if (len <= 0)
++ return;
++
++ tbuf = kmalloc(len, GFP_KERNEL);
++ if (!tbuf)
++ return;
+
+- ds_write_block(dev, (u8 *)buf, len);
++ memcpy(tbuf, buf, len);
++ ds_write_block(dev, tbuf, len);
++
++ kfree(tbuf);
+ }
+
+ static u8 ds9490r_read_block(void *data, u8 *buf, int len)
+ {
+ struct ds_device *dev = data;
+ int err;
++ u8 *tbuf;
+
+- err = ds_read_block(dev, buf, len);
+- if (err < 0)
++ if (len <= 0)
++ return 0;
++
++ tbuf = kmalloc(len, GFP_KERNEL);
++ if (!tbuf)
+ return 0;
+
+- return len;
++ err = ds_read_block(dev, tbuf, len);
++ if (err >= 0)
++ memcpy(buf, tbuf, len);
++
++ kfree(tbuf);
++
++ return err >= 0 ? len : 0;
+ }
+
+ static u8 ds9490r_reset(void *data)
+diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
+index e213c67..ab0931e 100644
+--- a/drivers/w1/w1.c
++++ b/drivers/w1/w1.c
+@@ -763,6 +763,7 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
+ dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__,
+ sl->name);
+ w1_family_put(sl->family);
++ atomic_dec(&sl->master->refcnt);
+ kfree(sl);
+ return err;
+ }
+diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
+index ef3ebd7..1e643c7 100644
+--- a/fs/ceph/addr.c
++++ b/fs/ceph/addr.c
+@@ -363,6 +363,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
+ nr_pages = i;
+ if (nr_pages > 0) {
+ len = nr_pages << PAGE_SHIFT;
++ osd_req_op_extent_update(req, 0, len);
+ break;
+ }
+ goto out_pages;
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 18a1e1d..1cd0e2e 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -2884,7 +2884,15 @@ cifs_readdata_to_iov(struct cifs_readdata *rdata, struct iov_iter *iter)
+ for (i = 0; i < rdata->nr_pages; i++) {
+ struct page *page = rdata->pages[i];
+ size_t copy = min_t(size_t, remaining, PAGE_SIZE);
+- size_t written = copy_page_to_iter(page, 0, copy, iter);
++ size_t written;
++
++ if (unlikely(iter->type & ITER_PIPE)) {
++ void *addr = kmap_atomic(page);
++
++ written = copy_to_iter(addr, copy, iter);
++ kunmap_atomic(addr);
++ } else
++ written = copy_page_to_iter(page, 0, copy, iter);
+ remaining -= written;
+ if (written < copy && iov_iter_count(iter) > 0)
+ break;
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index c930a01..9fbf92c 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5344,7 +5344,8 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ ext4_lblk_t stop, *iterator, ex_start, ex_end;
+
+ /* Let path point to the last extent */
+- path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, 0);
++ path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL,
++ EXT4_EX_NOCACHE);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+
+@@ -5353,15 +5354,15 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ if (!extent)
+ goto out;
+
+- stop = le32_to_cpu(extent->ee_block) +
+- ext4_ext_get_actual_len(extent);
++ stop = le32_to_cpu(extent->ee_block);
+
+ /*
+ * In case of left shift, Don't start shifting extents until we make
+ * sure the hole is big enough to accommodate the shift.
+ */
+ if (SHIFT == SHIFT_LEFT) {
+- path = ext4_find_extent(inode, start - 1, &path, 0);
++ path = ext4_find_extent(inode, start - 1, &path,
++ EXT4_EX_NOCACHE);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+ depth = path->p_depth;
+@@ -5393,9 +5394,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ else
+ iterator = &stop;
+
+- /* Its safe to start updating extents */
+- while (start < stop) {
+- path = ext4_find_extent(inode, *iterator, &path, 0);
++ /*
++ * Its safe to start updating extents. Start and stop are unsigned, so
++ * in case of right shift if extent with 0 block is reached, iterator
++ * becomes NULL to indicate the end of the loop.
++ */
++ while (iterator && start <= stop) {
++ path = ext4_find_extent(inode, *iterator, &path,
++ EXT4_EX_NOCACHE);
+ if (IS_ERR(path))
+ return PTR_ERR(path);
+ depth = path->p_depth;
+@@ -5422,8 +5428,11 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
+ ext4_ext_get_actual_len(extent);
+ } else {
+ extent = EXT_FIRST_EXTENT(path[depth].p_hdr);
+- *iterator = le32_to_cpu(extent->ee_block) > 0 ?
+- le32_to_cpu(extent->ee_block) - 1 : 0;
++ if (le32_to_cpu(extent->ee_block) > 0)
++ *iterator = le32_to_cpu(extent->ee_block) - 1;
++ else
++ /* Beginning is reached, end of the loop */
++ iterator = NULL;
+ /* Update path extent in case we need to stop */
+ while (le32_to_cpu(extent->ee_block) < start)
+ extent++;
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index d8ca4b9..37b521e 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -376,7 +376,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
+ static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
+ unsigned int len)
+ {
+- int ret, size;
++ int ret, size, no_expand;
+ struct ext4_inode_info *ei = EXT4_I(inode);
+
+ if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
+@@ -386,15 +386,14 @@ static int ext4_prepare_inline_data(handle_t *handle, struct inode *inode,
+ if (size < len)
+ return -ENOSPC;
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+
+ if (ei->i_inline_off)
+ ret = ext4_update_inline_data(handle, inode, len);
+ else
+ ret = ext4_create_inline_data(handle, inode, len);
+
+- up_write(&EXT4_I(inode)->xattr_sem);
+-
++ ext4_write_unlock_xattr(inode, &no_expand);
+ return ret;
+ }
+
+@@ -523,7 +522,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
+ struct inode *inode,
+ unsigned flags)
+ {
+- int ret, needed_blocks;
++ int ret, needed_blocks, no_expand;
+ handle_t *handle = NULL;
+ int retries = 0, sem_held = 0;
+ struct page *page = NULL;
+@@ -563,7 +562,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
+ goto out;
+ }
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+ sem_held = 1;
+ /* If some one has already done this for us, just exit. */
+ if (!ext4_has_inline_data(inode)) {
+@@ -600,7 +599,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
+ put_page(page);
+ page = NULL;
+ ext4_orphan_add(handle, inode);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ sem_held = 0;
+ ext4_journal_stop(handle);
+ handle = NULL;
+@@ -626,7 +625,7 @@ static int ext4_convert_inline_data_to_extent(struct address_space *mapping,
+ put_page(page);
+ }
+ if (sem_held)
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ if (handle)
+ ext4_journal_stop(handle);
+ brelse(iloc.bh);
+@@ -719,7 +718,7 @@ int ext4_try_to_write_inline_data(struct address_space *mapping,
+ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
+ unsigned copied, struct page *page)
+ {
+- int ret;
++ int ret, no_expand;
+ void *kaddr;
+ struct ext4_iloc iloc;
+
+@@ -737,7 +736,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
+ goto out;
+ }
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+ BUG_ON(!ext4_has_inline_data(inode));
+
+ kaddr = kmap_atomic(page);
+@@ -747,7 +746,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
+ /* clear page dirty so that writepages wouldn't work for us. */
+ ClearPageDirty(page);
+
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ brelse(iloc.bh);
+ out:
+ return copied;
+@@ -758,7 +757,7 @@ ext4_journalled_write_inline_data(struct inode *inode,
+ unsigned len,
+ struct page *page)
+ {
+- int ret;
++ int ret, no_expand;
+ void *kaddr;
+ struct ext4_iloc iloc;
+
+@@ -768,11 +767,11 @@ ext4_journalled_write_inline_data(struct inode *inode,
+ return NULL;
+ }
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+ kaddr = kmap_atomic(page);
+ ext4_write_inline_data(inode, &iloc, kaddr, 0, len);
+ kunmap_atomic(kaddr);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+
+ return iloc.bh;
+ }
+@@ -934,8 +933,15 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
+ struct page *page)
+ {
+ int i_size_changed = 0;
++ int ret;
+
+- copied = ext4_write_inline_data_end(inode, pos, len, copied, page);
++ ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
++ if (ret < 0) {
++ unlock_page(page);
++ put_page(page);
++ return ret;
++ }
++ copied = ret;
+
+ /*
+ * No need to use i_size_read() here, the i_size
+@@ -1249,7 +1255,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
+ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
+ struct inode *dir, struct inode *inode)
+ {
+- int ret, inline_size;
++ int ret, inline_size, no_expand;
+ void *inline_start;
+ struct ext4_iloc iloc;
+
+@@ -1257,7 +1263,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
+ if (ret)
+ return ret;
+
+- down_write(&EXT4_I(dir)->xattr_sem);
++ ext4_write_lock_xattr(dir, &no_expand);
+ if (!ext4_has_inline_data(dir))
+ goto out;
+
+@@ -1303,7 +1309,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
+
+ out:
+ ext4_mark_inode_dirty(handle, dir);
+- up_write(&EXT4_I(dir)->xattr_sem);
++ ext4_write_unlock_xattr(dir, &no_expand);
+ brelse(iloc.bh);
+ return ret;
+ }
+@@ -1663,7 +1669,7 @@ int ext4_delete_inline_entry(handle_t *handle,
+ struct buffer_head *bh,
+ int *has_inline_data)
+ {
+- int err, inline_size;
++ int err, inline_size, no_expand;
+ struct ext4_iloc iloc;
+ void *inline_start;
+
+@@ -1671,7 +1677,7 @@ int ext4_delete_inline_entry(handle_t *handle,
+ if (err)
+ return err;
+
+- down_write(&EXT4_I(dir)->xattr_sem);
++ ext4_write_lock_xattr(dir, &no_expand);
+ if (!ext4_has_inline_data(dir)) {
+ *has_inline_data = 0;
+ goto out;
+@@ -1705,7 +1711,7 @@ int ext4_delete_inline_entry(handle_t *handle,
+
+ ext4_show_inline_dir(dir, iloc.bh, inline_start, inline_size);
+ out:
+- up_write(&EXT4_I(dir)->xattr_sem);
++ ext4_write_unlock_xattr(dir, &no_expand);
+ brelse(iloc.bh);
+ if (err != -ENOENT)
+ ext4_std_error(dir->i_sb, err);
+@@ -1804,11 +1810,11 @@ bool empty_inline_dir(struct inode *dir, int *has_inline_data)
+
+ int ext4_destroy_inline_data(handle_t *handle, struct inode *inode)
+ {
+- int ret;
++ int ret, no_expand;
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+ ret = ext4_destroy_inline_data_nolock(handle, inode);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+
+ return ret;
+ }
+@@ -1893,7 +1899,7 @@ int ext4_try_to_evict_inline_data(handle_t *handle,
+ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+ {
+ handle_t *handle;
+- int inline_size, value_len, needed_blocks;
++ int inline_size, value_len, needed_blocks, no_expand;
+ size_t i_size;
+ void *value = NULL;
+ struct ext4_xattr_ibody_find is = {
+@@ -1910,7 +1916,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+ if (IS_ERR(handle))
+ return;
+
+- down_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_lock_xattr(inode, &no_expand);
+ if (!ext4_has_inline_data(inode)) {
+ *has_inline = 0;
+ ext4_journal_stop(handle);
+@@ -1968,7 +1974,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+ up_write(&EXT4_I(inode)->i_data_sem);
+ out:
+ brelse(is.iloc.bh);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ kfree(value);
+ if (inode->i_nlink)
+ ext4_orphan_del(handle, inode);
+@@ -1984,7 +1990,7 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+
+ int ext4_convert_inline_data(struct inode *inode)
+ {
+- int error, needed_blocks;
++ int error, needed_blocks, no_expand;
+ handle_t *handle;
+ struct ext4_iloc iloc;
+
+@@ -2006,15 +2012,10 @@ int ext4_convert_inline_data(struct inode *inode)
+ goto out_free;
+ }
+
+- down_write(&EXT4_I(inode)->xattr_sem);
+- if (!ext4_has_inline_data(inode)) {
+- up_write(&EXT4_I(inode)->xattr_sem);
+- goto out;
+- }
+-
+- error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
+- up_write(&EXT4_I(inode)->xattr_sem);
+-out:
++ ext4_write_lock_xattr(inode, &no_expand);
++ if (ext4_has_inline_data(inode))
++ error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ ext4_journal_stop(handle);
+ out_free:
+ brelse(iloc.bh);
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 33a509c..1d4f5fa 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -1324,8 +1324,11 @@ static int ext4_write_end(struct file *file,
+ if (ext4_has_inline_data(inode)) {
+ ret = ext4_write_inline_data_end(inode, pos, len,
+ copied, page);
+- if (ret < 0)
++ if (ret < 0) {
++ unlock_page(page);
++ put_page(page);
+ goto errout;
++ }
+ copied = ret;
+ } else
+ copied = block_write_end(file, mapping, pos,
+@@ -1379,7 +1382,9 @@ static int ext4_write_end(struct file *file,
+ * set the buffer to be dirty, since in data=journalled mode we need
+ * to call ext4_handle_dirty_metadata() instead.
+ */
+-static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
++static void ext4_journalled_zero_new_buffers(handle_t *handle,
++ struct page *page,
++ unsigned from, unsigned to)
+ {
+ unsigned int block_start = 0, block_end;
+ struct buffer_head *head, *bh;
+@@ -1396,7 +1401,7 @@ static void zero_new_buffers(struct page *page, unsigned from, unsigned to)
+ size = min(to, block_end) - start;
+
+ zero_user(page, start, size);
+- set_buffer_uptodate(bh);
++ write_end_fn(handle, bh);
+ }
+ clear_buffer_new(bh);
+ }
+@@ -1425,18 +1430,25 @@ static int ext4_journalled_write_end(struct file *file,
+
+ BUG_ON(!ext4_handle_valid(handle));
+
+- if (ext4_has_inline_data(inode))
+- copied = ext4_write_inline_data_end(inode, pos, len,
+- copied, page);
+- else {
+- if (copied < len) {
+- if (!PageUptodate(page))
+- copied = 0;
+- zero_new_buffers(page, from+copied, to);
++ if (ext4_has_inline_data(inode)) {
++ ret = ext4_write_inline_data_end(inode, pos, len,
++ copied, page);
++ if (ret < 0) {
++ unlock_page(page);
++ put_page(page);
++ goto errout;
+ }
+-
++ copied = ret;
++ } else if (unlikely(copied < len) && !PageUptodate(page)) {
++ copied = 0;
++ ext4_journalled_zero_new_buffers(handle, page, from, to);
++ } else {
++ if (unlikely(copied < len))
++ ext4_journalled_zero_new_buffers(handle, page,
++ from + copied, to);
+ ret = ext4_walk_page_buffers(handle, page_buffers(page), from,
+- to, &partial, write_end_fn);
++ from + copied, &partial,
++ write_end_fn);
+ if (!partial)
+ SetPageUptodate(page);
+ }
+@@ -1462,6 +1474,7 @@ static int ext4_journalled_write_end(struct file *file,
+ */
+ ext4_orphan_add(handle, inode);
+
++errout:
+ ret2 = ext4_journal_stop(handle);
+ if (!ret)
+ ret = ret2;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 7ae43c5..2e9fc7a 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -3123,6 +3123,13 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
+ if (ar->pright && start + size - 1 >= ar->lright)
+ size -= start + size - ar->lright;
+
++ /*
++ * Trim allocation request for filesystems with artificially small
++ * groups.
++ */
++ if (size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb))
++ size = EXT4_BLOCKS_PER_GROUP(ac->ac_sb);
++
+ end = start + size;
+
+ /* check we don't cross already preallocated blocks */
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 104f8bf..c4a389a 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -1616,13 +1616,15 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
+ !fscrypt_has_permitted_context(dir, inode)) {
+ int nokey = ext4_encrypted_inode(inode) &&
+ !fscrypt_has_encryption_key(inode);
+- iput(inode);
+- if (nokey)
++ if (nokey) {
++ iput(inode);
+ return ERR_PTR(-ENOKEY);
++ }
+ ext4_warning(inode->i_sb,
+ "Inconsistent encryption contexts: %lu/%lu",
+ (unsigned long) dir->i_ino,
+ (unsigned long) inode->i_ino);
++ iput(inode);
+ return ERR_PTR(-EPERM);
+ }
+ }
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index bbc316d..afe29ba 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -825,6 +825,7 @@ static void ext4_put_super(struct super_block *sb)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ struct ext4_super_block *es = sbi->s_es;
++ int aborted = 0;
+ int i, err;
+
+ ext4_unregister_li_request(sb);
+@@ -834,9 +835,10 @@ static void ext4_put_super(struct super_block *sb)
+ destroy_workqueue(sbi->rsv_conversion_wq);
+
+ if (sbi->s_journal) {
++ aborted = is_journal_aborted(sbi->s_journal);
+ err = jbd2_journal_destroy(sbi->s_journal);
+ sbi->s_journal = NULL;
+- if (err < 0)
++ if ((err < 0) && !aborted)
+ ext4_abort(sb, "Couldn't clean up the journal");
+ }
+
+@@ -847,7 +849,7 @@ static void ext4_put_super(struct super_block *sb)
+ ext4_mb_release(sb);
+ ext4_ext_release(sb);
+
+- if (!(sb->s_flags & MS_RDONLY)) {
++ if (!(sb->s_flags & MS_RDONLY) && !aborted) {
+ ext4_clear_feature_journal_needs_recovery(sb);
+ es->s_state = cpu_to_le16(sbi->s_mount_state);
+ }
+@@ -3911,7 +3913,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ * root first: it may be modified in the journal!
+ */
+ if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) {
+- if (ext4_load_journal(sb, es, journal_devnum))
++ err = ext4_load_journal(sb, es, journal_devnum);
++ if (err)
+ goto failed_mount3a;
+ } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
+ ext4_has_feature_journal_needs_recovery(sb)) {
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index d77be9e..4448ed3 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1174,16 +1174,14 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ struct ext4_xattr_block_find bs = {
+ .s = { .not_found = -ENODATA, },
+ };
+- unsigned long no_expand;
++ int no_expand;
+ int error;
+
+ if (!name)
+ return -EINVAL;
+ if (strlen(name) > 255)
+ return -ERANGE;
+- down_write(&EXT4_I(inode)->xattr_sem);
+- no_expand = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
+- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ ext4_write_lock_xattr(inode, &no_expand);
+
+ error = ext4_reserve_inode_write(handle, inode, &is.iloc);
+ if (error)
+@@ -1251,7 +1249,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ ext4_xattr_update_super_block(handle, inode->i_sb);
+ inode->i_ctime = ext4_current_time(inode);
+ if (!value)
+- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ no_expand = 0;
+ error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
+ /*
+ * The bh is consumed by ext4_mark_iloc_dirty, even with
+@@ -1265,9 +1263,7 @@ ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+- if (no_expand == 0)
+- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
+
+@@ -1484,12 +1480,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
+ int error = 0, tried_min_extra_isize = 0;
+ int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
+ int isize_diff; /* How much do we need to grow i_extra_isize */
++ int no_expand;
++
++ if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
++ return 0;
+
+- down_write(&EXT4_I(inode)->xattr_sem);
+- /*
+- * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
+- */
+- ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ retry:
+ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
+ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
+@@ -1571,17 +1566,16 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
+ EXT4_I(inode)->i_extra_isize = new_extra_isize;
+ brelse(bh);
+ out:
+- ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
+- up_write(&EXT4_I(inode)->xattr_sem);
++ ext4_write_unlock_xattr(inode, &no_expand);
+ return 0;
+
+ cleanup:
+ brelse(bh);
+ /*
+- * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
+- * size expansion failed.
++ * Inode size expansion failed; don't try again
+ */
+- up_write(&EXT4_I(inode)->xattr_sem);
++ no_expand = 1;
++ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
+
+diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
+index a92e783..099c8b6 100644
+--- a/fs/ext4/xattr.h
++++ b/fs/ext4/xattr.h
+@@ -102,6 +102,38 @@ extern const struct xattr_handler ext4_xattr_security_handler;
+
+ #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c"
+
++/*
++ * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes.
++ * The first is to signal that there the inline xattrs and data are
++ * taking up so much space that we might as well not keep trying to
++ * expand it. The second is that xattr_sem is taken for writing, so
++ * we shouldn't try to recurse into the inode expansion. For this
++ * second case, we need to make sure that we take save and restore the
++ * NO_EXPAND state flag appropriately.
++ */
++static inline void ext4_write_lock_xattr(struct inode *inode, int *save)
++{
++ down_write(&EXT4_I(inode)->xattr_sem);
++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
++}
++
++static inline int ext4_write_trylock_xattr(struct inode *inode, int *save)
++{
++ if (down_write_trylock(&EXT4_I(inode)->xattr_sem) == 0)
++ return 0;
++ *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ return 1;
++}
++
++static inline void ext4_write_unlock_xattr(struct inode *inode, int *save)
++{
++ if (*save == 0)
++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
++ up_write(&EXT4_I(inode)->xattr_sem);
++}
++
+ extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
+
+ extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
+diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
+index 369f451..ebdc90f 100644
+--- a/fs/f2fs/dir.c
++++ b/fs/f2fs/dir.c
+@@ -207,9 +207,13 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
+ f2fs_put_page(dentry_page, 0);
+ }
+
+- if (!de && room && F2FS_I(dir)->chash != namehash) {
+- F2FS_I(dir)->chash = namehash;
+- F2FS_I(dir)->clevel = level;
++ /* This is to increase the speed of f2fs_create */
++ if (!de && room) {
++ F2FS_I(dir)->task = current;
++ if (F2FS_I(dir)->chash != namehash) {
++ F2FS_I(dir)->chash = namehash;
++ F2FS_I(dir)->clevel = level;
++ }
+ }
+
+ return de;
+@@ -643,14 +647,34 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name,
+ struct inode *inode, nid_t ino, umode_t mode)
+ {
+ struct fscrypt_name fname;
++ struct page *page = NULL;
++ struct f2fs_dir_entry *de = NULL;
+ int err;
+
+ err = fscrypt_setup_filename(dir, name, 0, &fname);
+ if (err)
+ return err;
+
+- err = __f2fs_do_add_link(dir, &fname, inode, ino, mode);
+-
++ /*
++ * An immature stakable filesystem shows a race condition between lookup
++ * and create. If we have same task when doing lookup and create, it's
++ * definitely fine as expected by VFS normally. Otherwise, let's just
++ * verify on-disk dentry one more time, which guarantees filesystem
++ * consistency more.
++ */
++ if (current != F2FS_I(dir)->task) {
++ de = __f2fs_find_entry(dir, &fname, &page);
++ F2FS_I(dir)->task = NULL;
++ }
++ if (de) {
++ f2fs_dentry_kunmap(dir, page);
++ f2fs_put_page(page, 0);
++ err = -EEXIST;
++ } else if (IS_ERR(page)) {
++ err = PTR_ERR(page);
++ } else {
++ err = __f2fs_do_add_link(dir, &fname, inode, ino, mode);
++ }
+ fscrypt_free_filename(&fname);
+ return err;
+ }
+diff --git a/fs/f2fs/extent_cache.c b/fs/f2fs/extent_cache.c
+index 2b06d4f..7b32ce9 100644
+--- a/fs/f2fs/extent_cache.c
++++ b/fs/f2fs/extent_cache.c
+@@ -352,11 +352,12 @@ static struct extent_node *__try_merge_extent_node(struct inode *inode,
+ }
+
+ if (next_ex && __is_front_mergeable(ei, &next_ex->ei)) {
+- if (en)
+- __release_extent_node(sbi, et, prev_ex);
+ next_ex->ei.fofs = ei->fofs;
+ next_ex->ei.blk = ei->blk;
+ next_ex->ei.len += ei->len;
++ if (en)
++ __release_extent_node(sbi, et, prev_ex);
++
+ en = next_ex;
+ }
+
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 506af45..3a1640b 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -431,6 +431,7 @@ struct f2fs_inode_info {
+ atomic_t dirty_pages; /* # of dirty pages */
+ f2fs_hash_t chash; /* hash value of given file name */
+ unsigned int clevel; /* maximum level of given file name */
++ struct task_struct *task; /* lookup and create consistency */
+ nid_t i_xattr_nid; /* node id that contains xattrs */
+ unsigned long long xattr_ver; /* cp version of xattr modification */
+ loff_t last_disk_size; /* lastly written file size */
+@@ -833,6 +834,9 @@ struct f2fs_sb_info {
+ struct f2fs_gc_kthread *gc_thread; /* GC thread */
+ unsigned int cur_victim_sec; /* current victim section num */
+
++ /* threshold for converting bg victims for fg */
++ u64 fggc_threshold;
++
+ /* maximum # of trials to find a victim segment for SSR and GC */
+ unsigned int max_victim_search;
+
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
+index 6f14ee9..34a69e7 100644
+--- a/fs/f2fs/gc.c
++++ b/fs/f2fs/gc.c
+@@ -166,7 +166,8 @@ static void select_policy(struct f2fs_sb_info *sbi, int gc_type,
+ p->ofs_unit = sbi->segs_per_sec;
+ }
+
+- if (p->max_search > sbi->max_victim_search)
++ /* we need to check every dirty segments in the FG_GC case */
++ if (gc_type != FG_GC && p->max_search > sbi->max_victim_search)
+ p->max_search = sbi->max_victim_search;
+
+ p->offset = sbi->last_victim[p->gc_mode];
+@@ -199,6 +200,10 @@ static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
+ for_each_set_bit(secno, dirty_i->victim_secmap, MAIN_SECS(sbi)) {
+ if (sec_usage_check(sbi, secno))
+ continue;
++
++ if (no_fggc_candidate(sbi, secno))
++ continue;
++
+ clear_bit(secno, dirty_i->victim_secmap);
+ return secno * sbi->segs_per_sec;
+ }
+@@ -322,13 +327,15 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
+ nsearched++;
+ }
+
+-
+ secno = GET_SECNO(sbi, segno);
+
+ if (sec_usage_check(sbi, secno))
+ goto next;
+ if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
+ goto next;
++ if (gc_type == FG_GC && p.alloc_mode == LFS &&
++ no_fggc_candidate(sbi, secno))
++ goto next;
+
+ cost = get_gc_cost(sbi, segno, &p);
+
+@@ -972,5 +979,16 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync)
+
+ void build_gc_manager(struct f2fs_sb_info *sbi)
+ {
++ u64 main_count, resv_count, ovp_count, blocks_per_sec;
++
+ DIRTY_I(sbi)->v_ops = &default_v_ops;
++
++ /* threshold of # of valid blocks in a section for victims of FG_GC */
++ main_count = SM_I(sbi)->main_segments << sbi->log_blocks_per_seg;
++ resv_count = SM_I(sbi)->reserved_segments << sbi->log_blocks_per_seg;
++ ovp_count = SM_I(sbi)->ovp_segments << sbi->log_blocks_per_seg;
++ blocks_per_sec = sbi->blocks_per_seg * sbi->segs_per_sec;
++
++ sbi->fggc_threshold = div_u64((main_count - ovp_count) * blocks_per_sec,
++ (main_count - resv_count));
+ }
+diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
+index fc886f0..a7943f86 100644
+--- a/fs/f2fs/segment.c
++++ b/fs/f2fs/segment.c
+@@ -813,6 +813,8 @@ void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control *cpc)
+ start = start_segno + sbi->segs_per_sec;
+ if (start < end)
+ goto next;
++ else
++ end = start - 1;
+ }
+ mutex_unlock(&dirty_i->seglist_lock);
+
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
+index fecb856..b164f83 100644
+--- a/fs/f2fs/segment.h
++++ b/fs/f2fs/segment.h
+@@ -688,6 +688,15 @@ static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)
+ - (base + 1) + type;
+ }
+
++static inline bool no_fggc_candidate(struct f2fs_sb_info *sbi,
++ unsigned int secno)
++{
++ if (get_valid_blocks(sbi, secno, sbi->segs_per_sec) >=
++ sbi->fggc_threshold)
++ return true;
++ return false;
++}
++
+ static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno)
+ {
+ if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno))
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 2401c5d..5ec5870 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -100,6 +100,7 @@ static void fuse_file_put(struct fuse_file *ff, bool sync)
+ iput(req->misc.release.inode);
+ fuse_put_request(ff->fc, req);
+ } else if (sync) {
++ __set_bit(FR_FORCE, &req->flags);
+ __clear_bit(FR_BACKGROUND, &req->flags);
+ fuse_request_send(ff->fc, req);
+ iput(req->misc.release.inode);
+diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
+index 14cbf60..133f322 100644
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -658,9 +658,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+ struct kmem_cache *cachep;
+ int ret, tries = 0;
+
++ rcu_read_lock();
+ gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
+ if (gl && !lockref_get_not_dead(&gl->gl_lockref))
+ gl = NULL;
++ rcu_read_unlock();
+
+ *glp = gl;
+ if (gl)
+@@ -728,15 +730,18 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
+
+ if (ret == -EEXIST) {
+ ret = 0;
++ rcu_read_lock();
+ tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
+ if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) {
+ if (++tries < 100) {
++ rcu_read_unlock();
+ cond_resched();
+ goto again;
+ }
+ tmp = NULL;
+ ret = -ENOMEM;
+ }
++ rcu_read_unlock();
+ } else {
+ WARN_ON_ONCE(ret);
+ }
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e165266..5e659ee 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1863,7 +1863,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
+
+ __blist_del_buffer(list, jh);
+ jh->b_jlist = BJ_None;
+- if (test_clear_buffer_jbddirty(bh))
++ if (transaction && is_journal_aborted(transaction->t_journal))
++ clear_buffer_jbddirty(bh);
++ else if (test_clear_buffer_jbddirty(bh))
+ mark_buffer_dirty(bh); /* Expose it to the VM */
+ }
+
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index a5c3888..13abd60 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -1073,9 +1073,6 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
+ struct nfs_client *mds_client = mds_server->nfs_client;
+ struct nfs4_slot_table *tbl = &clp->cl_session->fc_slot_table;
+
+- if (task->tk_status >= 0)
+- return 0;
+-
+ switch (task->tk_status) {
+ /* MDS state errors */
+ case -NFS4ERR_DELEG_REVOKED:
+@@ -1176,9 +1173,6 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
+ {
+ struct nfs4_deviceid_node *devid = FF_LAYOUT_DEVID_NODE(lseg, idx);
+
+- if (task->tk_status >= 0)
+- return 0;
+-
+ switch (task->tk_status) {
+ /* File access problems. Don't mark the device as unavailable */
+ case -EACCES:
+@@ -1213,6 +1207,13 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
+ {
+ int vers = clp->cl_nfs_mod->rpc_vers->number;
+
++ if (task->tk_status >= 0)
++ return 0;
++
++ /* Handle the case of an invalid layout segment */
++ if (!pnfs_is_valid_lseg(lseg))
++ return -NFS4ERR_RESET_TO_PNFS;
++
+ switch (vers) {
+ case 3:
+ return ff_layout_async_handle_error_v3(task, lseg, idx);
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 6085019..5cda392 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -128,30 +128,26 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len)
+ return err;
+ }
+
+-static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
++static ssize_t _nfs42_proc_copy(struct file *src,
+ struct nfs_lock_context *src_lock,
+- struct file *dst, loff_t pos_dst,
++ struct file *dst,
+ struct nfs_lock_context *dst_lock,
+- size_t count)
++ struct nfs42_copy_args *args,
++ struct nfs42_copy_res *res)
+ {
+- struct nfs42_copy_args args = {
+- .src_fh = NFS_FH(file_inode(src)),
+- .src_pos = pos_src,
+- .dst_fh = NFS_FH(file_inode(dst)),
+- .dst_pos = pos_dst,
+- .count = count,
+- };
+- struct nfs42_copy_res res;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
+- .rpc_argp = &args,
+- .rpc_resp = &res,
++ .rpc_argp = args,
++ .rpc_resp = res,
+ };
+ struct inode *dst_inode = file_inode(dst);
+ struct nfs_server *server = NFS_SERVER(dst_inode);
++ loff_t pos_src = args->src_pos;
++ loff_t pos_dst = args->dst_pos;
++ size_t count = args->count;
+ int status;
+
+- status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
++ status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
+ src_lock, FMODE_READ);
+ if (status)
+ return status;
+@@ -161,7 +157,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
+ if (status)
+ return status;
+
+- status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
++ status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
+ dst_lock, FMODE_WRITE);
+ if (status)
+ return status;
+@@ -171,22 +167,22 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
+ return status;
+
+ status = nfs4_call_sync(server->client, server, &msg,
+- &args.seq_args, &res.seq_res, 0);
++ &args->seq_args, &res->seq_res, 0);
+ if (status == -ENOTSUPP)
+ server->caps &= ~NFS_CAP_COPY;
+ if (status)
+ return status;
+
+- if (res.write_res.verifier.committed != NFS_FILE_SYNC) {
+- status = nfs_commit_file(dst, &res.write_res.verifier.verifier);
++ if (res->write_res.verifier.committed != NFS_FILE_SYNC) {
++ status = nfs_commit_file(dst, &res->write_res.verifier.verifier);
+ if (status)
+ return status;
+ }
+
+ truncate_pagecache_range(dst_inode, pos_dst,
+- pos_dst + res.write_res.count);
++ pos_dst + res->write_res.count);
+
+- return res.write_res.count;
++ return res->write_res.count;
+ }
+
+ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
+@@ -196,8 +192,22 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
+ struct nfs_server *server = NFS_SERVER(file_inode(dst));
+ struct nfs_lock_context *src_lock;
+ struct nfs_lock_context *dst_lock;
+- struct nfs4_exception src_exception = { };
+- struct nfs4_exception dst_exception = { };
++ struct nfs42_copy_args args = {
++ .src_fh = NFS_FH(file_inode(src)),
++ .src_pos = pos_src,
++ .dst_fh = NFS_FH(file_inode(dst)),
++ .dst_pos = pos_dst,
++ .count = count,
++ };
++ struct nfs42_copy_res res;
++ struct nfs4_exception src_exception = {
++ .inode = file_inode(src),
++ .stateid = &args.src_stateid,
++ };
++ struct nfs4_exception dst_exception = {
++ .inode = file_inode(dst),
++ .stateid = &args.dst_stateid,
++ };
+ ssize_t err, err2;
+
+ if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY))
+@@ -207,7 +217,6 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
+ if (IS_ERR(src_lock))
+ return PTR_ERR(src_lock);
+
+- src_exception.inode = file_inode(src);
+ src_exception.state = src_lock->open_context->state;
+
+ dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
+@@ -216,15 +225,17 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
+ goto out_put_src_lock;
+ }
+
+- dst_exception.inode = file_inode(dst);
+ dst_exception.state = dst_lock->open_context->state;
+
+ do {
+ inode_lock(file_inode(dst));
+- err = _nfs42_proc_copy(src, pos_src, src_lock,
+- dst, pos_dst, dst_lock, count);
++ err = _nfs42_proc_copy(src, src_lock,
++ dst, dst_lock,
++ &args, &res);
+ inode_unlock(file_inode(dst));
+
++ if (err >= 0)
++ break;
+ if (err == -ENOTSUPP) {
+ err = -EOPNOTSUPP;
+ break;
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 78ff8b6..609840d 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2708,6 +2708,7 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
+ ret = PTR_ERR(state);
+ if (IS_ERR(state))
+ goto out;
++ ctx->state = state;
+ if (server->caps & NFS_CAP_POSIX_LOCK)
+ set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
+ if (opendata->o_res.rflags & NFS4_OPEN_RESULT_MAY_NOTIFY_LOCK)
+@@ -2733,7 +2734,6 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
+ if (ret != 0)
+ goto out;
+
+- ctx->state = state;
+ if (d_inode(dentry) == state->inode) {
+ nfs_inode_attach_open_context(ctx);
+ if (read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
+@@ -4990,7 +4990,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size
+ */
+ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+ {
+- struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
++ struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
+ struct nfs_getaclargs args = {
+ .fh = NFS_FH(inode),
+ .acl_pages = pages,
+@@ -5004,13 +5004,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
+ .rpc_argp = &args,
+ .rpc_resp = &res,
+ };
+- unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE);
++ unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+ int ret = -ENOMEM, i;
+
+- /* As long as we're doing a round trip to the server anyway,
+- * let's be prepared for a page of acl data. */
+- if (npages == 0)
+- npages = 1;
+ if (npages > ARRAY_SIZE(pages))
+ return -ERANGE;
+
+diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
+index fc89e5e..c9c4d985 100644
+--- a/fs/nfs/nfs4xdr.c
++++ b/fs/nfs/nfs4xdr.c
+@@ -2492,7 +2492,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
+ encode_compound_hdr(xdr, req, &hdr);
+ encode_sequence(xdr, &args->seq_args, &hdr);
+ encode_putfh(xdr, args->fh, &hdr);
+- replen = hdr.replen + op_decode_hdr_maxsz + 1;
++ replen = hdr.replen + op_decode_hdr_maxsz;
+ encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
+
+ xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 8ca642f..b829cc9 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -377,7 +377,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ __be32 err;
+ int host_err;
+ bool get_write_count;
+- int size_change = 0;
++ bool size_change = (iap->ia_valid & ATTR_SIZE);
+
+ if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
+ accmode |= NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE;
+@@ -390,11 +390,11 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ /* Get inode */
+ err = fh_verify(rqstp, fhp, ftype, accmode);
+ if (err)
+- goto out;
++ return err;
+ if (get_write_count) {
+ host_err = fh_want_write(fhp);
+ if (host_err)
+- return nfserrno(host_err);
++ goto out;
+ }
+
+ dentry = fhp->fh_dentry;
+@@ -405,20 +405,28 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ iap->ia_valid &= ~ATTR_MODE;
+
+ if (!iap->ia_valid)
+- goto out;
++ return 0;
+
+ nfsd_sanitize_attrs(inode, iap);
+
++ if (check_guard && guardtime != inode->i_ctime.tv_sec)
++ return nfserr_notsync;
++
+ /*
+ * The size case is special, it changes the file in addition to the
+- * attributes.
++ * attributes, and file systems don't expect it to be mixed with
++ * "random" attribute changes. We thus split out the size change
++ * into a separate call to ->setattr, and do the rest as a separate
++ * setattr call.
+ */
+- if (iap->ia_valid & ATTR_SIZE) {
++ if (size_change) {
+ err = nfsd_get_write_access(rqstp, fhp, iap);
+ if (err)
+- goto out;
+- size_change = 1;
++ return err;
++ }
+
++ fh_lock(fhp);
++ if (size_change) {
+ /*
+ * RFC5661, Section 18.30.4:
+ * Changing the size of a file with SETATTR indirectly
+@@ -426,29 +434,36 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
+ *
+ * (and similar for the older RFCs)
+ */
+- if (iap->ia_size != i_size_read(inode))
+- iap->ia_valid |= ATTR_MTIME;
+- }
++ struct iattr size_attr = {
++ .ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
++ .ia_size = iap->ia_size,
++ };
+
+- iap->ia_valid |= ATTR_CTIME;
++ host_err = notify_change(dentry, &size_attr, NULL);
++ if (host_err)
++ goto out_unlock;
++ iap->ia_valid &= ~ATTR_SIZE;
+
+- if (check_guard && guardtime != inode->i_ctime.tv_sec) {
+- err = nfserr_notsync;
+- goto out_put_write_access;
++ /*
++ * Avoid the additional setattr call below if the only other
++ * attribute that the client sends is the mtime, as we update
++ * it as part of the size change above.
++ */
++ if ((iap->ia_valid & ~ATTR_MTIME) == 0)
++ goto out_unlock;
+ }
+
+- fh_lock(fhp);
++ iap->ia_valid |= ATTR_CTIME;
+ host_err = notify_change(dentry, iap, NULL);
+- fh_unlock(fhp);
+- err = nfserrno(host_err);
+
+-out_put_write_access:
++out_unlock:
++ fh_unlock(fhp);
+ if (size_change)
+ put_write_access(inode);
+- if (!err)
+- err = nfserrno(commit_metadata(fhp));
+ out:
+- return err;
++ if (!host_err)
++ host_err = commit_metadata(fhp);
++ return nfserrno(host_err);
+ }
+
+ #if defined(CONFIG_NFSD_V4)
+diff --git a/include/linux/compat.h b/include/linux/compat.h
+index 6360939..d8535a4 100644
+--- a/include/linux/compat.h
++++ b/include/linux/compat.h
+@@ -711,8 +711,10 @@ int __compat_save_altstack(compat_stack_t __user *, unsigned long);
+ compat_stack_t __user *__uss = uss; \
+ struct task_struct *t = current; \
+ put_user_ex(ptr_to_compat((void __user *)t->sas_ss_sp), &__uss->ss_sp); \
+- put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \
++ put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
+ put_user_ex(t->sas_ss_size, &__uss->ss_size); \
++ if (t->sas_ss_flags & SS_AUTODISARM) \
++ sas_ss_reset(t); \
+ } while (0);
+
+ asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
+diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
+index 2de4e2e..e0acb0e 100644
+--- a/include/linux/devfreq.h
++++ b/include/linux/devfreq.h
+@@ -104,6 +104,8 @@ struct devfreq_dev_profile {
+ * struct devfreq_governor - Devfreq policy governor
+ * @node: list node - contains registered devfreq governors
+ * @name: Governor's name
++ * @immutable: Immutable flag for governor. If the value is 1,
++ * this govenror is never changeable to other governor.
+ * @get_target_freq: Returns desired operating frequency for the device.
+ * Basically, get_target_freq will run
+ * devfreq_dev_profile.get_dev_status() to get the
+@@ -121,6 +123,7 @@ struct devfreq_governor {
+ struct list_head node;
+
+ const char name[DEVFREQ_NAME_LEN];
++ const unsigned int immutable;
+ int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
+ int (*event_handler)(struct devfreq *devfreq,
+ unsigned int event, void *data);
+diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h
+index 3f9778c..c332f0a 100644
+--- a/include/linux/fsl_ifc.h
++++ b/include/linux/fsl_ifc.h
+@@ -733,8 +733,12 @@ struct fsl_ifc_nand {
+ __be32 nand_erattr1;
+ u32 res19[0x10];
+ __be32 nand_fsr;
+- u32 res20[0x3];
+- __be32 nand_eccstat[6];
++ u32 res20;
++ /* The V1 nand_eccstat is actually 4 words that overlaps the
++ * V2 nand_eccstat.
++ */
++ __be32 v1_nand_eccstat[2];
++ __be32 v2_nand_eccstat[6];
+ u32 res21[0x1c];
+ __be32 nanndcr;
+ u32 res22[0x2];
+diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
+index c92a083..192eef2f 100644
+--- a/include/linux/hyperv.h
++++ b/include/linux/hyperv.h
+@@ -641,6 +641,7 @@ struct vmbus_channel_msginfo {
+
+ /* Synchronize the request/response if needed */
+ struct completion waitevent;
++ struct vmbus_channel *waiting_channel;
+ union {
+ struct vmbus_channel_version_supported version_supported;
+ struct vmbus_channel_open_result open_result;
+diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
+index d49e26c..23e129e 100644
+--- a/include/linux/intel-iommu.h
++++ b/include/linux/intel-iommu.h
+@@ -153,8 +153,8 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
+ #define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
+ #define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
+ #define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
+-#define DMA_TLB_IIRG(type) ((type >> 60) & 7)
+-#define DMA_TLB_IAIG(val) (((val) >> 57) & 7)
++#define DMA_TLB_IIRG(type) ((type >> 60) & 3)
++#define DMA_TLB_IAIG(val) (((val) >> 57) & 3)
+ #define DMA_TLB_READ_DRAIN (((u64)1) << 49)
+ #define DMA_TLB_WRITE_DRAIN (((u64)1) << 48)
+ #define DMA_TLB_DID(id) (((u64)((id) & 0xffff)) << 32)
+@@ -164,9 +164,9 @@ static inline void dmar_writeq(void __iomem *addr, u64 val)
+
+ /* INVALID_DESC */
+ #define DMA_CCMD_INVL_GRANU_OFFSET 61
+-#define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3)
+-#define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3)
+-#define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3)
++#define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 4)
++#define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 4)
++#define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 4)
+ #define DMA_ID_TLB_READ_DRAIN (((u64)1) << 7)
+ #define DMA_ID_TLB_WRITE_DRAIN (((u64)1) << 6)
+ #define DMA_ID_TLB_DID(id) (((u64)((id & 0xffff) << 16)))
+@@ -316,8 +316,8 @@ enum {
+ #define QI_DEV_EIOTLB_SIZE (((u64)1) << 11)
+ #define QI_DEV_EIOTLB_GLOB(g) ((u64)g)
+ #define QI_DEV_EIOTLB_PASID(p) (((u64)p) << 32)
+-#define QI_DEV_EIOTLB_SID(sid) ((u64)((sid) & 0xffff) << 32)
+-#define QI_DEV_EIOTLB_QDEP(qd) (((qd) & 0x1f) << 16)
++#define QI_DEV_EIOTLB_SID(sid) ((u64)((sid) & 0xffff) << 16)
++#define QI_DEV_EIOTLB_QDEP(qd) ((u64)((qd) & 0x1f) << 4)
+ #define QI_DEV_EIOTLB_MAX_INVS 32
+
+ #define QI_PGRP_IDX(idx) (((u64)(idx)) << 55)
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
+index f99c993..7e273e2 100644
+--- a/include/linux/mmzone.h
++++ b/include/linux/mmzone.h
+@@ -779,7 +779,7 @@ static inline struct pglist_data *lruvec_pgdat(struct lruvec *lruvec)
+ #endif
+ }
+
+-extern unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru);
++extern unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx);
+
+ #ifdef CONFIG_HAVE_MEMORY_PRESENT
+ void memory_present(int nid, unsigned long start, unsigned long end);
+diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
+index 5ee7aab..fd0e532 100644
+--- a/include/rdma/ib_sa.h
++++ b/include/rdma/ib_sa.h
+@@ -153,12 +153,12 @@ struct ib_sa_path_rec {
+ union ib_gid sgid;
+ __be16 dlid;
+ __be16 slid;
+- int raw_traffic;
++ u8 raw_traffic;
+ /* reserved */
+ __be32 flow_label;
+ u8 hop_limit;
+ u8 traffic_class;
+- int reversible;
++ u8 reversible;
+ u8 numb_path;
+ __be16 pkey;
+ __be16 qos_class;
+@@ -220,7 +220,7 @@ struct ib_sa_mcmember_rec {
+ u8 hop_limit;
+ u8 scope;
+ u8 join_state;
+- int proxy_join;
++ u8 proxy_join;
+ };
+
+ /* Service Record Component Mask Sec 15.2.5.14 Ver 1.1 */
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 8a95631..b9ec493 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -315,6 +315,7 @@ extern void scsi_remove_device(struct scsi_device *);
+ extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
+ void scsi_attach_vpd(struct scsi_device *sdev);
+
++extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
+ extern int scsi_device_get(struct scsi_device *);
+ extern void scsi_device_put(struct scsi_device *);
+ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
+diff --git a/include/soc/at91/at91sam9_ddrsdr.h b/include/soc/at91/at91sam9_ddrsdr.h
+index dc10c52..393362b 100644
+--- a/include/soc/at91/at91sam9_ddrsdr.h
++++ b/include/soc/at91/at91sam9_ddrsdr.h
+@@ -81,6 +81,7 @@
+ #define AT91_DDRSDRC_LPCB_POWER_DOWN 2
+ #define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
+ #define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
++#define AT91_DDRSDRC_LPDDR2_PWOFF (1 << 3) /* LPDDR Power Off */
+ #define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
+ #define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
+ #define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
+@@ -96,7 +97,9 @@
+ #define AT91_DDRSDRC_MD_SDR 0
+ #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
+ #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
++#define AT91_DDRSDRC_MD_LPDDR3 5
+ #define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */
++#define AT91_DDRSDRC_MD_LPDDR2 7
+ #define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
+ #define AT91_DDRSDRC_DBW_32BITS (0 << 4)
+ #define AT91_DDRSDRC_DBW_16BITS (1 << 4)
+diff --git a/ipc/shm.c b/ipc/shm.c
+index dbac886..e2072ae 100644
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -1085,8 +1085,8 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+ * "raddr" thing points to kernel space, and there has to be a wrapper around
+ * this.
+ */
+-long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
+- unsigned long shmlba)
++long do_shmat(int shmid, char __user *shmaddr, int shmflg,
++ ulong *raddr, unsigned long shmlba)
+ {
+ struct shmid_kernel *shp;
+ unsigned long addr;
+@@ -1107,8 +1107,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
+ goto out;
+ else if ((addr = (ulong)shmaddr)) {
+ if (addr & (shmlba - 1)) {
+- if (shmflg & SHM_RND)
+- addr &= ~(shmlba - 1); /* round down */
++ /*
++ * Round down to the nearest multiple of shmlba.
++ * For sane do_mmap_pgoff() parameters, avoid
++ * round downs that trigger nil-page and MAP_FIXED.
++ */
++ if ((shmflg & SHM_RND) && addr >= shmlba)
++ addr &= ~(shmlba - 1);
+ else
+ #ifndef __ARCH_FORCE_SHMLBA
+ if (addr & ~PAGE_MASK)
+diff --git a/kernel/membarrier.c b/kernel/membarrier.c
+index 536c727..9f9284f 100644
+--- a/kernel/membarrier.c
++++ b/kernel/membarrier.c
+@@ -16,6 +16,7 @@
+
+ #include <linux/syscalls.h>
+ #include <linux/membarrier.h>
++#include <linux/tick.h>
+
+ /*
+ * Bitmask made from a "or" of all commands within enum membarrier_cmd,
+@@ -51,6 +52,9 @@
+ */
+ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
+ {
++ /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
++ if (tick_nohz_full_enabled())
++ return -ENOSYS;
+ if (unlikely(flags))
+ return -EINVAL;
+ switch (cmd) {
+diff --git a/kernel/memremap.c b/kernel/memremap.c
+index 9ecedc2..0612323 100644
+--- a/kernel/memremap.c
++++ b/kernel/memremap.c
+@@ -246,9 +246,13 @@ static void devm_memremap_pages_release(struct device *dev, void *data)
+ /* pages are dead and unused, undo the arch mapping */
+ align_start = res->start & ~(SECTION_SIZE - 1);
+ align_size = ALIGN(resource_size(res), SECTION_SIZE);
++
++ lock_device_hotplug();
+ mem_hotplug_begin();
+ arch_remove_memory(align_start, align_size);
+ mem_hotplug_done();
++ unlock_device_hotplug();
++
+ untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
+ pgmap_radix_release(res);
+ dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc,
+@@ -360,9 +364,11 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
+ if (error)
+ goto err_pfn_remap;
+
++ lock_device_hotplug();
+ mem_hotplug_begin();
+ error = arch_add_memory(nid, align_start, align_size, true);
+ mem_hotplug_done();
++ unlock_device_hotplug();
+ if (error)
+ goto err_add_memory;
+
+diff --git a/kernel/signal.c b/kernel/signal.c
+index 75761ac..0b14157 100644
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -3226,10 +3226,17 @@ int compat_restore_altstack(const compat_stack_t __user *uss)
+
+ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
+ {
++ int err;
+ struct task_struct *t = current;
+- return __put_user(ptr_to_compat((void __user *)t->sas_ss_sp), &uss->ss_sp) |
+- __put_user(sas_ss_flags(sp), &uss->ss_flags) |
++ err = __put_user(ptr_to_compat((void __user *)t->sas_ss_sp),
++ &uss->ss_sp) |
++ __put_user(t->sas_ss_flags, &uss->ss_flags) |
+ __put_user(t->sas_ss_size, &uss->ss_size);
++ if (err)
++ return err;
++ if (t->sas_ss_flags & SS_AUTODISARM)
++ sas_ss_reset(t);
++ return 0;
+ }
+ #endif
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index d8d7df8..edfb90e 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -910,9 +910,12 @@ void page_endio(struct page *page, bool is_write, int err)
+ unlock_page(page);
+ } else {
+ if (err) {
++ struct address_space *mapping;
++
+ SetPageError(page);
+- if (page->mapping)
+- mapping_set_error(page->mapping, err);
++ mapping = page_mapping(page);
++ if (mapping)
++ mapping_set_error(mapping, err);
+ }
+ end_page_writeback(page);
+ }
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index f4a02e2..1460e6a 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2858,7 +2858,7 @@ bool zone_watermark_ok_safe(struct zone *z, unsigned int order,
+ #ifdef CONFIG_NUMA
+ static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+ {
+- return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <
++ return node_distance(zone_to_nid(local_zone), zone_to_nid(zone)) <=
+ RECLAIM_DISTANCE;
+ }
+ #else /* CONFIG_NUMA */
+diff --git a/mm/vmpressure.c b/mm/vmpressure.c
+index 149fdf6..6063581 100644
+--- a/mm/vmpressure.c
++++ b/mm/vmpressure.c
+@@ -112,9 +112,16 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
+ unsigned long reclaimed)
+ {
+ unsigned long scale = scanned + reclaimed;
+- unsigned long pressure;
++ unsigned long pressure = 0;
+
+ /*
++ * reclaimed can be greater than scanned in cases
++ * like THP, where the scanned is 1 and reclaimed
++ * could be 512
++ */
++ if (reclaimed >= scanned)
++ goto out;
++ /*
+ * We calculate the ratio (in percents) of how many pages were
+ * scanned vs. reclaimed in a given time frame (window). Note that
+ * time is in VM reclaimer's "ticks", i.e. number of pages
+@@ -124,6 +131,7 @@ static enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
+ pressure = scale - (reclaimed * scale / scanned);
+ pressure = pressure * 100 / scale;
+
++out:
+ pr_debug("%s: %3lu (s: %lu r: %lu)\n", __func__, pressure,
+ scanned, reclaimed);
+
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index fa30010..30a88b9 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -234,22 +234,39 @@ bool pgdat_reclaimable(struct pglist_data *pgdat)
+ pgdat_reclaimable_pages(pgdat) * 6;
+ }
+
+-unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru)
++/**
++ * lruvec_lru_size - Returns the number of pages on the given LRU list.
++ * @lruvec: lru vector
++ * @lru: lru to use
++ * @zone_idx: zones to consider (use MAX_NR_ZONES for the whole LRU list)
++ */
++unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone_idx)
+ {
++ unsigned long lru_size;
++ int zid;
++
+ if (!mem_cgroup_disabled())
+- return mem_cgroup_get_lru_size(lruvec, lru);
++ lru_size = mem_cgroup_get_lru_size(lruvec, lru);
++ else
++ lru_size = node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
+
+- return node_page_state(lruvec_pgdat(lruvec), NR_LRU_BASE + lru);
+-}
++ for (zid = zone_idx + 1; zid < MAX_NR_ZONES; zid++) {
++ struct zone *zone = &lruvec_pgdat(lruvec)->node_zones[zid];
++ unsigned long size;
+
+-unsigned long lruvec_zone_lru_size(struct lruvec *lruvec, enum lru_list lru,
+- int zone_idx)
+-{
+- if (!mem_cgroup_disabled())
+- return mem_cgroup_get_zone_lru_size(lruvec, lru, zone_idx);
++ if (!managed_zone(zone))
++ continue;
++
++ if (!mem_cgroup_disabled())
++ size = mem_cgroup_get_zone_lru_size(lruvec, lru, zid);
++ else
++ size = zone_page_state(&lruvec_pgdat(lruvec)->node_zones[zid],
++ NR_ZONE_LRU_BASE + lru);
++ lru_size -= min(size, lru_size);
++ }
++
++ return lru_size;
+
+- return zone_page_state(&lruvec_pgdat(lruvec)->node_zones[zone_idx],
+- NR_ZONE_LRU_BASE + lru);
+ }
+
+ /*
+@@ -2028,11 +2045,10 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
+ struct scan_control *sc)
+ {
+ unsigned long inactive_ratio;
+- unsigned long inactive;
+- unsigned long active;
++ unsigned long inactive, active;
++ enum lru_list inactive_lru = file * LRU_FILE;
++ enum lru_list active_lru = file * LRU_FILE + LRU_ACTIVE;
+ unsigned long gb;
+- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+- int zid;
+
+ /*
+ * If we don't have swap space, anonymous page deactivation
+@@ -2041,27 +2057,8 @@ static bool inactive_list_is_low(struct lruvec *lruvec, bool file,
+ if (!file && !total_swap_pages)
+ return false;
+
+- inactive = lruvec_lru_size(lruvec, file * LRU_FILE);
+- active = lruvec_lru_size(lruvec, file * LRU_FILE + LRU_ACTIVE);
+-
+- /*
+- * For zone-constrained allocations, it is necessary to check if
+- * deactivations are required for lowmem to be reclaimed. This
+- * calculates the inactive/active pages available in eligible zones.
+- */
+- for (zid = sc->reclaim_idx + 1; zid < MAX_NR_ZONES; zid++) {
+- struct zone *zone = &pgdat->node_zones[zid];
+- unsigned long inactive_zone, active_zone;
+-
+- if (!managed_zone(zone))
+- continue;
+-
+- inactive_zone = lruvec_zone_lru_size(lruvec, file * LRU_FILE, zid);
+- active_zone = lruvec_zone_lru_size(lruvec, (file * LRU_FILE) + LRU_ACTIVE, zid);
+-
+- inactive -= min(inactive, inactive_zone);
+- active -= min(active, active_zone);
+- }
++ inactive = lruvec_lru_size(lruvec, inactive_lru, sc->reclaim_idx);
++ active = lruvec_lru_size(lruvec, active_lru, sc->reclaim_idx);
+
+ gb = (inactive + active) >> (30 - PAGE_SHIFT);
+ if (gb)
+@@ -2208,7 +2205,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
+ * system is under heavy pressure.
+ */
+ if (!inactive_list_is_low(lruvec, true, sc) &&
+- lruvec_lru_size(lruvec, LRU_INACTIVE_FILE) >> sc->priority) {
++ lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, sc->reclaim_idx) >> sc->priority) {
+ scan_balance = SCAN_FILE;
+ goto out;
+ }
+@@ -2234,10 +2231,10 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
+ * anon in [0], file in [1]
+ */
+
+- anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON) +
+- lruvec_lru_size(lruvec, LRU_INACTIVE_ANON);
+- file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE) +
+- lruvec_lru_size(lruvec, LRU_INACTIVE_FILE);
++ anon = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) +
++ lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES);
++ file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
++ lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES);
+
+ spin_lock_irq(&pgdat->lru_lock);
+ if (unlikely(reclaim_stat->recent_scanned[0] > anon / 4)) {
+@@ -2275,7 +2272,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,
+ unsigned long size;
+ unsigned long scan;
+
+- size = lruvec_lru_size(lruvec, lru);
++ size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
+ scan = size >> sc->priority;
+
+ if (!scan && pass && force_scan)
+diff --git a/mm/workingset.c b/mm/workingset.c
+index fb1f918..33f6f4d 100644
+--- a/mm/workingset.c
++++ b/mm/workingset.c
+@@ -266,7 +266,7 @@ bool workingset_refault(void *shadow)
+ }
+ lruvec = mem_cgroup_lruvec(pgdat, memcg);
+ refault = atomic_long_read(&lruvec->inactive_age);
+- active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE);
++ active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES);
+ rcu_read_unlock();
+
+ /*
+diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
+index e6ae15b..0ffeb60 100644
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -672,7 +672,8 @@ void osd_req_op_extent_update(struct ceph_osd_request *osd_req,
+ BUG_ON(length > previous);
+
+ op->extent.length = length;
+- op->indata_len -= previous - length;
++ if (op->op == CEPH_OSD_OP_WRITE || op->op == CEPH_OSD_OP_WRITEFULL)
++ op->indata_len -= previous - length;
+ }
+ EXPORT_SYMBOL(osd_req_op_extent_update);
+
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 0f87e5d..6bd1508 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -85,11 +85,11 @@ static __read_mostly DEFINE_SPINLOCK(nf_conntrack_locks_all_lock);
+ static __read_mostly bool nf_conntrack_locks_all;
+
+ /* every gc cycle scans at most 1/GC_MAX_BUCKETS_DIV part of table */
+-#define GC_MAX_BUCKETS_DIV 64u
+-/* upper bound of scan intervals */
+-#define GC_INTERVAL_MAX (2 * HZ)
+-/* maximum conntracks to evict per gc run */
+-#define GC_MAX_EVICTS 256u
++#define GC_MAX_BUCKETS_DIV 128u
++/* upper bound of full table scan */
++#define GC_MAX_SCAN_JIFFIES (16u * HZ)
++/* desired ratio of entries found to be expired */
++#define GC_EVICT_RATIO 50u
+
+ static struct conntrack_gc_work conntrack_gc_work;
+
+@@ -938,6 +938,7 @@ static noinline int early_drop(struct net *net, unsigned int _hash)
+
+ static void gc_worker(struct work_struct *work)
+ {
++ unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u);
+ unsigned int i, goal, buckets = 0, expired_count = 0;
+ struct conntrack_gc_work *gc_work;
+ unsigned int ratio, scanned = 0;
+@@ -979,8 +980,7 @@ static void gc_worker(struct work_struct *work)
+ */
+ rcu_read_unlock();
+ cond_resched_rcu_qs();
+- } while (++buckets < goal &&
+- expired_count < GC_MAX_EVICTS);
++ } while (++buckets < goal);
+
+ if (gc_work->exiting)
+ return;
+@@ -997,27 +997,25 @@ static void gc_worker(struct work_struct *work)
+ * 1. Minimize time until we notice a stale entry
+ * 2. Maximize scan intervals to not waste cycles
+ *
+- * Normally, expired_count will be 0, this increases the next_run time
+- * to priorize 2) above.
++ * Normally, expire ratio will be close to 0.
+ *
+- * As soon as a timed-out entry is found, move towards 1) and increase
+- * the scan frequency.
+- * In case we have lots of evictions next scan is done immediately.
++ * As soon as a sizeable fraction of the entries have expired
++ * increase scan frequency.
+ */
+ ratio = scanned ? expired_count * 100 / scanned : 0;
+- if (ratio >= 90 || expired_count == GC_MAX_EVICTS) {
+- gc_work->next_gc_run = 0;
+- next_run = 0;
+- } else if (expired_count) {
+- gc_work->next_gc_run /= 2U;
+- next_run = msecs_to_jiffies(1);
++ if (ratio > GC_EVICT_RATIO) {
++ gc_work->next_gc_run = min_interval;
+ } else {
+- if (gc_work->next_gc_run < GC_INTERVAL_MAX)
+- gc_work->next_gc_run += msecs_to_jiffies(1);
++ unsigned int max = GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV;
+
+- next_run = gc_work->next_gc_run;
++ BUILD_BUG_ON((GC_MAX_SCAN_JIFFIES / GC_MAX_BUCKETS_DIV) == 0);
++
++ gc_work->next_gc_run += min_interval;
++ if (gc_work->next_gc_run > max)
++ gc_work->next_gc_run = max;
+ }
+
++ next_run = gc_work->next_gc_run;
+ gc_work->last_bucket = i;
+ queue_delayed_work(system_long_wq, &gc_work->dwork, next_run);
+ }
+@@ -1025,7 +1023,7 @@ static void gc_worker(struct work_struct *work)
+ static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work)
+ {
+ INIT_DELAYED_WORK(&gc_work->dwork, gc_worker);
+- gc_work->next_gc_run = GC_INTERVAL_MAX;
++ gc_work->next_gc_run = HZ;
+ gc_work->exiting = false;
+ }
+
+@@ -1918,7 +1916,7 @@ int nf_conntrack_init_start(void)
+ nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED);
+
+ conntrack_gc_work_init(&conntrack_gc_work);
+- queue_delayed_work(system_long_wq, &conntrack_gc_work.dwork, GC_INTERVAL_MAX);
++ queue_delayed_work(system_long_wq, &conntrack_gc_work.dwork, HZ);
+
+ return 0;
+
+diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
+index d987c2d..f57c9f0 100644
+--- a/net/sunrpc/xprtrdma/rpc_rdma.c
++++ b/net/sunrpc/xprtrdma/rpc_rdma.c
+@@ -125,14 +125,34 @@ void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *r_xprt)
+ /* The client can send a request inline as long as the RPCRDMA header
+ * plus the RPC call fit under the transport's inline limit. If the
+ * combined call message size exceeds that limit, the client must use
+- * the read chunk list for this operation.
++ * a Read chunk for this operation.
++ *
++ * A Read chunk is also required if sending the RPC call inline would
++ * exceed this device's max_sge limit.
+ */
+ static bool rpcrdma_args_inline(struct rpcrdma_xprt *r_xprt,
+ struct rpc_rqst *rqst)
+ {
+- struct rpcrdma_ia *ia = &r_xprt->rx_ia;
++ struct xdr_buf *xdr = &rqst->rq_snd_buf;
++ unsigned int count, remaining, offset;
++
++ if (xdr->len > r_xprt->rx_ia.ri_max_inline_write)
++ return false;
++
++ if (xdr->page_len) {
++ remaining = xdr->page_len;
++ offset = xdr->page_base & ~PAGE_MASK;
++ count = 0;
++ while (remaining) {
++ remaining -= min_t(unsigned int,
++ PAGE_SIZE - offset, remaining);
++ offset = 0;
++ if (++count > r_xprt->rx_ia.ri_max_send_sges)
++ return false;
++ }
++ }
+
+- return rqst->rq_snd_buf.len <= ia->ri_max_inline_write;
++ return true;
+ }
+
+ /* The client can't know how large the actual reply will be. Thus it
+@@ -186,9 +206,9 @@ rpcrdma_convert_kvec(struct kvec *vec, struct rpcrdma_mr_seg *seg, int n)
+ */
+
+ static int
+-rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
+- enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg,
+- bool reminv_expected)
++rpcrdma_convert_iovs(struct rpcrdma_xprt *r_xprt, struct xdr_buf *xdrbuf,
++ unsigned int pos, enum rpcrdma_chunktype type,
++ struct rpcrdma_mr_seg *seg)
+ {
+ int len, n, p, page_base;
+ struct page **ppages;
+@@ -226,22 +246,21 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
+ if (len && n == RPCRDMA_MAX_SEGS)
+ goto out_overflow;
+
+- /* When encoding the read list, the tail is always sent inline */
+- if (type == rpcrdma_readch)
++ /* When encoding a Read chunk, the tail iovec contains an
++ * XDR pad and may be omitted.
++ */
++ if (type == rpcrdma_readch && r_xprt->rx_ia.ri_implicit_roundup)
+ return n;
+
+- /* When encoding the Write list, some servers need to see an extra
+- * segment for odd-length Write chunks. The upper layer provides
+- * space in the tail iovec for this purpose.
++ /* When encoding a Write chunk, some servers need to see an
++ * extra segment for non-XDR-aligned Write chunks. The upper
++ * layer provides space in the tail iovec that may be used
++ * for this purpose.
+ */
+- if (type == rpcrdma_writech && reminv_expected)
++ if (type == rpcrdma_writech && r_xprt->rx_ia.ri_implicit_roundup)
+ return n;
+
+ if (xdrbuf->tail[0].iov_len) {
+- /* the rpcrdma protocol allows us to omit any trailing
+- * xdr pad bytes, saving the server an RDMA operation. */
+- if (xdrbuf->tail[0].iov_len < 4 && xprt_rdma_pad_optimize)
+- return n;
+ n = rpcrdma_convert_kvec(&xdrbuf->tail[0], seg, n);
+ if (n == RPCRDMA_MAX_SEGS)
+ goto out_overflow;
+@@ -293,7 +312,8 @@ rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt,
+ if (rtype == rpcrdma_areadch)
+ pos = 0;
+ seg = req->rl_segments;
+- nsegs = rpcrdma_convert_iovs(&rqst->rq_snd_buf, pos, rtype, seg, false);
++ nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_snd_buf, pos,
++ rtype, seg);
+ if (nsegs < 0)
+ return ERR_PTR(nsegs);
+
+@@ -355,10 +375,9 @@ rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req,
+ }
+
+ seg = req->rl_segments;
+- nsegs = rpcrdma_convert_iovs(&rqst->rq_rcv_buf,
++ nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf,
+ rqst->rq_rcv_buf.head[0].iov_len,
+- wtype, seg,
+- r_xprt->rx_ia.ri_reminv_expected);
++ wtype, seg);
+ if (nsegs < 0)
+ return ERR_PTR(nsegs);
+
+@@ -423,8 +442,7 @@ rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt,
+ }
+
+ seg = req->rl_segments;
+- nsegs = rpcrdma_convert_iovs(&rqst->rq_rcv_buf, 0, wtype, seg,
+- r_xprt->rx_ia.ri_reminv_expected);
++ nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg);
+ if (nsegs < 0)
+ return ERR_PTR(nsegs);
+
+diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
+index ed5e285..fa324fe 100644
+--- a/net/sunrpc/xprtrdma/transport.c
++++ b/net/sunrpc/xprtrdma/transport.c
+@@ -67,7 +67,7 @@ unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
+ static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
+ static unsigned int xprt_rdma_inline_write_padding;
+ static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
+- int xprt_rdma_pad_optimize = 1;
++ int xprt_rdma_pad_optimize = 0;
+
+ #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
+
+diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
+index 8da7f6a..e2c37061 100644
+--- a/net/sunrpc/xprtrdma/verbs.c
++++ b/net/sunrpc/xprtrdma/verbs.c
+@@ -208,6 +208,7 @@ rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,
+
+ /* Default settings for RPC-over-RDMA Version One */
+ r_xprt->rx_ia.ri_reminv_expected = false;
++ r_xprt->rx_ia.ri_implicit_roundup = xprt_rdma_pad_optimize;
+ rsize = RPCRDMA_V1_DEF_INLINE_SIZE;
+ wsize = RPCRDMA_V1_DEF_INLINE_SIZE;
+
+@@ -215,6 +216,7 @@ rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,
+ pmsg->cp_magic == rpcrdma_cmp_magic &&
+ pmsg->cp_version == RPCRDMA_CMP_VERSION) {
+ r_xprt->rx_ia.ri_reminv_expected = true;
++ r_xprt->rx_ia.ri_implicit_roundup = true;
+ rsize = rpcrdma_decode_buffer_size(pmsg->cp_send_size);
+ wsize = rpcrdma_decode_buffer_size(pmsg->cp_recv_size);
+ }
+@@ -477,18 +479,19 @@ rpcrdma_ia_close(struct rpcrdma_ia *ia)
+ */
+ int
+ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
+- struct rpcrdma_create_data_internal *cdata)
++ struct rpcrdma_create_data_internal *cdata)
+ {
+ struct rpcrdma_connect_private *pmsg = &ep->rep_cm_private;
++ unsigned int max_qp_wr, max_sge;
+ struct ib_cq *sendcq, *recvcq;
+- unsigned int max_qp_wr;
+ int rc;
+
+- if (ia->ri_device->attrs.max_sge < RPCRDMA_MAX_SEND_SGES) {
+- dprintk("RPC: %s: insufficient sge's available\n",
+- __func__);
++ max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES);
++ if (max_sge < RPCRDMA_MIN_SEND_SGES) {
++ pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge);
+ return -ENOMEM;
+ }
++ ia->ri_max_send_sges = max_sge - RPCRDMA_MIN_SEND_SGES;
+
+ if (ia->ri_device->attrs.max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
+ dprintk("RPC: %s: insufficient wqe's available\n",
+@@ -513,7 +516,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
+ ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
+ ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
+ ep->rep_attr.cap.max_recv_wr += 1; /* drain cqe */
+- ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_SEND_SGES;
++ ep->rep_attr.cap.max_send_sge = max_sge;
+ ep->rep_attr.cap.max_recv_sge = 1;
+ ep->rep_attr.cap.max_inline_data = 0;
+ ep->rep_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
+diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
+index f6ae1b2..48989d5 100644
+--- a/net/sunrpc/xprtrdma/xprt_rdma.h
++++ b/net/sunrpc/xprtrdma/xprt_rdma.h
+@@ -74,7 +74,9 @@ struct rpcrdma_ia {
+ unsigned int ri_max_frmr_depth;
+ unsigned int ri_max_inline_write;
+ unsigned int ri_max_inline_read;
++ unsigned int ri_max_send_sges;
+ bool ri_reminv_expected;
++ bool ri_implicit_roundup;
+ struct ib_qp_attr ri_qp_attr;
+ struct ib_qp_init_attr ri_qp_init_attr;
+ };
+@@ -309,6 +311,7 @@ struct rpcrdma_mr_seg { /* chunk descriptors */
+ * - xdr_buf tail iovec
+ */
+ enum {
++ RPCRDMA_MIN_SEND_SGES = 3,
+ RPCRDMA_MAX_SEND_PAGES = PAGE_SIZE + RPCRDMA_MAX_INLINE - 1,
+ RPCRDMA_MAX_PAGE_SGES = (RPCRDMA_MAX_SEND_PAGES >> PAGE_SHIFT) + 1,
+ RPCRDMA_MAX_SEND_SGES = 1 + 1 + RPCRDMA_MAX_PAGE_SGES + 1,
+diff --git a/samples/seccomp/bpf-helper.h b/samples/seccomp/bpf-helper.h
+index 38ee70f..1d8de9e 100644
+--- a/samples/seccomp/bpf-helper.h
++++ b/samples/seccomp/bpf-helper.h
+@@ -138,7 +138,7 @@ union arg64 {
+ #define ARG_32(idx) \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
+
+-/* Loads hi into A and lo in X */
++/* Loads lo into M[0] and hi into M[1] and A */
+ #define ARG_64(idx) \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
+ BPF_STMT(BPF_ST, 0), /* lo -> M[0] */ \
+@@ -153,88 +153,107 @@ union arg64 {
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
+ jt
+
+-/* Checks the lo, then swaps to check the hi. A=lo,X=hi */
++#define JA32(value, jt) \
++ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
++ jt
++
++#define JGE32(value, jt) \
++ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
++ jt
++
++#define JGT32(value, jt) \
++ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
++ jt
++
++#define JLE32(value, jt) \
++ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
++ jt
++
++#define JLT32(value, jt) \
++ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
++ jt
++
++/*
++ * All the JXX64 checks assume lo is saved in M[0] and hi is saved in both
++ * A and M[1]. This invariant is kept by restoring A if necessary.
++ */
+ #define JEQ64(lo, hi, jt) \
++ /* if (hi != arg.hi) goto NOMATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+ BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ /* if (lo != arg.lo) goto NOMATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+ #define JNE64(lo, hi, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ /* if (hi != arg.hi) goto MATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo != arg.lo) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JA32(value, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
+- jt
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+ #define JA64(lo, hi, jt) \
++ /* if (hi & arg.hi) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo & arg.lo) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+-#define JGE32(value, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
+- jt
+-
+-#define JLT32(value, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
+- jt
+-
+-/* Shortcut checking if hi > arg.hi. */
+ #define JGE64(lo, hi, jt) \
++ /* if (hi > arg.hi) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++ /* if (hi != arg.hi) goto NOMATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo >= arg.lo) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
+- jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
+-
+-#define JLT64(lo, hi, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
+- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
+- BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+-#define JGT32(value, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
+- jt
+-
+-#define JLE32(value, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
+- jt
+-
+-/* Check hi > args.hi first, then do the GE checking */
+ #define JGT64(lo, hi, jt) \
++ /* if (hi > arg.hi) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
++ /* if (hi != arg.hi) goto NOMATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo > arg.lo) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+ #define JLE64(lo, hi, jt) \
+- BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
+- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
+- BPF_STMT(BPF_LD+BPF_MEM, 0), /* swap in lo */ \
++ /* if (hi < arg.hi) goto MATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++ /* if (hi != arg.hi) goto NOMATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo <= arg.lo) goto MATCH; */ \
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
+- BPF_STMT(BPF_LD+BPF_MEM, 1), /* passed: swap hi back in */ \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
++ jt, \
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
++
++#define JLT64(lo, hi, jt) \
++ /* if (hi < arg.hi) goto MATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
++ /* if (hi != arg.hi) goto NOMATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
++ BPF_STMT(BPF_LD+BPF_MEM, 0), \
++ /* if (lo < arg.lo) goto MATCH; */ \
++ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 2, 0), \
++ BPF_STMT(BPF_LD+BPF_MEM, 1), \
+ jt, \
+- BPF_STMT(BPF_LD+BPF_MEM, 1) /* failed: swap hi back in */
++ BPF_STMT(BPF_LD+BPF_MEM, 1)
+
+ #define LOAD_SYSCALL_NR \
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
+diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
+index db25f54..df7834a 100644
+--- a/security/integrity/ima/ima.h
++++ b/security/integrity/ima/ima.h
+@@ -173,7 +173,7 @@ int ima_store_template(struct ima_template_entry *entry, int violation,
+ struct inode *inode,
+ const unsigned char *filename, int pcr);
+ void ima_free_template_entry(struct ima_template_entry *entry);
+-const char *ima_d_path(const struct path *path, char **pathbuf);
++const char *ima_d_path(const struct path *path, char **pathbuf, char *filename);
+
+ /* IMA policy related functions */
+ int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask,
+diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
+index 9df26a2..d01a52f 100644
+--- a/security/integrity/ima/ima_api.c
++++ b/security/integrity/ima/ima_api.c
+@@ -318,7 +318,17 @@ void ima_audit_measurement(struct integrity_iint_cache *iint,
+ iint->flags |= IMA_AUDITED;
+ }
+
+-const char *ima_d_path(const struct path *path, char **pathbuf)
++/*
++ * ima_d_path - return a pointer to the full pathname
++ *
++ * Attempt to return a pointer to the full pathname for use in the
++ * IMA measurement list, IMA audit records, and auditing logs.
++ *
++ * On failure, return a pointer to a copy of the filename, not dname.
++ * Returning a pointer to dname, could result in using the pointer
++ * after the memory has been freed.
++ */
++const char *ima_d_path(const struct path *path, char **pathbuf, char *namebuf)
+ {
+ char *pathname = NULL;
+
+@@ -331,5 +341,11 @@ const char *ima_d_path(const struct path *path, char **pathbuf)
+ pathname = NULL;
+ }
+ }
+- return pathname ?: (const char *)path->dentry->d_name.name;
++
++ if (!pathname) {
++ strlcpy(namebuf, path->dentry->d_name.name, NAME_MAX);
++ pathname = namebuf;
++ }
++
++ return pathname;
+ }
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 423d111..0e87629 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -83,6 +83,7 @@ static void ima_rdwr_violation_check(struct file *file,
+ const char **pathname)
+ {
+ struct inode *inode = file_inode(file);
++ char filename[NAME_MAX];
+ fmode_t mode = file->f_mode;
+ bool send_tomtou = false, send_writers = false;
+
+@@ -102,7 +103,7 @@ static void ima_rdwr_violation_check(struct file *file,
+ if (!send_tomtou && !send_writers)
+ return;
+
+- *pathname = ima_d_path(&file->f_path, pathbuf);
++ *pathname = ima_d_path(&file->f_path, pathbuf, filename);
+
+ if (send_tomtou)
+ ima_add_violation(file, *pathname, iint,
+@@ -161,6 +162,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
+ struct integrity_iint_cache *iint = NULL;
+ struct ima_template_desc *template_desc;
+ char *pathbuf = NULL;
++ char filename[NAME_MAX];
+ const char *pathname = NULL;
+ int rc = -ENOMEM, action, must_appraise;
+ int pcr = CONFIG_IMA_MEASURE_PCR_IDX;
+@@ -239,8 +241,8 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
+ goto out_digsig;
+ }
+
+- if (!pathname) /* ima_rdwr_violation possibly pre-fetched */
+- pathname = ima_d_path(&file->f_path, &pathbuf);
++ if (!pathbuf) /* ima_rdwr_violation possibly pre-fetched */
++ pathname = ima_d_path(&file->f_path, &pathbuf, filename);
+
+ if (action & IMA_MEASURE)
+ ima_store_measurement(iint, file, pathname,
+diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
+index 1d5acbe..86240d0 100644
+--- a/sound/core/seq/seq_fifo.c
++++ b/sound/core/seq/seq_fifo.c
+@@ -135,6 +135,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
+ f->tail = cell;
+ if (f->head == NULL)
+ f->head = cell;
++ cell->next = NULL;
+ f->cells++;
+ spin_unlock_irqrestore(&f->lock, flags);
+
+@@ -214,6 +215,8 @@ void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f,
+ spin_lock_irqsave(&f->lock, flags);
+ cell->next = f->head;
+ f->head = cell;
++ if (!f->tail)
++ f->tail = cell;
+ f->cells++;
+ spin_unlock_irqrestore(&f->lock, flags);
+ }
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index fc144f4..ad15314 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1702,9 +1702,21 @@ static int snd_timer_user_params(struct file *file,
+ return -EBADFD;
+ if (copy_from_user(&params, _params, sizeof(params)))
+ return -EFAULT;
+- if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE) && params.ticks < 1) {
+- err = -EINVAL;
+- goto _end;
++ if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
++ u64 resolution;
++
++ if (params.ticks < 1) {
++ err = -EINVAL;
++ goto _end;
++ }
++
++ /* Don't allow resolution less than 1ms */
++ resolution = snd_timer_resolution(tu->timeri);
++ resolution *= params.ticks;
++ if (resolution < 1000000) {
++ err = -EINVAL;
++ goto _end;
++ }
+ }
+ if (params.queue_size > 0 &&
+ (params.queue_size < 32 || params.queue_size > 1024)) {
+diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
+index 9667cbf..ab4cdab 100644
+--- a/sound/pci/ctxfi/cthw20k1.c
++++ b/sound/pci/ctxfi/cthw20k1.c
+@@ -27,12 +27,6 @@
+ #include "cthw20k1.h"
+ #include "ct20k1reg.h"
+
+-#if BITS_PER_LONG == 32
+-#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
+-#else
+-#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
+-#endif
+-
+ struct hw20k1 {
+ struct hw hw;
+ spinlock_t reg_20k1_lock;
+@@ -1904,19 +1898,18 @@ static int hw_card_start(struct hw *hw)
+ {
+ int err;
+ struct pci_dev *pci = hw->pci;
++ const unsigned int dma_bits = BITS_PER_LONG;
+
+ err = pci_enable_device(pci);
+ if (err < 0)
+ return err;
+
+ /* Set DMA transfer mask */
+- if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 ||
+- dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) {
+- dev_err(hw->card->dev,
+- "architecture does not support PCI busmaster DMA with mask 0x%llx\n",
+- CT_XFI_DMA_MASK);
+- err = -ENXIO;
+- goto error1;
++ if (dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
++ dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
++ } else {
++ dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
++ dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
+ }
+
+ if (!hw->io_base) {
+diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
+index 6414ecf..18ee776 100644
+--- a/sound/pci/ctxfi/cthw20k2.c
++++ b/sound/pci/ctxfi/cthw20k2.c
+@@ -26,12 +26,6 @@
+ #include "cthw20k2.h"
+ #include "ct20k2reg.h"
+
+-#if BITS_PER_LONG == 32
+-#define CT_XFI_DMA_MASK DMA_BIT_MASK(32) /* 32 bit PTE */
+-#else
+-#define CT_XFI_DMA_MASK DMA_BIT_MASK(64) /* 64 bit PTE */
+-#endif
+-
+ struct hw20k2 {
+ struct hw hw;
+ /* for i2c */
+@@ -2029,19 +2023,18 @@ static int hw_card_start(struct hw *hw)
+ int err = 0;
+ struct pci_dev *pci = hw->pci;
+ unsigned int gctl;
++ const unsigned int dma_bits = BITS_PER_LONG;
+
+ err = pci_enable_device(pci);
+ if (err < 0)
+ return err;
+
+ /* Set DMA transfer mask */
+- if (dma_set_mask(&pci->dev, CT_XFI_DMA_MASK) < 0 ||
+- dma_set_coherent_mask(&pci->dev, CT_XFI_DMA_MASK) < 0) {
+- dev_err(hw->card->dev,
+- "architecture does not support PCI busmaster DMA with mask 0x%llx\n",
+- CT_XFI_DMA_MASK);
+- err = -ENXIO;
+- goto error1;
++ if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(dma_bits))) {
++ dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(dma_bits));
++ } else {
++ dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
++ dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
+ }
+
+ if (!hw->io_base) {
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index c64d986..bc44626 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -2197,9 +2197,9 @@ static const struct pci_device_id azx_ids[] = {
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+ /* Lewisburg */
+ { PCI_DEVICE(0x8086, 0xa1f0),
+- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ { PCI_DEVICE(0x8086, 0xa270),
+- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
++ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ /* Lynx Point-LP */
+ { PCI_DEVICE(0x8086, 0x9c20),
+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 758ac86..0c62b1d 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5577,6 +5577,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
+ SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+ SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
++ SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
+ SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+@@ -5692,6 +5693,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
+ SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+ SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
++ SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+ SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+ SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
+ SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
+@@ -6065,6 +6067,12 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+ ALC298_STANDARD_PINS,
+ {0x17, 0x90170150}),
++ SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_SPK_VOLUME,
++ {0x12, 0xb7a60140},
++ {0x13, 0xb7a60150},
++ {0x17, 0x90170110},
++ {0x1a, 0x03011020},
++ {0x21, 0x03211030}),
+ {}
+ };
+
+diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
+index ae58b49..ecf6236 100644
+--- a/tools/perf/util/callchain.c
++++ b/tools/perf/util/callchain.c
+@@ -437,7 +437,7 @@ fill_node(struct callchain_node *node, struct callchain_cursor *cursor)
+ }
+ call->ip = cursor_node->ip;
+ call->ms.sym = cursor_node->sym;
+- call->ms.map = cursor_node->map;
++ call->ms.map = map__get(cursor_node->map);
+ list_add_tail(&call->list, &node->val);
+
+ callchain_cursor_advance(cursor);
+@@ -462,6 +462,7 @@ add_child(struct callchain_node *parent,
+
+ list_for_each_entry_safe(call, tmp, &new->val, list) {
+ list_del(&call->list);
++ map__zput(call->ms.map);
+ free(call);
+ }
+ free(new);
+@@ -730,6 +731,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
+ callchain_cursor_append(cursor, list->ip,
+ list->ms.map, list->ms.sym);
+ list_del(&list->list);
++ map__zput(list->ms.map);
+ free(list);
+ }
+
+@@ -778,7 +780,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
+ }
+
+ node->ip = ip;
+- node->map = map;
++ map__zput(node->map);
++ node->map = map__get(map);
+ node->sym = sym;
+
+ cursor->nr++;
+@@ -945,11 +948,13 @@ static void free_callchain_node(struct callchain_node *node)
+
+ list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
+ list_del(&list->list);
++ map__zput(list->ms.map);
+ free(list);
+ }
+
+ list_for_each_entry_safe(list, tmp, &node->val, list) {
+ list_del(&list->list);
++ map__zput(list->ms.map);
+ free(list);
+ }
+
+@@ -1013,6 +1018,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
+ goto out;
+ *new = *chain;
+ new->has_children = false;
++ map__get(new->ms.map);
+ list_add_tail(&new->list, &head);
+ }
+ parent = parent->parent;
+@@ -1033,6 +1039,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
+ out:
+ list_for_each_entry_safe(chain, new, &head, list) {
+ list_del(&chain->list);
++ map__zput(chain->ms.map);
+ free(chain);
+ }
+ return -ENOMEM;
+diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
+index 47cfd10..b7cbabb 100644
+--- a/tools/perf/util/callchain.h
++++ b/tools/perf/util/callchain.h
+@@ -5,6 +5,7 @@
+ #include <linux/list.h>
+ #include <linux/rbtree.h>
+ #include "event.h"
++#include "map.h"
+ #include "symbol.h"
+
+ #define HELP_PAD "\t\t\t\t"
+@@ -174,8 +175,13 @@ int callchain_merge(struct callchain_cursor *cursor,
+ */
+ static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
+ {
++ struct callchain_cursor_node *node;
++
+ cursor->nr = 0;
+ cursor->last = &cursor->first;
++
++ for (node = cursor->first; node != NULL; node = node->next)
++ map__zput(node->map);
+ }
+
+ int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index a69f027..10849a0 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -1,6 +1,7 @@
+ #include "util.h"
+ #include "build-id.h"
+ #include "hist.h"
++#include "map.h"
+ #include "session.h"
+ #include "sort.h"
+ #include "evlist.h"
+@@ -1019,6 +1020,10 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
+ int max_stack_depth, void *arg)
+ {
+ int err, err2;
++ struct map *alm = NULL;
++
++ if (al && al->map)
++ alm = map__get(al->map);
+
+ err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
+ iter->evsel, al, max_stack_depth);
+@@ -1058,6 +1063,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
+ if (!err)
+ err = err2;
+
++ map__put(alm);
++
+ return err;
+ }
+
+diff --git a/virt/kvm/arm/vgic/vgic-irqfd.c b/virt/kvm/arm/vgic/vgic-irqfd.c
+index d918dcf..f138ed2 100644
+--- a/virt/kvm/arm/vgic/vgic-irqfd.c
++++ b/virt/kvm/arm/vgic/vgic-irqfd.c
+@@ -99,6 +99,9 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
+ if (!vgic_has_its(kvm))
+ return -ENODEV;
+
++ if (!level)
++ return -1;
++
+ return vgic_its_inject_msi(kvm, &msi);
+ }
+
diff --git a/4.9.15/1014_linux-4.9.15.patch b/4.9.15/1014_linux-4.9.15.patch
new file mode 100644
index 0000000..cd11900
--- /dev/null
+++ b/4.9.15/1014_linux-4.9.15.patch
@@ -0,0 +1,2838 @@
+diff --git a/Makefile b/Makefile
+index 5e7706e..03df4fc 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index 602af69..6bcbbec 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -89,7 +89,8 @@ extern void execve_tail(void);
+ * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
+ */
+
+-#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit)
++#define TASK_SIZE_OF(tsk) ((tsk)->mm ? \
++ (tsk)->mm->context.asce_limit : TASK_MAX_SIZE)
+ #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \
+ (1UL << 30) : (1UL << 41))
+ #define TASK_SIZE TASK_SIZE_OF(current)
+diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
+index f9293bf..408b4f4 100644
+--- a/arch/s390/kernel/crash_dump.c
++++ b/arch/s390/kernel/crash_dump.c
+@@ -329,7 +329,11 @@ static void *nt_init_name(void *buf, Elf64_Word type, void *desc, int d_len,
+
+ static inline void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len)
+ {
+- return nt_init_name(buf, type, desc, d_len, KEXEC_CORE_NOTE_NAME);
++ const char *note_name = "LINUX";
++
++ if (type == NT_PRPSINFO || type == NT_PRSTATUS || type == NT_PRFPREG)
++ note_name = KEXEC_CORE_NOTE_NAME;
++ return nt_init_name(buf, type, desc, d_len, note_name);
+ }
+
+ /*
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index d027f2e..e974e53 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -819,10 +819,10 @@ static void __init setup_randomness(void)
+ {
+ struct sysinfo_3_2_2 *vmms;
+
+- vmms = (struct sysinfo_3_2_2 *) alloc_page(GFP_KERNEL);
+- if (vmms && stsi(vmms, 3, 2, 2) == 0 && vmms->count)
+- add_device_randomness(&vmms, vmms->count);
+- free_page((unsigned long) vmms);
++ vmms = (struct sysinfo_3_2_2 *) memblock_alloc(PAGE_SIZE, PAGE_SIZE);
++ if (stsi(vmms, 3, 2, 2) == 0 && vmms->count)
++ add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count);
++ memblock_free((unsigned long) vmms, PAGE_SIZE);
+ }
+
+ /*
+diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
+index 47a1de7..5ba494e 100644
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -442,6 +442,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
+ struct kvm_memory_slot *memslot;
+ int is_dirty = 0;
+
++ if (kvm_is_ucontrol(kvm))
++ return -EINVAL;
++
+ mutex_lock(&kvm->slots_lock);
+
+ r = -EINVAL;
+diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
+index 6fa8594..fc5abff 100644
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -188,7 +188,7 @@ static inline void __native_flush_tlb_single(unsigned long addr)
+
+ static inline void __flush_tlb_all(void)
+ {
+- if (static_cpu_has(X86_FEATURE_PGE))
++ if (boot_cpu_has(X86_FEATURE_PGE))
+ __flush_tlb_global();
+ else
+ __flush_tlb();
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 64774f4..69b8f8a 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -3693,7 +3693,7 @@ static void fix_rmode_seg(int seg, struct kvm_segment *save)
+ }
+
+ vmcs_write16(sf->selector, var.selector);
+- vmcs_write32(sf->base, var.base);
++ vmcs_writel(sf->base, var.base);
+ vmcs_write32(sf->limit, var.limit);
+ vmcs_write32(sf->ar_bytes, vmx_segment_access_rights(&var));
+ }
+@@ -8202,7 +8202,7 @@ static void kvm_flush_pml_buffers(struct kvm *kvm)
+ static void vmx_dump_sel(char *name, uint32_t sel)
+ {
+ pr_err("%s sel=0x%04x, attr=0x%05x, limit=0x%08x, base=0x%016lx\n",
+- name, vmcs_read32(sel),
++ name, vmcs_read16(sel),
+ vmcs_read32(sel + GUEST_ES_AR_BYTES - GUEST_ES_SELECTOR),
+ vmcs_read32(sel + GUEST_ES_LIMIT - GUEST_ES_SELECTOR),
+ vmcs_readl(sel + GUEST_ES_BASE - GUEST_ES_SELECTOR));
+diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
+index 0d4fb3e..1680768 100644
+--- a/arch/x86/mm/gup.c
++++ b/arch/x86/mm/gup.c
+@@ -120,6 +120,11 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
+ return 0;
+ }
+
++ if (!pte_allows_gup(pte_val(pte), write)) {
++ pte_unmap(ptep);
++ return 0;
++ }
++
+ if (pte_devmap(pte)) {
+ pgmap = get_dev_pagemap(pte_pfn(pte), pgmap);
+ if (unlikely(!pgmap)) {
+@@ -127,8 +132,7 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
+ pte_unmap(ptep);
+ return 0;
+ }
+- } else if (!pte_allows_gup(pte_val(pte), write) ||
+- pte_special(pte)) {
++ } else if (pte_special(pte)) {
+ pte_unmap(ptep);
+ return 0;
+ }
+diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
+index 32cdc2c..a45d32a 100644
+--- a/arch/xtensa/kernel/setup.c
++++ b/arch/xtensa/kernel/setup.c
+@@ -133,6 +133,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
+
+ __tagtable(BP_TAG_INITRD, parse_tag_initrd);
+
++#endif /* CONFIG_BLK_DEV_INITRD */
++
+ #ifdef CONFIG_OF
+
+ static int __init parse_tag_fdt(const bp_tag_t *tag)
+@@ -145,8 +147,6 @@ __tagtable(BP_TAG_FDT, parse_tag_fdt);
+
+ #endif /* CONFIG_OF */
+
+-#endif /* CONFIG_BLK_DEV_INITRD */
+-
+ static int __init parse_tag_cmdline(const bp_tag_t* tag)
+ {
+ strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index 6eb6733..d1664df 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -1603,7 +1603,7 @@ static size_t sizeof_nfit_set_info(int num_mappings)
+ + num_mappings * sizeof(struct nfit_set_info_map);
+ }
+
+-static int cmp_map(const void *m0, const void *m1)
++static int cmp_map_compat(const void *m0, const void *m1)
+ {
+ const struct nfit_set_info_map *map0 = m0;
+ const struct nfit_set_info_map *map1 = m1;
+@@ -1612,6 +1612,14 @@ static int cmp_map(const void *m0, const void *m1)
+ sizeof(u64));
+ }
+
++static int cmp_map(const void *m0, const void *m1)
++{
++ const struct nfit_set_info_map *map0 = m0;
++ const struct nfit_set_info_map *map1 = m1;
++
++ return map0->region_offset - map1->region_offset;
++}
++
+ /* Retrieve the nth entry referencing this spa */
+ static struct acpi_nfit_memory_map *memdev_from_spa(
+ struct acpi_nfit_desc *acpi_desc, u16 range_index, int n)
+@@ -1667,6 +1675,12 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc,
+ sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
+ cmp_map, NULL);
+ nd_set->cookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
++
++ /* support namespaces created with the wrong sort order */
++ sort(&info->mapping[0], nr, sizeof(struct nfit_set_info_map),
++ cmp_map_compat, NULL);
++ nd_set->altcookie = nd_fletcher64(info, sizeof_nfit_set_info(nr), 0);
++
+ ndr_desc->nd_set = nd_set;
+ devm_kfree(dev, info);
+
+diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
+index fadba88..b793853 100644
+--- a/drivers/bluetooth/ath3k.c
++++ b/drivers/bluetooth/ath3k.c
+@@ -94,6 +94,7 @@ static const struct usb_device_id ath3k_table[] = {
+ { USB_DEVICE(0x04CA, 0x300f) },
+ { USB_DEVICE(0x04CA, 0x3010) },
+ { USB_DEVICE(0x04CA, 0x3014) },
++ { USB_DEVICE(0x04CA, 0x3018) },
+ { USB_DEVICE(0x0930, 0x0219) },
+ { USB_DEVICE(0x0930, 0x021c) },
+ { USB_DEVICE(0x0930, 0x0220) },
+@@ -162,6 +163,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
+ { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
++ { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 2f633df..dd220fa 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -209,6 +209,7 @@ static const struct usb_device_id blacklist_table[] = {
+ { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
++ { USB_DEVICE(0x04ca, 0x3018), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
+diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
+index b9629b2..d1651a5 100644
+--- a/drivers/dma/imx-sdma.c
++++ b/drivers/dma/imx-sdma.c
+@@ -298,6 +298,7 @@ struct sdma_engine;
+ * @event_id1 for channels that use 2 events
+ * @word_size peripheral access size
+ * @buf_tail ID of the buffer that was processed
++ * @buf_ptail ID of the previous buffer that was processed
+ * @num_bd max NUM_BD. number of descriptors currently handling
+ */
+ struct sdma_channel {
+@@ -309,6 +310,7 @@ struct sdma_channel {
+ unsigned int event_id1;
+ enum dma_slave_buswidth word_size;
+ unsigned int buf_tail;
++ unsigned int buf_ptail;
+ unsigned int num_bd;
+ unsigned int period_len;
+ struct sdma_buffer_descriptor *bd;
+@@ -700,6 +702,8 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
+ sdmac->chn_real_count = bd->mode.count;
+ bd->mode.status |= BD_DONE;
+ bd->mode.count = sdmac->period_len;
++ sdmac->buf_ptail = sdmac->buf_tail;
++ sdmac->buf_tail = (sdmac->buf_tail + 1) % sdmac->num_bd;
+
+ /*
+ * The callback is called from the interrupt context in order
+@@ -710,9 +714,6 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
+
+ dmaengine_desc_get_callback_invoke(&sdmac->desc, NULL);
+
+- sdmac->buf_tail++;
+- sdmac->buf_tail %= sdmac->num_bd;
+-
+ if (error)
+ sdmac->status = old_status;
+ }
+@@ -1186,6 +1187,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
+ sdmac->flags = 0;
+
+ sdmac->buf_tail = 0;
++ sdmac->buf_ptail = 0;
++ sdmac->chn_real_count = 0;
+
+ dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
+ sg_len, channel);
+@@ -1288,6 +1291,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
+ sdmac->status = DMA_IN_PROGRESS;
+
+ sdmac->buf_tail = 0;
++ sdmac->buf_ptail = 0;
++ sdmac->chn_real_count = 0;
+ sdmac->period_len = period_len;
+
+ sdmac->flags |= IMX_DMA_SG_LOOP;
+@@ -1385,7 +1390,7 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
+ u32 residue;
+
+ if (sdmac->flags & IMX_DMA_SG_LOOP)
+- residue = (sdmac->num_bd - sdmac->buf_tail) *
++ residue = (sdmac->num_bd - sdmac->buf_ptail) *
+ sdmac->period_len - sdmac->chn_real_count;
+ else
+ residue = sdmac->chn_count - sdmac->chn_real_count;
+diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+index 7ddc321..64a1df6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+@@ -3814,9 +3814,15 @@ static void dce_v11_0_encoder_add(struct amdgpu_device *adev,
+ default:
+ encoder->possible_crtcs = 0x3;
+ break;
++ case 3:
++ encoder->possible_crtcs = 0x7;
++ break;
+ case 4:
+ encoder->possible_crtcs = 0xf;
+ break;
++ case 5:
++ encoder->possible_crtcs = 0x1f;
++ break;
+ case 6:
+ encoder->possible_crtcs = 0x3f;
+ break;
+diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
+index 810c51d..30672a3 100644
+--- a/drivers/gpu/drm/ast/ast_post.c
++++ b/drivers/gpu/drm/ast/ast_post.c
+@@ -58,13 +58,9 @@ bool ast_is_vga_enabled(struct drm_device *dev)
+ /* TODO 1180 */
+ } else {
+ ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT);
+- if (ch) {
+- ast_open_key(ast);
+- ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
+- return ch & 0x04;
+- }
++ return !!(ch & 0x01);
+ }
+- return 0;
++ return false;
+ }
+
+ static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
+@@ -375,8 +371,8 @@ void ast_post_gpu(struct drm_device *dev)
+ pci_write_config_dword(ast->dev->pdev, 0x04, reg);
+
+ ast_enable_vga(dev);
+- ast_enable_mmio(dev);
+ ast_open_key(ast);
++ ast_enable_mmio(dev);
+ ast_set_def_ext_reg(dev);
+
+ if (ast->chip == AST2300 || ast->chip == AST2400)
+@@ -1630,12 +1626,44 @@ static void ast_init_dram_2300(struct drm_device *dev)
+ temp |= 0x73;
+ ast_write32(ast, 0x12008, temp);
+
++ param.dram_freq = 396;
+ param.dram_type = AST_DDR3;
++ temp = ast_mindwm(ast, 0x1e6e2070);
+ if (temp & 0x01000000)
+ param.dram_type = AST_DDR2;
+- param.dram_chipid = ast->dram_type;
+- param.dram_freq = ast->mclk;
+- param.vram_size = ast->vram_size;
++ switch (temp & 0x18000000) {
++ case 0:
++ param.dram_chipid = AST_DRAM_512Mx16;
++ break;
++ default:
++ case 0x08000000:
++ param.dram_chipid = AST_DRAM_1Gx16;
++ break;
++ case 0x10000000:
++ param.dram_chipid = AST_DRAM_2Gx16;
++ break;
++ case 0x18000000:
++ param.dram_chipid = AST_DRAM_4Gx16;
++ break;
++ }
++ switch (temp & 0x0c) {
++ default:
++ case 0x00:
++ param.vram_size = AST_VIDMEM_SIZE_8M;
++ break;
++
++ case 0x04:
++ param.vram_size = AST_VIDMEM_SIZE_16M;
++ break;
++
++ case 0x08:
++ param.vram_size = AST_VIDMEM_SIZE_32M;
++ break;
++
++ case 0x0c:
++ param.vram_size = AST_VIDMEM_SIZE_64M;
++ break;
++ }
+
+ if (param.dram_type == AST_DDR3) {
+ get_ddr3_info(ast, &param);
+diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
+index a05bb38..2e42a05 100644
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -362,7 +362,7 @@ mode_fixup(struct drm_atomic_state *state)
+ struct drm_connector *connector;
+ struct drm_connector_state *conn_state;
+ int i;
+- bool ret;
++ int ret;
+
+ for_each_crtc_in_state(state, crtc, crtc_state, i) {
+ if (!crtc_state->mode_changed &&
+diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
+index ec77bd3..7491180 100644
+--- a/drivers/gpu/drm/drm_edid.c
++++ b/drivers/gpu/drm/drm_edid.c
+@@ -145,6 +145,9 @@ static struct edid_quirk {
+
+ /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
+ { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },
++
++ /* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
++ { "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
+ };
+
+ /*
+diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
+index 6c75e62..6a48d66 100644
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -848,6 +848,9 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
+ if (!drm_fbdev_emulation)
+ return;
+
++ cancel_work_sync(&fb_helper->resume_work);
++ cancel_work_sync(&fb_helper->dirty_work);
++
+ if (!list_empty(&fb_helper->kernel_fb_list)) {
+ list_del(&fb_helper->kernel_fb_list);
+ if (list_empty(&kernel_fb_helper_list)) {
+diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
+index 9a71ed5..f46aac1 100644
+--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
+@@ -415,6 +415,11 @@ int i915_gem_init_stolen(struct drm_device *dev)
+
+ mutex_init(&dev_priv->mm.stolen_lock);
+
++ if (intel_vgpu_active(dev_priv)) {
++ DRM_INFO("iGVT-g active, disabling use of stolen memory\n");
++ return 0;
++ }
++
+ #ifdef CONFIG_INTEL_IOMMU
+ if (intel_iommu_gfx_mapped && INTEL_INFO(dev)->gen < 8) {
+ DRM_INFO("DMAR active, disabling use of stolen memory\n");
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 0555250..7b06280 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -2832,6 +2832,9 @@ static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
+ enum pipe pipe = intel_dp->pps_pipe;
+ i915_reg_t pp_on_reg = PP_ON_DELAYS(pipe);
+
++ if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
++ return;
++
+ edp_panel_vdd_off_sync(intel_dp);
+
+ /*
+@@ -2859,9 +2862,6 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
+
+ lockdep_assert_held(&dev_priv->pps_mutex);
+
+- if (WARN_ON(pipe != PIPE_A && pipe != PIPE_B))
+- return;
+-
+ for_each_intel_encoder(dev, encoder) {
+ struct intel_dp *intel_dp;
+ enum port port;
+diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
+index 7acbbbf..4534e4c 100644
+--- a/drivers/gpu/drm/i915/intel_opregion.c
++++ b/drivers/gpu/drm/i915/intel_opregion.c
+@@ -1031,7 +1031,18 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
+ opregion->vbt_size = vbt_size;
+ } else {
+ vbt = base + OPREGION_VBT_OFFSET;
+- vbt_size = OPREGION_ASLE_EXT_OFFSET - OPREGION_VBT_OFFSET;
++ /*
++ * The VBT specification says that if the ASLE ext
++ * mailbox is not used its area is reserved, but
++ * on some CHT boards the VBT extends into the
++ * ASLE ext area. Allow this even though it is
++ * against the spec, so we do not end up rejecting
++ * the VBT on those boards (and end up not finding the
++ * LCD panel because of this).
++ */
++ vbt_size = (mboxes & MBOX_ASLE_EXT) ?
++ OPREGION_ASLE_EXT_OFFSET : OPREGION_SIZE;
++ vbt_size -= OPREGION_VBT_OFFSET;
+ if (intel_bios_is_valid_vbt(vbt, vbt_size)) {
+ DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (Mailbox #4)\n");
+ opregion->vbt = vbt;
+diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
+index 8fc0888..89cf009 100644
+--- a/drivers/gpu/drm/imx/imx-tve.c
++++ b/drivers/gpu/drm/imx/imx-tve.c
+@@ -98,6 +98,8 @@
+ /* TVE_TST_MODE_REG */
+ #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0)
+
++#define IMX_TVE_DAC_VOLTAGE 2750000
++
+ enum {
+ TVE_MODE_TVOUT,
+ TVE_MODE_VGA,
+@@ -628,9 +630,8 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data)
+
+ tve->dac_reg = devm_regulator_get(dev, "dac");
+ if (!IS_ERR(tve->dac_reg)) {
+- ret = regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
+- if (ret)
+- return ret;
++ if (regulator_get_voltage(tve->dac_reg) != IMX_TVE_DAC_VOLTAGE)
++ dev_warn(dev, "dac voltage is not %d uV\n", IMX_TVE_DAC_VOLTAGE);
+ ret = regulator_enable(tve->dac_reg);
+ if (ret)
+ return ret;
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
+index fc6217d..35cc16f 100644
+--- a/drivers/gpu/drm/ttm/ttm_bo.c
++++ b/drivers/gpu/drm/ttm/ttm_bo.c
+@@ -1654,7 +1654,6 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
+ struct ttm_buffer_object *bo;
+ int ret = -EBUSY;
+ int put_count;
+- uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
+
+ spin_lock(&glob->lru_lock);
+ list_for_each_entry(bo, &glob->swap_lru, swap) {
+@@ -1685,7 +1684,8 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
+ * Move to system cached
+ */
+
+- if ((bo->mem.placement & swap_placement) != swap_placement) {
++ if (bo->mem.mem_type != TTM_PL_SYSTEM ||
++ bo->ttm->caching_state != tt_cached) {
+ struct ttm_mem_reg evict_mem;
+
+ evict_mem = bo->mem;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index 18061a4..36005bd 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -199,9 +199,14 @@ static const struct drm_ioctl_desc vmw_ioctls[] = {
+ VMW_IOCTL_DEF(VMW_PRESENT_READBACK,
+ vmw_present_readback_ioctl,
+ DRM_MASTER | DRM_AUTH),
++ /*
++ * The permissions of the below ioctl are overridden in
++ * vmw_generic_ioctl(). We require either
++ * DRM_MASTER or capable(CAP_SYS_ADMIN).
++ */
+ VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT,
+ vmw_kms_update_layout_ioctl,
+- DRM_MASTER | DRM_CONTROL_ALLOW),
++ DRM_RENDER_ALLOW),
+ VMW_IOCTL_DEF(VMW_CREATE_SHADER,
+ vmw_shader_define_ioctl,
+ DRM_AUTH | DRM_RENDER_ALLOW),
+@@ -1125,6 +1130,10 @@ static long vmw_generic_ioctl(struct file *filp, unsigned int cmd,
+
+ return (long) vmw_execbuf_ioctl(dev, arg, file_priv,
+ _IOC_SIZE(cmd));
++ } else if (nr == DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT) {
++ if (!drm_is_current_master(file_priv) &&
++ !capable(CAP_SYS_ADMIN))
++ return -EACCES;
+ }
+
+ if (unlikely(ioctl->cmd != cmd))
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index 1e59a48..59ff419 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -41,9 +41,9 @@
+ #include <drm/ttm/ttm_module.h>
+ #include "vmwgfx_fence.h"
+
+-#define VMWGFX_DRIVER_DATE "20160210"
++#define VMWGFX_DRIVER_DATE "20170221"
+ #define VMWGFX_DRIVER_MAJOR 2
+-#define VMWGFX_DRIVER_MINOR 11
++#define VMWGFX_DRIVER_MINOR 12
+ #define VMWGFX_DRIVER_PATCHLEVEL 0
+ #define VMWGFX_FILE_PAGE_OFFSET 0x00100000
+ #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 6e49a4d..e0a8216 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -220,7 +220,7 @@ int hv_init(void)
+ /* See if the hypercall page is already set */
+ rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+- virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
++ virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX);
+
+ if (!virtaddr)
+ goto cleanup;
+diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
+index 729b069..d61fd2c 100644
+--- a/drivers/infiniband/hw/mlx5/srq.c
++++ b/drivers/infiniband/hw/mlx5/srq.c
+@@ -165,8 +165,6 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
+ int err;
+ int i;
+ struct mlx5_wqe_srq_next_seg *next;
+- int page_shift;
+- int npages;
+
+ err = mlx5_db_alloc(dev->mdev, &srq->db);
+ if (err) {
+@@ -179,7 +177,6 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
+ err = -ENOMEM;
+ goto err_db;
+ }
+- page_shift = srq->buf.page_shift;
+
+ srq->head = 0;
+ srq->tail = srq->msrq.max - 1;
+@@ -191,10 +188,8 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
+ cpu_to_be16((i + 1) & (srq->msrq.max - 1));
+ }
+
+- npages = DIV_ROUND_UP(srq->buf.npages, 1 << (page_shift - PAGE_SHIFT));
+- mlx5_ib_dbg(dev, "buf_size %d, page_shift %d, npages %d, calc npages %d\n",
+- buf_size, page_shift, srq->buf.npages, npages);
+- in->pas = mlx5_vzalloc(sizeof(*in->pas) * npages);
++ mlx5_ib_dbg(dev, "srq->buf.page_shift = %d\n", srq->buf.page_shift);
++ in->pas = mlx5_vzalloc(sizeof(*in->pas) * srq->buf.npages);
+ if (!in->pas) {
+ err = -ENOMEM;
+ goto err_buf;
+@@ -210,7 +205,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
+ }
+ srq->wq_sig = !!srq_signature;
+
+- in->log_page_size = page_shift - MLX5_ADAPTER_PAGE_SHIFT;
++ in->log_page_size = srq->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT;
+ if (MLX5_CAP_GEN(dev->mdev, cqe_version) == MLX5_CQE_VERSION_V1 &&
+ in->type == IB_SRQT_XRC)
+ in->user_index = MLX5_IB_DEFAULT_UIDX;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+index 81a8080..0616a65 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -1511,12 +1511,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
+
+ ret = ipoib_set_mode(dev, buf);
+
+- rtnl_unlock();
+-
+- if (!ret)
+- return count;
++ /* The assumption is that the function ipoib_set_mode returned
++ * with the rtnl held by it, if not the value -EBUSY returned,
++ * then no need to rtnl_unlock
++ */
++ if (ret != -EBUSY)
++ rtnl_unlock();
+
+- return ret;
++ return (!ret || ret == -EBUSY) ? count : ret;
+ }
+
+ static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+index b58d9dc..3ef7b8f 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -468,8 +468,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
+ priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM;
+
+ ipoib_flush_paths(dev);
+- rtnl_lock();
+- return 0;
++ return (!rtnl_trylock()) ? -EBUSY : 0;
+ }
+
+ if (!strcmp(buf, "datagram\n")) {
+@@ -478,8 +477,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
+ dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
+ rtnl_unlock();
+ ipoib_flush_paths(dev);
+- rtnl_lock();
+- return 0;
++ return (!rtnl_trylock()) ? -EBUSY : 0;
+ }
+
+ return -EINVAL;
+@@ -703,6 +701,14 @@ int ipoib_check_sm_sendonly_fullmember_support(struct ipoib_dev_priv *priv)
+ return ret;
+ }
+
++static void push_pseudo_header(struct sk_buff *skb, const char *daddr)
++{
++ struct ipoib_pseudo_header *phdr;
++
++ phdr = (struct ipoib_pseudo_header *)skb_push(skb, sizeof(*phdr));
++ memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
++}
++
+ void ipoib_flush_paths(struct net_device *dev)
+ {
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+@@ -927,8 +933,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
+ }
+ if (skb_queue_len(&neigh->queue) <
+ IPOIB_MAX_PATH_REC_QUEUE) {
+- /* put pseudoheader back on for next time */
+- skb_push(skb, IPOIB_PSEUDO_LEN);
++ push_pseudo_header(skb, neigh->daddr);
+ __skb_queue_tail(&neigh->queue, skb);
+ } else {
+ ipoib_warn(priv, "queue length limit %d. Packet drop.\n",
+@@ -946,10 +951,12 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
+
+ if (!path->query && path_rec_start(dev, path))
+ goto err_path;
+- if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE)
++ if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
++ push_pseudo_header(skb, neigh->daddr);
+ __skb_queue_tail(&neigh->queue, skb);
+- else
++ } else {
+ goto err_drop;
++ }
+ }
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -985,8 +992,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+ }
+ if (path) {
+ if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+- /* put pseudoheader back on for next time */
+- skb_push(skb, IPOIB_PSEUDO_LEN);
++ push_pseudo_header(skb, phdr->hwaddr);
+ __skb_queue_tail(&path->queue, skb);
+ } else {
+ ++dev->stats.tx_dropped;
+@@ -1018,8 +1024,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+ return;
+ } else if ((path->query || !path_rec_start(dev, path)) &&
+ skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+- /* put pseudoheader back on for next time */
+- skb_push(skb, IPOIB_PSEUDO_LEN);
++ push_pseudo_header(skb, phdr->hwaddr);
+ __skb_queue_tail(&path->queue, skb);
+ } else {
+ ++dev->stats.tx_dropped;
+@@ -1100,8 +1105,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ }
+
+ if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
+- /* put pseudoheader back on for next time */
+- skb_push(skb, sizeof(*phdr));
++ push_pseudo_header(skb, phdr->hwaddr);
+ spin_lock_irqsave(&priv->lock, flags);
+ __skb_queue_tail(&neigh->queue, skb);
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -1133,7 +1137,6 @@ static int ipoib_hard_header(struct sk_buff *skb,
+ unsigned short type,
+ const void *daddr, const void *saddr, unsigned len)
+ {
+- struct ipoib_pseudo_header *phdr;
+ struct ipoib_header *header;
+
+ header = (struct ipoib_header *) skb_push(skb, sizeof *header);
+@@ -1146,8 +1149,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
+ * destination address into skb hard header so we can figure out where
+ * to send the packet later.
+ */
+- phdr = (struct ipoib_pseudo_header *) skb_push(skb, sizeof(*phdr));
+- memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
++ push_pseudo_header(skb, daddr);
+
+ return IPOIB_HARD_LEN;
+ }
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index e7dcf14..1eee8f7 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -366,7 +366,6 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device,
+ struct srp_fr_desc *d;
+ struct ib_mr *mr;
+ int i, ret = -EINVAL;
+- enum ib_mr_type mr_type;
+
+ if (pool_size <= 0)
+ goto err;
+@@ -380,13 +379,9 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device,
+ spin_lock_init(&pool->lock);
+ INIT_LIST_HEAD(&pool->free_list);
+
+- if (device->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG)
+- mr_type = IB_MR_TYPE_SG_GAPS;
+- else
+- mr_type = IB_MR_TYPE_MEM_REG;
+-
+ for (i = 0, d = &pool->desc[0]; i < pool->size; i++, d++) {
+- mr = ib_alloc_mr(pd, mr_type, max_page_list_len);
++ mr = ib_alloc_mr(pd, IB_MR_TYPE_MEM_REG,
++ max_page_list_len);
+ if (IS_ERR(mr)) {
+ ret = PTR_ERR(mr);
+ goto destroy_pool;
+@@ -1877,17 +1872,24 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
+ if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) {
+ spin_lock_irqsave(&ch->lock, flags);
+ ch->req_lim += be32_to_cpu(rsp->req_lim_delta);
++ if (rsp->tag == ch->tsk_mgmt_tag) {
++ ch->tsk_mgmt_status = -1;
++ if (be32_to_cpu(rsp->resp_data_len) >= 4)
++ ch->tsk_mgmt_status = rsp->data[3];
++ complete(&ch->tsk_mgmt_done);
++ } else {
++ shost_printk(KERN_ERR, target->scsi_host,
++ "Received tsk mgmt response too late for tag %#llx\n",
++ rsp->tag);
++ }
+ spin_unlock_irqrestore(&ch->lock, flags);
+-
+- ch->tsk_mgmt_status = -1;
+- if (be32_to_cpu(rsp->resp_data_len) >= 4)
+- ch->tsk_mgmt_status = rsp->data[3];
+- complete(&ch->tsk_mgmt_done);
+ } else {
+ scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag);
+- if (scmnd) {
++ if (scmnd && scmnd->host_scribble) {
+ req = (void *)scmnd->host_scribble;
+ scmnd = srp_claim_req(ch, req, NULL, scmnd);
++ } else {
++ scmnd = NULL;
+ }
+ if (!scmnd) {
+ shost_printk(KERN_ERR, target->scsi_host,
+@@ -2519,19 +2521,18 @@ srp_change_queue_depth(struct scsi_device *sdev, int qdepth)
+ }
+
+ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
+- u8 func)
++ u8 func, u8 *status)
+ {
+ struct srp_target_port *target = ch->target;
+ struct srp_rport *rport = target->rport;
+ struct ib_device *dev = target->srp_host->srp_dev->dev;
+ struct srp_iu *iu;
+ struct srp_tsk_mgmt *tsk_mgmt;
++ int res;
+
+ if (!ch->connected || target->qp_in_error)
+ return -1;
+
+- init_completion(&ch->tsk_mgmt_done);
+-
+ /*
+ * Lock the rport mutex to avoid that srp_create_ch_ib() is
+ * invoked while a task management function is being sent.
+@@ -2554,10 +2555,16 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
+
+ tsk_mgmt->opcode = SRP_TSK_MGMT;
+ int_to_scsilun(lun, &tsk_mgmt->lun);
+- tsk_mgmt->tag = req_tag | SRP_TAG_TSK_MGMT;
+ tsk_mgmt->tsk_mgmt_func = func;
+ tsk_mgmt->task_tag = req_tag;
+
++ spin_lock_irq(&ch->lock);
++ ch->tsk_mgmt_tag = (ch->tsk_mgmt_tag + 1) | SRP_TAG_TSK_MGMT;
++ tsk_mgmt->tag = ch->tsk_mgmt_tag;
++ spin_unlock_irq(&ch->lock);
++
++ init_completion(&ch->tsk_mgmt_done);
++
+ ib_dma_sync_single_for_device(dev, iu->dma, sizeof *tsk_mgmt,
+ DMA_TO_DEVICE);
+ if (srp_post_send(ch, iu, sizeof(*tsk_mgmt))) {
+@@ -2566,13 +2573,15 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
+
+ return -1;
+ }
++ res = wait_for_completion_timeout(&ch->tsk_mgmt_done,
++ msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS));
++ if (res > 0 && status)
++ *status = ch->tsk_mgmt_status;
+ mutex_unlock(&rport->mutex);
+
+- if (!wait_for_completion_timeout(&ch->tsk_mgmt_done,
+- msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
+- return -1;
++ WARN_ON_ONCE(res < 0);
+
+- return 0;
++ return res > 0 ? 0 : -1;
+ }
+
+ static int srp_abort(struct scsi_cmnd *scmnd)
+@@ -2598,7 +2607,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
+ shost_printk(KERN_ERR, target->scsi_host,
+ "Sending SRP abort for tag %#x\n", tag);
+ if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun,
+- SRP_TSK_ABORT_TASK) == 0)
++ SRP_TSK_ABORT_TASK, NULL) == 0)
+ ret = SUCCESS;
+ else if (target->rport->state == SRP_RPORT_LOST)
+ ret = FAST_IO_FAIL;
+@@ -2616,14 +2625,15 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
+ struct srp_target_port *target = host_to_target(scmnd->device->host);
+ struct srp_rdma_ch *ch;
+ int i;
++ u8 status;
+
+ shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
+
+ ch = &target->ch[0];
+ if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun,
+- SRP_TSK_LUN_RESET))
++ SRP_TSK_LUN_RESET, &status))
+ return FAILED;
+- if (ch->tsk_mgmt_status)
++ if (status)
+ return FAILED;
+
+ for (i = 0; i < target->ch_count; i++) {
+@@ -2652,9 +2662,8 @@ static int srp_slave_alloc(struct scsi_device *sdev)
+ struct Scsi_Host *shost = sdev->host;
+ struct srp_target_port *target = host_to_target(shost);
+ struct srp_device *srp_dev = target->srp_host->srp_dev;
+- struct ib_device *ibdev = srp_dev->dev;
+
+- if (!(ibdev->attrs.device_cap_flags & IB_DEVICE_SG_GAPS_REG))
++ if (true)
+ blk_queue_virt_boundary(sdev->request_queue,
+ ~srp_dev->mr_page_mask);
+
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
+index 21c6969..32ed40d 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.h
++++ b/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -163,6 +163,7 @@ struct srp_rdma_ch {
+ int max_ti_iu_len;
+ int comp_vector;
+
++ u64 tsk_mgmt_tag;
+ struct completion tsk_mgmt_done;
+ u8 tsk_mgmt_status;
+ bool connected;
+diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c
+index b5ed3bd..e9ebc4f 100644
+--- a/drivers/memory/atmel-ebi.c
++++ b/drivers/memory/atmel-ebi.c
+@@ -93,7 +93,7 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
+ struct at91_ebi_dev_config *conf)
+ {
+ struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
+- unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
++ unsigned int clk_period = NSEC_PER_SEC / clk_get_rate(ebid->ebi->clk);
+ struct at91sam9_ebi_dev_config *config = &conf->sam9;
+ struct at91sam9_smc_timings *timings = &config->timings;
+ unsigned int val;
+@@ -102,43 +102,43 @@ static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid,
+ config->mode = val & ~AT91_SMC_TDF;
+
+ val = (val & AT91_SMC_TDF) >> 16;
+- timings->tdf_ns = clk_rate * val;
++ timings->tdf_ns = clk_period * val;
+
+ regmap_fields_read(fields->setup, conf->cs, &val);
+ timings->ncs_rd_setup_ns = (val >> 24) & 0x1f;
+ timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128;
+- timings->ncs_rd_setup_ns *= clk_rate;
++ timings->ncs_rd_setup_ns *= clk_period;
+ timings->nrd_setup_ns = (val >> 16) & 0x1f;
+ timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128;
+- timings->nrd_setup_ns *= clk_rate;
++ timings->nrd_setup_ns *= clk_period;
+ timings->ncs_wr_setup_ns = (val >> 8) & 0x1f;
+ timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128;
+- timings->ncs_wr_setup_ns *= clk_rate;
++ timings->ncs_wr_setup_ns *= clk_period;
+ timings->nwe_setup_ns = val & 0x1f;
+ timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128;
+- timings->nwe_setup_ns *= clk_rate;
++ timings->nwe_setup_ns *= clk_period;
+
+ regmap_fields_read(fields->pulse, conf->cs, &val);
+ timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f;
+ timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256;
+- timings->ncs_rd_pulse_ns *= clk_rate;
++ timings->ncs_rd_pulse_ns *= clk_period;
+ timings->nrd_pulse_ns = (val >> 16) & 0x3f;
+ timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256;
+- timings->nrd_pulse_ns *= clk_rate;
++ timings->nrd_pulse_ns *= clk_period;
+ timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f;
+ timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256;
+- timings->ncs_wr_pulse_ns *= clk_rate;
++ timings->ncs_wr_pulse_ns *= clk_period;
+ timings->nwe_pulse_ns = val & 0x3f;
+ timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256;
+- timings->nwe_pulse_ns *= clk_rate;
++ timings->nwe_pulse_ns *= clk_period;
+
+ regmap_fields_read(fields->cycle, conf->cs, &val);
+ timings->nrd_cycle_ns = (val >> 16) & 0x7f;
+ timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256;
+- timings->nrd_cycle_ns *= clk_rate;
++ timings->nrd_cycle_ns *= clk_period;
+ timings->nwe_cycle_ns = val & 0x7f;
+ timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256;
+- timings->nwe_cycle_ns *= clk_rate;
++ timings->nwe_cycle_ns *= clk_period;
+ }
+
+ static int at91_xlate_timing(struct device_node *np, const char *prop,
+@@ -334,6 +334,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
+ struct at91_ebi_dev_config *conf)
+ {
+ unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
++ unsigned int clk_period = NSEC_PER_SEC / clk_rate;
+ struct at91sam9_ebi_dev_config *config = &conf->sam9;
+ struct at91sam9_smc_timings *timings = &config->timings;
+ struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9;
+@@ -376,7 +377,7 @@ static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid,
+ val |= AT91SAM9_SMC_NWECYCLE(coded_val);
+ regmap_fields_write(fields->cycle, conf->cs, val);
+
+- val = DIV_ROUND_UP(timings->tdf_ns, clk_rate);
++ val = DIV_ROUND_UP(timings->tdf_ns, clk_period);
+ if (val > AT91_SMC_TDF_MAX)
+ val = AT91_SMC_TDF_MAX;
+ regmap_fields_write(fields->mode, conf->cs,
+diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
+index a144073..52ee3da 100644
+--- a/drivers/misc/cxl/cxl.h
++++ b/drivers/misc/cxl/cxl.h
+@@ -419,6 +419,9 @@ struct cxl_afu {
+ struct mutex contexts_lock;
+ spinlock_t afu_cntl_lock;
+
++ /* -1: AFU deconfigured/locked, >= 0: number of readers */
++ atomic_t configured_state;
++
+ /* AFU error buffer fields and bin attribute for sysfs */
+ u64 eb_len, eb_offset;
+ struct bin_attribute attr_eb;
+diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
+index 62e0dfb..cc1706a 100644
+--- a/drivers/misc/cxl/main.c
++++ b/drivers/misc/cxl/main.c
+@@ -268,7 +268,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
+ idr_init(&afu->contexts_idr);
+ mutex_init(&afu->contexts_lock);
+ spin_lock_init(&afu->afu_cntl_lock);
+-
++ atomic_set(&afu->configured_state, -1);
+ afu->prefault_mode = CXL_PREFAULT_NONE;
+ afu->irqs_max = afu->adapter->user_irqs;
+
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index e96be9c..dd99b06 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1129,6 +1129,7 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
+ if ((rc = cxl_native_register_psl_irq(afu)))
+ goto err2;
+
++ atomic_set(&afu->configured_state, 0);
+ return 0;
+
+ err2:
+@@ -1141,6 +1142,14 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
+
+ static void pci_deconfigure_afu(struct cxl_afu *afu)
+ {
++ /*
++ * It's okay to deconfigure when AFU is already locked, otherwise wait
++ * until there are no readers
++ */
++ if (atomic_read(&afu->configured_state) != -1) {
++ while (atomic_cmpxchg(&afu->configured_state, 0, -1) != -1)
++ schedule();
++ }
+ cxl_native_release_psl_irq(afu);
+ if (afu->adapter->native->sl_ops->release_serr_irq)
+ afu->adapter->native->sl_ops->release_serr_irq(afu);
+diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
+index 3519ace..512a489 100644
+--- a/drivers/misc/cxl/vphb.c
++++ b/drivers/misc/cxl/vphb.c
+@@ -76,23 +76,32 @@ static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
+ return (bus << 8) + devfn;
+ }
+
+-static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
+- struct cxl_afu **_afu, int *_record)
++static inline struct cxl_afu *pci_bus_to_afu(struct pci_bus *bus)
+ {
+- struct pci_controller *phb;
+- struct cxl_afu *afu;
+- int record;
++ struct pci_controller *phb = bus ? pci_bus_to_host(bus) : NULL;
+
+- phb = pci_bus_to_host(bus);
+- if (phb == NULL)
+- return PCIBIOS_DEVICE_NOT_FOUND;
++ return phb ? phb->private_data : NULL;
++}
++
++static void cxl_afu_configured_put(struct cxl_afu *afu)
++{
++ atomic_dec_if_positive(&afu->configured_state);
++}
++
++static bool cxl_afu_configured_get(struct cxl_afu *afu)
++{
++ return atomic_inc_unless_negative(&afu->configured_state);
++}
++
++static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
++ struct cxl_afu *afu, int *_record)
++{
++ int record;
+
+- afu = (struct cxl_afu *)phb->private_data;
+ record = cxl_pcie_cfg_record(bus->number, devfn);
+ if (record > afu->crs_num)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+- *_afu = afu;
+ *_record = record;
+ return 0;
+ }
+@@ -106,9 +115,14 @@ static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ u16 val16;
+ u32 val32;
+
+- rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
++ afu = pci_bus_to_afu(bus);
++ /* Grab a reader lock on afu. */
++ if (afu == NULL || !cxl_afu_configured_get(afu))
++ return PCIBIOS_DEVICE_NOT_FOUND;
++
++ rc = cxl_pcie_config_info(bus, devfn, afu, &record);
+ if (rc)
+- return rc;
++ goto out;
+
+ switch (len) {
+ case 1:
+@@ -127,10 +141,9 @@ static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ WARN_ON(1);
+ }
+
+- if (rc)
+- return PCIBIOS_DEVICE_NOT_FOUND;
+-
+- return PCIBIOS_SUCCESSFUL;
++out:
++ cxl_afu_configured_put(afu);
++ return rc ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+ }
+
+ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+@@ -139,9 +152,14 @@ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ int rc, record;
+ struct cxl_afu *afu;
+
+- rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
++ afu = pci_bus_to_afu(bus);
++ /* Grab a reader lock on afu. */
++ if (afu == NULL || !cxl_afu_configured_get(afu))
++ return PCIBIOS_DEVICE_NOT_FOUND;
++
++ rc = cxl_pcie_config_info(bus, devfn, afu, &record);
+ if (rc)
+- return rc;
++ goto out;
+
+ switch (len) {
+ case 1:
+@@ -157,10 +175,9 @@ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ WARN_ON(1);
+ }
+
+- if (rc)
+- return PCIBIOS_SET_FAILED;
+-
+- return PCIBIOS_SUCCESSFUL;
++out:
++ cxl_afu_configured_put(afu);
++ return rc ? PCIBIOS_SET_FAILED : PCIBIOS_SUCCESSFUL;
+ }
+
+ static struct pci_ops cxl_pcie_pci_ops =
+diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
+index 930c816..0a4e81a 100644
+--- a/drivers/net/ethernet/marvell/mvpp2.c
++++ b/drivers/net/ethernet/marvell/mvpp2.c
+@@ -991,7 +991,7 @@ static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
+ txq_pcpu->buffs + txq_pcpu->txq_put_index;
+ tx_buf->skb = skb;
+ tx_buf->size = tx_desc->data_size;
+- tx_buf->phys = tx_desc->buf_phys_addr;
++ tx_buf->phys = tx_desc->buf_phys_addr + tx_desc->packet_offset;
+ txq_pcpu->txq_put_index++;
+ if (txq_pcpu->txq_put_index == txq_pcpu->size)
+ txq_pcpu->txq_put_index = 0;
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+index b892dac..2458e6e 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -1660,7 +1660,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
+ pfirst->len, pfirst->next,
+ pfirst->prev);
+ skb_unlink(pfirst, &bus->glom);
+- if (brcmf_sdio_fromevntchan(pfirst->data))
++ if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN]))
+ brcmf_rx_event(bus->sdiodev->dev, pfirst);
+ else
+ brcmf_rx_frame(bus->sdiodev->dev, pfirst,
+diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
+index aefca64..a38ae34 100644
+--- a/drivers/nvdimm/namespace_devs.c
++++ b/drivers/nvdimm/namespace_devs.c
+@@ -1700,6 +1700,7 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
+ struct device *create_namespace_pmem(struct nd_region *nd_region,
+ struct nd_namespace_label *nd_label)
+ {
++ u64 altcookie = nd_region_interleave_set_altcookie(nd_region);
+ u64 cookie = nd_region_interleave_set_cookie(nd_region);
+ struct nd_label_ent *label_ent;
+ struct nd_namespace_pmem *nspm;
+@@ -1718,7 +1719,11 @@ struct device *create_namespace_pmem(struct nd_region *nd_region,
+ if (__le64_to_cpu(nd_label->isetcookie) != cookie) {
+ dev_dbg(&nd_region->dev, "invalid cookie in label: %pUb\n",
+ nd_label->uuid);
+- return ERR_PTR(-EAGAIN);
++ if (__le64_to_cpu(nd_label->isetcookie) != altcookie)
++ return ERR_PTR(-EAGAIN);
++
++ dev_dbg(&nd_region->dev, "valid altcookie in label: %pUb\n",
++ nd_label->uuid);
+ }
+
+ nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
+@@ -1733,9 +1738,14 @@ struct device *create_namespace_pmem(struct nd_region *nd_region,
+ res->name = dev_name(&nd_region->dev);
+ res->flags = IORESOURCE_MEM;
+
+- for (i = 0; i < nd_region->ndr_mappings; i++)
+- if (!has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
+- break;
++ for (i = 0; i < nd_region->ndr_mappings; i++) {
++ if (has_uuid_at_pos(nd_region, nd_label->uuid, cookie, i))
++ continue;
++ if (has_uuid_at_pos(nd_region, nd_label->uuid, altcookie, i))
++ continue;
++ break;
++ }
++
+ if (i < nd_region->ndr_mappings) {
+ struct nvdimm_drvdata *ndd = to_ndd(&nd_region->mapping[i]);
+
+diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
+index d3b2fca..d869236 100644
+--- a/drivers/nvdimm/nd.h
++++ b/drivers/nvdimm/nd.h
+@@ -327,6 +327,7 @@ struct nd_region *to_nd_region(struct device *dev);
+ int nd_region_to_nstype(struct nd_region *nd_region);
+ int nd_region_register_namespaces(struct nd_region *nd_region, int *err);
+ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region);
++u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region);
+ void nvdimm_bus_lock(struct device *dev);
+ void nvdimm_bus_unlock(struct device *dev);
+ bool is_nvdimm_bus_locked(struct device *dev);
+diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
+index 6af5e62..9cf6f1a 100644
+--- a/drivers/nvdimm/region_devs.c
++++ b/drivers/nvdimm/region_devs.c
+@@ -505,6 +505,15 @@ u64 nd_region_interleave_set_cookie(struct nd_region *nd_region)
+ return 0;
+ }
+
++u64 nd_region_interleave_set_altcookie(struct nd_region *nd_region)
++{
++ struct nd_interleave_set *nd_set = nd_region->nd_set;
++
++ if (nd_set)
++ return nd_set->altcookie;
++ return 0;
++}
++
+ void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
+ {
+ struct nd_label_ent *label_ent, *e;
+diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
+index acb2be0..e96973b 100644
+--- a/drivers/pci/hotplug/pnv_php.c
++++ b/drivers/pci/hotplug/pnv_php.c
+@@ -82,7 +82,7 @@ static void pnv_php_free_slot(struct kref *kref)
+ static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot)
+ {
+
+- if (WARN_ON(!php_slot))
++ if (!php_slot)
+ return;
+
+ kref_put(&php_slot->kref, pnv_php_free_slot);
+@@ -436,9 +436,21 @@ static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan)
+ if (ret)
+ return ret;
+
+- /* Proceed if there have nothing behind the slot */
+- if (presence == OPAL_PCI_SLOT_EMPTY)
++ /*
++ * Proceed if there have nothing behind the slot. However,
++ * we should leave the slot in registered state at the
++ * beginning. Otherwise, the PCI devices inserted afterwards
++ * won't be probed and populated.
++ */
++ if (presence == OPAL_PCI_SLOT_EMPTY) {
++ if (!php_slot->power_state_check) {
++ php_slot->power_state_check = true;
++
++ return 0;
++ }
++
+ goto scan;
++ }
+
+ /*
+ * If the power supply to the slot is off, we can't detect
+@@ -713,8 +725,12 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
+ added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
+ } else if (sts & PCI_EXP_SLTSTA_PDC) {
+ ret = pnv_pci_get_presence_state(php_slot->id, &presence);
+- if (!ret)
++ if (ret) {
++ dev_warn(&pdev->dev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
++ php_slot->name, ret, sts);
+ return IRQ_HANDLED;
++ }
++
+ added = !!(presence == OPAL_PCI_SLOT_PRESENT);
+ } else {
+ return IRQ_NONE;
+@@ -799,6 +815,14 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
+ struct pci_dev *pdev = php_slot->pdev;
+ int irq, ret;
+
++ /*
++ * The MSI/MSIx interrupt might have been occupied by other
++ * drivers. Don't populate the surprise hotplug capability
++ * in that case.
++ */
++ if (pci_dev_msi_enabled(pdev))
++ return;
++
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ dev_warn(&pdev->dev, "Error %d enabling device\n", ret);
+diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
+index 117fccf..01a6a83 100644
+--- a/drivers/pwm/pwm-pca9685.c
++++ b/drivers/pwm/pwm-pca9685.c
+@@ -65,7 +65,6 @@
+ #define PCA9685_MAXCHAN 0x10
+
+ #define LED_FULL (1 << 4)
+-#define MODE1_RESTART (1 << 7)
+ #define MODE1_SLEEP (1 << 4)
+ #define MODE2_INVRT (1 << 4)
+ #define MODE2_OUTDRV (1 << 2)
+@@ -117,16 +116,6 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+ udelay(500);
+
+ pca->period_ns = period_ns;
+-
+- /*
+- * If the duty cycle did not change, restart PWM with
+- * the same duty cycle to period ratio and return.
+- */
+- if (duty_ns == pca->duty_ns) {
+- regmap_update_bits(pca->regmap, PCA9685_MODE1,
+- MODE1_RESTART, 0x1);
+- return 0;
+- }
+ } else {
+ dev_err(chip->dev,
+ "prescaler not set: period out of bounds!\n");
+diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
+index 9d66b4f..415d10a 100644
+--- a/drivers/s390/block/dcssblk.c
++++ b/drivers/s390/block/dcssblk.c
+@@ -892,7 +892,7 @@ dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
+ dev_info = bdev->bd_disk->private_data;
+ if (!dev_info)
+ return -ENODEV;
+- dev_sz = dev_info->end - dev_info->start;
++ dev_sz = dev_info->end - dev_info->start + 1;
+ offset = secnum * 512;
+ *kaddr = (void *) dev_info->start + offset;
+ *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
+diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c
+index 8225da6..4182f60 100644
+--- a/drivers/s390/cio/ioasm.c
++++ b/drivers/s390/cio/ioasm.c
+@@ -165,13 +165,15 @@ int tpi(struct tpi_info *addr)
+ int chsc(void *chsc_area)
+ {
+ typedef struct { char _[4096]; } addr_type;
+- int cc;
++ int cc = -EIO;
+
+ asm volatile(
+ " .insn rre,0xb25f0000,%2,0\n"
+- " ipm %0\n"
++ "0: ipm %0\n"
+ " srl %0,28\n"
+- : "=d" (cc), "=m" (*(addr_type *) chsc_area)
++ "1:\n"
++ EX_TABLE(0b, 1b)
++ : "+d" (cc), "=m" (*(addr_type *) chsc_area)
+ : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
+ : "cc");
+ trace_s390_cio_chsc(chsc_area, cc);
+diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
+index 5d06253c..30e9fbbf 100644
+--- a/drivers/s390/cio/qdio_thinint.c
++++ b/drivers/s390/cio/qdio_thinint.c
+@@ -147,11 +147,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
+ struct qdio_q *q;
+ int i;
+
+- for_each_input_queue(irq, q, i) {
+- if (!references_shared_dsci(irq) &&
+- has_multiple_inq_on_dsci(irq))
+- xchg(q->irq_ptr->dsci, 0);
++ if (!references_shared_dsci(irq) &&
++ has_multiple_inq_on_dsci(irq))
++ xchg(irq->dsci, 0);
+
++ for_each_input_queue(irq, q, i) {
+ if (q->u.in.queue_start_poll) {
+ /* skip if polling is enabled or already in work */
+ if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
+diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
+index ea9617c..cc38a35 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -77,12 +77,16 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
+ &deve->read_bytes);
+
+ se_lun = rcu_dereference(deve->se_lun);
++
++ if (!percpu_ref_tryget_live(&se_lun->lun_ref)) {
++ se_lun = NULL;
++ goto out_unlock;
++ }
++
+ se_cmd->se_lun = rcu_dereference(deve->se_lun);
+ se_cmd->pr_res_key = deve->pr_res_key;
+ se_cmd->orig_fe_lun = unpacked_lun;
+ se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD;
+-
+- percpu_ref_get(&se_lun->lun_ref);
+ se_cmd->lun_ref_active = true;
+
+ if ((se_cmd->data_direction == DMA_TO_DEVICE) &&
+@@ -96,6 +100,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u64 unpacked_lun)
+ goto ref_dev;
+ }
+ }
++out_unlock:
+ rcu_read_unlock();
+
+ if (!se_lun) {
+@@ -815,6 +820,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
+ xcopy_lun = &dev->xcopy_lun;
+ rcu_assign_pointer(xcopy_lun->lun_se_dev, dev);
+ init_completion(&xcopy_lun->lun_ref_comp);
++ init_completion(&xcopy_lun->lun_shutdown_comp);
+ INIT_LIST_HEAD(&xcopy_lun->lun_deve_list);
+ INIT_LIST_HEAD(&xcopy_lun->lun_dev_link);
+ mutex_init(&xcopy_lun->lun_tg_pt_md_mutex);
+diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
+index d99752c..2744251 100644
+--- a/drivers/target/target_core_tpg.c
++++ b/drivers/target/target_core_tpg.c
+@@ -445,7 +445,7 @@ static void core_tpg_lun_ref_release(struct percpu_ref *ref)
+ {
+ struct se_lun *lun = container_of(ref, struct se_lun, lun_ref);
+
+- complete(&lun->lun_ref_comp);
++ complete(&lun->lun_shutdown_comp);
+ }
+
+ int core_tpg_register(
+@@ -571,6 +571,7 @@ struct se_lun *core_tpg_alloc_lun(
+ lun->lun_link_magic = SE_LUN_LINK_MAGIC;
+ atomic_set(&lun->lun_acl_count, 0);
+ init_completion(&lun->lun_ref_comp);
++ init_completion(&lun->lun_shutdown_comp);
+ INIT_LIST_HEAD(&lun->lun_deve_list);
+ INIT_LIST_HEAD(&lun->lun_dev_link);
+ atomic_set(&lun->lun_tg_pt_secondary_offline, 0);
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 767d1eb6..cae4dea 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -2702,10 +2702,39 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
+ }
+ EXPORT_SYMBOL(target_wait_for_sess_cmds);
+
++static void target_lun_confirm(struct percpu_ref *ref)
++{
++ struct se_lun *lun = container_of(ref, struct se_lun, lun_ref);
++
++ complete(&lun->lun_ref_comp);
++}
++
+ void transport_clear_lun_ref(struct se_lun *lun)
+ {
+- percpu_ref_kill(&lun->lun_ref);
++ /*
++ * Mark the percpu-ref as DEAD, switch to atomic_t mode, drop
++ * the initial reference and schedule confirm kill to be
++ * executed after one full RCU grace period has completed.
++ */
++ percpu_ref_kill_and_confirm(&lun->lun_ref, target_lun_confirm);
++ /*
++ * The first completion waits for percpu_ref_switch_to_atomic_rcu()
++ * to call target_lun_confirm after lun->lun_ref has been marked
++ * as __PERCPU_REF_DEAD on all CPUs, and switches to atomic_t
++ * mode so that percpu_ref_tryget_live() lookup of lun->lun_ref
++ * fails for all new incoming I/O.
++ */
+ wait_for_completion(&lun->lun_ref_comp);
++ /*
++ * The second completion waits for percpu_ref_put_many() to
++ * invoke ->release() after lun->lun_ref has switched to
++ * atomic_t mode, and lun->lun_ref.count has reached zero.
++ *
++ * At this point all target-core lun->lun_ref references have
++ * been dropped via transport_lun_remove_cmd(), and it's safe
++ * to proceed with the remaining LUN shutdown.
++ */
++ wait_for_completion(&lun->lun_shutdown_comp);
+ }
+
+ static bool
+diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
+index a7fa016..6d1e2f7 100644
+--- a/drivers/tty/n_hdlc.c
++++ b/drivers/tty/n_hdlc.c
+@@ -114,7 +114,7 @@
+ #define DEFAULT_TX_BUF_COUNT 3
+
+ struct n_hdlc_buf {
+- struct n_hdlc_buf *link;
++ struct list_head list_item;
+ int count;
+ char buf[1];
+ };
+@@ -122,8 +122,7 @@ struct n_hdlc_buf {
+ #define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
+
+ struct n_hdlc_buf_list {
+- struct n_hdlc_buf *head;
+- struct n_hdlc_buf *tail;
++ struct list_head list;
+ int count;
+ spinlock_t spinlock;
+ };
+@@ -136,7 +135,6 @@ struct n_hdlc_buf_list {
+ * @backup_tty - TTY to use if tty gets closed
+ * @tbusy - reentrancy flag for tx wakeup code
+ * @woke_up - FIXME: describe this field
+- * @tbuf - currently transmitting tx buffer
+ * @tx_buf_list - list of pending transmit frame buffers
+ * @rx_buf_list - list of received frame buffers
+ * @tx_free_buf_list - list unused transmit frame buffers
+@@ -149,7 +147,6 @@ struct n_hdlc {
+ struct tty_struct *backup_tty;
+ int tbusy;
+ int woke_up;
+- struct n_hdlc_buf *tbuf;
+ struct n_hdlc_buf_list tx_buf_list;
+ struct n_hdlc_buf_list rx_buf_list;
+ struct n_hdlc_buf_list tx_free_buf_list;
+@@ -159,6 +156,8 @@ struct n_hdlc {
+ /*
+ * HDLC buffer list manipulation functions
+ */
++static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
++ struct n_hdlc_buf *buf);
+ static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
+ struct n_hdlc_buf *buf);
+ static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *list);
+@@ -208,16 +207,9 @@ static void flush_tx_queue(struct tty_struct *tty)
+ {
+ struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
+ struct n_hdlc_buf *buf;
+- unsigned long flags;
+
+ while ((buf = n_hdlc_buf_get(&n_hdlc->tx_buf_list)))
+ n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, buf);
+- spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock, flags);
+- if (n_hdlc->tbuf) {
+- n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, n_hdlc->tbuf);
+- n_hdlc->tbuf = NULL;
+- }
+- spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
+ }
+
+ static struct tty_ldisc_ops n_hdlc_ldisc = {
+@@ -283,7 +275,6 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
+ } else
+ break;
+ }
+- kfree(n_hdlc->tbuf);
+ kfree(n_hdlc);
+
+ } /* end of n_hdlc_release() */
+@@ -402,13 +393,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
+ n_hdlc->woke_up = 0;
+ spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock, flags);
+
+- /* get current transmit buffer or get new transmit */
+- /* buffer from list of pending transmit buffers */
+-
+- tbuf = n_hdlc->tbuf;
+- if (!tbuf)
+- tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
+-
++ tbuf = n_hdlc_buf_get(&n_hdlc->tx_buf_list);
+ while (tbuf) {
+ if (debuglevel >= DEBUG_LEVEL_INFO)
+ printk("%s(%d)sending frame %p, count=%d\n",
+@@ -420,7 +405,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
+
+ /* rollback was possible and has been done */
+ if (actual == -ERESTARTSYS) {
+- n_hdlc->tbuf = tbuf;
++ n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf);
+ break;
+ }
+ /* if transmit error, throw frame away by */
+@@ -435,10 +420,7 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
+
+ /* free current transmit buffer */
+ n_hdlc_buf_put(&n_hdlc->tx_free_buf_list, tbuf);
+-
+- /* this tx buffer is done */
+- n_hdlc->tbuf = NULL;
+-
++
+ /* wait up sleeping writers */
+ wake_up_interruptible(&tty->write_wait);
+
+@@ -448,10 +430,12 @@ static void n_hdlc_send_frames(struct n_hdlc *n_hdlc, struct tty_struct *tty)
+ if (debuglevel >= DEBUG_LEVEL_INFO)
+ printk("%s(%d)frame %p pending\n",
+ __FILE__,__LINE__,tbuf);
+-
+- /* buffer not accepted by driver */
+- /* set this buffer as pending buffer */
+- n_hdlc->tbuf = tbuf;
++
++ /*
++ * the buffer was not accepted by driver,
++ * return it back into tx queue
++ */
++ n_hdlc_buf_return(&n_hdlc->tx_buf_list, tbuf);
+ break;
+ }
+ }
+@@ -749,7 +733,8 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+ int error = 0;
+ int count;
+ unsigned long flags;
+-
++ struct n_hdlc_buf *buf = NULL;
++
+ if (debuglevel >= DEBUG_LEVEL_INFO)
+ printk("%s(%d)n_hdlc_tty_ioctl() called %d\n",
+ __FILE__,__LINE__,cmd);
+@@ -763,8 +748,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+ /* report count of read data available */
+ /* in next available frame (if any) */
+ spin_lock_irqsave(&n_hdlc->rx_buf_list.spinlock,flags);
+- if (n_hdlc->rx_buf_list.head)
+- count = n_hdlc->rx_buf_list.head->count;
++ buf = list_first_entry_or_null(&n_hdlc->rx_buf_list.list,
++ struct n_hdlc_buf, list_item);
++ if (buf)
++ count = buf->count;
+ else
+ count = 0;
+ spin_unlock_irqrestore(&n_hdlc->rx_buf_list.spinlock,flags);
+@@ -776,8 +763,10 @@ static int n_hdlc_tty_ioctl(struct tty_struct *tty, struct file *file,
+ count = tty_chars_in_buffer(tty);
+ /* add size of next output frame in queue */
+ spin_lock_irqsave(&n_hdlc->tx_buf_list.spinlock,flags);
+- if (n_hdlc->tx_buf_list.head)
+- count += n_hdlc->tx_buf_list.head->count;
++ buf = list_first_entry_or_null(&n_hdlc->tx_buf_list.list,
++ struct n_hdlc_buf, list_item);
++ if (buf)
++ count += buf->count;
+ spin_unlock_irqrestore(&n_hdlc->tx_buf_list.spinlock,flags);
+ error = put_user(count, (int __user *)arg);
+ break;
+@@ -825,14 +814,14 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+ poll_wait(filp, &tty->write_wait, wait);
+
+ /* set bits for operations that won't block */
+- if (n_hdlc->rx_buf_list.head)
++ if (!list_empty(&n_hdlc->rx_buf_list.list))
+ mask |= POLLIN | POLLRDNORM; /* readable */
+ if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+ mask |= POLLHUP;
+ if (tty_hung_up_p(filp))
+ mask |= POLLHUP;
+ if (!tty_is_writelocked(tty) &&
+- n_hdlc->tx_free_buf_list.head)
++ !list_empty(&n_hdlc->tx_free_buf_list.list))
+ mask |= POLLOUT | POLLWRNORM; /* writable */
+ }
+ return mask;
+@@ -856,7 +845,12 @@ static struct n_hdlc *n_hdlc_alloc(void)
+ spin_lock_init(&n_hdlc->tx_free_buf_list.spinlock);
+ spin_lock_init(&n_hdlc->rx_buf_list.spinlock);
+ spin_lock_init(&n_hdlc->tx_buf_list.spinlock);
+-
++
++ INIT_LIST_HEAD(&n_hdlc->rx_free_buf_list.list);
++ INIT_LIST_HEAD(&n_hdlc->tx_free_buf_list.list);
++ INIT_LIST_HEAD(&n_hdlc->rx_buf_list.list);
++ INIT_LIST_HEAD(&n_hdlc->tx_buf_list.list);
++
+ /* allocate free rx buffer list */
+ for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
+ buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
+@@ -884,53 +878,65 @@ static struct n_hdlc *n_hdlc_alloc(void)
+ } /* end of n_hdlc_alloc() */
+
+ /**
++ * n_hdlc_buf_return - put the HDLC buffer after the head of the specified list
++ * @buf_list - pointer to the buffer list
++ * @buf - pointer to the buffer
++ */
++static void n_hdlc_buf_return(struct n_hdlc_buf_list *buf_list,
++ struct n_hdlc_buf *buf)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&buf_list->spinlock, flags);
++
++ list_add(&buf->list_item, &buf_list->list);
++ buf_list->count++;
++
++ spin_unlock_irqrestore(&buf_list->spinlock, flags);
++}
++
++/**
+ * n_hdlc_buf_put - add specified HDLC buffer to tail of specified list
+- * @list - pointer to buffer list
++ * @buf_list - pointer to buffer list
+ * @buf - pointer to buffer
+ */
+-static void n_hdlc_buf_put(struct n_hdlc_buf_list *list,
++static void n_hdlc_buf_put(struct n_hdlc_buf_list *buf_list,
+ struct n_hdlc_buf *buf)
+ {
+ unsigned long flags;
+- spin_lock_irqsave(&list->spinlock,flags);
+-
+- buf->link=NULL;
+- if (list->tail)
+- list->tail->link = buf;
+- else
+- list->head = buf;
+- list->tail = buf;
+- (list->count)++;
+-
+- spin_unlock_irqrestore(&list->spinlock,flags);
+-
++
++ spin_lock_irqsave(&buf_list->spinlock, flags);
++
++ list_add_tail(&buf->list_item, &buf_list->list);
++ buf_list->count++;
++
++ spin_unlock_irqrestore(&buf_list->spinlock, flags);
+ } /* end of n_hdlc_buf_put() */
+
+ /**
+ * n_hdlc_buf_get - remove and return an HDLC buffer from list
+- * @list - pointer to HDLC buffer list
++ * @buf_list - pointer to HDLC buffer list
+ *
+ * Remove and return an HDLC buffer from the head of the specified HDLC buffer
+ * list.
+ * Returns a pointer to HDLC buffer if available, otherwise %NULL.
+ */
+-static struct n_hdlc_buf* n_hdlc_buf_get(struct n_hdlc_buf_list *list)
++static struct n_hdlc_buf *n_hdlc_buf_get(struct n_hdlc_buf_list *buf_list)
+ {
+ unsigned long flags;
+ struct n_hdlc_buf *buf;
+- spin_lock_irqsave(&list->spinlock,flags);
+-
+- buf = list->head;
++
++ spin_lock_irqsave(&buf_list->spinlock, flags);
++
++ buf = list_first_entry_or_null(&buf_list->list,
++ struct n_hdlc_buf, list_item);
+ if (buf) {
+- list->head = buf->link;
+- (list->count)--;
++ list_del(&buf->list_item);
++ buf_list->count--;
+ }
+- if (!list->head)
+- list->tail = NULL;
+-
+- spin_unlock_irqrestore(&list->spinlock,flags);
++
++ spin_unlock_irqrestore(&buf_list->spinlock, flags);
+ return buf;
+-
+ } /* end of n_hdlc_buf_get() */
+
+ static char hdlc_banner[] __initdata =
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index b98c157..4d09bd4 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -2688,6 +2688,8 @@ enum pci_board_num_t {
+ pbn_b0_4_1152000_200,
+ pbn_b0_8_1152000_200,
+
++ pbn_b0_4_1250000,
++
+ pbn_b0_2_1843200,
+ pbn_b0_4_1843200,
+
+@@ -2919,6 +2921,13 @@ static struct pciserial_board pci_boards[] = {
+ .uart_offset = 0x200,
+ },
+
++ [pbn_b0_4_1250000] = {
++ .flags = FL_BASE0,
++ .num_ports = 4,
++ .base_baud = 1250000,
++ .uart_offset = 8,
++ },
++
+ [pbn_b0_2_1843200] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+@@ -5549,6 +5558,10 @@ static struct pci_device_id serial_pci_tbl[] = {
+ { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
+ { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
+
++ /* MKS Tenta SCOM-080x serial cards */
++ { PCI_DEVICE(0x1601, 0x0800), .driver_data = pbn_b0_4_1250000 },
++ { PCI_DEVICE(0x1601, 0xa801), .driver_data = pbn_b0_4_1250000 },
++
+ /*
+ * These entries match devices with class COMMUNICATION_SERIAL,
+ * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
+diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
+index 81dd075..d4fb0af 100644
+--- a/fs/afs/mntpt.c
++++ b/fs/afs/mntpt.c
+@@ -202,7 +202,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
+
+ /* try and do the mount */
+ _debug("--- attempting mount %s -o %s ---", devname, options);
+- mnt = vfs_kern_mount(&afs_fs_type, 0, devname, options);
++ mnt = vfs_submount(mntpt, &afs_fs_type, devname, options);
+ _debug("--- mount result %p ---", mnt);
+
+ free_page((unsigned long) devname);
+diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
+index e44271d..5db6c8d 100644
+--- a/fs/autofs4/waitq.c
++++ b/fs/autofs4/waitq.c
+@@ -431,8 +431,8 @@ int autofs4_wait(struct autofs_sb_info *sbi,
+ memcpy(&wq->name, &qstr, sizeof(struct qstr));
+ wq->dev = autofs4_get_dev(sbi);
+ wq->ino = autofs4_get_ino(sbi);
+- wq->uid = current_real_cred()->uid;
+- wq->gid = current_real_cred()->gid;
++ wq->uid = current_cred()->uid;
++ wq->gid = current_cred()->gid;
+ wq->pid = pid;
+ wq->tgid = tgid;
+ wq->status = -EINTR; /* Status return if interrupted */
+diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
+index 6a26c7b..e3e1a80 100644
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -628,6 +628,9 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
+ {
+ dout("__unregister_request %p tid %lld\n", req, req->r_tid);
+
++ /* Never leave an unregistered request on an unsafe list! */
++ list_del_init(&req->r_unsafe_item);
++
+ if (req->r_tid == mdsc->oldest_tid) {
+ struct rb_node *p = rb_next(&req->r_node);
+ mdsc->oldest_tid = 0;
+@@ -1036,7 +1039,6 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
+ while (!list_empty(&session->s_unsafe)) {
+ req = list_first_entry(&session->s_unsafe,
+ struct ceph_mds_request, r_unsafe_item);
+- list_del_init(&req->r_unsafe_item);
+ pr_warn_ratelimited(" dropping unsafe request %llu\n",
+ req->r_tid);
+ __unregister_request(mdsc, req);
+@@ -2423,7 +2425,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
+ * useful we could do with a revised return value.
+ */
+ dout("got safe reply %llu, mds%d\n", tid, mds);
+- list_del_init(&req->r_unsafe_item);
+
+ /* last unsafe request during umount? */
+ if (mdsc->stopping && !__get_oldest_req(mdsc))
+diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
+index ec9dbbc..9156be5 100644
+--- a/fs/cifs/cifs_dfs_ref.c
++++ b/fs/cifs/cifs_dfs_ref.c
+@@ -245,7 +245,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
+ * @fullpath: full path in UNC format
+ * @ref: server's referral
+ */
+-static struct vfsmount *cifs_dfs_do_refmount(struct cifs_sb_info *cifs_sb,
++static struct vfsmount *cifs_dfs_do_refmount(struct dentry *mntpt,
++ struct cifs_sb_info *cifs_sb,
+ const char *fullpath, const struct dfs_info3_param *ref)
+ {
+ struct vfsmount *mnt;
+@@ -259,7 +260,7 @@ static struct vfsmount *cifs_dfs_do_refmount(struct cifs_sb_info *cifs_sb,
+ if (IS_ERR(mountdata))
+ return (struct vfsmount *)mountdata;
+
+- mnt = vfs_kern_mount(&cifs_fs_type, 0, devname, mountdata);
++ mnt = vfs_submount(mntpt, &cifs_fs_type, devname, mountdata);
+ kfree(mountdata);
+ kfree(devname);
+ return mnt;
+@@ -334,7 +335,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
+ mnt = ERR_PTR(-EINVAL);
+ break;
+ }
+- mnt = cifs_dfs_do_refmount(cifs_sb,
++ mnt = cifs_dfs_do_refmount(mntpt, cifs_sb,
+ full_path, referrals + i);
+ cifs_dbg(FYI, "%s: cifs_dfs_do_refmount:%s , mnt:%p\n",
+ __func__, referrals[i].node_name, mnt);
+diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
+index f17fcf8..1e30f74 100644
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -187,9 +187,9 @@ static const struct super_operations debugfs_super_operations = {
+
+ static struct vfsmount *debugfs_automount(struct path *path)
+ {
+- struct vfsmount *(*f)(void *);
+- f = (struct vfsmount *(*)(void *))path->dentry->d_fsdata;
+- return f(d_inode(path->dentry)->i_private);
++ debugfs_automount_t f;
++ f = (debugfs_automount_t)path->dentry->d_fsdata;
++ return f(path->dentry, d_inode(path->dentry)->i_private);
+ }
+
+ static const struct dentry_operations debugfs_dops = {
+@@ -504,7 +504,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_dir);
+ */
+ struct dentry *debugfs_create_automount(const char *name,
+ struct dentry *parent,
+- struct vfsmount *(*f)(void *),
++ debugfs_automount_t f,
+ void *data)
+ {
+ struct dentry *dentry = start_creating(name, parent);
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c
+index 338d2f7..a2c05f2 100644
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -1359,6 +1359,16 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
+ return 0;
+ }
+
++static void fat_dummy_inode_init(struct inode *inode)
++{
++ /* Initialize this dummy inode to work as no-op. */
++ MSDOS_I(inode)->mmu_private = 0;
++ MSDOS_I(inode)->i_start = 0;
++ MSDOS_I(inode)->i_logstart = 0;
++ MSDOS_I(inode)->i_attrs = 0;
++ MSDOS_I(inode)->i_pos = 0;
++}
++
+ static int fat_read_root(struct inode *inode)
+ {
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+@@ -1803,12 +1813,13 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
+ fat_inode = new_inode(sb);
+ if (!fat_inode)
+ goto out_fail;
+- MSDOS_I(fat_inode)->i_pos = 0;
++ fat_dummy_inode_init(fat_inode);
+ sbi->fat_inode = fat_inode;
+
+ fsinfo_inode = new_inode(sb);
+ if (!fsinfo_inode)
+ goto out_fail;
++ fat_dummy_inode_init(fsinfo_inode);
+ fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
+ sbi->fsinfo_inode = fsinfo_inode;
+ insert_inode_hash(fsinfo_inode);
+diff --git a/fs/mount.h b/fs/mount.h
+index d2e25d7..d8295f2 100644
+--- a/fs/mount.h
++++ b/fs/mount.h
+@@ -89,7 +89,6 @@ static inline int is_mounted(struct vfsmount *mnt)
+ }
+
+ extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
+-extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *);
+
+ extern int __legitimize_mnt(struct vfsmount *, unsigned);
+ extern bool legitimize_mnt(struct vfsmount *, unsigned);
+diff --git a/fs/namei.c b/fs/namei.c
+index 5b4eed2..d5e5140 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -1100,7 +1100,6 @@ static int follow_automount(struct path *path, struct nameidata *nd,
+ bool *need_mntput)
+ {
+ struct vfsmount *mnt;
+- const struct cred *old_cred;
+ int err;
+
+ if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
+@@ -1129,9 +1128,7 @@ static int follow_automount(struct path *path, struct nameidata *nd,
+ if (nd->total_link_count >= 40)
+ return -ELOOP;
+
+- old_cred = override_creds(&init_cred);
+ mnt = path->dentry->d_op->d_automount(path);
+- revert_creds(old_cred);
+ if (IS_ERR(mnt)) {
+ /*
+ * The filesystem is allowed to return -EISDIR here to indicate
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 7cea503..5e35057 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -641,28 +641,6 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+ }
+
+ /*
+- * find the last mount at @dentry on vfsmount @mnt.
+- * mount_lock must be held.
+- */
+-struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
+-{
+- struct mount *p, *res = NULL;
+- p = __lookup_mnt(mnt, dentry);
+- if (!p)
+- goto out;
+- if (!(p->mnt.mnt_flags & MNT_UMOUNT))
+- res = p;
+- hlist_for_each_entry_continue(p, mnt_hash) {
+- if (&p->mnt_parent->mnt != mnt || p->mnt_mountpoint != dentry)
+- break;
+- if (!(p->mnt.mnt_flags & MNT_UMOUNT))
+- res = p;
+- }
+-out:
+- return res;
+-}
+-
+-/*
+ * lookup_mnt - Return the first child mount mounted at path
+ *
+ * "First" means first mounted chronologically. If you create the
+@@ -882,6 +860,13 @@ void mnt_set_mountpoint(struct mount *mnt,
+ hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list);
+ }
+
++static void __attach_mnt(struct mount *mnt, struct mount *parent)
++{
++ hlist_add_head_rcu(&mnt->mnt_hash,
++ m_hash(&parent->mnt, mnt->mnt_mountpoint));
++ list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
++}
++
+ /*
+ * vfsmount lock must be held for write
+ */
+@@ -890,28 +875,45 @@ static void attach_mnt(struct mount *mnt,
+ struct mountpoint *mp)
+ {
+ mnt_set_mountpoint(parent, mp, mnt);
+- hlist_add_head_rcu(&mnt->mnt_hash, m_hash(&parent->mnt, mp->m_dentry));
+- list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
++ __attach_mnt(mnt, parent);
+ }
+
+-static void attach_shadowed(struct mount *mnt,
+- struct mount *parent,
+- struct mount *shadows)
++void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt)
+ {
+- if (shadows) {
+- hlist_add_behind_rcu(&mnt->mnt_hash, &shadows->mnt_hash);
+- list_add(&mnt->mnt_child, &shadows->mnt_child);
+- } else {
+- hlist_add_head_rcu(&mnt->mnt_hash,
+- m_hash(&parent->mnt, mnt->mnt_mountpoint));
+- list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
+- }
++ struct mountpoint *old_mp = mnt->mnt_mp;
++ struct dentry *old_mountpoint = mnt->mnt_mountpoint;
++ struct mount *old_parent = mnt->mnt_parent;
++
++ list_del_init(&mnt->mnt_child);
++ hlist_del_init(&mnt->mnt_mp_list);
++ hlist_del_init_rcu(&mnt->mnt_hash);
++
++ attach_mnt(mnt, parent, mp);
++
++ put_mountpoint(old_mp);
++
++ /*
++ * Safely avoid even the suggestion this code might sleep or
++ * lock the mount hash by taking advantage of the knowledge that
++ * mnt_change_mountpoint will not release the final reference
++ * to a mountpoint.
++ *
++ * During mounting, the mount passed in as the parent mount will
++ * continue to use the old mountpoint and during unmounting, the
++ * old mountpoint will continue to exist until namespace_unlock,
++ * which happens well after mnt_change_mountpoint.
++ */
++ spin_lock(&old_mountpoint->d_lock);
++ old_mountpoint->d_lockref.count--;
++ spin_unlock(&old_mountpoint->d_lock);
++
++ mnt_add_count(old_parent, -1);
+ }
+
+ /*
+ * vfsmount lock must be held for write
+ */
+-static void commit_tree(struct mount *mnt, struct mount *shadows)
++static void commit_tree(struct mount *mnt)
+ {
+ struct mount *parent = mnt->mnt_parent;
+ struct mount *m;
+@@ -929,7 +931,7 @@ static void commit_tree(struct mount *mnt, struct mount *shadows)
+ n->mounts += n->pending_mounts;
+ n->pending_mounts = 0;
+
+- attach_shadowed(mnt, parent, shadows);
++ __attach_mnt(mnt, parent);
+ touch_mnt_namespace(n);
+ }
+
+@@ -993,6 +995,21 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
+ }
+ EXPORT_SYMBOL_GPL(vfs_kern_mount);
+
++struct vfsmount *
++vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
++ const char *name, void *data)
++{
++ /* Until it is worked out how to pass the user namespace
++ * through from the parent mount to the submount don't support
++ * unprivileged mounts with submounts.
++ */
++ if (mountpoint->d_sb->s_user_ns != &init_user_ns)
++ return ERR_PTR(-EPERM);
++
++ return vfs_kern_mount(type, MS_SUBMOUNT, name, data);
++}
++EXPORT_SYMBOL_GPL(vfs_submount);
++
+ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
+ int flag)
+ {
+@@ -1737,7 +1754,6 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
+ continue;
+
+ for (s = r; s; s = next_mnt(s, r)) {
+- struct mount *t = NULL;
+ if (!(flag & CL_COPY_UNBINDABLE) &&
+ IS_MNT_UNBINDABLE(s)) {
+ s = skip_mnt_tree(s);
+@@ -1759,14 +1775,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
+ goto out;
+ lock_mount_hash();
+ list_add_tail(&q->mnt_list, &res->mnt_list);
+- mnt_set_mountpoint(parent, p->mnt_mp, q);
+- if (!list_empty(&parent->mnt_mounts)) {
+- t = list_last_entry(&parent->mnt_mounts,
+- struct mount, mnt_child);
+- if (t->mnt_mp != p->mnt_mp)
+- t = NULL;
+- }
+- attach_shadowed(q, parent, t);
++ attach_mnt(q, parent, p->mnt_mp);
+ unlock_mount_hash();
+ }
+ }
+@@ -1967,10 +1976,18 @@ static int attach_recursive_mnt(struct mount *source_mnt,
+ {
+ HLIST_HEAD(tree_list);
+ struct mnt_namespace *ns = dest_mnt->mnt_ns;
++ struct mountpoint *smp;
+ struct mount *child, *p;
+ struct hlist_node *n;
+ int err;
+
++ /* Preallocate a mountpoint in case the new mounts need
++ * to be tucked under other mounts.
++ */
++ smp = get_mountpoint(source_mnt->mnt.mnt_root);
++ if (IS_ERR(smp))
++ return PTR_ERR(smp);
++
+ /* Is there space to add these mounts to the mount namespace? */
+ if (!parent_path) {
+ err = count_mounts(ns, source_mnt);
+@@ -1997,16 +2014,19 @@ static int attach_recursive_mnt(struct mount *source_mnt,
+ touch_mnt_namespace(source_mnt->mnt_ns);
+ } else {
+ mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
+- commit_tree(source_mnt, NULL);
++ commit_tree(source_mnt);
+ }
+
+ hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
+ struct mount *q;
+ hlist_del_init(&child->mnt_hash);
+- q = __lookup_mnt_last(&child->mnt_parent->mnt,
+- child->mnt_mountpoint);
+- commit_tree(child, q);
++ q = __lookup_mnt(&child->mnt_parent->mnt,
++ child->mnt_mountpoint);
++ if (q)
++ mnt_change_mountpoint(child, smp, q);
++ commit_tree(child);
+ }
++ put_mountpoint(smp);
+ unlock_mount_hash();
+
+ return 0;
+@@ -2021,6 +2041,11 @@ static int attach_recursive_mnt(struct mount *source_mnt,
+ cleanup_group_ids(source_mnt, NULL);
+ out:
+ ns->pending_mounts = 0;
++
++ read_seqlock_excl(&mount_lock);
++ put_mountpoint(smp);
++ read_sequnlock_excl(&mount_lock);
++
+ return err;
+ }
+
+@@ -2769,7 +2794,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
+
+ flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
+ MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
+- MS_STRICTATIME | MS_NOREMOTELOCK);
++ MS_STRICTATIME | MS_NOREMOTELOCK | MS_SUBMOUNT);
+
+ if (flags & MS_REMOUNT)
+ retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
+diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
+index 5551e8e..e49d831 100644
+--- a/fs/nfs/namespace.c
++++ b/fs/nfs/namespace.c
+@@ -226,7 +226,7 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
+ const char *devname,
+ struct nfs_clone_mount *mountdata)
+ {
+- return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
++ return vfs_submount(mountdata->dentry, &nfs_xdev_fs_type, devname, mountdata);
+ }
+
+ /**
+diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
+index d211049..d8b040b 100644
+--- a/fs/nfs/nfs4namespace.c
++++ b/fs/nfs/nfs4namespace.c
+@@ -279,7 +279,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
+ mountdata->hostname,
+ mountdata->mnt_path);
+
+- mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, mountdata);
++ mnt = vfs_submount(mountdata->dentry, &nfs4_referral_fs_type, page, mountdata);
+ if (!IS_ERR(mnt))
+ break;
+ }
+diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c
+index c48859f..67c2435 100644
+--- a/fs/orangefs/super.c
++++ b/fs/orangefs/super.c
+@@ -115,6 +115,13 @@ static struct inode *orangefs_alloc_inode(struct super_block *sb)
+ return &orangefs_inode->vfs_inode;
+ }
+
++static void orangefs_i_callback(struct rcu_head *head)
++{
++ struct inode *inode = container_of(head, struct inode, i_rcu);
++ struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
++ kmem_cache_free(orangefs_inode_cache, orangefs_inode);
++}
++
+ static void orangefs_destroy_inode(struct inode *inode)
+ {
+ struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
+@@ -123,7 +130,7 @@ static void orangefs_destroy_inode(struct inode *inode)
+ "%s: deallocated %p destroying inode %pU\n",
+ __func__, orangefs_inode, get_khandle_from_ino(inode));
+
+- kmem_cache_free(orangefs_inode_cache, orangefs_inode);
++ call_rcu(&inode->i_rcu, orangefs_i_callback);
+ }
+
+ /*
+diff --git a/fs/pnode.c b/fs/pnode.c
+index 234a9ac..b394ca5 100644
+--- a/fs/pnode.c
++++ b/fs/pnode.c
+@@ -324,6 +324,21 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
+ return ret;
+ }
+
++static struct mount *find_topper(struct mount *mnt)
++{
++ /* If there is exactly one mount covering mnt completely return it. */
++ struct mount *child;
++
++ if (!list_is_singular(&mnt->mnt_mounts))
++ return NULL;
++
++ child = list_first_entry(&mnt->mnt_mounts, struct mount, mnt_child);
++ if (child->mnt_mountpoint != mnt->mnt.mnt_root)
++ return NULL;
++
++ return child;
++}
++
+ /*
+ * return true if the refcount is greater than count
+ */
+@@ -344,9 +359,8 @@ static inline int do_refcount_check(struct mount *mnt, int count)
+ */
+ int propagate_mount_busy(struct mount *mnt, int refcnt)
+ {
+- struct mount *m, *child;
++ struct mount *m, *child, *topper;
+ struct mount *parent = mnt->mnt_parent;
+- int ret = 0;
+
+ if (mnt == parent)
+ return do_refcount_check(mnt, refcnt);
+@@ -361,12 +375,24 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+- child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
+- if (child && list_empty(&child->mnt_mounts) &&
+- (ret = do_refcount_check(child, 1)))
+- break;
++ int count = 1;
++ child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
++ if (!child)
++ continue;
++
++ /* Is there exactly one mount on the child that covers
++ * it completely whose reference should be ignored?
++ */
++ topper = find_topper(child);
++ if (topper)
++ count += 1;
++ else if (!list_empty(&child->mnt_mounts))
++ continue;
++
++ if (do_refcount_check(child, count))
++ return 1;
+ }
+- return ret;
++ return 0;
+ }
+
+ /*
+@@ -383,7 +409,7 @@ void propagate_mount_unlock(struct mount *mnt)
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+- child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
++ child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint);
+ if (child)
+ child->mnt.mnt_flags &= ~MNT_LOCKED;
+ }
+@@ -401,9 +427,11 @@ static void mark_umount_candidates(struct mount *mnt)
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+- struct mount *child = __lookup_mnt_last(&m->mnt,
++ struct mount *child = __lookup_mnt(&m->mnt,
+ mnt->mnt_mountpoint);
+- if (child && (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m))) {
++ if (!child || (child->mnt.mnt_flags & MNT_UMOUNT))
++ continue;
++ if (!IS_MNT_LOCKED(child) || IS_MNT_MARKED(m)) {
+ SET_MNT_MARK(child);
+ }
+ }
+@@ -422,8 +450,8 @@ static void __propagate_umount(struct mount *mnt)
+
+ for (m = propagation_next(parent, parent); m;
+ m = propagation_next(m, parent)) {
+-
+- struct mount *child = __lookup_mnt_last(&m->mnt,
++ struct mount *topper;
++ struct mount *child = __lookup_mnt(&m->mnt,
+ mnt->mnt_mountpoint);
+ /*
+ * umount the child only if the child has no children
+@@ -432,6 +460,15 @@ static void __propagate_umount(struct mount *mnt)
+ if (!child || !IS_MNT_MARKED(child))
+ continue;
+ CLEAR_MNT_MARK(child);
++
++ /* If there is exactly one mount covering all of child
++ * replace child with that mount.
++ */
++ topper = find_topper(child);
++ if (topper)
++ mnt_change_mountpoint(child->mnt_parent, child->mnt_mp,
++ topper);
++
+ if (list_empty(&child->mnt_mounts)) {
+ list_del_init(&child->mnt_child);
+ child->mnt.mnt_flags |= MNT_UMOUNT;
+diff --git a/fs/pnode.h b/fs/pnode.h
+index 550f5a8..dc87e65 100644
+--- a/fs/pnode.h
++++ b/fs/pnode.h
+@@ -49,6 +49,8 @@ int get_dominating_id(struct mount *mnt, const struct path *root);
+ unsigned int mnt_get_count(struct mount *mnt);
+ void mnt_set_mountpoint(struct mount *, struct mountpoint *,
+ struct mount *);
++void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
++ struct mount *mnt);
+ struct mount *copy_tree(struct mount *, struct dentry *, int);
+ bool is_path_reachable(struct mount *, struct dentry *,
+ const struct path *root);
+diff --git a/fs/super.c b/fs/super.c
+index c183835..1058bf3 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -470,7 +470,7 @@ struct super_block *sget_userns(struct file_system_type *type,
+ struct super_block *old;
+ int err;
+
+- if (!(flags & MS_KERNMOUNT) &&
++ if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) &&
+ !(type->fs_flags & FS_USERNS_MOUNT) &&
+ !capable(CAP_SYS_ADMIN))
+ return ERR_PTR(-EPERM);
+@@ -500,7 +500,7 @@ struct super_block *sget_userns(struct file_system_type *type,
+ }
+ if (!s) {
+ spin_unlock(&sb_lock);
+- s = alloc_super(type, flags, user_ns);
++ s = alloc_super(type, (flags & ~MS_SUBMOUNT), user_ns);
+ if (!s)
+ return ERR_PTR(-ENOMEM);
+ goto retry;
+@@ -541,8 +541,15 @@ struct super_block *sget(struct file_system_type *type,
+ {
+ struct user_namespace *user_ns = current_user_ns();
+
++ /* We don't yet pass the user namespace of the parent
++ * mount through to here so always use &init_user_ns
++ * until that changes.
++ */
++ if (flags & MS_SUBMOUNT)
++ user_ns = &init_user_ns;
++
+ /* Ensure the requestor has permissions over the target filesystem */
+- if (!(flags & MS_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN))
++ if (!(flags & (MS_KERNMOUNT|MS_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN))
+ return ERR_PTR(-EPERM);
+
+ return sget_userns(type, test, set, flags, user_ns, data);
+diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
+index 9a90417..4129066 100644
+--- a/include/linux/ceph/osdmap.h
++++ b/include/linux/ceph/osdmap.h
+@@ -57,7 +57,7 @@ static inline bool ceph_can_shift_osds(struct ceph_pg_pool_info *pool)
+ case CEPH_POOL_TYPE_EC:
+ return false;
+ default:
+- BUG_ON(1);
++ BUG();
+ }
+ }
+
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index 1b413a9..b20a094 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -96,9 +96,10 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
+ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
+ const char *dest);
+
++typedef struct vfsmount *(*debugfs_automount_t)(struct dentry *, void *);
+ struct dentry *debugfs_create_automount(const char *name,
+ struct dentry *parent,
+- struct vfsmount *(*f)(void *),
++ debugfs_automount_t f,
+ void *data);
+
+ void debugfs_remove(struct dentry *dentry);
+diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
+index 8458c53..77e7af3 100644
+--- a/include/linux/libnvdimm.h
++++ b/include/linux/libnvdimm.h
+@@ -70,6 +70,8 @@ struct nd_cmd_desc {
+
+ struct nd_interleave_set {
+ u64 cookie;
++ /* compatibility with initial buggy Linux implementation */
++ u64 altcookie;
+ };
+
+ struct nd_mapping_desc {
+diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
+index c153738..b37dee3 100644
+--- a/include/linux/lockd/lockd.h
++++ b/include/linux/lockd/lockd.h
+@@ -355,7 +355,8 @@ static inline int nlm_privileged_requester(const struct svc_rqst *rqstp)
+ static inline int nlm_compare_locks(const struct file_lock *fl1,
+ const struct file_lock *fl2)
+ {
+- return fl1->fl_pid == fl2->fl_pid
++ return file_inode(fl1->fl_file) == file_inode(fl2->fl_file)
++ && fl1->fl_pid == fl2->fl_pid
+ && fl1->fl_owner == fl2->fl_owner
+ && fl1->fl_start == fl2->fl_start
+ && fl1->fl_end == fl2->fl_end
+diff --git a/include/linux/mount.h b/include/linux/mount.h
+index 1172cce..e0f3a82 100644
+--- a/include/linux/mount.h
++++ b/include/linux/mount.h
+@@ -90,6 +90,9 @@ struct file_system_type;
+ extern struct vfsmount *vfs_kern_mount(struct file_system_type *type,
+ int flags, const char *name,
+ void *data);
++extern struct vfsmount *vfs_submount(const struct dentry *mountpoint,
++ struct file_system_type *type,
++ const char *name, void *data);
+
+ extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list);
+ extern void mark_mounts_for_expiry(struct list_head *mounts);
+diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
+index 48bc1ac..6233e8f 100644
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -732,6 +732,7 @@ struct se_lun {
+ struct config_group lun_group;
+ struct se_port_stat_grps port_stat_grps;
+ struct completion lun_ref_comp;
++ struct completion lun_shutdown_comp;
+ struct percpu_ref lun_ref;
+ struct list_head lun_dev_link;
+ struct hlist_node link;
+diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
+index acb2b61..4749955 100644
+--- a/include/uapi/linux/fs.h
++++ b/include/uapi/linux/fs.h
+@@ -132,6 +132,7 @@ struct inodes_stat_t {
+ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */
+
+ /* These sb flags are internal to the kernel */
++#define MS_SUBMOUNT (1<<26)
+ #define MS_NOREMOTELOCK (1<<27)
+ #define MS_NOSEC (1<<28)
+ #define MS_BORN (1<<29)
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 8696ce6..90b66ed 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -7241,7 +7241,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
+ ftrace_init_tracefs(tr, d_tracer);
+ }
+
+-static struct vfsmount *trace_automount(void *ingore)
++static struct vfsmount *trace_automount(struct dentry *mntpt, void *ingore)
+ {
+ struct vfsmount *mnt;
+ struct file_system_type *type;
+@@ -7254,7 +7254,7 @@ static struct vfsmount *trace_automount(void *ingore)
+ type = get_fs_type("tracefs");
+ if (!type)
+ return NULL;
+- mnt = vfs_kern_mount(type, 0, "tracefs", NULL);
++ mnt = vfs_submount(mntpt, type, "tracefs", NULL);
+ put_filesystem(type);
+ if (IS_ERR(mnt))
+ return NULL;
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 4c6ade5..0de2669 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4139,17 +4139,22 @@ static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node)
+ kfree(memcg->nodeinfo[node]);
+ }
+
+-static void mem_cgroup_free(struct mem_cgroup *memcg)
++static void __mem_cgroup_free(struct mem_cgroup *memcg)
+ {
+ int node;
+
+- memcg_wb_domain_exit(memcg);
+ for_each_node(node)
+ free_mem_cgroup_per_node_info(memcg, node);
+ free_percpu(memcg->stat);
+ kfree(memcg);
+ }
+
++static void mem_cgroup_free(struct mem_cgroup *memcg)
++{
++ memcg_wb_domain_exit(memcg);
++ __mem_cgroup_free(memcg);
++}
++
+ static struct mem_cgroup *mem_cgroup_alloc(void)
+ {
+ struct mem_cgroup *memcg;
+@@ -4200,7 +4205,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
+ fail:
+ if (memcg->id.id > 0)
+ idr_remove(&mem_cgroup_idr, memcg->id.id);
+- mem_cgroup_free(memcg);
++ __mem_cgroup_free(memcg);
+ return NULL;
+ }
+
+diff --git a/mm/mlock.c b/mm/mlock.c
+index cdbed8a..665ab75 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -441,7 +441,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
+
+ while (start < end) {
+ struct page *page;
+- unsigned int page_mask;
++ unsigned int page_mask = 0;
+ unsigned long page_increm;
+ struct pagevec pvec;
+ struct zone *zone;
+@@ -455,8 +455,7 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
+ * suits munlock very well (and if somehow an abnormal page
+ * has sneaked into the range, we won't oops here: great).
+ */
+- page = follow_page_mask(vma, start, FOLL_GET | FOLL_DUMP,
+- &page_mask);
++ page = follow_page(vma, start, FOLL_GET | FOLL_DUMP);
+
+ if (page && !IS_ERR(page)) {
+ if (PageTransTail(page)) {
+@@ -467,8 +466,8 @@ void munlock_vma_pages_range(struct vm_area_struct *vma,
+ /*
+ * Any THP page found by follow_page_mask() may
+ * have gotten split before reaching
+- * munlock_vma_page(), so we need to recompute
+- * the page_mask here.
++ * munlock_vma_page(), so we need to compute
++ * the page_mask here instead.
+ */
+ page_mask = munlock_vma_page(page);
+ unlock_page(page);
+diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
+index 3b5fd41..58ad23a 100644
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -398,6 +398,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
+ tid_agg_rx->timeout = timeout;
+ tid_agg_rx->stored_mpdu_num = 0;
+ tid_agg_rx->auto_seq = auto_seq;
++ tid_agg_rx->started = false;
+ tid_agg_rx->reorder_buf_filtered = 0;
+ status = WLAN_STATUS_SUCCESS;
+
+diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
+index 28a3a09..76a8bcd 100644
+--- a/net/mac80211/pm.c
++++ b/net/mac80211/pm.c
+@@ -168,6 +168,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+ break;
+ }
+
++ flush_delayed_work(&sdata->dec_tailroom_needed_wk);
+ drv_remove_interface(local, sdata);
+ }
+
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 2384b4a..a697ddf 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -4,7 +4,7 @@
+ * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
+ * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2013-2014 Intel Mobile Communications GmbH
+- * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
++ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+@@ -1034,6 +1034,18 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
+ buf_size = tid_agg_rx->buf_size;
+ head_seq_num = tid_agg_rx->head_seq_num;
+
++ /*
++ * If the current MPDU's SN is smaller than the SSN, it shouldn't
++ * be reordered.
++ */
++ if (unlikely(!tid_agg_rx->started)) {
++ if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
++ ret = false;
++ goto out;
++ }
++ tid_agg_rx->started = true;
++ }
++
+ /* frame with out of date sequence number */
+ if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
+ dev_kfree_skb(skb);
+@@ -4080,15 +4092,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+ ieee80211_is_beacon(hdr->frame_control)))
+ ieee80211_scan_rx(local, skb);
+
+- if (pubsta) {
+- rx.sta = container_of(pubsta, struct sta_info, sta);
+- rx.sdata = rx.sta->sdata;
+- if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+- return;
+- goto out;
+- } else if (ieee80211_is_data(fc)) {
++ if (ieee80211_is_data(fc)) {
+ struct sta_info *sta, *prev_sta;
+
++ if (pubsta) {
++ rx.sta = container_of(pubsta, struct sta_info, sta);
++ rx.sdata = rx.sta->sdata;
++ if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
++ return;
++ goto out;
++ }
++
+ prev_sta = NULL;
+
+ for_each_sta_info(local, hdr->addr2, sta, tmp) {
+diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
+index dd06ef0..15599c7 100644
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -189,6 +189,7 @@ struct tid_ampdu_tx {
+ * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and
+ * and ssn.
+ * @removed: this session is removed (but might have been found due to RCU)
++ * @started: this session has started (head ssn or higher was received)
+ *
+ * This structure's lifetime is managed by RCU, assignments to
+ * the array holding it must hold the aggregation mutex.
+@@ -212,8 +213,9 @@ struct tid_ampdu_rx {
+ u16 ssn;
+ u16 buf_size;
+ u16 timeout;
+- bool auto_seq;
+- bool removed;
++ u8 auto_seq:1,
++ removed:1,
++ started:1;
+ };
+
+ /**
+diff --git a/net/mac80211/status.c b/net/mac80211/status.c
+index ddf71c6..ad37b4e 100644
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -51,7 +51,8 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
+ struct ieee80211_hdr *hdr = (void *)skb->data;
+ int ac;
+
+- if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
++ if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
++ IEEE80211_TX_CTL_AMPDU)) {
+ ieee80211_free_txskb(&local->hw, skb);
+ return;
+ }
+diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
+index d08e214..223d88e 100755
+--- a/tools/testing/ktest/ktest.pl
++++ b/tools/testing/ktest/ktest.pl
+@@ -2629,7 +2629,7 @@ sub do_run_test {
+ }
+
+ waitpid $child_pid, 0;
+- $child_exit = $?;
++ $child_exit = $? >> 8;
+
+ my $end_time = time;
+ $test_time = $end_time - $start_time;
diff --git a/4.9.15/4420_grsecurity-3.1-4.9.15-201703150049.patch b/4.9.15/4420_grsecurity-3.1-4.9.15-201703150049.patch
new file mode 100644
index 0000000..71528ee
--- /dev/null
+++ b/4.9.15/4420_grsecurity-3.1-4.9.15-201703150049.patch
@@ -0,0 +1,225862 @@
+diff --git a/Documentation/dontdiff b/Documentation/dontdiff
+index 5385cba..607c6a0 100644
+--- a/Documentation/dontdiff
++++ b/Documentation/dontdiff
+@@ -7,6 +7,7 @@
+ *.cis
+ *.cpio
+ *.csp
++*.dbg
+ *.dsp
+ *.dvi
+ *.elf
+@@ -16,6 +17,7 @@
+ *.gcov
+ *.gen.S
+ *.gif
++*.gmo
+ *.grep
+ *.grp
+ *.gz
+@@ -52,14 +54,17 @@
+ *.tab.h
+ *.tex
+ *.ver
++*.vim
+ *.xml
+ *.xz
+ *_MODULES
++*_reg_safe.h
+ *_vga16.c
+ *~
+ \#*#
+ *.9
+-.*
++.[^g]*
++.gen*
+ .*.d
+ .mm
+ 53c700_d.h
+@@ -73,9 +78,11 @@ Image
+ Module.markers
+ Module.symvers
+ PENDING
++PERF*
+ SCCS
+ System.map*
+ TAGS
++TRACEEVENT-CFLAGS
+ aconf
+ af_names.h
+ aic7*reg.h*
+@@ -84,6 +91,7 @@ aic7*seq.h*
+ aicasm
+ aicdb.h*
+ altivec*.c
++ashldi3.S
+ asm-offsets.h
+ asm_offsets.h
+ autoconf.h*
+@@ -96,11 +104,14 @@ 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
+@@ -109,19 +120,23 @@ config-*
+ config_data.h*
+ config.mak
+ config.mak.autogen
++config.tmp
+ conmakehash
+ consolemap_deftbl.c*
+ cpustr.h
+ crc32table.h*
+ cscope.*
+ defkeymap.c
++devicetable-offsets.h
+ devlist.h*
+ dnotify_test
+ docproc
+ dslm
++dtc-lexer.lex.c
+ elf2ecoff
+ elfconfig.h*
+ evergreen_reg_safe.h
++exception_policy.conf
+ fixdep
+ flask.h
+ fore200e_mkfirm
+@@ -129,12 +144,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
+@@ -149,14 +167,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
+@@ -167,12 +185,14 @@ machtypes.h
+ map
+ map_hugetlb
+ mconf
++mdp
+ miboot*
+ mk_elfconfig
+ mkboot
+ mkbugboot
+ mkcpustr
+ mkdep
++mkpiggy
+ mkprep
+ mkregtable
+ mktables
+@@ -188,6 +208,8 @@ oui.c*
+ page-types
+ parse.c
+ parse.h
++parse-events*
++pasyms.h
+ patches*
+ pca200e.bin
+ pca200e_ecd.bin2
+@@ -197,6 +219,7 @@ perf-archive
+ piggyback
+ piggy.gzip
+ piggy.S
++pmu-*
+ pnmtologo
+ ppc_defs.h*
+ pss_boot.h
+@@ -206,7 +229,12 @@ r200_reg_safe.h
+ r300_reg_safe.h
+ r420_reg_safe.h
+ r600_reg_safe.h
++randomize_layout_hash.h
++randomize_layout_seed.h
++realmode.lds
++realmode.relocs
+ recordmcount
++regdb.c
+ relocs
+ rlim_names.h
+ rn50_reg_safe.h
+@@ -216,8 +244,17 @@ series
+ setup
+ setup.bin
+ setup.elf
++signing_key*
++aux.h
++disable.h
++e_fields.h
++e_fns.h
++e_fptrs.h
++e_vars.h
+ sImage
++slabinfo
+ sm_tbl*
++sortextable
+ split-include
+ syscalltab.h
+ tables.c
+@@ -227,6 +264,7 @@ tftpboot.img
+ timeconst.h
+ times.h*
+ trix_boot.h
++user_constants.h
+ utsrelease.h*
+ vdso-syms.lds
+ vdso.lds
+@@ -238,13 +276,17 @@ vdso32.lds
+ vdso32.so.dbg
+ vdso64.lds
+ vdso64.so.dbg
++vdsox32.lds
++vdsox32-syms.lds
+ version.h*
+ vmImage
+ vmlinux
+ vmlinux-*
+ vmlinux.aout
+ vmlinux.bin.all
++vmlinux.bin.bz2
+ vmlinux.lds
++vmlinux.relocs
+ vmlinuz
+ voffset.h
+ vsyscall.lds
+@@ -252,9 +294,12 @@ vsyscall_32.lds
+ wanxlfw.inc
+ uImage
+ unifdef
++utsrelease.h
+ wakeup.bin
+ wakeup.elf
+ wakeup.lds
++x509*
+ zImage*
+ zconf.hash.c
++zconf.lex.c
+ zoffset.h
+diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
+index 9b9c479..5a635ff 100644
+--- a/Documentation/kbuild/makefiles.txt
++++ b/Documentation/kbuild/makefiles.txt
+@@ -23,10 +23,11 @@ This document describes the Linux kernel Makefiles.
+ === 4 Host Program support
+ --- 4.1 Simple Host Program
+ --- 4.2 Composite Host Programs
+- --- 4.3 Using C++ for host programs
+- --- 4.4 Controlling compiler options for host programs
+- --- 4.5 When host programs are actually built
+- --- 4.6 Using hostprogs-$(CONFIG_FOO)
++ --- 4.3 Defining shared libraries
++ --- 4.4 Using C++ for host programs
++ --- 4.5 Controlling compiler options for host programs
++ --- 4.6 When host programs are actually built
++ --- 4.7 Using hostprogs-$(CONFIG_FOO)
+
+ === 5 Kbuild clean infrastructure
+
+@@ -645,7 +646,29 @@ Both possibilities are described in the following.
+ Finally, the two .o files are linked to the executable, lxdialog.
+ Note: The syntax <executable>-y is not permitted for host-programs.
+
+---- 4.3 Using C++ for host programs
++--- 4.3 Defining shared libraries
++
++ Objects with extension .so are considered shared libraries, and
++ will be compiled as position independent objects.
++ Kbuild provides support for shared libraries, but the usage
++ shall be restricted.
++ In the following example the libkconfig.so shared library is used
++ to link the executable conf.
++
++ Example:
++ #scripts/kconfig/Makefile
++ hostprogs-y := conf
++ conf-objs := conf.o libkconfig.so
++ libkconfig-objs := expr.o type.o
++
++ Shared libraries always require a corresponding -objs line, and
++ in the example above the shared library libkconfig is composed by
++ the two objects expr.o and type.o.
++ expr.o and type.o will be built as position independent code and
++ linked as a shared library libkconfig.so. C++ is not supported for
++ shared libraries.
++
++--- 4.4 Using C++ for host programs
+
+ kbuild offers support for host programs written in C++. This was
+ introduced solely to support kconfig, and is not recommended
+@@ -668,7 +691,7 @@ Both possibilities are described in the following.
+ qconf-cxxobjs := qconf.o
+ qconf-objs := check.o
+
+---- 4.4 Controlling compiler options for host programs
++--- 4.5 Controlling compiler options for host programs
+
+ When compiling host programs, it is possible to set specific flags.
+ The programs will always be compiled utilising $(HOSTCC) passed
+@@ -696,7 +719,7 @@ Both possibilities are described in the following.
+ When linking qconf, it will be passed the extra option
+ "-L$(QTDIR)/lib".
+
+---- 4.5 When host programs are actually built
++--- 4.6 When host programs are actually built
+
+ Kbuild will only build host-programs when they are referenced
+ as a prerequisite.
+@@ -727,7 +750,7 @@ Both possibilities are described in the following.
+ This will tell kbuild to build lxdialog even if not referenced in
+ any rule.
+
+---- 4.6 Using hostprogs-$(CONFIG_FOO)
++--- 4.7 Using hostprogs-$(CONFIG_FOO)
+
+ A typical pattern in a Kbuild file looks like this:
+
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 65b05ba..725a42a 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1426,6 +1426,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ [KNL] Should the hard-lockup detector generate
+ backtraces on all cpus.
+ Format: <integer>
++ grsec_proc_gid= [GRKERNSEC_PROC_USERGROUP] Chooses GID to
++ ignore grsecurity's /proc restrictions
++
++ grsec_sysfs_restrict= Format: 0 | 1
++ Default: 1
++ Disables GRKERNSEC_SYSFS_RESTRICT if enabled in config
+
+ hashdist= [KNL,NUMA] Large hashes allocated during boot
+ are distributed across NUMA nodes. Defaults on
+@@ -2655,6 +2661,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ noexec=on: enable non-executable mappings (default)
+ noexec=off: disable non-executable mappings
+
++ nopcid [X86-64]
++ Disable PCID (Process-Context IDentifier) even if it
++ is supported by the processor.
++
+ nosmap [X86]
+ Disable SMAP (Supervisor Mode Access Prevention)
+ even if it is supported by processor.
+@@ -2963,6 +2973,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ the specified number of seconds. This is to be used if
+ your oopses keep scrolling off the screen.
+
++ pax_nouderef [X86] disables UDEREF. Most likely needed under certain
++ virtualization environments that don't cope well with the
++ expand down segment used by UDEREF on X86-32 or the frequent
++ page table updates on X86-64.
++
++ pax_sanitize_slab=
++ Format: { 0 | 1 | off | fast | full }
++ Options '0' and '1' are only provided for backward
++ compatibility, 'off' or 'fast' should be used instead.
++ 0|off : disable slab object sanitization
++ 1|fast: enable slab object sanitization excluding
++ whitelisted slabs (default)
++ full : sanitize all slabs, even the whitelisted ones
++
++ pax_softmode= 0/1 to disable/enable PaX softmode on boot already.
++
++ pax_extra_latent_entropy
++ Enable a very simple form of latent entropy extraction
++ from the first 4GB of memory as the bootmem allocator
++ passes the memory pages to the buddy allocator.
++
++ pax_size_overflow_report_only
++ Enables rate-limited logging of size_overflow plugin
++ violations while disabling killing of the violating
++ task.
++
++ pax_weakuderef [X86-64] enables the weaker but faster form of UDEREF
++ when the processor supports PCID.
++
+ pcbit= [HW,ISDN]
+
+ pcd. [PARIDE]
+diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
+index ffab8b5..b8fcd61 100644
+--- a/Documentation/sysctl/kernel.txt
++++ b/Documentation/sysctl/kernel.txt
+@@ -42,6 +42,7 @@ show up in /proc/sys/kernel:
+ - kptr_restrict
+ - kstack_depth_to_print [ X86 only ]
+ - l2cr [ PPC only ]
++- modify_ldt [ X86 only ]
+ - modprobe ==> Documentation/debugging-modules.txt
+ - modules_disabled
+ - msg_next_id [ sysv ipc ]
+@@ -409,6 +410,20 @@ This flag controls the L2 cache of G3 processor boards. If
+
+ ==============================================================
+
++modify_ldt: (X86 only)
++
++Enables (1) or disables (0) the modify_ldt syscall. Modifying the LDT
++(Local Descriptor Table) may be needed to run a 16-bit or segmented code
++such as Dosemu or Wine. This is done via a system call which is not needed
++to run portable applications, and which can sometimes be abused to exploit
++some weaknesses of the architecture, opening new vulnerabilities.
++
++This sysctl allows one to increase the system's security by disabling the
++system call, or to restore compatibility with specific applications when it
++was already disabled.
++
++==============================================================
++
+ modules_disabled:
+
+ A toggle value indicating if modules are allowed to be loaded
+diff --git a/Kbuild b/Kbuild
+index 3d0ae15..84e5412 100644
+--- a/Kbuild
++++ b/Kbuild
+@@ -91,6 +91,7 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE
+ always += missing-syscalls
+ targets += missing-syscalls
+
++GCC_PLUGINS_missing-syscalls := n
+ quiet_cmd_syscalls = CALL $<
+ cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags)
+
+diff --git a/Makefile b/Makefile
+index 03df4fc..e57ff003 100644
+--- a/Makefile
++++ b/Makefile
+@@ -302,7 +302,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+ HOSTCC = gcc
+ HOSTCXX = g++
+ HOSTCFLAGS = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu89
+-HOSTCXXFLAGS = -O2
++HOSTCFLAGS = -W -Wno-unused-parameter -Wno-missing-field-initializers -fno-delete-null-pointer-checks
++HOSTCFLAGS += $(call cc-option, -Wno-empty-body)
++HOSTCXXFLAGS = -O2 -Wall -W -Wno-array-bounds
+
+ ifeq ($(shell $(HOSTCC) -v 2>&1 | grep -c "clang version"), 1)
+ HOSTCFLAGS += -Wno-unused-value -Wno-unused-parameter \
+@@ -731,7 +733,7 @@ KBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g)
+ else
+ KBUILD_CFLAGS += -g
+ endif
+-KBUILD_AFLAGS += -Wa,-gdwarf-2
++KBUILD_AFLAGS += -Wa,--gdwarf-2
+ endif
+ ifdef CONFIG_DEBUG_INFO_DWARF4
+ KBUILD_CFLAGS += $(call cc-option, -gdwarf-4,)
+@@ -910,7 +912,7 @@ export mod_sign_cmd
+
+
+ ifeq ($(KBUILD_EXTMOD),)
+-core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
++core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
+
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
+@@ -1274,7 +1276,10 @@ MRPROPER_FILES += .config .config.old .version .old_version \
+ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \
+ signing_key.pem signing_key.priv signing_key.x509 \
+ x509.genkey extra_certificates signing_key.x509.keyid \
+- signing_key.x509.signer vmlinux-gdb.py
++ signing_key.x509.signer vmlinux-gdb.py \
++ scripts/gcc-plugins/size_overflow_plugin/e_*.h \
++ scripts/gcc-plugins/size_overflow_plugin/disable.h \
++ scripts/gcc-plugins/randomize_layout_seed.h
+
+ # clean - Delete most, but leave enough to build external modules
+ #
+@@ -1314,7 +1319,7 @@ distclean: mrproper
+ @find $(srctree) $(RCS_FIND_IGNORE) \
+ \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+- -o -name '.*.rej' -o -name '*%' -o -name 'core' \) \
++ -o -name '.*.rej' -o -name '*.so' -o -name '*%' -o -name 'core' \) \
+ -type f -print | xargs rm -f
+
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 659bdd0..4179181 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -164,6 +164,7 @@ config ARCH_USE_BUILTIN_BSWAP
+ config KRETPROBES
+ def_bool y
+ depends on KPROBES && HAVE_KRETPROBES
++ depends on !PAX_RAP
+
+ config USER_RETURN_NOTIFIER
+ bool
+@@ -355,7 +356,7 @@ config HAVE_GCC_PLUGINS
+ menuconfig GCC_PLUGINS
+ bool "GCC plugins"
+ depends on HAVE_GCC_PLUGINS
+- depends on !COMPILE_TEST
++ default y
+ help
+ GCC plugins are loadable modules that provide extra features to the
+ compiler. They are useful for runtime instrumentation and static analysis.
+@@ -759,6 +760,7 @@ config VMAP_STACK
+ default y
+ bool "Use a virtually-mapped stack"
+ depends on HAVE_ARCH_VMAP_STACK && !KASAN
++ depends on !GRKERNSEC_KSTACKOVERFLOW
+ ---help---
+ Enable this if you want the use virtually-mapped kernel stacks
+ with guard pages. This causes kernel stack overflows to be
+diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
+index 498933a..78d2b22 100644
+--- a/arch/alpha/include/asm/atomic.h
++++ b/arch/alpha/include/asm/atomic.h
+@@ -308,4 +308,14 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
+ #define atomic_dec(v) atomic_sub(1,(v))
+ #define atomic64_dec(v) atomic64_sub(1,(v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* _ALPHA_ATOMIC_H */
+diff --git a/arch/alpha/include/asm/cache.h b/arch/alpha/include/asm/cache.h
+index ad368a9..fbe0f25 100644
+--- a/arch/alpha/include/asm/cache.h
++++ b/arch/alpha/include/asm/cache.h
+@@ -4,19 +4,19 @@
+ #ifndef __ARCH_ALPHA_CACHE_H
+ #define __ARCH_ALPHA_CACHE_H
+
++#include <linux/const.h>
+
+ /* Bytes per L1 (data) cache line. */
+ #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EV6)
+-# define L1_CACHE_BYTES 64
+ # define L1_CACHE_SHIFT 6
+ #else
+ /* Both EV4 and EV5 are write-through, read-allocate,
+ direct-mapped, physical.
+ */
+-# define L1_CACHE_BYTES 32
+ # define L1_CACHE_SHIFT 5
+ #endif
+
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+ #endif
+diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
+index 968d999..d36b2df 100644
+--- a/arch/alpha/include/asm/elf.h
++++ b/arch/alpha/include/asm/elf.h
+@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
++
++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
++#endif
++
+ /* $0 is set by ld.so to a pointer to a function which might be
+ registered using atexit. This provides a mean for the dynamic
+ linker to call DT_FINI functions for shared libraries that have
+diff --git a/arch/alpha/include/asm/pgalloc.h b/arch/alpha/include/asm/pgalloc.h
+index c2ebb6f..93a0613 100644
+--- a/arch/alpha/include/asm/pgalloc.h
++++ b/arch/alpha/include/asm/pgalloc.h
+@@ -29,6 +29,12 @@ pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+ pgd_set(pgd, pmd);
+ }
+
++static inline void
++pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
++{
++ pgd_populate(mm, pgd, pmd);
++}
++
+ extern pgd_t *pgd_alloc(struct mm_struct *mm);
+
+ static inline void
+diff --git a/arch/alpha/include/asm/pgtable.h b/arch/alpha/include/asm/pgtable.h
+index a9a1195..e9b8417 100644
+--- a/arch/alpha/include/asm/pgtable.h
++++ b/arch/alpha/include/asm/pgtable.h
+@@ -101,6 +101,17 @@ struct vm_area_struct;
+ #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
+ #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
+ #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
++#else
++# define PAGE_SHARED_NOEXEC PAGE_SHARED
++# define PAGE_COPY_NOEXEC PAGE_COPY
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
+
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
+diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
+index 936bc8f..bb1859f 100644
+--- a/arch/alpha/kernel/module.c
++++ b/arch/alpha/kernel/module.c
+@@ -160,7 +160,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, const char *strtab,
+
+ /* The small sections were sorted to the end of the segment.
+ The following should definitely cover them. */
+- gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000;
++ gp = (u64)me->core_layout.base_rw + me->core_layout.size_rw - 0x8000;
+ got = sechdrs[me->arch.gotsecindex].sh_addr;
+
+ for (i = 0; i < n; i++) {
+diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
+index ffb93f49..ced8233 100644
+--- a/arch/alpha/kernel/osf_sys.c
++++ b/arch/alpha/kernel/osf_sys.c
+@@ -1300,10 +1300,11 @@ SYSCALL_DEFINE1(old_adjtimex, struct timex32 __user *, txc_p)
+ generic version except that we know how to honor ADDR_LIMIT_32BIT. */
+
+ static unsigned long
+-arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
+- unsigned long limit)
++arch_get_unmapped_area_1(struct file *filp, unsigned long addr, unsigned long len,
++ unsigned long limit, unsigned long flags)
+ {
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ info.flags = 0;
+ info.length = len;
+@@ -1311,6 +1312,7 @@ arch_get_unmapped_area_1(unsigned long addr, unsigned long len,
+ info.high_limit = limit;
+ info.align_mask = 0;
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ return vm_unmapped_area(&info);
+ }
+
+@@ -1343,20 +1345,24 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ merely specific addresses, but regions of memory -- perhaps
+ this feature should be incorporated into all ports? */
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
++ addr = arch_get_unmapped_area_1 (filp, PAGE_ALIGN(addr), len, limit, flags);
+ if (addr != (unsigned long) -ENOMEM)
+ return addr;
+ }
+
+ /* Next, try allocating at TASK_UNMAPPED_BASE. */
+- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
+- len, limit);
++ addr = arch_get_unmapped_area_1 (filp, PAGE_ALIGN(current->mm->mmap_base), len, limit, flags);
++
+ if (addr != (unsigned long) -ENOMEM)
+ return addr;
+
+ /* Finally, try allocating in low memory. */
+- addr = arch_get_unmapped_area_1 (PAGE_SIZE, len, limit);
++ addr = arch_get_unmapped_area_1 (filp, PAGE_SIZE, len, limit, flags);
+
+ return addr;
+ }
+diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
+index 83e9eee..db02682 100644
+--- a/arch/alpha/mm/fault.c
++++ b/arch/alpha/mm/fault.c
+@@ -52,6 +52,124 @@ __load_new_mm_context(struct mm_struct *next_mm)
+ __reload_thread(pcb);
+ }
+
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (regs->pc = fault address)
++ *
++ * returns 1 when task should be killed
++ * 2 when patched PLT trampoline was detected
++ * 3 when unpatched PLT trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++
++#ifdef CONFIG_PAX_EMUPLT
++ int err;
++
++ do { /* PaX: patched PLT emulation #1 */
++ unsigned int ldah, ldq, jmp;
++
++ err = get_user(ldah, (unsigned int *)regs->pc);
++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
++
++ if (err)
++ break;
++
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
++ jmp == 0x6BFB0000U)
++ {
++ unsigned long r27, addr;
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
++
++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++ err = get_user(r27, (unsigned long *)addr);
++ if (err)
++ break;
++
++ regs->r27 = r27;
++ regs->pc = r27;
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: patched PLT emulation #2 */
++ unsigned int ldah, lda, br;
++
++ err = get_user(ldah, (unsigned int *)regs->pc);
++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
++ err |= get_user(br, (unsigned int *)(regs->pc+8));
++
++ if (err)
++ break;
++
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
++ (br & 0xFFE00000U) == 0xC3E00000U)
++ {
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
++
++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++ return 2;
++ }
++ } while (0);
++
++ do { /* PaX: unpatched PLT emulation */
++ unsigned int br;
++
++ err = get_user(br, (unsigned int *)regs->pc);
++
++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
++ unsigned int br2, ldq, nop, jmp;
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
++
++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
++ err = get_user(br2, (unsigned int *)addr);
++ err |= get_user(ldq, (unsigned int *)(addr+4));
++ err |= get_user(nop, (unsigned int *)(addr+8));
++ err |= get_user(jmp, (unsigned int *)(addr+12));
++ err |= get_user(resolver, (unsigned long *)(addr+16));
++
++ if (err)
++ break;
++
++ if (br2 == 0xC3600000U &&
++ ldq == 0xA77B000CU &&
++ nop == 0x47FF041FU &&
++ jmp == 0x6B7B0000U)
++ {
++ regs->r28 = regs->pc+4;
++ regs->r27 = addr+16;
++ regs->pc = resolver;
++ return 3;
++ }
++ }
++ } while (0);
++#endif
++
++ return 1;
++}
++
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ unsigned long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 5; i++) {
++ unsigned int c;
++ if (get_user(c, (unsigned int *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08x ", c);
++ }
++ printk("\n");
++}
++#endif
+
+ /*
+ * This routine handles page faults. It determines the address,
+@@ -132,8 +250,29 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
+ good_area:
+ si_code = SEGV_ACCERR;
+ if (cause < 0) {
+- if (!(vma->vm_flags & VM_EXEC))
++ if (!(vma->vm_flags & VM_EXEC)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
++ goto bad_area;
++
++ up_read(&mm->mmap_sem);
++ switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_PAX_EMUPLT
++ case 2:
++ case 3:
++ return;
++#endif
++
++ }
++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
++ do_group_exit(SIGKILL);
++#else
+ goto bad_area;
++#endif
++
++ }
+ } else if (!cause) {
+ /* Allow reads even for write-only mappings */
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
+index 42b0504..6013221 100644
+--- a/arch/arc/kernel/kprobes.c
++++ b/arch/arc/kernel/kprobes.c
+@@ -424,6 +424,7 @@ static void __used kretprobe_trampoline_holder(void)
+ "kretprobe_trampoline:\n" "nop\n");
+ }
+
++#ifdef CONFIG_KRETPROBES
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+ {
+@@ -433,6 +434,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ /* Replace the return addr with trampoline addr */
+ regs->blink = (unsigned long)&kretprobe_trampoline;
+ }
++#endif
+
+ static int __kprobes trampoline_probe_handler(struct kprobe *p,
+ struct pt_regs *regs)
+@@ -509,6 +511,7 @@ int __init arch_init_kprobes(void)
+ return register_kprobe(&trampoline_p);
+ }
+
++#ifdef CONFIG_KRETPROBES
+ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+ {
+ if (p->addr == (kprobe_opcode_t *) &kretprobe_trampoline)
+@@ -516,6 +519,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+
+ return 0;
+ }
++#endif
+
+ void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
+ {
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index b5d529f..0bb4d4f 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1622,6 +1622,7 @@ config AEABI
+ config OABI_COMPAT
+ bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+ depends on AEABI && !THUMB2_KERNEL
++ depends on !GRKERNSEC
+ help
+ This option preserves the old syscall interface along with the
+ new (ARM EABI) one. It also provides a compatibility layer to
+@@ -1690,6 +1691,7 @@ config HIGHPTE
+ config CPU_SW_DOMAIN_PAN
+ bool "Enable use of CPU domains to implement privileged no-access"
+ depends on MMU && !ARM_LPAE
++ depends on !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ default y
+ help
+ Increase kernel security by ensuring that normal kernel accesses
+@@ -1766,7 +1768,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
+@@ -2021,6 +2023,7 @@ config KEXEC
+ depends on (!SMP || PM_SLEEP_SMP)
+ depends on !CPU_V7M
+ select KEXEC_CORE
++ depends on !GRKERNSEC_KMEM
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+@@ -2065,7 +2068,7 @@ config EFI_STUB
+
+ config EFI
+ bool "UEFI runtime support"
+- depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL
++ depends on OF && !CPU_BIG_ENDIAN && MMU && AUTO_ZRELADDR && !XIP_KERNEL && !PAX_KERNEXEC
+ select UCS2_STRING
+ select EFI_PARAMS_FROM_FDT
+ select EFI_STUB
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index d83f7c3..a6aba4c 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -7,6 +7,7 @@ config ARM_PTDUMP
+ depends on DEBUG_KERNEL
+ depends on MMU
+ select DEBUG_FS
++ depends on !GRKERNSEC_KMEM
+ ---help---
+ Say Y here if you want to show the kernel pagetable layout in a
+ debugfs file. This information is only useful for kernel developers
+diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
+index d50430c..39509a6 100644
+--- a/arch/arm/boot/compressed/Makefile
++++ b/arch/arm/boot/compressed/Makefile
+@@ -24,6 +24,8 @@ endif
+
+ GCOV_PROFILE := n
+
++GCC_PLUGINS := n
++
+ #
+ # Architecture dependencies
+ #
+diff --git a/arch/arm/crypto/sha1_glue.c b/arch/arm/crypto/sha1_glue.c
+index 6fc73bf..d0af3c7b 100644
+--- a/arch/arm/crypto/sha1_glue.c
++++ b/arch/arm/crypto/sha1_glue.c
+@@ -27,8 +27,8 @@
+
+ #include "sha1.h"
+
+-asmlinkage void sha1_block_data_order(u32 *digest,
+- const unsigned char *data, unsigned int rounds);
++asmlinkage void sha1_block_data_order(struct sha1_state *digest,
++ const u8 *data, int rounds);
+
+ int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -36,22 +36,20 @@ int sha1_update_arm(struct shash_desc *desc, const u8 *data,
+ /* make sure casting to sha1_block_fn() is safe */
+ BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0);
+
+- return sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_block_data_order);
++ return sha1_base_do_update(desc, data, len, sha1_block_data_order);
+ }
+ EXPORT_SYMBOL_GPL(sha1_update_arm);
+
+ static int sha1_final(struct shash_desc *desc, u8 *out)
+ {
+- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_block_data_order);
++ sha1_base_do_finalize(desc, sha1_block_data_order);
+ return sha1_base_finish(desc, out);
+ }
+
+ int sha1_finup_arm(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_block_data_order);
++ sha1_base_do_update(desc, data, len, sha1_block_data_order);
+ return sha1_final(desc, out);
+ }
+ EXPORT_SYMBOL_GPL(sha1_finup_arm);
+diff --git a/arch/arm/crypto/sha1_neon_glue.c b/arch/arm/crypto/sha1_neon_glue.c
+index 4e22f12..49902aa 100644
+--- a/arch/arm/crypto/sha1_neon_glue.c
++++ b/arch/arm/crypto/sha1_neon_glue.c
+@@ -31,8 +31,8 @@
+
+ #include "sha1.h"
+
+-asmlinkage void sha1_transform_neon(void *state_h, const char *data,
+- unsigned int rounds);
++asmlinkage void sha1_transform_neon(struct sha1_state *state_h, const u8 *data,
++ int rounds);
+
+ static int sha1_neon_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -45,7 +45,7 @@ static int sha1_neon_update(struct shash_desc *desc, const u8 *data,
+
+ kernel_neon_begin();
+ sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_transform_neon);
++ sha1_transform_neon);
+ kernel_neon_end();
+
+ return 0;
+@@ -60,8 +60,8 @@ static int sha1_neon_finup(struct shash_desc *desc, const u8 *data,
+ kernel_neon_begin();
+ if (len)
+ sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_transform_neon);
+- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_transform_neon);
++ sha1_transform_neon);
++ sha1_base_do_finalize(desc, sha1_transform_neon);
+ kernel_neon_end();
+
+ return sha1_base_finish(desc, out);
+diff --git a/arch/arm/crypto/sha256_glue.c b/arch/arm/crypto/sha256_glue.c
+index a84e869..53a0c61 100644
+--- a/arch/arm/crypto/sha256_glue.c
++++ b/arch/arm/crypto/sha256_glue.c
+@@ -30,8 +30,8 @@
+
+ #include "sha256_glue.h"
+
+-asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
+- unsigned int num_blks);
++asmlinkage void sha256_block_data_order(struct sha256_state *digest, const u8 *data,
++ int num_blks);
+
+ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -39,23 +39,20 @@ int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
+ /* make sure casting to sha256_block_fn() is safe */
+ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
+
+- return sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order);
++ return sha256_base_do_update(desc, data, len, sha256_block_data_order);
+ }
+ EXPORT_SYMBOL(crypto_sha256_arm_update);
+
+ static int sha256_final(struct shash_desc *desc, u8 *out)
+ {
+- sha256_base_do_finalize(desc,
+- (sha256_block_fn *)sha256_block_data_order);
++ sha256_base_do_finalize(desc, sha256_block_data_order);
+ return sha256_base_finish(desc, out);
+ }
+
+ int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order);
++ sha256_base_do_update(desc, data, len, sha256_block_data_order);
+ return sha256_final(desc, out);
+ }
+ EXPORT_SYMBOL(crypto_sha256_arm_finup);
+diff --git a/arch/arm/crypto/sha256_neon_glue.c b/arch/arm/crypto/sha256_neon_glue.c
+index 39ccd65..f9511cb 100644
+--- a/arch/arm/crypto/sha256_neon_glue.c
++++ b/arch/arm/crypto/sha256_neon_glue.c
+@@ -26,8 +26,8 @@
+
+ #include "sha256_glue.h"
+
+-asmlinkage void sha256_block_data_order_neon(u32 *digest, const void *data,
+- unsigned int num_blks);
++asmlinkage void sha256_block_data_order_neon(struct sha256_state *digest, const u8 *data,
++ int num_blks);
+
+ static int sha256_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+@@ -39,8 +39,7 @@ static int sha256_update(struct shash_desc *desc, const u8 *data,
+ return crypto_sha256_arm_update(desc, data, len);
+
+ kernel_neon_begin();
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order_neon);
++ sha256_base_do_update(desc, data, len, sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return 0;
+@@ -54,10 +53,8 @@ static int sha256_finup(struct shash_desc *desc, const u8 *data,
+
+ kernel_neon_begin();
+ if (len)
+- sha256_base_do_update(desc, data, len,
+- (sha256_block_fn *)sha256_block_data_order_neon);
+- sha256_base_do_finalize(desc,
+- (sha256_block_fn *)sha256_block_data_order_neon);
++ sha256_base_do_update(desc, data, len, sha256_block_data_order_neon);
++ sha256_base_do_finalize(desc, sha256_block_data_order_neon);
+ kernel_neon_end();
+
+ return sha256_base_finish(desc, out);
+diff --git a/arch/arm/crypto/sha512-glue.c b/arch/arm/crypto/sha512-glue.c
+index 269a394..c7a91f1 100644
+--- a/arch/arm/crypto/sha512-glue.c
++++ b/arch/arm/crypto/sha512-glue.c
+@@ -28,27 +28,24 @@ MODULE_ALIAS_CRYPTO("sha512");
+ MODULE_ALIAS_CRYPTO("sha384-arm");
+ MODULE_ALIAS_CRYPTO("sha512-arm");
+
+-asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
++asmlinkage void sha512_block_data_order(struct sha512_state *state, u8 const *src, int blocks);
+
+ int sha512_arm_update(struct shash_desc *desc, const u8 *data,
+ unsigned int len)
+ {
+- return sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order);
++ return sha512_base_do_update(desc, data, len, sha512_block_data_order);
+ }
+
+ int sha512_arm_final(struct shash_desc *desc, u8 *out)
+ {
+- sha512_base_do_finalize(desc,
+- (sha512_block_fn *)sha512_block_data_order);
++ sha512_base_do_finalize(desc, sha512_block_data_order);
+ return sha512_base_finish(desc, out);
+ }
+
+ int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+ {
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order);
++ sha512_base_do_update(desc, data, len, sha512_block_data_order);
+ return sha512_arm_final(desc, out);
+ }
+
+diff --git a/arch/arm/crypto/sha512-neon-glue.c b/arch/arm/crypto/sha512-neon-glue.c
+index 3269368..9fcbc00 100644
+--- a/arch/arm/crypto/sha512-neon-glue.c
++++ b/arch/arm/crypto/sha512-neon-glue.c
+@@ -22,7 +22,7 @@
+ MODULE_ALIAS_CRYPTO("sha384-neon");
+ MODULE_ALIAS_CRYPTO("sha512-neon");
+
+-asmlinkage void sha512_block_data_order_neon(u64 *state, u8 const *src,
++asmlinkage void sha512_block_data_order_neon(struct sha512_state *state, u8 const *src,
+ int blocks);
+
+ static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
+@@ -35,8 +35,7 @@ static int sha512_neon_update(struct shash_desc *desc, const u8 *data,
+ return sha512_arm_update(desc, data, len);
+
+ kernel_neon_begin();
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order_neon);
++ sha512_base_do_update(desc, data, len, sha512_block_data_order_neon);
+ kernel_neon_end();
+
+ return 0;
+@@ -50,10 +49,8 @@ static int sha512_neon_finup(struct shash_desc *desc, const u8 *data,
+
+ kernel_neon_begin();
+ if (len)
+- sha512_base_do_update(desc, data, len,
+- (sha512_block_fn *)sha512_block_data_order_neon);
+- sha512_base_do_finalize(desc,
+- (sha512_block_fn *)sha512_block_data_order_neon);
++ sha512_base_do_update(desc, data, len, sha512_block_data_order_neon);
++ sha512_base_do_finalize(desc, sha512_block_data_order_neon);
+ kernel_neon_end();
+
+ return sha512_base_finish(desc, out);
+diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
+index 66d0e21..8fa3237 100644
+--- a/arch/arm/include/asm/atomic.h
++++ b/arch/arm/include/asm/atomic.h
+@@ -18,17 +18,41 @@
+ #include <asm/barrier.h>
+ #include <asm/cmpxchg.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
+ #ifdef __KERNEL__
+
++#ifdef CONFIG_THUMB2_KERNEL
++#define REFCOUNT_TRAP_INSN "bkpt 0xf1"
++#else
++#define REFCOUNT_TRAP_INSN "bkpt 0xf103"
++#endif
++
++#define _ASM_EXTABLE(from, to) \
++" .pushsection __ex_table,\"a\"\n"\
++" .align 3\n" \
++" .long " #from ", " #to"\n" \
++" .popsection"
++
+ /*
+ * On ARM, ordinary assignment (str instruction) doesn't clear the local
+ * strex/ldrex monitor on some implementations. The reason we can use it for
+ * atomic_set() is the clrex or dummy strex done on every exception return.
+ */
+ #define atomic_read(v) READ_ONCE((v)->counter)
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+ #define atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+
+ #if __LINUX_ARM_ARCH__ >= 6
+
+@@ -38,45 +62,74 @@
+ * to ensure that the update happens.
+ */
+
+-#define ATOMIC_OP(op, c_op, asm_op) \
+-static inline void atomic_##op(int i, atomic_t *v) \
++#ifdef CONFIG_PAX_REFCOUNT
++#define __OVERFLOW_POST \
++ " bvc 3f\n" \
++ "2: " REFCOUNT_TRAP_INSN "\n"\
++ "3:\n"
++#define __OVERFLOW_POST_RETURN \
++ " bvc 3f\n" \
++ " mov %1, %0\n" \
++ "2: " REFCOUNT_TRAP_INSN "\n"\
++ "3:\n"
++#define __OVERFLOW_EXTABLE \
++ "4:\n" \
++ _ASM_EXTABLE(2b, 4b)
++#else
++#define __OVERFLOW_POST
++#define __OVERFLOW_POST_RETURN
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, c_op, asm_op) \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t *v) \
+ { \
+ unsigned long tmp; \
+ int result; \
+ \
+ prefetchw(&v->counter); \
+- __asm__ __volatile__("@ atomic_" #op "\n" \
++ __asm__ __volatile__("@ atomic_" #op #suffix "\n" \
+ "1: ldrex %0, [%3]\n" \
+ " " #asm_op " %0, %0, %4\n" \
++ __OVERFLOW_POST \
+ " strex %1, %0, [%3]\n" \
+ " teq %1, #0\n" \
+-" bne 1b" \
++" bne 1b\n" \
++ __OVERFLOW_EXTABLE \
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
+ : "r" (&v->counter), "Ir" (i) \
+ : "cc"); \
+ } \
+
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+-static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
++#define ATOMIC_OP(op, c_op, asm_op) __ATOMIC_OP(op, _unchecked, c_op, asm_op)\
++ __ATOMIC_OP(op, , c_op, asm_op##s)
++
++#define __ATOMIC_OP_RETURN(op, suffix, c_op, asm_op) \
++static inline int atomic_##op##_return##suffix##_relaxed(int i, atomic##suffix##_t *v)\
+ { \
+- unsigned long tmp; \
++ int tmp; \
+ int result; \
+ \
+ prefetchw(&v->counter); \
+ \
+- __asm__ __volatile__("@ atomic_" #op "_return\n" \
++ __asm__ __volatile__("@ atomic_" #op "_return" #suffix "\n" \
+ "1: ldrex %0, [%3]\n" \
+-" " #asm_op " %0, %0, %4\n" \
+-" strex %1, %0, [%3]\n" \
+-" teq %1, #0\n" \
+-" bne 1b" \
+- : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
++" " #asm_op " %1, %0, %4\n" \
++ __OVERFLOW_POST_RETURN \
++" strex %0, %1, [%3]\n" \
++" teq %0, #0\n" \
++" bne 1b\n" \
++ __OVERFLOW_EXTABLE \
++ : "=&r" (tmp), "=&r" (result), "+Qo" (v->counter) \
+ : "r" (&v->counter), "Ir" (i) \
+ : "cc"); \
+ \
+ return result; \
+ }
+
++#define ATOMIC_OP_RETURN(op, c_op, asm_op) __ATOMIC_OP_RETURN(op, _unchecked, c_op, asm_op)\
++ __ATOMIC_OP_RETURN(op, , c_op, asm_op##s)
++
+ #define ATOMIC_FETCH_OP(op, c_op, asm_op) \
+ static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
+ { \
+@@ -99,6 +152,7 @@ static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
+ }
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked_relaxed atomic_add_return_unchecked_relaxed
+ #define atomic_sub_return_relaxed atomic_sub_return_relaxed
+ #define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
+ #define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
+@@ -141,12 +195,17 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ __asm__ __volatile__ ("@ atomic_add_unless\n"
+ "1: ldrex %0, [%4]\n"
+ " teq %0, %5\n"
+-" beq 2f\n"
+-" add %1, %0, %6\n"
++" beq 4f\n"
++" adds %1, %0, %6\n"
++
++ __OVERFLOW_POST
++
+ " strex %2, %1, [%4]\n"
+ " teq %2, #0\n"
+ " bne 1b\n"
+-"2:"
++
++ __OVERFLOW_EXTABLE
++
+ : "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (u), "r" (a)
+ : "cc");
+@@ -157,14 +216,36 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ return oldval;
+ }
+
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *ptr, int old, int new)
++{
++ unsigned long oldval, res;
++
++ smp_mb();
++
++ do {
++ __asm__ __volatile__("@ atomic_cmpxchg_unchecked\n"
++ "ldrex %1, [%3]\n"
++ "mov %0, #0\n"
++ "teq %1, %4\n"
++ "strexeq %0, %5, [%3]\n"
++ : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
++ : "r" (&ptr->counter), "Ir" (old), "r" (new)
++ : "cc");
++ } while (res);
++
++ smp_mb();
++
++ return oldval;
++}
++
+ #else /* ARM_ARCH_6 */
+
+ #ifdef CONFIG_SMP
+ #error SMP not supported on pre-ARMv6 CPUs
+ #endif
+
+-#define ATOMIC_OP(op, c_op, asm_op) \
+-static inline void atomic_##op(int i, atomic_t *v) \
++#define __ATOMIC_OP(op, suffix, c_op, asm_op) \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t *v) \
+ { \
+ unsigned long flags; \
+ \
+@@ -173,8 +254,11 @@ static inline void atomic_##op(int i, atomic_t *v) \
+ raw_local_irq_restore(flags); \
+ } \
+
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+-static inline int atomic_##op##_return(int i, atomic_t *v) \
++#define ATOMIC_OP(op, c_op, asm_op) __ATOMIC_OP(op, , c_op, asm_op) \
++ __ATOMIC_OP(op, _unchecked, c_op, asm_op)
++
++#define __ATOMIC_OP_RETURN(op, suffix, c_op, asm_op) \
++static inline int atomic_##op##_return##suffix(int i, atomic##suffix##_t *v)\
+ { \
+ unsigned long flags; \
+ int val; \
+@@ -201,6 +285,9 @@ static inline int atomic_fetch_##op(int i, atomic_t *v) \
+ return val; \
+ }
+
++#define ATOMIC_OP_RETURN(op, c_op, asm_op) __ATOMIC_OP_RETURN(op, , c_op, asm_op)\
++ __ATOMIC_OP_RETURN(op, _unchecked, c_op, asm_op)
++
+ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+ {
+ int ret;
+@@ -215,6 +302,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+ return ret;
+ }
+
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, int new)
++{
++ return atomic_cmpxchg((atomic_t *)v, old, new);
++}
++
+ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+ int c, old;
+@@ -250,16 +342,29 @@ ATOMIC_OPS(xor, ^=, eor)
+ #undef ATOMIC_OPS
+ #undef ATOMIC_FETCH_OP
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
++#define atomic_xchg_unchecked(v, new) (xchg_unchecked(&((v)->counter), new))
+
+ #define atomic_inc(v) atomic_add(1, v)
++static inline void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++ atomic_add_unchecked(1, v);
++}
+ #define atomic_dec(v) atomic_sub(1, v)
++static inline void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++ atomic_sub_unchecked(1, v);
++}
+
+ #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
++#define atomic_inc_and_test_unchecked(v) (atomic_add_return_unchecked(1, v) == 0)
+ #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
+ #define atomic_inc_return_relaxed(v) (atomic_add_return_relaxed(1, v))
++#define atomic_inc_return_unchecked_relaxed(v) (atomic_add_return_unchecked_relaxed(1, v))
+ #define atomic_dec_return_relaxed(v) (atomic_sub_return_relaxed(1, v))
+ #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+@@ -270,6 +375,14 @@ typedef struct {
+ long long counter;
+ } atomic64_t;
+
++#ifdef CONFIG_PAX_REFCOUNT
++typedef struct {
++ long long counter;
++} atomic64_unchecked_t;
++#else
++typedef atomic64_t atomic64_unchecked_t;
++#endif
++
+ #define ATOMIC64_INIT(i) { (i) }
+
+ #ifdef CONFIG_ARM_LPAE
+@@ -286,6 +399,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+ return result;
+ }
+
++static inline long long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ long long result;
++
++ __asm__ __volatile__("@ atomic64_read_unchecked\n"
++" ldrd %0, %H0, [%1]"
++ : "=&r" (result)
++ : "r" (&v->counter), "Qo" (v->counter)
++ );
++
++ return result;
++}
++
+ static inline void atomic64_set(atomic64_t *v, long long i)
+ {
+ __asm__ __volatile__("@ atomic64_set\n"
+@@ -294,6 +420,15 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+ : "r" (&v->counter), "r" (i)
+ );
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long long i)
++{
++ __asm__ __volatile__("@ atomic64_set_unchecked\n"
++" strd %2, %H2, [%1]"
++ : "=Qo" (v->counter)
++ : "r" (&v->counter), "r" (i)
++ );
++}
+ #else
+ static inline long long atomic64_read(const atomic64_t *v)
+ {
+@@ -308,6 +443,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+ return result;
+ }
+
++static inline long long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ long long result;
++
++ __asm__ __volatile__("@ atomic64_read_unchecked\n"
++" ldrexd %0, %H0, [%1]"
++ : "=&r" (result)
++ : "r" (&v->counter), "Qo" (v->counter)
++ );
++
++ return result;
++}
++
+ static inline void atomic64_set(atomic64_t *v, long long i)
+ {
+ long long tmp;
+@@ -322,50 +470,82 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+ }
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long long i)
++{
++ long long tmp;
++
++ prefetchw(&v->counter);
++ __asm__ __volatile__("@ atomic64_set_unchecked\n"
++"1: ldrexd %0, %H0, [%2]\n"
++" strexd %0, %3, %H3, [%2]\n"
++" teq %0, #0\n"
++" bne 1b"
++ : "=&r" (tmp), "=Qo" (v->counter)
++ : "r" (&v->counter), "r" (i)
++ : "cc");
++}
+ #endif
+
+-#define ATOMIC64_OP(op, op1, op2) \
+-static inline void atomic64_##op(long long i, atomic64_t *v) \
++#define __OVERFLOW_POST_RETURN64 \
++ " bvc 3f\n" \
++" mov %Q1, %Q0\n" \
++" mov %R1, %R0\n" \
++ "2: " REFCOUNT_TRAP_INSN "\n"\
++ "3:\n"
++
++#define __ATOMIC64_OP(op, suffix, op1, op2) \
++static inline void atomic64_##op##suffix(long long i, atomic64##suffix##_t *v)\
+ { \
+ long long result; \
+ unsigned long tmp; \
+ \
+ prefetchw(&v->counter); \
+- __asm__ __volatile__("@ atomic64_" #op "\n" \
++ __asm__ __volatile__("@ atomic64_" #op #suffix "\n" \
+ "1: ldrexd %0, %H0, [%3]\n" \
+ " " #op1 " %Q0, %Q0, %Q4\n" \
+ " " #op2 " %R0, %R0, %R4\n" \
++ __OVERFLOW_POST \
+ " strexd %1, %0, %H0, [%3]\n" \
+ " teq %1, #0\n" \
+-" bne 1b" \
++" bne 1b\n" \
++ __OVERFLOW_EXTABLE \
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
+ : "r" (&v->counter), "r" (i) \
+ : "cc"); \
+ } \
+
+-#define ATOMIC64_OP_RETURN(op, op1, op2) \
++#define ATOMIC64_OP(op, op1, op2) __ATOMIC64_OP(op, _unchecked, op1, op2) \
++ __ATOMIC64_OP(op, , op1, op2##s)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, op1, op2) \
+ static inline long long \
+-atomic64_##op##_return_relaxed(long long i, atomic64_t *v) \
++atomic64_##op##_return##suffix##_relaxed(long long i, atomic64##suffix##_t *v) \
+ { \
+ long long result; \
+- unsigned long tmp; \
++ long long tmp; \
+ \
+ prefetchw(&v->counter); \
+ \
+- __asm__ __volatile__("@ atomic64_" #op "_return\n" \
++ __asm__ __volatile__("@ atomic64_" #op "_return" #suffix "\n" \
+ "1: ldrexd %0, %H0, [%3]\n" \
+-" " #op1 " %Q0, %Q0, %Q4\n" \
+-" " #op2 " %R0, %R0, %R4\n" \
+-" strexd %1, %0, %H0, [%3]\n" \
+-" teq %1, #0\n" \
+-" bne 1b" \
+- : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
++" " #op1 " %Q1, %Q0, %Q4\n" \
++" " #op2 " %R1, %R0, %R4\n" \
++ __OVERFLOW_POST_RETURN64 \
++" strexd %0, %1, %H1, [%3]\n" \
++" teq %0, #0\n" \
++" bne 1b\n" \
++ __OVERFLOW_EXTABLE \
++ : "=&r" (tmp), "=&r" (result), "+Qo" (v->counter) \
+ : "r" (&v->counter), "r" (i) \
+ : "cc"); \
+ \
+ return result; \
+ }
+
++#define ATOMIC64_OP_RETURN(op, op1, op2) __ATOMIC64_OP_RETURN(op, _unchecked, op1, op2) \
++ __ATOMIC64_OP_RETURN(op, , op1, op2##s)
++
+ #define ATOMIC64_FETCH_OP(op, op1, op2) \
+ static inline long long \
+ atomic64_fetch_##op##_relaxed(long long i, atomic64_t *v) \
+@@ -398,6 +578,7 @@ ATOMIC64_OPS(add, adds, adc)
+ ATOMIC64_OPS(sub, subs, sbc)
+
+ #define atomic64_add_return_relaxed atomic64_add_return_relaxed
++#define atomic64_add_return_unchecked_relaxed atomic64_add_return_unchecked_relaxed
+ #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+ #define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
+ #define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
+@@ -422,7 +603,10 @@ ATOMIC64_OPS(xor, eor, eor)
+ #undef ATOMIC64_OPS
+ #undef ATOMIC64_FETCH_OP
+ #undef ATOMIC64_OP_RETURN
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_POST_RETURN
+
+ static inline long long
+ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
+@@ -448,6 +632,13 @@ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
+ }
+ #define atomic64_cmpxchg_relaxed atomic64_cmpxchg_relaxed
+
++static inline long long
++atomic64_cmpxchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long old, long long new)
++{
++ return atomic64_cmpxchg_relaxed((atomic64_t *)ptr, old, new);
++}
++#define atomic64_cmpxchg_unchecked_relaxed atomic64_cmpxchg_unchecked_relaxed
++
+ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
+ {
+ long long result;
+@@ -468,25 +659,36 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
+ }
+ #define atomic64_xchg_relaxed atomic64_xchg_relaxed
+
++static inline long long atomic64_xchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long new)
++{
++ return atomic64_xchg_relaxed((atomic64_t *)ptr, new);
++}
++#define atomic64_xchg_unchecked_relaxed atomic64_xchg_unchecked_relaxed
++
+ static inline long long atomic64_dec_if_positive(atomic64_t *v)
+ {
+ long long result;
+- unsigned long tmp;
++ u64 tmp;
+
+ smp_mb();
+ prefetchw(&v->counter);
+
+ __asm__ __volatile__("@ atomic64_dec_if_positive\n"
+ "1: ldrexd %0, %H0, [%3]\n"
+-" subs %Q0, %Q0, #1\n"
+-" sbc %R0, %R0, #0\n"
+-" teq %R0, #0\n"
+-" bmi 2f\n"
+-" strexd %1, %0, %H0, [%3]\n"
+-" teq %1, #0\n"
++" subs %Q1, %Q0, #1\n"
++" sbcs %R1, %R0, #0\n"
++
++ __OVERFLOW_POST_RETURN64
++
++" teq %R1, #0\n"
++" bmi 4f\n"
++" strexd %0, %1, %H1, [%3]\n"
++" teq %0, #0\n"
+ " bne 1b\n"
+-"2:"
+- : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
++
++ __OVERFLOW_EXTABLE
++
++ : "=&r" (tmp), "=&r" (result), "+Qo" (v->counter)
+ : "r" (&v->counter)
+ : "cc");
+
+@@ -509,13 +711,18 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+ " teq %0, %5\n"
+ " teqeq %H0, %H5\n"
+ " moveq %1, #0\n"
+-" beq 2f\n"
++" beq 4f\n"
+ " adds %Q0, %Q0, %Q6\n"
+-" adc %R0, %R0, %R6\n"
++" adcs %R0, %R0, %R6\n"
++
++ __OVERFLOW_POST
++
+ " strexd %2, %0, %H0, [%4]\n"
+ " teq %2, #0\n"
+ " bne 1b\n"
+-"2:"
++
++ __OVERFLOW_EXTABLE
++
+ : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (u), "r" (a)
+ : "cc");
+@@ -526,12 +733,19 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+ return ret;
+ }
+
++#undef __OVERFLOW_EXTABLE
++#undef __OVERFLOW_POST_RETURN64
++#undef __OVERFLOW_POST
++
+ #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
+ #define atomic64_inc(v) atomic64_add(1LL, (v))
++#define atomic64_inc_unchecked(v) atomic64_add_unchecked(1LL, (v))
+ #define atomic64_inc_return_relaxed(v) atomic64_add_return_relaxed(1LL, (v))
++#define atomic64_inc_return_unchecked_relaxed(v) atomic64_add_return_unchecked_relaxed(1LL, (v))
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+ #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
+ #define atomic64_dec(v) atomic64_sub(1LL, (v))
++#define atomic64_dec_unchecked(v) atomic64_sub_unchecked(1LL, (v))
+ #define atomic64_dec_return_relaxed(v) atomic64_sub_return_relaxed(1LL, (v))
+ #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
+diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
+index 75fe66b..2255c86 100644
+--- a/arch/arm/include/asm/cache.h
++++ b/arch/arm/include/asm/cache.h
+@@ -4,8 +4,10 @@
+ #ifndef __ASMARM_CACHE_H
+ #define __ASMARM_CACHE_H
+
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT CONFIG_ARM_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ /*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
+index bdd283b..e66fb83 100644
+--- a/arch/arm/include/asm/cacheflush.h
++++ b/arch/arm/include/asm/cacheflush.h
+@@ -116,7 +116,7 @@ struct cpu_cache_fns {
+ void (*dma_unmap_area)(const void *, size_t, int);
+
+ void (*dma_flush_range)(const void *, const void *);
+-};
++} __no_const __no_randomize_layout;
+
+ /*
+ * Select the calling method
+diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h
+index 524692f..a8871ec 100644
+--- a/arch/arm/include/asm/checksum.h
++++ b/arch/arm/include/asm/checksum.h
+@@ -37,7 +37,19 @@ __wsum
+ csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
+
+ __wsum
+-csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
++__csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
++
++static inline __wsum
++csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr)
++{
++ __wsum ret;
++ pax_open_userland();
++ ret = __csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
++ pax_close_userland();
++ return ret;
++}
++
++
+
+ /*
+ * Fold a partial checksum without adding pseudo headers
+diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
+index 97882f9..ff9d6ac 100644
+--- a/arch/arm/include/asm/cmpxchg.h
++++ b/arch/arm/include/asm/cmpxchg.h
+@@ -117,6 +117,10 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
+ (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), \
+ sizeof(*(ptr))); \
+ })
++#define xchg_unchecked_relaxed(ptr, x) ({ \
++ (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), \
++ sizeof(*(ptr))); \
++})
+
+ #include <asm-generic/cmpxchg-local.h>
+
+@@ -128,6 +132,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
+ #endif
+
+ #define xchg xchg_relaxed
++#define xchg_unchecked xchg_unchecked_relaxed
+
+ /*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h
+index baefe1d..29cb35a 100644
+--- a/arch/arm/include/asm/cpuidle.h
++++ b/arch/arm/include/asm/cpuidle.h
+@@ -32,7 +32,7 @@ struct device_node;
+ struct cpuidle_ops {
+ int (*suspend)(unsigned long arg);
+ int (*init)(struct device_node *, int cpu);
+-};
++} __no_const;
+
+ struct of_cpuidle_method {
+ const char *method;
+diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
+index 99d9f63..ec44cb5 100644
+--- a/arch/arm/include/asm/domain.h
++++ b/arch/arm/include/asm/domain.h
+@@ -42,7 +42,6 @@
+ #define DOMAIN_USER 1
+ #define DOMAIN_IO 0
+ #endif
+-#define DOMAIN_VECTORS 3
+
+ /*
+ * Domain types
+@@ -51,9 +50,28 @@
+ #define DOMAIN_CLIENT 1
+ #ifdef CONFIG_CPU_USE_DOMAINS
+ #define DOMAIN_MANAGER 3
++#define DOMAIN_VECTORS 3
++#define DOMAIN_USERCLIENT DOMAIN_CLIENT
+ #else
++
++#ifdef CONFIG_PAX_KERNEXEC
+ #define DOMAIN_MANAGER 1
++#define DOMAIN_KERNEXEC 3
++#else
++#define DOMAIN_MANAGER 1
++#endif
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++#define DOMAIN_USERCLIENT 0
++#define DOMAIN_UDEREF 1
++#define DOMAIN_VECTORS DOMAIN_KERNEL
++#else
++#define DOMAIN_USERCLIENT 1
++#define DOMAIN_VECTORS DOMAIN_USER
++#endif
++
+ #endif
++#define DOMAIN_KERNELCLIENT 1
+
+ #define domain_mask(dom) ((3) << (2 * (dom)))
+ #define domain_val(dom,type) ((type) << (2 * (dom)))
+@@ -62,13 +80,19 @@
+ #define DACR_INIT \
+ (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+- domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT) | \
+ domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
++#elif defined(CONFIG_PAX_MEMORY_UDEREF)
++ /* DOMAIN_VECTORS is defined to DOMAIN_KERNEL */
++#define DACR_INIT \
++ (domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) | \
++ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT))
+ #else
+ #define DACR_INIT \
+- (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
++ (domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+- domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT) | \
+ domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+ #endif
+
+@@ -124,6 +148,17 @@ static inline void set_domain(unsigned val)
+ set_domain(domain); \
+ } while (0)
+
++#elif defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++#define modify_domain(dom,type) \
++ do { \
++ struct thread_info *thread = current_thread_info(); \
++ unsigned int domain = get_domain(); \
++ domain &= ~domain_mask(dom); \
++ domain = domain | domain_val(dom, type); \
++ thread->cpu_domain = domain; \
++ set_domain(domain); \
++ } while (0)
++
+ #else
+ static inline void modify_domain(unsigned dom, unsigned type) { }
+ #endif
+diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
+index d2315ff..f60b47b 100644
+--- a/arch/arm/include/asm/elf.h
++++ b/arch/arm/include/asm/elf.h
+@@ -117,7 +117,14 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+-#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
++
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
++
++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
++#endif
+
+ /* When the program starts, a1 contains a pointer to a function to be
+ registered with atexit, as per the SVR4 ABI. A value of 0 means we
+diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
+index de53547..52b9a28 100644
+--- a/arch/arm/include/asm/fncpy.h
++++ b/arch/arm/include/asm/fncpy.h
+@@ -81,7 +81,9 @@
+ BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
+ (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+ \
++ pax_open_kernel(); \
+ memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
++ pax_close_kernel(); \
+ flush_icache_range((unsigned long)(dest_buf), \
+ (unsigned long)(dest_buf) + (size)); \
+ \
+diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
+index 6795368..6c4d749 100644
+--- a/arch/arm/include/asm/futex.h
++++ b/arch/arm/include/asm/futex.h
+@@ -107,6 +107,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ return -EFAULT;
+
+ preempt_disable();
++
+ __ua_flags = uaccess_save_and_enable();
+ __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ "1: " TUSER(ldr) " %1, [%4]\n"
+diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
+index 83eb2f7..ed77159 100644
+--- a/arch/arm/include/asm/kmap_types.h
++++ b/arch/arm/include/asm/kmap_types.h
+@@ -4,6 +4,6 @@
+ /*
+ * This is the "bare minimum". AIO seems to require this.
+ */
+-#define KM_TYPE_NR 16
++#define KM_TYPE_NR 17
+
+ #endif
+diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h
+index 9e614a1..3302cca 100644
+--- a/arch/arm/include/asm/mach/dma.h
++++ b/arch/arm/include/asm/mach/dma.h
+@@ -22,7 +22,7 @@ struct dma_ops {
+ int (*residue)(unsigned int, dma_t *); /* optional */
+ int (*setspeed)(unsigned int, dma_t *, int); /* optional */
+ const char *type;
+-};
++} __do_const;
+
+ struct dma_struct {
+ void *addr; /* single DMA address */
+diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
+index 9b7c328..2dfe68b 100644
+--- a/arch/arm/include/asm/mach/map.h
++++ b/arch/arm/include/asm/mach/map.h
+@@ -23,17 +23,19 @@ struct map_desc {
+
+ /* types 0-3 are defined in asm/io.h */
+ enum {
+- MT_UNCACHED = 4,
+- MT_CACHECLEAN,
+- MT_MINICLEAN,
++ MT_UNCACHED_RW = 4,
++ MT_CACHECLEAN_RO,
++ MT_MINICLEAN_RO,
+ MT_LOW_VECTORS,
+ MT_HIGH_VECTORS,
+- MT_MEMORY_RWX,
++ __MT_MEMORY_RWX,
+ MT_MEMORY_RW,
+- MT_ROM,
+- MT_MEMORY_RWX_NONCACHED,
++ MT_MEMORY_RX,
++ MT_ROM_RX,
++ MT_MEMORY_RW_NONCACHED,
++ MT_MEMORY_RX_NONCACHED,
+ MT_MEMORY_RW_DTCM,
+- MT_MEMORY_RWX_ITCM,
++ MT_MEMORY_RX_ITCM,
+ MT_MEMORY_RW_SO,
+ MT_MEMORY_DMA_READY,
+ };
+diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
+index c2bf24f..69e437c 100644
+--- a/arch/arm/include/asm/outercache.h
++++ b/arch/arm/include/asm/outercache.h
+@@ -39,7 +39,7 @@ struct outer_cache_fns {
+ /* This is an ARM L2C thing */
+ void (*write_sec)(unsigned long, unsigned);
+ void (*configure)(const struct l2x0_regs *);
+-};
++} __no_const;
+
+ extern struct outer_cache_fns outer_cache;
+
+diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
+index 4355f0e..cd9168e 100644
+--- a/arch/arm/include/asm/page.h
++++ b/arch/arm/include/asm/page.h
+@@ -23,6 +23,7 @@
+
+ #else
+
++#include <linux/compiler.h>
+ #include <asm/glue.h>
+
+ /*
+@@ -114,7 +115,7 @@ struct cpu_user_fns {
+ void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
+ void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma);
+-};
++} __no_const;
+
+ #ifdef MULTI_USER
+ extern struct cpu_user_fns cpu_user;
+diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
+index b2902a5..da11e4d 100644
+--- a/arch/arm/include/asm/pgalloc.h
++++ b/arch/arm/include/asm/pgalloc.h
+@@ -17,6 +17,7 @@
+ #include <asm/processor.h>
+ #include <asm/cacheflush.h>
+ #include <asm/tlbflush.h>
++#include <asm/system_info.h>
+
+ #define check_pgt_cache() do { } while (0)
+
+@@ -43,6 +44,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
+ }
+
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++ pud_populate(mm, pud, pmd);
++}
++
+ #else /* !CONFIG_ARM_LPAE */
+
+ /*
+@@ -51,6 +57,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
+ #define pmd_free(mm, pmd) do { } while (0)
+ #define pud_populate(mm,pmd,pte) BUG()
++#define pud_populate_kernel(mm,pmd,pte) BUG()
+
+ #endif /* CONFIG_ARM_LPAE */
+
+@@ -128,6 +135,19 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+ __free_page(pte);
+ }
+
++static inline void __section_update(pmd_t *pmdp, unsigned long addr, pmdval_t prot)
++{
++#ifdef CONFIG_ARM_LPAE
++ pmdp[0] = __pmd(pmd_val(pmdp[0]) | prot);
++#else
++ if (addr & SECTION_SIZE)
++ pmdp[1] = __pmd(pmd_val(pmdp[1]) | prot);
++ else
++ pmdp[0] = __pmd(pmd_val(pmdp[0]) | prot);
++#endif
++ flush_pmd_entry(pmdp);
++}
++
+ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
+ pmdval_t prot)
+ {
+diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
+index 3f82e9d..2a85e8b 100644
+--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
++++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
+@@ -28,7 +28,7 @@
+ /*
+ * - section
+ */
+-#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
++#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 0) /* v7 */
+ #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
+ #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
+ #define PMD_SECT_XN (_AT(pmdval_t, 1) << 4) /* v6 */
+@@ -40,6 +40,7 @@
+ #define PMD_SECT_nG (_AT(pmdval_t, 1) << 17) /* v6 */
+ #define PMD_SECT_SUPER (_AT(pmdval_t, 1) << 18) /* v6 */
+ #define PMD_SECT_AF (_AT(pmdval_t, 0))
++#define PMD_SECT_RDONLY (_AT(pmdval_t, 0))
+
+ #define PMD_SECT_UNCACHED (_AT(pmdval_t, 0))
+ #define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
+@@ -70,6 +71,7 @@
+ * - extended small page/tiny page
+ */
+ #define PTE_EXT_XN (_AT(pteval_t, 1) << 0) /* v6 */
++#define PTE_EXT_PXN (_AT(pteval_t, 1) << 2) /* v7 */
+ #define PTE_EXT_AP_MASK (_AT(pteval_t, 3) << 4)
+ #define PTE_EXT_AP0 (_AT(pteval_t, 1) << 4)
+ #define PTE_EXT_AP1 (_AT(pteval_t, 2) << 4)
+diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
+index 92fd2c8..061dae1 100644
+--- a/arch/arm/include/asm/pgtable-2level.h
++++ b/arch/arm/include/asm/pgtable-2level.h
+@@ -127,6 +127,9 @@
+ #define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
+ #define L_PTE_NONE (_AT(pteval_t, 1) << 11)
+
++/* Two-level page tables only have PXN in the PGD, not in the PTE. */
++#define L_PTE_PXN (_AT(pteval_t, 0))
++
+ /*
+ * These are the memory types, defined to be compatible with
+ * pre-ARMv6 CPUs cacheable and bufferable bits: n/a,n/a,C,B
+diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
+index 2a029bc..a0524c7 100644
+--- a/arch/arm/include/asm/pgtable-3level.h
++++ b/arch/arm/include/asm/pgtable-3level.h
+@@ -80,6 +80,7 @@
+ #define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
+ #define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
+ #define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */
++#define L_PTE_PXN (_AT(pteval_t, 1) << 53) /* PXN */
+ #define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
+ #define L_PTE_DIRTY (_AT(pteval_t, 1) << 55)
+ #define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56)
+@@ -90,10 +91,12 @@
+ #define L_PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55)
+ #define L_PMD_SECT_NONE (_AT(pmdval_t, 1) << 57)
+ #define L_PMD_SECT_RDONLY (_AT(pteval_t, 1) << 58)
++#define PMD_SECT_RDONLY PMD_SECT_AP2
+
+ /*
+ * To be used in assembly code with the upper page attributes.
+ */
++#define L_PTE_PXN_HIGH (1 << (53 - 32))
+ #define L_PTE_XN_HIGH (1 << (54 - 32))
+ #define L_PTE_DIRTY_HIGH (1 << (55 - 32))
+
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index a8d656d..2febb8a 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -33,6 +33,9 @@
+ #include <asm/pgtable-2level.h>
+ #endif
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ /*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+@@ -48,6 +51,9 @@
+ #define LIBRARY_TEXT_START 0x0c000000
+
+ #ifndef __ASSEMBLY__
++extern pteval_t __supported_pte_mask;
++extern pmdval_t __supported_pmd_mask;
++
+ extern void __pte_error(const char *file, int line, pte_t);
+ extern void __pmd_error(const char *file, int line, pmd_t);
+ extern void __pgd_error(const char *file, int line, pgd_t);
+@@ -56,6 +62,48 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+ #define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
+ #define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
+
++#define __HAVE_ARCH_PAX_OPEN_KERNEL
++#define __HAVE_ARCH_PAX_CLOSE_KERNEL
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++#include <asm/domain.h>
++#include <linux/thread_info.h>
++#include <linux/preempt.h>
++
++static inline int test_domain(int domain, int domaintype)
++{
++ return ((current_thread_info()->cpu_domain) & domain_val(domain, 3)) == domain_val(domain, domaintype);
++}
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++static inline unsigned long pax_open_kernel(void) {
++#ifdef CONFIG_ARM_LPAE
++ /* TODO */
++#else
++ preempt_disable();
++ BUG_ON(test_domain(DOMAIN_KERNEL, DOMAIN_KERNEXEC));
++ modify_domain(DOMAIN_KERNEL, DOMAIN_KERNEXEC);
++#endif
++ return 0;
++}
++
++static inline unsigned long pax_close_kernel(void) {
++#ifdef CONFIG_ARM_LPAE
++ /* TODO */
++#else
++ BUG_ON(test_domain(DOMAIN_KERNEL, DOMAIN_MANAGER));
++ /* DOMAIN_MANAGER = "client" under KERNEXEC */
++ modify_domain(DOMAIN_KERNEL, DOMAIN_MANAGER);
++ preempt_enable_no_resched();
++#endif
++ return 0;
++}
++#else
++static inline unsigned long pax_open_kernel(void) { return 0; }
++static inline unsigned long pax_close_kernel(void) { return 0; }
++#endif
++
+ /*
+ * This is the lowest virtual address we can permit any user space
+ * mapping to be mapped at. This is particularly important for
+@@ -75,8 +123,8 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+ /*
+ * The pgprot_* and protection_map entries will be fixed up in runtime
+ * to include the cachable and bufferable bits based on memory policy,
+- * as well as any architecture dependent bits like global/ASID and SMP
+- * shared mapping bits.
++ * as well as any architecture dependent bits like global/ASID, PXN,
++ * and SMP shared mapping bits.
+ */
+ #define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
+
+@@ -308,7 +356,7 @@ static inline pte_t pte_mknexec(pte_t pte)
+ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ {
+ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
+- L_PTE_NONE | L_PTE_VALID;
++ L_PTE_NONE | L_PTE_VALID | __supported_pte_mask;
+ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
+ return pte;
+ }
+diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
+index 3d6dc8b..1262ad3 100644
+--- a/arch/arm/include/asm/smp.h
++++ b/arch/arm/include/asm/smp.h
+@@ -108,7 +108,7 @@ struct smp_operations {
+ int (*cpu_disable)(unsigned int cpu);
+ #endif
+ #endif
+-};
++} __no_const;
+
+ struct of_cpu_method {
+ const char *method;
+diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
+index cf4f3aa..8f2f2d9 100644
+--- a/arch/arm/include/asm/string.h
++++ b/arch/arm/include/asm/string.h
+@@ -7,19 +7,19 @@
+ */
+
+ #define __HAVE_ARCH_STRRCHR
+-extern char * strrchr(const char * s, int c);
++extern char * strrchr(const char * s, int c) __nocapture(-1);
+
+ #define __HAVE_ARCH_STRCHR
+-extern char * strchr(const char * s, int c);
++extern char * strchr(const char * s, int c) __nocapture(-1);
+
+ #define __HAVE_ARCH_MEMCPY
+-extern void * memcpy(void *, const void *, __kernel_size_t);
++extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMMOVE
+-extern void * memmove(void *, const void *, __kernel_size_t);
++extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMCHR
+-extern void * memchr(const void *, int, __kernel_size_t);
++extern void * memchr(const void *, int, __kernel_size_t) __nocapture(-1);
+
+ #define __HAVE_ARCH_MEMSET
+ extern void * memset(void *, int, __kernel_size_t);
+diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
+index 776757d..a552c1d 100644
+--- a/arch/arm/include/asm/thread_info.h
++++ b/arch/arm/include/asm/thread_info.h
+@@ -73,6 +73,9 @@ struct thread_info {
+ .flags = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
++ .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_USERCLIENT) | \
++ domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT) | \
++ domain_val(DOMAIN_IO, DOMAIN_KERNELCLIENT), \
+ }
+
+ #define init_thread_info (init_thread_union.thread_info)
+@@ -143,6 +146,10 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */
+ #define TIF_SECCOMP 7 /* seccomp syscall filtering active */
++/* within 8 bits of TIF_SYSCALL_TRACE
++ * to meet flexible second operand requirements
++ */
++#define TIF_GRSEC_SETXID 8
+
+ #define TIF_NOHZ 12 /* in adaptive nohz mode */
+ #define TIF_USING_IWMMXT 17
+@@ -158,10 +165,11 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
+ #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT)
+ #define _TIF_SECCOMP (1 << TIF_SECCOMP)
+ #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
++#define _TIF_GRSEC_SETXID (1 << TIF_GRSEC_SETXID)
+
+ /* Checks for any syscall work in entry-common.S */
+ #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+- _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
++ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | _TIF_GRSEC_SETXID)
+
+ /*
+ * Change these and you break ASM code in entry-common.S
+diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h
+index f6fcc67..5895d62 100644
+--- a/arch/arm/include/asm/timex.h
++++ b/arch/arm/include/asm/timex.h
+@@ -13,6 +13,7 @@
+ #define _ASMARM_TIMEX_H
+
+ typedef unsigned long cycles_t;
++extern int read_current_timer(unsigned long *timer_val);
+ #define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; })
+
+ #endif
+diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
+index 5f833f7..76e6644 100644
+--- a/arch/arm/include/asm/tls.h
++++ b/arch/arm/include/asm/tls.h
+@@ -3,6 +3,7 @@
+
+ #include <linux/compiler.h>
+ #include <asm/thread_info.h>
++#include <asm/pgtable.h>
+
+ #ifdef __ASSEMBLY__
+ #include <asm/asm-offsets.h>
+@@ -89,7 +90,9 @@ static inline void set_tls(unsigned long val)
+ * at 0xffff0fe0 must be used instead. (see
+ * entry-armv.S for details)
+ */
++ pax_open_kernel();
+ *((unsigned int *)0xffff0ff0) = val;
++ pax_close_kernel();
+ #endif
+ }
+
+diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
+index 1f59ea05..81245f0 100644
+--- a/arch/arm/include/asm/uaccess.h
++++ b/arch/arm/include/asm/uaccess.h
+@@ -18,6 +18,7 @@
+ #include <asm/domain.h>
+ #include <asm/unified.h>
+ #include <asm/compiler.h>
++#include <asm/pgtable.h>
+
+ #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ #include <asm-generic/uaccess-unaligned.h>
+@@ -50,6 +51,59 @@ struct exception_table_entry
+ extern int fixup_exception(struct pt_regs *regs);
+
+ /*
++ * These two are intentionally not defined anywhere - if the kernel
++ * code generates any references to them, that's a bug.
++ */
++extern int __get_user_bad(void);
++extern int __put_user_bad(void);
++
++/*
++ * Note that this is actually 0x1,0000,0000
++ */
++#define KERNEL_DS 0x00000000
++#define get_ds() (KERNEL_DS)
++
++#ifdef CONFIG_MMU
++
++#define USER_DS TASK_SIZE
++#define get_fs() (current_thread_info()->addr_limit)
++
++static inline void set_fs(mm_segment_t fs)
++{
++ current_thread_info()->addr_limit = fs;
++ modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_KERNELCLIENT : DOMAIN_MANAGER);
++}
++
++#define segment_eq(a, b) ((a) == (b))
++
++#define __HAVE_ARCH_PAX_OPEN_USERLAND
++#define __HAVE_ARCH_PAX_CLOSE_USERLAND
++
++static inline void pax_open_userland(void)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ if (segment_eq(get_fs(), USER_DS)) {
++ BUG_ON(test_domain(DOMAIN_USER, DOMAIN_UDEREF));
++ modify_domain(DOMAIN_USER, DOMAIN_UDEREF);
++ }
++#endif
++
++}
++
++static inline void pax_close_userland(void)
++{
++
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ if (segment_eq(get_fs(), USER_DS)) {
++ BUG_ON(test_domain(DOMAIN_USER, DOMAIN_NOACCESS));
++ modify_domain(DOMAIN_USER, DOMAIN_NOACCESS);
++ }
++#endif
++
++}
++
++/*
+ * These two functions allow hooking accesses to userspace to increase
+ * system integrity by ensuring that the kernel can not inadvertantly
+ * perform such accesses (eg, via list poison values) which could then
+@@ -66,6 +120,7 @@ static inline unsigned int uaccess_save_and_enable(void)
+
+ return old_domain;
+ #else
++ pax_open_userland();
+ return 0;
+ #endif
+ }
+@@ -75,35 +130,11 @@ static inline void uaccess_restore(unsigned int flags)
+ #ifdef CONFIG_CPU_SW_DOMAIN_PAN
+ /* Restore the user access mask */
+ set_domain(flags);
++#else
++ pax_close_userland();
+ #endif
+ }
+
+-/*
+- * These two are intentionally not defined anywhere - if the kernel
+- * code generates any references to them, that's a bug.
+- */
+-extern int __get_user_bad(void);
+-extern int __put_user_bad(void);
+-
+-/*
+- * Note that this is actually 0x1,0000,0000
+- */
+-#define KERNEL_DS 0x00000000
+-#define get_ds() (KERNEL_DS)
+-
+-#ifdef CONFIG_MMU
+-
+-#define USER_DS TASK_SIZE
+-#define get_fs() (current_thread_info()->addr_limit)
+-
+-static inline void set_fs(mm_segment_t fs)
+-{
+- current_thread_info()->addr_limit = fs;
+- modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
+-}
+-
+-#define segment_eq(a, b) ((a) == (b))
+-
+ /* We use 33-bit arithmetic here... */
+ #define __range_ok(addr, size) ({ \
+ unsigned long flag, roksum; \
+@@ -268,6 +299,7 @@ static inline void set_fs(mm_segment_t fs)
+
+ #endif /* CONFIG_MMU */
+
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
+
+ #define user_addr_max() \
+@@ -474,10 +506,10 @@ do { \
+
+
+ #ifdef CONFIG_MMU
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ arm_copy_from_user(void *to, const void __user *from, unsigned long n);
+
+-static inline unsigned long __must_check
++static inline unsigned long __must_check __size_overflow(3)
+ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ unsigned int __ua_flags;
+@@ -489,9 +521,9 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
+ return n;
+ }
+
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ arm_copy_to_user(void __user *to, const void *from, unsigned long n);
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(3)
+ __copy_to_user_std(void __user *to, const void *from, unsigned long n);
+
+ static inline unsigned long __must_check
+@@ -511,9 +543,9 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
+ #endif
+ }
+
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(2)
+ arm_clear_user(void __user *addr, unsigned long n);
+-extern unsigned long __must_check
++extern unsigned long __must_check __size_overflow(2)
+ __clear_user_std(void __user *addr, unsigned long n);
+
+ static inline unsigned long __must_check
+@@ -534,6 +566,10 @@ __clear_user(void __user *addr, unsigned long n)
+ static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ unsigned long res = n;
++
++ if ((long)n < 0)
++ return n;
++
+ if (likely(access_ok(VERIFY_READ, from, n)))
+ res = __copy_from_user(to, from, n);
+ if (unlikely(res))
+@@ -543,6 +579,9 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
+
+ static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ if (access_ok(VERIFY_WRITE, to, n))
+ n = __copy_to_user(to, from, n);
+ return n;
+diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
+index 5af0ed1..cea83883 100644
+--- a/arch/arm/include/uapi/asm/ptrace.h
++++ b/arch/arm/include/uapi/asm/ptrace.h
+@@ -92,7 +92,7 @@
+ * ARMv7 groups of PSR bits
+ */
+ #define APSR_MASK 0xf80f0000 /* N, Z, C, V, Q and GE flags */
+-#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */
++#define PSR_ISET_MASK 0x01000020 /* ISA state (J, T) mask */
+ #define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
+ #define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
+
+diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
+index 7e45f69..2c047db 100644
+--- a/arch/arm/kernel/armksyms.c
++++ b/arch/arm/kernel/armksyms.c
+@@ -59,7 +59,7 @@ EXPORT_SYMBOL(arm_delay_ops);
+
+ /* networking */
+ EXPORT_SYMBOL(csum_partial);
+-EXPORT_SYMBOL(csum_partial_copy_from_user);
++EXPORT_SYMBOL(__csum_partial_copy_from_user);
+ EXPORT_SYMBOL(csum_partial_copy_nocheck);
+ EXPORT_SYMBOL(__csum_ipv6_magic);
+
+diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c
+index 9f43ba0..1cee475 100644
+--- a/arch/arm/kernel/efi.c
++++ b/arch/arm/kernel/efi.c
+@@ -60,9 +60,9 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
+ * preference.
+ */
+ if (md->attribute & EFI_MEMORY_WB)
+- desc.type = MT_MEMORY_RWX;
++ desc.type = __MT_MEMORY_RWX;
+ else if (md->attribute & EFI_MEMORY_WT)
+- desc.type = MT_MEMORY_RWX_NONCACHED;
++ desc.type = MT_MEMORY_RW_NONCACHED;
+ else if (md->attribute & EFI_MEMORY_WC)
+ desc.type = MT_DEVICE_WC;
+ else
+diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
+index 9f157e7..8e3f857 100644
+--- a/arch/arm/kernel/entry-armv.S
++++ b/arch/arm/kernel/entry-armv.S
+@@ -50,6 +50,87 @@
+ 9997:
+ .endm
+
++ .macro pax_enter_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ @ make aligned space for saved DACR
++ sub sp, sp, #8
++ @ save regs
++ stmdb sp!, {r1, r2}
++ @ read DACR from cpu_domain into r1
++ mov r2, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r2, r2, #(0x1fc0)
++ bic r2, r2, #(0x3f)
++ ldr r1, [r2, #TI_CPU_DOMAIN]
++ @ store old DACR on stack
++ str r1, [sp, #8]
++#ifdef CONFIG_PAX_KERNEXEC
++ @ set type of DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++ bic r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++ orr r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ @ set current DOMAIN_USER to DOMAIN_NOACCESS
++ bic r1, r1, #(domain_val(DOMAIN_USER, 3))
++#endif
++ @ write r1 to current_thread_info()->cpu_domain
++ str r1, [r2, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r1, r2}
++#endif
++ .endm
++
++ .macro pax_open_userland
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ @ save regs
++ stmdb sp!, {r0, r1}
++ @ read DACR from cpu_domain into r1
++ mov r0, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r0, r0, #(0x1fc0)
++ bic r0, r0, #(0x3f)
++ ldr r1, [r0, #TI_CPU_DOMAIN]
++ @ set current DOMAIN_USER to DOMAIN_CLIENT
++ bic r1, r1, #(domain_val(DOMAIN_USER, 3))
++ orr r1, r1, #(domain_val(DOMAIN_USER, DOMAIN_UDEREF))
++ @ write r1 to current_thread_info()->cpu_domain
++ str r1, [r0, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r0, r1}
++#endif
++ .endm
++
++ .macro pax_close_userland
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ @ save regs
++ stmdb sp!, {r0, r1}
++ @ read DACR from cpu_domain into r1
++ mov r0, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r0, r0, #(0x1fc0)
++ bic r0, r0, #(0x3f)
++ ldr r1, [r0, #TI_CPU_DOMAIN]
++ @ set current DOMAIN_USER to DOMAIN_NOACCESS
++ bic r1, r1, #(domain_val(DOMAIN_USER, 3))
++ @ write r1 to current_thread_info()->cpu_domain
++ str r1, [r0, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r0, r1}
++#endif
++ .endm
++
+ .macro pabt_helper
+ @ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
+ #ifdef MULTI_PABORT
+@@ -92,11 +173,15 @@
+ * Invalid mode handlers
+ */
+ .macro inv_entry, reason
++
++ pax_enter_kernel
++
+ sub sp, sp, #PT_REGS_SIZE
+ ARM( stmib sp, {r1 - lr} )
+ THUMB( stmia sp, {r0 - r12} )
+ THUMB( str sp, [sp, #S_SP] )
+ THUMB( str lr, [sp, #S_LR] )
++
+ mov r1, #\reason
+ .endm
+
+@@ -152,6 +237,9 @@ ENDPROC(__und_invalid)
+ .macro svc_entry, stack_hole=0, trace=1, uaccess=1
+ UNWIND(.fnstart )
+ UNWIND(.save {r0 - pc} )
++
++ pax_enter_kernel
++
+ sub sp, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
+ #ifdef CONFIG_THUMB2_KERNEL
+ SPFIX( str r0, [sp] ) @ temporarily saved
+@@ -167,7 +255,12 @@ ENDPROC(__und_invalid)
+ ldmia r0, {r3 - r5}
+ add r7, sp, #S_SP - 4 @ here for interlock avoidance
+ mov r6, #-1 @ "" "" "" ""
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ @ offset sp by 8 as done in pax_enter_kernel
++ add r2, sp, #(SVC_REGS_SIZE + \stack_hole + 4)
++#else
+ add r2, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
++#endif
+ SPFIX( addeq r2, r2, #4 )
+ str r3, [sp, #-4]! @ save the "real" r0 copied
+ @ from the exception stack
+@@ -382,6 +475,9 @@ ENDPROC(__fiq_abt)
+ .macro usr_entry, trace=1, uaccess=1
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind ) @ don't unwind the user space
++
++ pax_enter_kernel_user
++
+ sub sp, sp, #PT_REGS_SIZE
+ ARM( stmib sp, {r1 - r12} )
+ THUMB( stmia sp, {r0 - r12} )
+@@ -495,7 +591,9 @@ __und_usr:
+ tst r3, #PSR_T_BIT @ Thumb mode?
+ bne __und_usr_thumb
+ sub r4, r2, #4 @ ARM instr at LR - 4
++ pax_open_userland
+ 1: ldrt r0, [r4]
++ pax_close_userland
+ ARM_BE8(rev r0, r0) @ little endian instruction
+
+ uaccess_disable ip
+@@ -531,11 +629,15 @@ __und_usr_thumb:
+ */
+ .arch armv6t2
+ #endif
++ pax_open_userland
+ 2: ldrht r5, [r4]
++ pax_close_userland
+ ARM_BE8(rev16 r5, r5) @ little endian instruction
+ cmp r5, #0xe800 @ 32bit instruction if xx != 0
+ blo __und_usr_fault_16_pan @ 16bit undefined instruction
++ pax_open_userland
+ 3: ldrht r0, [r2]
++ pax_close_userland
+ ARM_BE8(rev16 r0, r0) @ little endian instruction
+ uaccess_disable ip
+ add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
+@@ -566,7 +668,8 @@ ENDPROC(__und_usr)
+ */
+ .pushsection .text.fixup, "ax"
+ .align 2
+-4: str r4, [sp, #S_PC] @ retry current instruction
++4: pax_close_userland
++ str r4, [sp, #S_PC] @ retry current instruction
+ ret r9
+ .popsection
+ .pushsection __ex_table,"a"
+@@ -788,7 +891,7 @@ ENTRY(__switch_to)
+ THUMB( str lr, [ip], #4 )
+ ldr r4, [r2, #TI_TP_VALUE]
+ ldr r5, [r2, #TI_TP_VALUE + 4]
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+ mrc p15, 0, r6, c3, c0, 0 @ Get domain register
+ str r6, [r1, #TI_CPU_DOMAIN] @ Save old domain register
+ ldr r6, [r2, #TI_CPU_DOMAIN]
+@@ -799,7 +902,7 @@ ENTRY(__switch_to)
+ ldr r8, =__stack_chk_guard
+ ldr r7, [r7, #TSK_STACK_CANARY]
+ #endif
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+ mcr p15, 0, r6, c3, c0, 0 @ Set domain register
+ #endif
+ mov r5, r0
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index 10c3283..c47cdf5 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -11,18 +11,46 @@
+ #include <asm/assembler.h>
+ #include <asm/unistd.h>
+ #include <asm/ftrace.h>
++#include <asm/domain.h>
+ #include <asm/unwind.h>
+
++#include "entry-header.S"
++
+ #ifdef CONFIG_NEED_RET_TO_USER
+ #include <mach/entry-macro.S>
+ #else
+ .macro arch_ret_to_user, tmp1, tmp2
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ @ save regs
++ stmdb sp!, {r1, r2}
++ @ read DACR from cpu_domain into r1
++ mov r2, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r2, r2, #(0x1fc0)
++ bic r2, r2, #(0x3f)
++ ldr r1, [r2, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_KERNEXEC
++ @ set type of DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++ bic r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++ orr r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ @ set current DOMAIN_USER to DOMAIN_UDEREF
++ bic r1, r1, #(domain_val(DOMAIN_USER, 3))
++ orr r1, r1, #(domain_val(DOMAIN_USER, DOMAIN_UDEREF))
++#endif
++ @ write r1 to current_thread_info()->cpu_domain
++ str r1, [r2, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r1, r2}
++#endif
+ .endm
+ #endif
+
+-#include "entry-header.S"
+-
+-
+ .align 5
+ #if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
+ /*
+@@ -36,7 +64,9 @@ ret_fast_syscall:
+ UNWIND(.cantunwind )
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne fast_work_pending
++ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+
+ /* perform architecture specific actions before user return */
+@@ -62,7 +92,9 @@ ret_fast_syscall:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne __sys_trace_return_nosave
++ tst r1, #_TIF_WORK_MASK
+ beq no_work_pending
+ UNWIND(.fnend )
+ ENDPROC(ret_fast_syscall)
+@@ -199,6 +231,12 @@ ENTRY(vector_swi)
+
+ uaccess_disable tbl
+
++ /*
++ * do this here to avoid a performance hit of wrapping the code above
++ * that directly dereferences userland to parse the SWI instruction
++ */
++ pax_enter_kernel_user
++
+ adr tbl, sys_call_table @ load syscall table pointer
+
+ #if defined(CONFIG_OABI_COMPAT)
+diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
+index 6391728..6bf90b8 100644
+--- a/arch/arm/kernel/entry-header.S
++++ b/arch/arm/kernel/entry-header.S
+@@ -196,6 +196,59 @@
+ msr cpsr_c, \rtemp @ switch back to the SVC mode
+ .endm
+
++ .macro pax_enter_kernel_user
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ @ save regs
++ stmdb sp!, {r0, r1}
++ @ read DACR from cpu_domain into r1
++ mov r0, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r0, r0, #(0x1fc0)
++ bic r0, r0, #(0x3f)
++ ldr r1, [r0, #TI_CPU_DOMAIN]
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ @ set current DOMAIN_USER to DOMAIN_NOACCESS
++ bic r1, r1, #(domain_val(DOMAIN_USER, 3))
++#endif
++#ifdef CONFIG_PAX_KERNEXEC
++ @ set current DOMAIN_KERNEL to DOMAIN_KERNELCLIENT
++ bic r1, r1, #(domain_val(DOMAIN_KERNEL, 3))
++ orr r1, r1, #(domain_val(DOMAIN_KERNEL, DOMAIN_KERNELCLIENT))
++#endif
++ @ write r1 to current_thread_info()->cpu_domain
++ str r1, [r0, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r0, r1}
++#endif
++ .endm
++
++ .macro pax_exit_kernel
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ @ save regs
++ stmdb sp!, {r0, r1}
++ @ read old DACR from stack into r1
++ ldr r1, [sp, #(8 + S_SP)]
++ sub r1, r1, #8
++ ldr r1, [r1]
++
++ @ write r1 to current_thread_info()->cpu_domain
++ mov r0, sp
++ @ assume 8K pages, since we have to split the immediate in two
++ bic r0, r0, #(0x1fc0)
++ bic r0, r0, #(0x3f)
++ str r1, [r0, #TI_CPU_DOMAIN]
++ @ write r1 to DACR
++ mcr p15, 0, r1, c3, c0, 0
++ @ instruction sync
++ instr_sync
++ @ restore regs
++ ldmia sp!, {r0, r1}
++#endif
++ .endm
+
+ .macro svc_exit, rpsr, irq = 0
+ .if \irq != 0
+@@ -219,6 +272,8 @@
+ uaccess_restore
+ str r1, [tsk, #TI_ADDR_LIMIT]
+
++ pax_exit_kernel
++
+ #ifndef CONFIG_THUMB2_KERNEL
+ @ ARM mode SVC restore
+ msr spsr_cxsf, \rpsr
+diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
+index 059c3da..8e45cfc 100644
+--- a/arch/arm/kernel/fiq.c
++++ b/arch/arm/kernel/fiq.c
+@@ -95,7 +95,10 @@ void set_fiq_handler(void *start, unsigned int length)
+ void *base = vectors_page;
+ unsigned offset = FIQ_OFFSET;
+
++ pax_open_kernel();
+ memcpy(base + offset, start, length);
++ pax_close_kernel();
++
+ if (!cache_is_vipt_nonaliasing())
+ flush_icache_range((unsigned long)base + offset, offset +
+ length);
+diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
+index 4f14b5c..91ff261 100644
+--- a/arch/arm/kernel/module.c
++++ b/arch/arm/kernel/module.c
+@@ -38,17 +38,47 @@
+ #endif
+
+ #ifdef CONFIG_MMU
+-void *module_alloc(unsigned long size)
++static inline void *__module_alloc(unsigned long size, pgprot_t prot)
+ {
+- void *p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+- GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
++ void *p;
++
++ if (!size || (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) && PAGE_ALIGN(size) > MODULES_END - MODULES_VADDR))
++ return NULL;
++
++ p = __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
++ GFP_KERNEL, prot, 0, NUMA_NO_NODE,
+ __builtin_return_address(0));
+ if (!IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || p)
+ return p;
+ return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
+- GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
++ GFP_KERNEL, prot, 0, NUMA_NO_NODE,
+ __builtin_return_address(0));
+ }
++
++void *module_alloc(unsigned long size)
++{
++
++#ifdef CONFIG_PAX_KERNEXEC
++ return __module_alloc(size, PAGE_KERNEL);
++#else
++ return __module_alloc(size, PAGE_KERNEL_EXEC);
++#endif
++
++}
++
++#ifdef CONFIG_PAX_KERNEXEC
++void module_memfree_exec(void *module_region)
++{
++ module_memfree(module_region);
++}
++EXPORT_SYMBOL(module_memfree_exec);
++
++void *module_alloc_exec(unsigned long size)
++{
++ return __module_alloc(size, PAGE_KERNEL_EXEC);
++}
++EXPORT_SYMBOL(module_alloc_exec);
++#endif
+ #endif
+
+ int
+diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
+index 69bda1a..755113a 100644
+--- a/arch/arm/kernel/patch.c
++++ b/arch/arm/kernel/patch.c
+@@ -66,6 +66,7 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
+ else
+ __acquire(&patch_lock);
+
++ pax_open_kernel();
+ if (thumb2 && __opcode_is_thumb16(insn)) {
+ *(u16 *)waddr = __opcode_to_mem_thumb16(insn);
+ size = sizeof(u16);
+@@ -97,6 +98,7 @@ void __kprobes __patch_text_real(void *addr, unsigned int insn, bool remap)
+ *(u32 *)waddr = insn;
+ size = sizeof(u32);
+ }
++ pax_close_kernel();
+
+ if (waddr != addr) {
+ flush_kernel_vmap_range(waddr, twopage ? size / 2 : size);
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index 91d2d5b..042c26e 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -118,8 +118,8 @@ void __show_regs(struct pt_regs *regs)
+
+ show_regs_print_info(KERN_DEFAULT);
+
+- print_symbol("PC is at %s\n", instruction_pointer(regs));
+- print_symbol("LR is at %s\n", regs->ARM_lr);
++ printk("PC is at %pA\n", (void *)instruction_pointer(regs));
++ printk("LR is at %pA\n", (void *)regs->ARM_lr);
+ printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
+@@ -233,7 +233,7 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+
+-#ifdef CONFIG_CPU_USE_DOMAINS
++#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+ /*
+ * Copy the initial value of the domain access control register
+ * from the current thread: thread->addr_limit will have been
+@@ -336,7 +336,7 @@ static struct vm_area_struct gate_vma = {
+
+ static int __init gate_vma_init(void)
+ {
+- gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
+ return 0;
+ }
+ arch_initcall(gate_vma_init);
+@@ -365,92 +365,14 @@ const char *arch_vma_name(struct vm_area_struct *vma)
+ return is_gate_vma(vma) ? "[vectors]" : NULL;
+ }
+
+-/* If possible, provide a placement hint at a random offset from the
+- * stack for the sigpage and vdso pages.
+- */
+-static unsigned long sigpage_addr(const struct mm_struct *mm,
+- unsigned int npages)
+-{
+- unsigned long offset;
+- unsigned long first;
+- unsigned long last;
+- unsigned long addr;
+- unsigned int slots;
+-
+- first = PAGE_ALIGN(mm->start_stack);
+-
+- last = TASK_SIZE - (npages << PAGE_SHIFT);
+-
+- /* No room after stack? */
+- if (first > last)
+- return 0;
+-
+- /* Just enough room? */
+- if (first == last)
+- return first;
+-
+- slots = ((last - first) >> PAGE_SHIFT) + 1;
+-
+- offset = get_random_int() % slots;
+-
+- addr = first + (offset << PAGE_SHIFT);
+-
+- return addr;
+-}
+-
+-static struct page *signal_page;
+-extern struct page *get_signal_page(void);
+-
+-static const struct vm_special_mapping sigpage_mapping = {
+- .name = "[sigpage]",
+- .pages = &signal_page,
+-};
+-
+ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ {
+ struct mm_struct *mm = current->mm;
+- struct vm_area_struct *vma;
+- unsigned long npages;
+- unsigned long addr;
+- unsigned long hint;
+- int ret = 0;
+-
+- if (!signal_page)
+- signal_page = get_signal_page();
+- if (!signal_page)
+- return -ENOMEM;
+-
+- npages = 1; /* for sigpage */
+- npages += vdso_total_pages;
+
+ if (down_write_killable(&mm->mmap_sem))
+ return -EINTR;
+- hint = sigpage_addr(mm, npages);
+- addr = get_unmapped_area(NULL, hint, npages << PAGE_SHIFT, 0, 0);
+- if (IS_ERR_VALUE(addr)) {
+- ret = addr;
+- goto up_fail;
+- }
+-
+- vma = _install_special_mapping(mm, addr, PAGE_SIZE,
+- VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
+- &sigpage_mapping);
+-
+- if (IS_ERR(vma)) {
+- ret = PTR_ERR(vma);
+- goto up_fail;
+- }
+-
+- mm->context.sigpage = addr;
+-
+- /* Unlike the sigpage, failure to install the vdso is unlikely
+- * to be fatal to the process, so no error check needed
+- * here.
+- */
+- arm_install_vdso(mm, addr + PAGE_SIZE);
+-
+- up_fail:
++ mm->context.sigpage = (PAGE_OFFSET + (get_random_int() % 0x3FFEFFE0)) & 0xFFFFFFFC;
+ up_write(&mm->mmap_sem);
+- return ret;
++ return 0;
+ }
+ #endif
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index ae738a6..ee4d46f 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -928,10 +928,19 @@ static void tracehook_report_syscall(struct pt_regs *regs,
+ regs->ARM_ip = ip;
+ }
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
+ {
+ current_thread_info()->syscall = scno;
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
+index 3fa867a..d610607 100644
+--- a/arch/arm/kernel/reboot.c
++++ b/arch/arm/kernel/reboot.c
+@@ -120,6 +120,7 @@ void machine_power_off(void)
+
+ if (pm_power_off)
+ pm_power_off();
++ while (1);
+ }
+
+ /*
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index 34e3f3c..3d2dada 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -112,6 +112,8 @@ EXPORT_SYMBOL(elf_hwcap);
+ unsigned int elf_hwcap2 __read_mostly;
+ EXPORT_SYMBOL(elf_hwcap2);
+
++pteval_t __supported_pte_mask __read_only;
++pmdval_t __supported_pmd_mask __read_only;
+
+ #ifdef MULTI_CPU
+ struct processor processor __ro_after_init;
+@@ -257,9 +259,13 @@ static int __get_cpu_architecture(void)
+ * Register 0 and check for VMSAv7 or PMSAv7 */
+ unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0);
+ if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
+- (mmfr0 & 0x000000f0) >= 0x00000030)
++ (mmfr0 & 0x000000f0) >= 0x00000030) {
+ cpu_arch = CPU_ARCH_ARMv7;
+- else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
++ if ((mmfr0 & 0x0000000f) == 0x00000005 || (mmfr0 & 0x0000000f) == 0x00000004) {
++ __supported_pte_mask |= L_PTE_PXN;
++ __supported_pmd_mask |= PMD_PXNTABLE;
++ }
++ } else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
+ (mmfr0 & 0x000000f0) == 0x00000020)
+ cpu_arch = CPU_ARCH_ARMv6;
+ else
+diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
+index 7b8f214..ece8e28 100644
+--- a/arch/arm/kernel/signal.c
++++ b/arch/arm/kernel/signal.c
+@@ -24,8 +24,6 @@
+
+ extern const unsigned long sigreturn_codes[7];
+
+-static unsigned long signal_return_offset;
+-
+ #ifdef CONFIG_CRUNCH
+ static int preserve_crunch_context(struct crunch_sigframe __user *frame)
+ {
+@@ -388,8 +386,7 @@ setup_return(struct pt_regs *regs, struct ksignal *ksig,
+ * except when the MPU has protected the vectors
+ * page from PL0
+ */
+- retcode = mm->context.sigpage + signal_return_offset +
+- (idx << 2) + thumb;
++ retcode = mm->context.sigpage + (idx << 2) + thumb;
+ } else
+ #endif
+ {
+@@ -601,33 +598,3 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+ } while (thread_flags & _TIF_WORK_MASK);
+ return 0;
+ }
+-
+-struct page *get_signal_page(void)
+-{
+- unsigned long ptr;
+- unsigned offset;
+- struct page *page;
+- void *addr;
+-
+- page = alloc_pages(GFP_KERNEL, 0);
+-
+- if (!page)
+- return NULL;
+-
+- addr = page_address(page);
+-
+- /* Give the signal return code some randomness */
+- offset = 0x200 + (get_random_int() & 0x7fc);
+- signal_return_offset = offset;
+-
+- /*
+- * Copy signal return handlers into the vector page, and
+- * set sigreturn to be a pointer to these.
+- */
+- memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes));
+-
+- ptr = (unsigned long)addr + offset;
+- flush_icache_range(ptr, ptr + sizeof(sigreturn_codes));
+-
+- return page;
+-}
+diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
+index b10e136..cb5edf9 100644
+--- a/arch/arm/kernel/tcm.c
++++ b/arch/arm/kernel/tcm.c
+@@ -64,7 +64,7 @@ static struct map_desc itcm_iomap[] __initdata = {
+ .virtual = ITCM_OFFSET,
+ .pfn = __phys_to_pfn(ITCM_OFFSET),
+ .length = 0,
+- .type = MT_MEMORY_RWX_ITCM,
++ .type = MT_MEMORY_RX_ITCM,
+ }
+ };
+
+@@ -362,7 +362,9 @@ void __init tcm_init(void)
+ start = &__sitcm_text;
+ end = &__eitcm_text;
+ ram = &__itcm_start;
++ pax_open_kernel();
+ memcpy(start, ram, itcm_code_sz);
++ pax_close_kernel();
+ pr_debug("CPU ITCM: copied code from %p - %p\n",
+ start, end);
+ itcm_present = true;
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index 9688ec0..dd072c0 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -65,7 +65,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
+ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
+ {
+ #ifdef CONFIG_KALLSYMS
+- printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
++ printk("[<%08lx>] (%pA) from [<%08lx>] (%pA)\n", where, (void *)where, from, (void *)from);
+ #else
+ printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+ #endif
+@@ -287,6 +287,8 @@ static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+ static int die_owner = -1;
+ static unsigned int die_nest_count;
+
++extern void gr_handle_kernel_exploit(void);
++
+ static unsigned long oops_begin(void)
+ {
+ int cpu;
+@@ -329,6 +331,9 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
+ panic("Fatal exception in interrupt");
+ if (panic_on_oops)
+ panic("Fatal exception");
++
++ gr_handle_kernel_exploit();
++
+ if (signr)
+ do_exit(signr);
+ }
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index f7f55df..49c9f9e 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -44,7 +44,8 @@
+ #endif
+
+ #if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \
+- defined(CONFIG_GENERIC_BUG) || defined(CONFIG_JUMP_LABEL)
++ defined(CONFIG_GENERIC_BUG) || defined(CONFIG_JUMP_LABEL) || \
++ defined(CONFIG_PAX_REFCOUNT)
+ #define ARM_EXIT_KEEP(x) x
+ #define ARM_EXIT_DISCARD(x)
+ #else
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index 19b5f5c..9aa8e58 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -59,7 +59,7 @@ static unsigned long hyp_default_vectors;
+ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
+
+ /* The VMID used in the VTTBR */
+-static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
++static atomic64_unchecked_t kvm_vmid_gen = ATOMIC64_INIT(1);
+ static u32 kvm_next_vmid;
+ static unsigned int kvm_vmid_bits __read_mostly;
+ static DEFINE_SPINLOCK(kvm_vmid_lock);
+@@ -423,7 +423,7 @@ void force_vm_exit(const cpumask_t *mask)
+ */
+ static bool need_new_vmid_gen(struct kvm *kvm)
+ {
+- return unlikely(kvm->arch.vmid_gen != atomic64_read(&kvm_vmid_gen));
++ return unlikely(kvm->arch.vmid_gen != atomic64_read_unchecked(&kvm_vmid_gen));
+ }
+
+ /**
+@@ -456,7 +456,7 @@ static void update_vttbr(struct kvm *kvm)
+
+ /* First user of a new VMID generation? */
+ if (unlikely(kvm_next_vmid == 0)) {
+- atomic64_inc(&kvm_vmid_gen);
++ atomic64_inc_unchecked(&kvm_vmid_gen);
+ kvm_next_vmid = 1;
+
+ /*
+@@ -473,7 +473,7 @@ static void update_vttbr(struct kvm *kvm)
+ kvm_call_hyp(__kvm_flush_vm_context);
+ }
+
+- kvm->arch.vmid_gen = atomic64_read(&kvm_vmid_gen);
++ kvm->arch.vmid_gen = atomic64_read_unchecked(&kvm_vmid_gen);
+ kvm->arch.vmid = kvm_next_vmid;
+ kvm_next_vmid++;
+ kvm_next_vmid &= (1 << kvm_vmid_bits) - 1;
+diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
+index 6ee2f67..d1cce76 100644
+--- a/arch/arm/lib/copy_page.S
++++ b/arch/arm/lib/copy_page.S
+@@ -10,6 +10,7 @@
+ * ASM optimised string functions
+ */
+ #include <linux/linkage.h>
++#include <linux/const.h>
+ #include <asm/assembler.h>
+ #include <asm/asm-offsets.h>
+ #include <asm/cache.h>
+diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
+index 1712f13..a3165dc 100644
+--- a/arch/arm/lib/csumpartialcopyuser.S
++++ b/arch/arm/lib/csumpartialcopyuser.S
+@@ -71,8 +71,8 @@
+ * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+ */
+
+-#define FN_ENTRY ENTRY(csum_partial_copy_from_user)
+-#define FN_EXIT ENDPROC(csum_partial_copy_from_user)
++#define FN_ENTRY ENTRY(__csum_partial_copy_from_user)
++#define FN_EXIT ENDPROC(__csum_partial_copy_from_user)
+
+ #include "csumpartialcopygeneric.S"
+
+diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
+index 6bd1089..e999400 100644
+--- a/arch/arm/lib/uaccess_with_memcpy.c
++++ b/arch/arm/lib/uaccess_with_memcpy.c
+@@ -84,7 +84,7 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
+ return 1;
+ }
+
+-static unsigned long noinline
++static unsigned long noinline __size_overflow(3)
+ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
+ {
+ unsigned long ua_flags;
+@@ -157,7 +157,7 @@ arm_copy_to_user(void __user *to, const void *from, unsigned long n)
+ return n;
+ }
+
+-static unsigned long noinline
++static unsigned long noinline __size_overflow(2)
+ __clear_user_memset(void __user *addr, unsigned long n)
+ {
+ unsigned long ua_flags;
+diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
+index 06332f6..1fa0c71 100644
+--- a/arch/arm/mach-exynos/suspend.c
++++ b/arch/arm/mach-exynos/suspend.c
+@@ -724,8 +724,10 @@ void __init exynos_pm_init(void)
+ tmp |= pm_data->wake_disable_mask;
+ pmu_raw_writel(tmp, S5P_WAKEUP_MASK);
+
+- exynos_pm_syscore_ops.suspend = pm_data->pm_suspend;
+- exynos_pm_syscore_ops.resume = pm_data->pm_resume;
++ pax_open_kernel();
++ const_cast(exynos_pm_syscore_ops.suspend) = pm_data->pm_suspend;
++ const_cast(exynos_pm_syscore_ops.resume) = pm_data->pm_resume;
++ pax_close_kernel();
+
+ register_syscore_ops(&exynos_pm_syscore_ops);
+ suspend_set_ops(&exynos_suspend_ops);
+diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
+index afba546..9e5403d 100644
+--- a/arch/arm/mach-mmp/mmp2.c
++++ b/arch/arm/mach-mmp/mmp2.c
+@@ -98,7 +98,9 @@ void __init mmp2_init_irq(void)
+ {
+ mmp2_init_icu();
+ #ifdef CONFIG_PM
+- icu_irq_chip.irq_set_wake = mmp2_set_wake;
++ pax_open_kernel();
++ const_cast(icu_irq_chip.irq_set_wake) = mmp2_set_wake;
++ pax_close_kernel();
+ #endif
+ }
+
+diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
+index 1ccbba9..7a95c29 100644
+--- a/arch/arm/mach-mmp/pxa910.c
++++ b/arch/arm/mach-mmp/pxa910.c
+@@ -84,7 +84,9 @@ void __init pxa910_init_irq(void)
+ {
+ icu_init_irq();
+ #ifdef CONFIG_PM
+- icu_irq_chip.irq_set_wake = pxa910_set_wake;
++ pax_open_kernel();
++ const_cast(icu_irq_chip.irq_set_wake) = pxa910_set_wake;
++ pax_close_kernel();
+ #endif
+ }
+
+diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
+index ae2a018..297ad08 100644
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -156,7 +156,7 @@ static void __init armada_370_coherency_init(struct device_node *np)
+
+ /*
+ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
+- * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
++ * areas are mapped as MT_UNCACHED_RW instead of MT_DEVICE. This is
+ * needed for the HW I/O coherency mechanism to work properly without
+ * deadlock.
+ */
+@@ -164,7 +164,7 @@ static void __iomem *
+ armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+ {
+- mtype = MT_UNCACHED;
++ mtype = MT_UNCACHED_RW;
+ return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+
+@@ -174,7 +174,7 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
+
+ coherency_cpu_base = of_iomap(np, 0);
+ arch_ioremap_caller = armada_wa_ioremap_caller;
+- pci_ioremap_set_mem_type(MT_UNCACHED);
++ pci_ioremap_set_mem_type(MT_UNCACHED_RW);
+
+ /*
+ * We should switch the PL310 to I/O coherency mode only if
+diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
+index f39bd51..866c780 100644
+--- a/arch/arm/mach-mvebu/pmsu.c
++++ b/arch/arm/mach-mvebu/pmsu.c
+@@ -93,7 +93,7 @@
+ #define ARMADA_370_CRYPT0_ENG_ATTR 0x1
+
+ extern void ll_disable_coherency(void);
+-extern void ll_enable_coherency(void);
++extern int ll_enable_coherency(void);
+
+ extern void armada_370_xp_cpu_resume(void);
+ extern void armada_38x_cpu_resume(void);
+diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
+index 6b6fda6..232df1e 100644
+--- a/arch/arm/mach-omap2/board-n8x0.c
++++ b/arch/arm/mach-omap2/board-n8x0.c
+@@ -568,7 +568,7 @@ static int n8x0_menelaus_late_init(struct device *dev)
+ }
+ #endif
+
+-struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
++struct menelaus_platform_data n8x0_menelaus_platform_data __initconst = {
+ .late_init = n8x0_menelaus_late_init,
+ };
+
+diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+index 7d62ad4..97774b1 100644
+--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
++++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+@@ -89,7 +89,7 @@ struct cpu_pm_ops {
+ void (*resume)(void);
+ void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+ void (*hotplug_restart)(void);
+-};
++} __no_const;
+
+ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+ static struct powerdomain *mpuss_pd;
+@@ -107,7 +107,7 @@ static void dummy_cpu_resume(void)
+ static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+ {}
+
+-static struct cpu_pm_ops omap_pm_ops = {
++static struct cpu_pm_ops omap_pm_ops __read_only = {
+ .finish_suspend = default_finish_suspend,
+ .resume = dummy_cpu_resume,
+ .scu_prepare = dummy_scu_prepare,
+diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
+index b4de3da..e027393 100644
+--- a/arch/arm/mach-omap2/omap-smp.c
++++ b/arch/arm/mach-omap2/omap-smp.c
+@@ -19,6 +19,7 @@
+ #include <linux/device.h>
+ #include <linux/smp.h>
+ #include <linux/io.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+
+ #include <asm/smp_scu.h>
+diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
+index e920dd8..ef999171 100644
+--- a/arch/arm/mach-omap2/omap_device.c
++++ b/arch/arm/mach-omap2/omap_device.c
+@@ -530,7 +530,7 @@ void omap_device_delete(struct omap_device *od)
+ struct platform_device __init *omap_device_build(const char *pdev_name,
+ int pdev_id,
+ struct omap_hwmod *oh,
+- void *pdata, int pdata_len)
++ const void *pdata, int pdata_len)
+ {
+ struct omap_hwmod *ohs[] = { oh };
+
+@@ -558,7 +558,7 @@ struct platform_device __init *omap_device_build(const char *pdev_name,
+ struct platform_device __init *omap_device_build_ss(const char *pdev_name,
+ int pdev_id,
+ struct omap_hwmod **ohs,
+- int oh_cnt, void *pdata,
++ int oh_cnt, const void *pdata,
+ int pdata_len)
+ {
+ int ret = -ENOMEM;
+diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h
+index 78c02b3..c94109a 100644
+--- a/arch/arm/mach-omap2/omap_device.h
++++ b/arch/arm/mach-omap2/omap_device.h
+@@ -72,12 +72,12 @@ int omap_device_idle(struct platform_device *pdev);
+ /* Core code interface */
+
+ struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
+- struct omap_hwmod *oh, void *pdata,
++ struct omap_hwmod *oh, const void *pdata,
+ int pdata_len);
+
+ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+ struct omap_hwmod **oh, int oh_cnt,
+- void *pdata, int pdata_len);
++ const void *pdata, int pdata_len);
+
+ struct omap_device *omap_device_alloc(struct platform_device *pdev,
+ struct omap_hwmod **ohs, int oh_cnt);
+diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
+index 1052b29..54669b0 100644
+--- a/arch/arm/mach-omap2/omap_hwmod.c
++++ b/arch/arm/mach-omap2/omap_hwmod.c
+@@ -206,10 +206,10 @@ struct omap_hwmod_soc_ops {
+ void (*update_context_lost)(struct omap_hwmod *oh);
+ int (*get_context_lost)(struct omap_hwmod *oh);
+ int (*disable_direct_prcm)(struct omap_hwmod *oh);
+-};
++} __no_const;
+
+ /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
+-static struct omap_hwmod_soc_ops soc_ops;
++static struct omap_hwmod_soc_ops soc_ops __read_only;
+
+ /* omap_hwmod_list contains all registered struct omap_hwmods */
+ static LIST_HEAD(omap_hwmod_list);
+diff --git a/arch/arm/mach-omap2/powerdomains43xx_data.c b/arch/arm/mach-omap2/powerdomains43xx_data.c
+index 95fee54..b5dd79d 100644
+--- a/arch/arm/mach-omap2/powerdomains43xx_data.c
++++ b/arch/arm/mach-omap2/powerdomains43xx_data.c
+@@ -10,6 +10,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/init.h>
++#include <asm/pgtable.h>
+
+ #include "powerdomain.h"
+
+@@ -129,7 +130,9 @@ static int am43xx_check_vcvp(void)
+
+ void __init am43xx_powerdomains_init(void)
+ {
+- omap4_pwrdm_operations.pwrdm_has_voltdm = am43xx_check_vcvp;
++ pax_open_kernel();
++ const_cast(omap4_pwrdm_operations.pwrdm_has_voltdm) = am43xx_check_vcvp;
++ pax_close_kernel();
+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_am43xx);
+ pwrdm_complete_init();
+diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
+index ff0a68c..b312aa0 100644
+--- a/arch/arm/mach-omap2/wd_timer.c
++++ b/arch/arm/mach-omap2/wd_timer.c
+@@ -110,7 +110,9 @@ static int __init omap_init_wdt(void)
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+- struct omap_wd_timer_platform_data pdata;
++ static struct omap_wd_timer_platform_data pdata = {
++ .read_reset_sources = prm_read_reset_sources
++ };
+
+ if (!cpu_class_is_omap2() || of_have_populated_dt())
+ return 0;
+@@ -121,8 +123,6 @@ static int __init omap_init_wdt(void)
+ return -EINVAL;
+ }
+
+- pdata.read_reset_sources = prm_read_reset_sources;
+-
+ pdev = omap_device_build(dev_name, id, oh, &pdata,
+ sizeof(struct omap_wd_timer_platform_data));
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
+diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
+index 92ec8c3..3b09472 100644
+--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
++++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
+@@ -240,7 +240,7 @@ static struct platform_device smdk6410_b_pwr_5v = {
+ };
+ #endif
+
+-static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
++static const struct s3c_ide_platdata smdk6410_ide_pdata __initconst = {
+ .setup_gpio = s3c64xx_ide_setup_gpio,
+ };
+
+diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
+index 0c6bb45..0f18d70 100644
+--- a/arch/arm/mach-shmobile/platsmp-apmu.c
++++ b/arch/arm/mach-shmobile/platsmp-apmu.c
+@@ -22,6 +22,7 @@
+ #include <asm/proc-fns.h>
+ #include <asm/smp_plat.h>
+ #include <asm/suspend.h>
++#include <asm/pgtable.h>
+ #include "common.h"
+ #include "platsmp-apmu.h"
+ #include "rcar-gen2.h"
+@@ -316,6 +317,8 @@ static int shmobile_smp_apmu_enter_suspend(suspend_state_t state)
+
+ void __init shmobile_smp_apmu_suspend_init(void)
+ {
+- shmobile_suspend_ops.enter = shmobile_smp_apmu_enter_suspend;
++ pax_open_kernel();
++ const_cast(shmobile_suspend_ops.enter) = shmobile_smp_apmu_enter_suspend;
++ pax_close_kernel();
+ }
+ #endif
+diff --git a/arch/arm/mach-tegra/cpuidle-tegra20.c b/arch/arm/mach-tegra/cpuidle-tegra20.c
+index afcee04..63e52ac 100644
+--- a/arch/arm/mach-tegra/cpuidle-tegra20.c
++++ b/arch/arm/mach-tegra/cpuidle-tegra20.c
+@@ -178,7 +178,7 @@ static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
+ bool entered_lp2 = false;
+
+ if (tegra_pending_sgi())
+- ACCESS_ONCE(abort_flag) = true;
++ ACCESS_ONCE_RW(abort_flag) = true;
+
+ cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
+
+diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
+index a69b22d..8523a03 100644
+--- a/arch/arm/mach-tegra/irq.c
++++ b/arch/arm/mach-tegra/irq.c
+@@ -20,6 +20,7 @@
+ #include <linux/cpu_pm.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include <linux/irq.h>
+ #include <linux/kernel.h>
+diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c
+index a970e7f..6f2bf9a 100644
+--- a/arch/arm/mach-ux500/pm.c
++++ b/arch/arm/mach-ux500/pm.c
+@@ -10,6 +10,7 @@
+ */
+
+ #include <linux/kernel.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
+diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
+index 7cd9865..a00b6ab 100644
+--- a/arch/arm/mach-zynq/platsmp.c
++++ b/arch/arm/mach-zynq/platsmp.c
+@@ -24,6 +24,7 @@
+ #include <linux/io.h>
+ #include <asm/cacheflush.h>
+ #include <asm/smp_scu.h>
++#include <linux/irq.h>
+ #include <linux/irqchip/arm-gic.h>
+ #include "common.h"
+
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index c1799dd..9111dcc 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -446,6 +446,7 @@ config CPU_32v5
+
+ config CPU_32v6
+ bool
++ select CPU_USE_DOMAINS if CPU_V6 && MMU && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ select TLS_REG_EMUL if !CPU_32v6K && !MMU
+
+ config CPU_32v6K
+@@ -603,6 +604,7 @@ config CPU_CP15_MPU
+
+ config CPU_USE_DOMAINS
+ bool
++ depends on !ARM_LPAE && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ help
+ This option enables or disables the use of domain switching
+ via the set_fs() function.
+@@ -813,7 +815,7 @@ config NEED_KUSER_HELPERS
+
+ config KUSER_HELPERS
+ bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
+- depends on MMU
++ depends on MMU && (!(CPU_V6 || CPU_V6K || CPU_V7) || GRKERNSEC_OLD_ARM_USERLAND)
+ default y
+ help
+ Warning: disabling this option may break user programs.
+@@ -827,7 +829,7 @@ config KUSER_HELPERS
+ See Documentation/arm/kernel_user_helpers.txt for details.
+
+ However, the fixed address nature of these helpers can be used
+- by ROP (return orientated programming) authors when creating
++ by ROP (Return Oriented Programming) authors when creating
+ exploits.
+
+ If all of the binaries and libraries which run on your platform
+@@ -842,7 +844,7 @@ config KUSER_HELPERS
+
+ config VDSO
+ bool "Enable VDSO for acceleration of some system calls"
+- depends on AEABI && MMU && CPU_V7
++ depends on AEABI && MMU && CPU_V7 && !PAX_KERNEXEC && !PAX_MEMORY_UDEREF
+ default y if ARM_ARCH_TIMER
+ select GENERIC_TIME_VSYSCALL
+ help
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index 7d5f4c7..c6a0816 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -778,6 +778,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ u16 tinstr = 0;
+ int isize = 4;
+ int thumb2_32b = 0;
++ bool is_user_mode = user_mode(regs);
+
+ if (interrupts_enabled(regs))
+ local_irq_enable();
+@@ -786,14 +787,24 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+
+ if (thumb_mode(regs)) {
+ u16 *ptr = (u16 *)(instrptr & ~1);
+- fault = probe_kernel_address(ptr, tinstr);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address(ptr, tinstr);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address(ptr, tinstr);
+ tinstr = __mem_to_opcode_thumb16(tinstr);
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+ u16 tinst2 = 0;
+- fault = probe_kernel_address(ptr + 1, tinst2);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address(ptr + 1, tinst2);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address(ptr + 1, tinst2);
+ tinst2 = __mem_to_opcode_thumb16(tinst2);
+ instr = __opcode_thumb32_compose(tinstr, tinst2);
+ thumb2_32b = 1;
+@@ -803,7 +814,12 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ }
+ } else {
+- fault = probe_kernel_address((void *)instrptr, instr);
++ if (is_user_mode) {
++ pax_open_userland();
++ fault = probe_kernel_address((void *)instrptr, instr);
++ pax_close_userland();
++ } else
++ fault = probe_kernel_address((void *)instrptr, instr);
+ instr = __mem_to_opcode_arm(instr);
+ }
+
+@@ -812,7 +828,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ goto bad_or_fault;
+ }
+
+- if (user_mode(regs))
++ if (is_user_mode)
+ goto user;
+
+ ai_sys += 1;
+diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
+index d1870c7..36d500f 100644
+--- a/arch/arm/mm/cache-l2x0.c
++++ b/arch/arm/mm/cache-l2x0.c
+@@ -44,7 +44,7 @@ struct l2c_init_data {
+ void (*configure)(void __iomem *);
+ void (*unlock)(void __iomem *, unsigned);
+ struct outer_cache_fns outer_cache;
+-};
++} __do_const;
+
+ #define CACHE_LINE_SIZE 32
+
+diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
+index c8c8b9e..c55cc79 100644
+--- a/arch/arm/mm/context.c
++++ b/arch/arm/mm/context.c
+@@ -43,7 +43,7 @@
+ #define NUM_USER_ASIDS ASID_FIRST_VERSION
+
+ static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
+-static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
++static atomic64_unchecked_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION);
+ static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS);
+
+ static DEFINE_PER_CPU(atomic64_t, active_asids);
+@@ -193,7 +193,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ {
+ static u32 cur_idx = 1;
+ u64 asid = atomic64_read(&mm->context.id);
+- u64 generation = atomic64_read(&asid_generation);
++ u64 generation = atomic64_read_unchecked(&asid_generation);
+
+ if (asid != 0) {
+ u64 newasid = generation | (asid & ~ASID_MASK);
+@@ -225,7 +225,7 @@ static u64 new_context(struct mm_struct *mm, unsigned int cpu)
+ */
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
+ if (asid == NUM_USER_ASIDS) {
+- generation = atomic64_add_return(ASID_FIRST_VERSION,
++ generation = atomic64_add_return_unchecked(ASID_FIRST_VERSION,
+ &asid_generation);
+ flush_context(cpu);
+ asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
+@@ -254,14 +254,14 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
+ cpu_set_reserved_ttbr0();
+
+ asid = atomic64_read(&mm->context.id);
+- if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
++ if (!((asid ^ atomic64_read_unchecked(&asid_generation)) >> ASID_BITS)
+ && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
+ goto switch_mm_fastpath;
+
+ raw_spin_lock_irqsave(&cpu_asid_lock, flags);
+ /* Check that our ASID belongs to the current generation. */
+ asid = atomic64_read(&mm->context.id);
+- if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
++ if ((asid ^ atomic64_read_unchecked(&asid_generation)) >> ASID_BITS) {
+ asid = new_context(mm, cpu);
+ atomic64_set(&mm->context.id, asid);
+ }
+diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
+index 0122ad1..1aae1cb 100644
+--- a/arch/arm/mm/fault.c
++++ b/arch/arm/mm/fault.c
+@@ -25,6 +25,7 @@
+ #include <asm/system_misc.h>
+ #include <asm/system_info.h>
+ #include <asm/tlbflush.h>
++#include <asm/sections.h>
+
+ #include "fault.h"
+
+@@ -138,6 +139,31 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+ if (fixup_exception(regs))
+ return;
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ if (addr < TASK_SIZE) {
++ if (current->signal->curr_ip)
++ printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++ else
++ printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++ }
++#endif
++
++#ifdef CONFIG_PAX_KERNEXEC
++ if ((fsr & FSR_WRITE) &&
++ (((unsigned long)_stext <= addr && addr < init_mm.end_code) ||
++ (MODULES_VADDR <= addr && addr < MODULES_END)))
++ {
++ if (current->signal->curr_ip)
++ printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()));
++ else
++ printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n", current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()));
++ }
++#endif
++
+ /*
+ * No handler, we'll have to terminate things with extreme prejudice.
+ */
+@@ -173,6 +199,13 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr,
+ }
+ #endif
+
++#ifdef CONFIG_PAX_PAGEEXEC
++ if ((tsk->mm->pax_flags & MF_PAX_PAGEEXEC) && (fsr & FSR_LNX_PF)) {
++ pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ tsk->thread.address = addr;
+ tsk->thread.error_code = fsr;
+ tsk->thread.trap_no = 14;
+@@ -400,6 +433,33 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ }
+ #endif /* CONFIG_MMU */
+
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 20; i++) {
++ unsigned char c;
++ if (get_user(c, (__force unsigned char __user *)pc+i))
++ printk(KERN_CONT "?? ");
++ else
++ printk(KERN_CONT "%02x ", c);
++ }
++ printk("\n");
++
++ printk(KERN_ERR "PAX: bytes at SP-4: ");
++ for (i = -1; i < 20; i++) {
++ unsigned long c;
++ if (get_user(c, (__force unsigned long __user *)sp+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08lx ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ /*
+ * First Level Translation Fault Handler
+ *
+@@ -547,9 +607,22 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+ const struct fsr_info *inf = fsr_info + fsr_fs(fsr);
+ struct siginfo info;
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ if (addr < TASK_SIZE && is_domain_fault(fsr)) {
++ if (current->signal->curr_ip)
++ printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++ else
++ printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to access userland memory at %08lx\n", current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()), addr);
++ goto die;
++ }
++#endif
++
+ if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
+ return;
+
++die:
+ pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
+ inf->name, fsr, addr);
+ show_pte(current->mm, addr);
+@@ -574,15 +647,118 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *
+ ifsr_info[nr].name = name;
+ }
+
++asmlinkage int sys_sigreturn(struct pt_regs *regs);
++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
++
+ asmlinkage void __exception
+ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+ {
+ const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ struct siginfo info;
++ unsigned long pc = instruction_pointer(regs);
++
++ if (user_mode(regs)) {
++ unsigned long sigpage = current->mm->context.sigpage;
++
++ if (sigpage <= pc && pc < sigpage + 7*4) {
++ if (pc < sigpage + 3*4)
++ sys_sigreturn(regs);
++ else
++ sys_rt_sigreturn(regs);
++ return;
++ }
++ if (pc == 0xffff0f60UL) {
++ /*
++ * PaX: __kuser_cmpxchg64 emulation
++ */
++ // TODO
++ //regs->ARM_pc = regs->ARM_lr;
++ //return;
++ }
++ if (pc == 0xffff0fa0UL) {
++ /*
++ * PaX: __kuser_memory_barrier emulation
++ */
++ // dmb(); implied by the exception
++ regs->ARM_pc = regs->ARM_lr;
++#ifdef CONFIG_ARM_THUMB
++ if (regs->ARM_lr & 1) {
++ regs->ARM_cpsr |= PSR_T_BIT;
++ regs->ARM_pc &= ~0x1U;
++ } else
++ regs->ARM_cpsr &= ~PSR_T_BIT;
++#endif
++ return;
++ }
++ if (pc == 0xffff0fc0UL) {
++ /*
++ * PaX: __kuser_cmpxchg emulation
++ */
++ // TODO
++ //long new;
++ //int op;
++
++ //op = FUTEX_OP_SET << 28;
++ //new = futex_atomic_op_inuser(op, regs->ARM_r2);
++ //regs->ARM_r0 = old != new;
++ //regs->ARM_pc = regs->ARM_lr;
++ //return;
++ }
++ if (pc == 0xffff0fe0UL) {
++ /*
++ * PaX: __kuser_get_tls emulation
++ */
++ regs->ARM_r0 = current_thread_info()->tp_value[0];
++ regs->ARM_pc = regs->ARM_lr;
++#ifdef CONFIG_ARM_THUMB
++ if (regs->ARM_lr & 1) {
++ regs->ARM_cpsr |= PSR_T_BIT;
++ regs->ARM_pc &= ~0x1U;
++ } else
++ regs->ARM_cpsr &= ~PSR_T_BIT;
++#endif
++ return;
++ }
++ }
++
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
++ else if (is_domain_fault(ifsr) || is_xn_fault(ifsr)) {
++ if (current->signal->curr_ip)
++ printk(KERN_EMERG "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", &current->signal->curr_ip, current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
++ else
++ printk(KERN_EMERG "PAX: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", current->comm, task_pid_nr(current),
++ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
++ goto die;
++ }
++#endif
++
++#ifdef CONFIG_PAX_REFCOUNT
++ if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) {
++#ifdef CONFIG_THUMB2_KERNEL
++ unsigned short bkpt;
++
++ if (!probe_kernel_address((const unsigned short *)pc, bkpt) && cpu_to_le16(bkpt) == 0xbef1) {
++#else
++ unsigned int bkpt;
++
++ if (!probe_kernel_address((const unsigned int *)pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) {
++#endif
++ current->thread.error_code = ifsr;
++ current->thread.trap_no = 0;
++ pax_report_refcount_error(regs, NULL);
++ fixup_exception(regs);
++ return;
++ }
++ }
++#endif
+
+ if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+ return;
+
++die:
+ pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+ inf->name, ifsr, addr);
+
+diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
+index afc1f84..b1daab5 100644
+--- a/arch/arm/mm/fault.h
++++ b/arch/arm/mm/fault.h
+@@ -3,6 +3,7 @@
+
+ /*
+ * Fault status register encodings. We steal bit 31 for our own purposes.
++ * Set when the FSR value is from an instruction fault.
+ */
+ #define FSR_LNX_PF (1 << 31)
+ #define FSR_WRITE (1 << 11)
+@@ -26,6 +27,17 @@ static inline int fsr_fs(unsigned int fsr)
+ }
+ #endif
+
++/* valid for LPAE and !LPAE */
++static inline int is_xn_fault(unsigned int fsr)
++{
++ return ((fsr_fs(fsr) & 0x3c) == 0xc);
++}
++
++static inline int is_domain_fault(unsigned int fsr)
++{
++ return ((fsr_fs(fsr) & 0xD) == 0x9);
++}
++
+ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+ void early_abt_enable(void);
+
+diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
+index 370581a..b985cc1 100644
+--- a/arch/arm/mm/init.c
++++ b/arch/arm/mm/init.c
+@@ -747,7 +747,46 @@ void free_tcmmem(void)
+ {
+ #ifdef CONFIG_HAVE_TCM
+ extern char __tcm_start, __tcm_end;
++#endif
+
++#ifdef CONFIG_PAX_KERNEXEC
++ unsigned long addr;
++ pgd_t *pgd;
++ pud_t *pud;
++ pmd_t *pmd;
++ int cpu_arch = cpu_architecture();
++ unsigned int cr = get_cr();
++
++ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
++ /* make pages tables, etc before .text NX */
++ for (addr = PAGE_OFFSET; addr < (unsigned long)_stext; addr += SECTION_SIZE) {
++ pgd = pgd_offset_k(addr);
++ pud = pud_offset(pgd, addr);
++ pmd = pmd_offset(pud, addr);
++ __section_update(pmd, addr, PMD_SECT_XN);
++ }
++ /* make init NX */
++ for (addr = (unsigned long)__init_begin; addr < (unsigned long)_sdata; addr += SECTION_SIZE) {
++ pgd = pgd_offset_k(addr);
++ pud = pud_offset(pgd, addr);
++ pmd = pmd_offset(pud, addr);
++ __section_update(pmd, addr, PMD_SECT_XN);
++ }
++ /* make kernel code/rodata RX */
++ for (addr = (unsigned long)_stext; addr < (unsigned long)__init_begin; addr += SECTION_SIZE) {
++ pgd = pgd_offset_k(addr);
++ pud = pud_offset(pgd, addr);
++ pmd = pmd_offset(pud, addr);
++#ifdef CONFIG_ARM_LPAE
++ __section_update(pmd, addr, PMD_SECT_RDONLY);
++#else
++ __section_update(pmd, addr, PMD_SECT_APX|PMD_SECT_AP_WRITE);
++#endif
++ }
++ }
++#endif
++
++#ifdef CONFIG_HAVE_TCM
+ poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start);
+ free_reserved_area(&__tcm_start, &__tcm_end, -1, "TCM link");
+ #endif
+diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
+index ff0eed2..f17f1c9 100644
+--- a/arch/arm/mm/ioremap.c
++++ b/arch/arm/mm/ioremap.c
+@@ -411,9 +411,9 @@ __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached)
+ unsigned int mtype;
+
+ if (cached)
+- mtype = MT_MEMORY_RWX;
++ mtype = MT_MEMORY_RX;
+ else
+- mtype = MT_MEMORY_RWX_NONCACHED;
++ mtype = MT_MEMORY_RX_NONCACHED;
+
+ return __arm_ioremap_caller(phys_addr, size, mtype,
+ __builtin_return_address(0));
+diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
+index 66353ca..8aad9f8 100644
+--- a/arch/arm/mm/mmap.c
++++ b/arch/arm/mm/mmap.c
+@@ -59,6 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ struct vm_area_struct *vma;
+ int do_align = 0;
+ int aliasing = cache_is_vipt_aliasing();
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ /*
+@@ -81,6 +82,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+@@ -88,8 +93,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ return addr;
+ }
+
+@@ -99,19 +103,21 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ info.high_limit = TASK_SIZE;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
++ info.threadstack_offset = offset;
+ return vm_unmapped_area(&info);
+ }
+
+ unsigned long
+-arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+- const unsigned long len, const unsigned long pgoff,
+- const unsigned long flags)
++arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr0,
++ unsigned long len, unsigned long pgoff,
++ unsigned long flags)
+ {
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = current->mm;
+ unsigned long addr = addr0;
+ int do_align = 0;
+ int aliasing = cache_is_vipt_aliasing();
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ /*
+@@ -132,6 +138,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ return addr;
+ }
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ /* requesting a specific address */
+ if (addr) {
+ if (do_align)
+@@ -139,8 +149,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ else
+ addr = PAGE_ALIGN(addr);
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ return addr;
+ }
+
+@@ -150,6 +159,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ info.high_limit = mm->mmap_base;
+ info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ /*
+@@ -182,14 +192,30 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+ unsigned long random_factor = 0UL;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = arch_mmap_rnd();
+
+ if (mmap_is_legacy()) {
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ mm->mmap_base += mm->delta_mmap;
++#endif
++
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ } else {
+ mm->mmap_base = mmap_base(random_factor);
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++#endif
++
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ }
+ }
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index 4001dd1..c6dce7b 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -243,6 +243,14 @@ __setup("noalign", noalign_setup);
+ #define PROT_PTE_S2_DEVICE PROT_PTE_DEVICE
+ #define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
+
++#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[] __ro_after_init = {
+ [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+@@ -272,19 +280,19 @@ static struct mem_type mem_types[] __ro_after_init = {
+ .prot_sect = PROT_SECT_DEVICE,
+ .domain = DOMAIN_IO,
+ },
+- [MT_UNCACHED] = {
++ [MT_UNCACHED_RW] = {
+ .prot_pte = PROT_PTE_DEVICE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_IO,
+ },
+- [MT_CACHECLEAN] = {
+- .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
++ [MT_CACHECLEAN_RO] = {
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_RDONLY,
+ .domain = DOMAIN_KERNEL,
+ },
+ #ifndef CONFIG_ARM_LPAE
+- [MT_MINICLEAN] = {
+- .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
++ [MT_MINICLEAN_RO] = {
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE | PMD_SECT_XN | PMD_SECT_RDONLY,
+ .domain = DOMAIN_KERNEL,
+ },
+ #endif
+@@ -300,7 +308,7 @@ static struct mem_type mem_types[] __ro_after_init = {
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_VECTORS,
+ },
+- [MT_MEMORY_RWX] = {
++ [__MT_MEMORY_RWX] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+@@ -313,17 +321,30 @@ static struct mem_type mem_types[] __ro_after_init = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
+- [MT_ROM] = {
+- .prot_sect = PMD_TYPE_SECT,
++ [MT_MEMORY_RX] = {
++ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC,
++ .prot_l1 = PMD_TYPE_TABLE,
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
++ .domain = DOMAIN_KERNEL,
++ },
++ [MT_ROM_RX] = {
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_RDONLY,
+ .domain = DOMAIN_KERNEL,
+ },
+- [MT_MEMORY_RWX_NONCACHED] = {
++ [MT_MEMORY_RW_NONCACHED] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_MT_BUFFERABLE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
++ [MT_MEMORY_RX_NONCACHED] = {
++ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC |
++ L_PTE_MT_BUFFERABLE,
++ .prot_l1 = PMD_TYPE_TABLE,
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
++ .domain = DOMAIN_KERNEL,
++ },
+ [MT_MEMORY_RW_DTCM] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_XN,
+@@ -331,9 +352,10 @@ static struct mem_type mem_types[] __ro_after_init = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
+ },
+- [MT_MEMORY_RWX_ITCM] = {
+- .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
++ [MT_MEMORY_RX_ITCM] = {
++ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_KERNEXEC,
+ .prot_l1 = PMD_TYPE_TABLE,
++ .prot_sect = PMD_TYPE_SECT | PMD_SECT_KERNEXEC,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_RW_SO] = {
+@@ -586,9 +608,14 @@ static void __init build_mem_type_table(void)
+ * Mark cache clean areas and XIP ROM read only
+ * from SVC mode and no access from userspace.
+ */
+- mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+- mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+- mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++ mem_types[MT_ROM_RX].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#ifdef CONFIG_PAX_KERNEXEC
++ mem_types[MT_MEMORY_RX].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++ mem_types[MT_MEMORY_RX_ITCM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++#endif
++ mem_types[MT_MINICLEAN_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
++ mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ #endif
+
+ /*
+@@ -605,13 +632,17 @@ static void __init build_mem_type_table(void)
+ mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
+- mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
+- mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
++ mem_types[__MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
++ mem_types[__MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
++ mem_types[MT_MEMORY_RX].prot_sect |= PMD_SECT_S;
++ mem_types[MT_MEMORY_RX].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= PMD_SECT_S;
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_pte |= L_PTE_SHARED;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_S;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
+ }
+
+@@ -622,15 +653,20 @@ static void __init build_mem_type_table(void)
+ if (cpu_arch >= CPU_ARCH_ARMv6) {
+ if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ /* Non-cacheable Normal is XCB = 001 */
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |=
++ PMD_SECT_BUFFERED;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |=
+ PMD_SECT_BUFFERED;
+ } else {
+ /* For both ARMv6 and non-TEX-remapping ARMv7 */
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |=
++ PMD_SECT_TEX(1);
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |=
+ PMD_SECT_TEX(1);
+ }
+ } else {
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+ }
+
+ #ifdef CONFIG_ARM_LPAE
+@@ -651,6 +687,8 @@ static void __init build_mem_type_table(void)
+ user_pgprot |= PTE_EXT_PXN;
+ #endif
+
++ user_pgprot |= __supported_pte_mask;
++
+ for (i = 0; i < 16; i++) {
+ pteval_t v = pgprot_val(protection_map[i]);
+ protection_map[i] = __pgprot(v | user_pgprot);
+@@ -668,21 +706,24 @@ static void __init build_mem_type_table(void)
+
+ mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
+ mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
+- mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
+- mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
++ mem_types[__MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
++ mem_types[__MT_MEMORY_RWX].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
++ mem_types[MT_MEMORY_RX].prot_sect |= ecc_mask | cp->pmd;
++ mem_types[MT_MEMORY_RX].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
+- mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
+- mem_types[MT_ROM].prot_sect |= cp->pmd;
++ mem_types[MT_MEMORY_RW_NONCACHED].prot_sect |= ecc_mask;
++ mem_types[MT_MEMORY_RX_NONCACHED].prot_sect |= ecc_mask;
++ mem_types[MT_ROM_RX].prot_sect |= cp->pmd;
+
+ switch (cp->pmd) {
+ case PMD_SECT_WT:
+- mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
++ mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_WT;
+ break;
+ case PMD_SECT_WB:
+ case PMD_SECT_WBWA:
+- mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
++ mem_types[MT_CACHECLEAN_RO].prot_sect |= PMD_SECT_WB;
+ break;
+ }
+ pr_info("Memory policy: %sData cache %s\n",
+@@ -959,7 +1000,7 @@ static void __init create_mapping(struct map_desc *md)
+ return;
+ }
+
+- if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
++ if ((md->type == MT_DEVICE || md->type == MT_ROM_RX) &&
+ md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START &&
+ (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
+ pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
+@@ -1320,18 +1361,15 @@ void __init arm_mm_memblock_reserve(void)
+ * Any other function or debugging method which may touch any device _will_
+ * crash the kernel.
+ */
++
++static char vectors[PAGE_SIZE * 2] __read_only __aligned(PAGE_SIZE);
++
+ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ {
+ struct map_desc map;
+ unsigned long addr;
+- void *vectors;
+
+- /*
+- * Allocate the vector page early.
+- */
+- vectors = early_alloc(PAGE_SIZE * 2);
+-
+- early_trap_init(vectors);
++ early_trap_init(&vectors);
+
+ /*
+ * Clear page table except top pmd used by early fixmaps
+@@ -1347,7 +1385,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+ map.virtual = MODULES_VADDR;
+ map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+- map.type = MT_ROM;
++ map.type = MT_ROM_RX;
+ create_mapping(&map);
+ #endif
+
+@@ -1358,14 +1396,14 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+ map.virtual = FLUSH_BASE;
+ map.length = SZ_1M;
+- map.type = MT_CACHECLEAN;
++ map.type = MT_CACHECLEAN_RO;
+ create_mapping(&map);
+ #endif
+ #ifdef FLUSH_BASE_MINICACHE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
+ map.virtual = FLUSH_BASE_MINICACHE;
+ map.length = SZ_1M;
+- map.type = MT_MINICLEAN;
++ map.type = MT_MINICLEAN_RO;
+ create_mapping(&map);
+ #endif
+
+@@ -1374,7 +1412,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
+ * location (0xffff0000). If we aren't using high-vectors, also
+ * create a mapping at the low-vectors virtual address.
+ */
+- map.pfn = __phys_to_pfn(virt_to_phys(vectors));
++ map.pfn = __phys_to_pfn(virt_to_phys(&vectors));
+ map.virtual = 0xffff0000;
+ map.length = PAGE_SIZE;
+ #ifdef CONFIG_KUSER_HELPERS
+@@ -1437,12 +1475,14 @@ static void __init kmap_init(void)
+ static void __init map_lowmem(void)
+ {
+ struct memblock_region *reg;
++#ifndef CONFIG_PAX_KERNEXEC
+ #ifdef CONFIG_XIP_KERNEL
+ phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE);
+ #else
+ phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE);
+ #endif
+ phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
++#endif
+
+ /* Map all the lowmem memory banks. */
+ for_each_memblock(memory, reg) {
+@@ -1458,11 +1498,48 @@ static void __init map_lowmem(void)
+ if (start >= end)
+ break;
+
++#ifdef CONFIG_PAX_KERNEXEC
++ map.pfn = __phys_to_pfn(start);
++ map.virtual = __phys_to_virt(start);
++ map.length = end - start;
++
++ if (map.virtual <= (unsigned long)_stext && ((unsigned long)_end < (map.virtual + map.length))) {
++ struct map_desc kernel;
++ struct map_desc initmap;
++
++ /* when freeing initmem we will make this RW */
++ initmap.pfn = __phys_to_pfn(__pa(__init_begin));
++ initmap.virtual = (unsigned long)__init_begin;
++ initmap.length = _sdata - __init_begin;
++ initmap.type = __MT_MEMORY_RWX;
++ create_mapping(&initmap);
++
++ /* when freeing initmem we will make this RX */
++ kernel.pfn = __phys_to_pfn(__pa(_stext));
++ kernel.virtual = (unsigned long)_stext;
++ kernel.length = __init_begin - _stext;
++ kernel.type = __MT_MEMORY_RWX;
++ create_mapping(&kernel);
++
++ if (map.virtual < (unsigned long)_stext) {
++ map.length = (unsigned long)_stext - map.virtual;
++ map.type = __MT_MEMORY_RWX;
++ create_mapping(&map);
++ }
++
++ map.pfn = __phys_to_pfn(__pa(_sdata));
++ map.virtual = (unsigned long)_sdata;
++ map.length = end - __pa(_sdata);
++ }
++
++ map.type = MT_MEMORY_RW;
++ create_mapping(&map);
++#else
+ if (end < kernel_x_start) {
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+- map.type = MT_MEMORY_RWX;
++ map.type = __MT_MEMORY_RWX;
+
+ create_mapping(&map);
+ } else if (start >= kernel_x_end) {
+@@ -1486,7 +1563,7 @@ static void __init map_lowmem(void)
+ map.pfn = __phys_to_pfn(kernel_x_start);
+ map.virtual = __phys_to_virt(kernel_x_start);
+ map.length = kernel_x_end - kernel_x_start;
+- map.type = MT_MEMORY_RWX;
++ map.type = __MT_MEMORY_RWX;
+
+ create_mapping(&map);
+
+@@ -1499,6 +1576,7 @@ static void __init map_lowmem(void)
+ create_mapping(&map);
+ }
+ }
++#endif
+ }
+ }
+
+diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
+index 93d0b6d..2db6d99 100644
+--- a/arch/arm/net/bpf_jit_32.c
++++ b/arch/arm/net/bpf_jit_32.c
+@@ -20,6 +20,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/hwcap.h>
+ #include <asm/opcodes.h>
++#include <asm/pgtable.h>
+
+ #include "bpf_jit_32.h"
+
+@@ -72,54 +73,38 @@ struct jit_ctx {
+ #endif
+ };
+
++#ifdef CONFIG_GRKERNSEC_BPF_HARDEN
++int bpf_jit_enable __read_only;
++#else
+ int bpf_jit_enable __read_mostly;
++#endif
+
+-static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret,
+- unsigned int size)
+-{
+- void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size);
+-
+- if (!ptr)
+- return -EFAULT;
+- memcpy(ret, ptr, size);
+- return 0;
+-}
+-
+-static u64 jit_get_skb_b(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
+ {
+ u8 ret;
+ int err;
+
+- if (offset < 0)
+- err = call_neg_helper(skb, offset, &ret, 1);
+- else
+- err = skb_copy_bits(skb, offset, &ret, 1);
++ err = skb_copy_bits(skb, offset, &ret, 1);
+
+ return (u64)err << 32 | ret;
+ }
+
+-static u64 jit_get_skb_h(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
+ {
+ u16 ret;
+ int err;
+
+- if (offset < 0)
+- err = call_neg_helper(skb, offset, &ret, 2);
+- else
+- err = skb_copy_bits(skb, offset, &ret, 2);
++ err = skb_copy_bits(skb, offset, &ret, 2);
+
+ return (u64)err << 32 | ntohs(ret);
+ }
+
+-static u64 jit_get_skb_w(struct sk_buff *skb, int offset)
++static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
+ {
+ u32 ret;
+ int err;
+
+- if (offset < 0)
+- err = call_neg_helper(skb, offset, &ret, 4);
+- else
+- err = skb_copy_bits(skb, offset, &ret, 4);
++ err = skb_copy_bits(skb, offset, &ret, 4);
+
+ return (u64)err << 32 | ntohl(ret);
+ }
+@@ -191,8 +176,10 @@ static void jit_fill_hole(void *area, unsigned int size)
+ {
+ u32 *ptr;
+ /* We are guaranteed to have aligned memory. */
++ pax_open_kernel();
+ for (ptr = area; size >= sizeof(u32); size -= sizeof(u32))
+ *ptr++ = __opcode_to_mem_arm(ARM_INST_UDF);
++ pax_close_kernel();
+ }
+
+ static void build_prologue(struct jit_ctx *ctx)
+@@ -554,6 +541,9 @@ static int build_body(struct jit_ctx *ctx)
+ case BPF_LD | BPF_B | BPF_ABS:
+ load_order = 0;
+ load:
++ /* the interpreter will deal with the negative K */
++ if ((int)k < 0)
++ return -ENOTSUPP;
+ emit_mov_i(r_off, k, ctx);
+ load_common:
+ ctx->seen |= SEEN_DATA | SEEN_CALL;
+@@ -568,18 +558,6 @@ static int build_body(struct jit_ctx *ctx)
+ condt = ARM_COND_HI;
+ }
+
+- /*
+- * test for negative offset, only if we are
+- * currently scheduled to take the fast
+- * path. this will update the flags so that
+- * the slowpath instruction are ignored if the
+- * offset is negative.
+- *
+- * for loard_order == 0 the HI condition will
+- * make loads at offset 0 take the slow path too.
+- */
+- _emit(condt, ARM_CMP_I(r_off, 0), ctx);
+-
+ _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
+ ctx);
+
+diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
+index 8151bde..9be301f 100644
+--- a/arch/arm/plat-iop/setup.c
++++ b/arch/arm/plat-iop/setup.c
+@@ -24,7 +24,7 @@ static struct map_desc iop3xx_std_desc[] __initdata = {
+ .virtual = IOP3XX_PERIPHERAL_VIRT_BASE,
+ .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
+ .length = IOP3XX_PERIPHERAL_SIZE,
+- .type = MT_UNCACHED,
++ .type = MT_UNCACHED_RW,
+ },
+ };
+
+diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
+index a5bc92d..0bb4730 100644
+--- a/arch/arm/plat-omap/sram.c
++++ b/arch/arm/plat-omap/sram.c
+@@ -93,6 +93,8 @@ void __init omap_map_sram(unsigned long start, unsigned long size,
+ * Looks like we need to preserve some bootloader code at the
+ * beginning of SRAM for jumping to flash for reboot to work...
+ */
++ pax_open_kernel();
+ memset_io(omap_sram_base + omap_sram_skip, 0,
+ omap_sram_size - omap_sram_skip);
++ pax_close_kernel();
+ }
+diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
+index a4ec240..96faf9b 100644
+--- a/arch/arm/probes/kprobes/core.c
++++ b/arch/arm/probes/kprobes/core.c
+@@ -485,6 +485,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
+ return (void *)orig_ret_address;
+ }
+
++#ifdef CONFIG_KRETPROBES
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+ {
+@@ -493,6 +494,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ /* Replace the return addr with trampoline addr. */
+ regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
+ }
++#endif
+
+ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+ {
+@@ -605,10 +607,12 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+ return 0;
+ }
+
++#ifdef CONFIG_KRETPROBES
+ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+ {
+ return 0;
+ }
++#endif
+
+ #ifdef CONFIG_THUMB2_KERNEL
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 969ef88..305b856 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -896,6 +896,7 @@ config RELOCATABLE
+
+ config RANDOMIZE_BASE
+ bool "Randomize the address of the kernel image"
++ depends on BROKEN_SECURITY
+ select ARM64_MODULE_PLTS if MODULES
+ select RELOCATABLE
+ help
+diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
+index b661fe7..6d124fc 100644
+--- a/arch/arm64/Kconfig.debug
++++ b/arch/arm64/Kconfig.debug
+@@ -6,6 +6,7 @@ config ARM64_PTDUMP
+ bool "Export kernel pagetable layout to userspace via debugfs"
+ depends on DEBUG_KERNEL
+ select DEBUG_FS
++ depends on !GRKERNSEC_KMEM
+ help
+ Say Y here if you want to show the kernel pagetable layout in a
+ debugfs file. This information is only useful for kernel developers
+diff --git a/arch/arm64/crypto/sha1-ce-glue.c b/arch/arm64/crypto/sha1-ce-glue.c
+index aefda98..2937874 100644
+--- a/arch/arm64/crypto/sha1-ce-glue.c
++++ b/arch/arm64/crypto/sha1-ce-glue.c
+@@ -29,7 +29,7 @@ struct sha1_ce_state {
+ u32 finalize;
+ };
+
+-asmlinkage void sha1_ce_transform(struct sha1_ce_state *sst, u8 const *src,
++asmlinkage void sha1_ce_transform(struct sha1_state *sst, u8 const *src,
+ int blocks);
+
+ static int sha1_ce_update(struct shash_desc *desc, const u8 *data,
+@@ -39,8 +39,7 @@ static int sha1_ce_update(struct shash_desc *desc, const u8 *data,
+
+ sctx->finalize = 0;
+ kernel_neon_begin_partial(16);
+- sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_ce_transform);
++ sha1_base_do_update(desc, data, len, sha1_ce_transform);
+ kernel_neon_end();
+
+ return 0;
+@@ -64,10 +63,9 @@ static int sha1_ce_finup(struct shash_desc *desc, const u8 *data,
+ sctx->finalize = finalize;
+
+ kernel_neon_begin_partial(16);
+- sha1_base_do_update(desc, data, len,
+- (sha1_block_fn *)sha1_ce_transform);
++ sha1_base_do_update(desc, data, len, sha1_ce_transform);
+ if (!finalize)
+- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform);
++ sha1_base_do_finalize(desc, sha1_ce_transform);
+ kernel_neon_end();
+ return sha1_base_finish(desc, out);
+ }
+@@ -78,7 +76,7 @@ static int sha1_ce_final(struct shash_desc *desc, u8 *out)
+
+ sctx->finalize = 0;
+ kernel_neon_begin_partial(16);
+- sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_ce_transform);
++ sha1_base_do_finalize(desc, sha1_ce_transform);
+ kernel_neon_end();
+ return sha1_base_finish(desc, out);
+ }
+diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h
+index c0235e0..86eb684 100644
+--- a/arch/arm64/include/asm/atomic.h
++++ b/arch/arm64/include/asm/atomic.h
+@@ -57,11 +57,13 @@
+ #define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked_relaxed atomic_add_return_relaxed
+ #define atomic_add_return_acquire atomic_add_return_acquire
+ #define atomic_add_return_release atomic_add_return_release
+ #define atomic_add_return atomic_add_return
+
+ #define atomic_inc_return_relaxed(v) atomic_add_return_relaxed(1, (v))
++#define atomic_inc_return_unchecked_relaxed(v) atomic_add_return_relaxed(1, (v))
+ #define atomic_inc_return_acquire(v) atomic_add_return_acquire(1, (v))
+ #define atomic_inc_return_release(v) atomic_add_return_release(1, (v))
+ #define atomic_inc_return(v) atomic_add_return(1, (v))
+@@ -128,6 +130,8 @@
+ #define __atomic_add_unless(v, a, u) ___atomic_add_unless(v, a, u,)
+ #define atomic_andnot atomic_andnot
+
++#define atomic_inc_return_unchecked_relaxed(v) atomic_add_return_relaxed(1, (v))
++
+ /*
+ * 64-bit atomic operations.
+ */
+@@ -206,5 +210,16 @@
+
+ #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++#define atomic64_xchg_unchecked(v, n) atomic64_xchg((v), (n))
++
+ #endif
+ #endif
+diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
+index 5082b30..9ef38c2 100644
+--- a/arch/arm64/include/asm/cache.h
++++ b/arch/arm64/include/asm/cache.h
+@@ -16,10 +16,14 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+
++#include <linux/const.h>
++
+ #include <asm/cachetype.h>
+
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 7
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ /*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
+index 5394c84..05e5a95 100644
+--- a/arch/arm64/include/asm/percpu.h
++++ b/arch/arm64/include/asm/percpu.h
+@@ -123,16 +123,16 @@ static inline void __percpu_write(void *ptr, unsigned long val, int size)
+ {
+ switch (size) {
+ case 1:
+- ACCESS_ONCE(*(u8 *)ptr) = (u8)val;
++ ACCESS_ONCE_RW(*(u8 *)ptr) = (u8)val;
+ break;
+ case 2:
+- ACCESS_ONCE(*(u16 *)ptr) = (u16)val;
++ ACCESS_ONCE_RW(*(u16 *)ptr) = (u16)val;
+ break;
+ case 4:
+- ACCESS_ONCE(*(u32 *)ptr) = (u32)val;
++ ACCESS_ONCE_RW(*(u32 *)ptr) = (u32)val;
+ break;
+ case 8:
+- ACCESS_ONCE(*(u64 *)ptr) = (u64)val;
++ ACCESS_ONCE_RW(*(u64 *)ptr) = (u64)val;
+ break;
+ default:
+ BUILD_BUG();
+diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
+index d25f4f1..61d52da 100644
+--- a/arch/arm64/include/asm/pgalloc.h
++++ b/arch/arm64/include/asm/pgalloc.h
+@@ -51,6 +51,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+ __pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE);
+ }
++
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++ pud_populate(mm, pud, pmd);
++}
+ #else
+ static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
+ {
+@@ -80,6 +85,11 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
+ {
+ __pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE);
+ }
++
++static inline void pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
++{
++ pgd_populate(mm, pgd, pud);
++}
+ #else
+ static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
+ {
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index ffbb9a5..d8b49ff 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -23,6 +23,9 @@
+ #include <asm/pgtable-hwdef.h>
+ #include <asm/pgtable-prot.h>
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ /*
+ * VMALLOC range.
+ *
+@@ -728,6 +731,9 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ #define kc_vaddr_to_offset(v) ((v) & ~VA_START)
+ #define kc_offset_to_vaddr(o) ((o) | VA_START)
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ #endif /* !__ASSEMBLY__ */
+
+ #endif /* __ASM_PGTABLE_H */
+diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
+index 2eb714c..3a10471 100644
+--- a/arch/arm64/include/asm/string.h
++++ b/arch/arm64/include/asm/string.h
+@@ -17,40 +17,40 @@
+ #define __ASM_STRING_H
+
+ #define __HAVE_ARCH_STRRCHR
+-extern char *strrchr(const char *, int c);
++extern char *strrchr(const char *, int c) __nocapture(-1);
+
+ #define __HAVE_ARCH_STRCHR
+-extern char *strchr(const char *, int c);
++extern char *strchr(const char *, int c) __nocapture(-1);
+
+ #define __HAVE_ARCH_STRCMP
+-extern int strcmp(const char *, const char *);
++extern int strcmp(const char *, const char *) __nocapture();
+
+ #define __HAVE_ARCH_STRNCMP
+-extern int strncmp(const char *, const char *, __kernel_size_t);
++extern int strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
+
+ #define __HAVE_ARCH_STRLEN
+-extern __kernel_size_t strlen(const char *);
++extern __kernel_size_t strlen(const char *) __nocapture(1);
+
+ #define __HAVE_ARCH_STRNLEN
+-extern __kernel_size_t strnlen(const char *, __kernel_size_t);
++extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1);
+
+ #define __HAVE_ARCH_MEMCPY
+-extern void *memcpy(void *, const void *, __kernel_size_t);
+-extern void *__memcpy(void *, const void *, __kernel_size_t);
++extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
++extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMMOVE
+-extern void *memmove(void *, const void *, __kernel_size_t);
+-extern void *__memmove(void *, const void *, __kernel_size_t);
++extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2);
++extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+
+ #define __HAVE_ARCH_MEMCHR
+-extern void *memchr(const void *, int, __kernel_size_t);
++extern void *memchr(const void *, int, __kernel_size_t) __nocapture(-1);
+
+ #define __HAVE_ARCH_MEMSET
+ extern void *memset(void *, int, __kernel_size_t);
+ extern void *__memset(void *, int, __kernel_size_t);
+
+ #define __HAVE_ARCH_MEMCMP
+-extern int memcmp(const void *, const void *, size_t);
++extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2);
+
+
+ #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
+index 55d0adb..b986918 100644
+--- a/arch/arm64/include/asm/uaccess.h
++++ b/arch/arm64/include/asm/uaccess.h
+@@ -110,6 +110,7 @@ static inline void set_fs(mm_segment_t fs)
+ */
+ #define untagged_addr(addr) sign_extend64(addr, 55)
+
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) __range_ok(addr, size)
+ #define user_addr_max get_fs
+
+@@ -279,6 +280,9 @@ static inline unsigned long __must_check __copy_from_user(void *to, const void _
+
+ static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ kasan_check_read(from, n);
+ check_object_size(from, n, true);
+ return __arch_copy_to_user(to, from, n);
+@@ -287,6 +291,10 @@ static inline unsigned long __must_check __copy_to_user(void __user *to, const v
+ static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+ unsigned long res = n;
++
++ if ((long)n < 0)
++ return n;
++
+ kasan_check_write(to, n);
+
+ if (access_ok(VERIFY_READ, from, n)) {
+@@ -300,6 +308,9 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
+
+ static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ kasan_check_read(from, n);
+
+ if (access_ok(VERIFY_WRITE, to, n)) {
+diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
+index d55a7b0..d8dbd8a 100644
+--- a/arch/arm64/kernel/hibernate.c
++++ b/arch/arm64/kernel/hibernate.c
+@@ -198,7 +198,7 @@ EXPORT_SYMBOL(arch_hibernation_header_restore);
+ static int create_safe_exec_page(void *src_start, size_t length,
+ unsigned long dst_addr,
+ phys_addr_t *phys_dst_addr,
+- void *(*allocator)(gfp_t mask),
++ unsigned long (*allocator)(gfp_t mask),
+ gfp_t mask)
+ {
+ int rc = 0;
+@@ -206,7 +206,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+- unsigned long dst = (unsigned long)allocator(mask);
++ unsigned long dst = allocator(mask);
+
+ if (!dst) {
+ rc = -ENOMEM;
+@@ -216,9 +216,9 @@ static int create_safe_exec_page(void *src_start, size_t length,
+ memcpy((void *)dst, src_start, length);
+ flush_icache_range(dst, dst + length);
+
+- pgd = pgd_offset_raw(allocator(mask), dst_addr);
++ pgd = pgd_offset_raw((pgd_t *)allocator(mask), dst_addr);
+ if (pgd_none(*pgd)) {
+- pud = allocator(mask);
++ pud = (pud_t *)allocator(mask);
+ if (!pud) {
+ rc = -ENOMEM;
+ goto out;
+@@ -228,7 +228,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
+
+ pud = pud_offset(pgd, dst_addr);
+ if (pud_none(*pud)) {
+- pmd = allocator(mask);
++ pmd = (pmd_t *)allocator(mask);
+ if (!pmd) {
+ rc = -ENOMEM;
+ goto out;
+@@ -238,7 +238,7 @@ static int create_safe_exec_page(void *src_start, size_t length,
+
+ pmd = pmd_offset(pud, dst_addr);
+ if (pmd_none(*pmd)) {
+- pte = allocator(mask);
++ pte = (pte_t *)allocator(mask);
+ if (!pte) {
+ rc = -ENOMEM;
+ goto out;
+@@ -510,7 +510,7 @@ int swsusp_arch_resume(void)
+ rc = create_safe_exec_page(__hibernate_exit_text_start, exit_size,
+ (unsigned long)hibernate_exit,
+ &phys_hibernate_exit,
+- (void *)get_safe_page, GFP_ATOMIC);
++ get_safe_page, GFP_ATOMIC);
+ if (rc) {
+ pr_err("Failed to create safe executable page for hibernate_exit code.");
+ goto out;
+diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
+index f5077ea..46b4664 100644
+--- a/arch/arm64/kernel/probes/kprobes.c
++++ b/arch/arm64/kernel/probes/kprobes.c
+@@ -639,6 +639,7 @@ void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
+ return (void *)orig_ret_address;
+ }
+
++#ifdef CONFIG_KRETPROBES
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+ {
+@@ -652,6 +653,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+ {
+ return 0;
+ }
++#endif
+
+ int __init arch_init_kprobes(void)
+ {
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
+index 01753cd..b65d17a 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -64,7 +64,7 @@ EXPORT_SYMBOL(__stack_chk_guard);
+ /*
+ * Function pointers to optional machine specific functions
+ */
+-void (*pm_power_off)(void);
++void (* pm_power_off)(void);
+ EXPORT_SYMBOL_GPL(pm_power_off);
+
+ void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
+@@ -110,7 +110,7 @@ void machine_shutdown(void)
+ * activity (executing tasks, handling interrupts). smp_send_stop()
+ * achieves this.
+ */
+-void machine_halt(void)
++void __noreturn machine_halt(void)
+ {
+ local_irq_disable();
+ smp_send_stop();
+@@ -123,12 +123,13 @@ void machine_halt(void)
+ * achieves this. When the system power is turned off, it will take all CPUs
+ * with it.
+ */
+-void machine_power_off(void)
++void __noreturn machine_power_off(void)
+ {
+ local_irq_disable();
+ smp_send_stop();
+ if (pm_power_off)
+ pm_power_off();
++ while(1);
+ }
+
+ /*
+@@ -140,7 +141,7 @@ void machine_power_off(void)
+ * executing pre-reset code, and using RAM that the primary CPU's code wishes
+ * to use. Implementing such co-ordination would be essentially impossible.
+ */
+-void machine_restart(char *cmd)
++void __noreturn machine_restart(char *cmd)
+ {
+ /* Disable interrupts first */
+ local_irq_disable();
+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
+index c2efddf..c58e0a2 100644
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -95,8 +95,8 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+ struct pt_regs *irq_args;
+ unsigned long orig_sp = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
+
+- if (object_is_on_stack((void *)orig_sp) &&
+- object_is_on_stack((void *)frame->fp)) {
++ if (object_starts_on_stack((void *)orig_sp) &&
++ object_starts_on_stack((void *)frame->fp)) {
+ frame->sp = orig_sp;
+
+ /* orig_sp is the saved pt_regs, find the elr */
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index 11e5eae..d8cdfa7 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -547,7 +547,7 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
+ __show_regs(regs);
+ }
+
+- return sys_ni_syscall();
++ return -ENOSYS;
+ }
+
+ static const char *esr_class_str[] = {
+diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h
+index c3a58a1..78fbf54 100644
+--- a/arch/avr32/include/asm/cache.h
++++ b/arch/avr32/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef __ASM_AVR32_CACHE_H
+ #define __ASM_AVR32_CACHE_H
+
++#include <linux/const.h>
++
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ /*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
+index 0388ece..87c8df1 100644
+--- a/arch/avr32/include/asm/elf.h
++++ b/arch/avr32/include/asm/elf.h
+@@ -84,8 +84,14 @@ typedef struct user_fpu_struct elf_fpregset_t;
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+-#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
++
++#define PAX_DELTA_MMAP_LEN 15
++#define PAX_DELTA_STACK_LEN 15
++#endif
+
+ /* This yields a mask that user programs can use to figure out what
+ instruction set this CPU supports. This could be done in user space,
+diff --git a/arch/avr32/include/asm/kmap_types.h b/arch/avr32/include/asm/kmap_types.h
+index 479330b..53717a8 100644
+--- a/arch/avr32/include/asm/kmap_types.h
++++ b/arch/avr32/include/asm/kmap_types.h
+@@ -2,9 +2,9 @@
+ #define __ASM_AVR32_KMAP_TYPES_H
+
+ #ifdef CONFIG_DEBUG_HIGHMEM
+-# define KM_TYPE_NR 29
++# define KM_TYPE_NR 30
+ #else
+-# define KM_TYPE_NR 14
++# define KM_TYPE_NR 15
+ #endif
+
+ #endif /* __ASM_AVR32_KMAP_TYPES_H */
+diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
+index b3977e9..4230c51a 100644
+--- a/arch/avr32/mm/fault.c
++++ b/arch/avr32/mm/fault.c
+@@ -41,6 +41,23 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
+
+ int exception_trace = 1;
+
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ unsigned long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 20; i++) {
++ unsigned char c;
++ if (get_user(c, (unsigned char *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%02x ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ /*
+ * This routine handles page faults. It determines the address and the
+ * problem, and then passes it off to one of the appropriate routines.
+@@ -178,6 +195,16 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
+ up_read(&mm->mmap_sem);
+
+ if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
++ do_group_exit(SIGKILL);
++ }
++ }
++#endif
++
+ if (exception_trace && printk_ratelimit())
+ printk("%s%s[%d]: segfault at %08lx pc %08lx "
+ "sp %08lx ecr %lu\n",
+diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug
+index f3337ee..15b6f8d 100644
+--- a/arch/blackfin/Kconfig.debug
++++ b/arch/blackfin/Kconfig.debug
+@@ -18,6 +18,7 @@ config DEBUG_VERBOSE
+ config DEBUG_MMRS
+ tristate "Generate Blackfin MMR tree"
+ select DEBUG_FS
++ depends on !GRKERNSEC_KMEM
+ help
+ Create a tree of Blackfin MMRs via the debugfs tree. If
+ you enable this, you will find all MMRs laid out in the
+diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
+index 568885a..f8008df 100644
+--- a/arch/blackfin/include/asm/cache.h
++++ b/arch/blackfin/include/asm/cache.h
+@@ -7,6 +7,7 @@
+ #ifndef __ARCH_BLACKFIN_CACHE_H
+ #define __ARCH_BLACKFIN_CACHE_H
+
++#include <linux/const.h>
+ #include <linux/linkage.h> /* for asmlinkage */
+
+ /*
+@@ -14,7 +15,7 @@
+ * Blackfin loads 32 bytes for cache
+ */
+ #define L1_CACHE_SHIFT 5
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+diff --git a/arch/cris/include/arch-v10/arch/cache.h b/arch/cris/include/arch-v10/arch/cache.h
+index aea2718..3639a60 100644
+--- a/arch/cris/include/arch-v10/arch/cache.h
++++ b/arch/cris/include/arch-v10/arch/cache.h
+@@ -1,8 +1,9 @@
+ #ifndef _ASM_ARCH_CACHE_H
+ #define _ASM_ARCH_CACHE_H
+
++#include <linux/const.h>
+ /* Etrax 100LX have 32-byte cache-lines. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #endif /* _ASM_ARCH_CACHE_H */
+diff --git a/arch/cris/include/arch-v32/arch/cache.h b/arch/cris/include/arch-v32/arch/cache.h
+index 7caf25d..ee65ac5 100644
+--- a/arch/cris/include/arch-v32/arch/cache.h
++++ b/arch/cris/include/arch-v32/arch/cache.h
+@@ -1,11 +1,12 @@
+ #ifndef _ASM_CRIS_ARCH_CACHE_H
+ #define _ASM_CRIS_ARCH_CACHE_H
+
++#include <linux/const.h>
+ #include <arch/hwregs/dma.h>
+
+ /* A cache-line is 32 bytes. */
+-#define L1_CACHE_BYTES 32
+ #define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define __read_mostly __attribute__((__section__(".data..read_mostly")))
+
+diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
+index 1c2a5e2..2579e5f 100644
+--- a/arch/frv/include/asm/atomic.h
++++ b/arch/frv/include/asm/atomic.h
+@@ -146,6 +146,16 @@ static inline void atomic64_dec(atomic64_t *v)
+ #define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
+ #define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ {
+ int c, old;
+diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h
+index 2797163..c2a401df9 100644
+--- a/arch/frv/include/asm/cache.h
++++ b/arch/frv/include/asm/cache.h
+@@ -12,10 +12,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+
++#include <linux/const.h>
+
+ /* bytes per L1 cache line */
+ #define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT)
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+ #define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
+index 43901f2..0d8b865 100644
+--- a/arch/frv/include/asm/kmap_types.h
++++ b/arch/frv/include/asm/kmap_types.h
+@@ -2,6 +2,6 @@
+ #ifndef _ASM_KMAP_TYPES_H
+ #define _ASM_KMAP_TYPES_H
+
+-#define KM_TYPE_NR 17
++#define KM_TYPE_NR 18
+
+ #endif
+diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
+index 836f1470..4cf23f5 100644
+--- a/arch/frv/mm/elf-fdpic.c
++++ b/arch/frv/mm/elf-fdpic.c
+@@ -61,6 +61,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ {
+ struct vm_area_struct *vma;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+@@ -73,8 +74,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ if (addr) {
+ addr = PAGE_ALIGN(addr);
+ vma = find_vma(current->mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ goto success;
+ }
+
+@@ -85,6 +85,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
+ info.high_limit = (current->mm->start_stack - 0x00200000);
+ info.align_mask = 0;
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ goto success;
+diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h
+index 69952c18..4fa2908 100644
+--- a/arch/hexagon/include/asm/cache.h
++++ b/arch/hexagon/include/asm/cache.h
+@@ -21,9 +21,11 @@
+ #ifndef __ASM_CACHE_H
+ #define __ASM_CACHE_H
+
++#include <linux/const.h>
++
+ /* Bytes per L1 cache line */
+-#define L1_CACHE_SHIFT (5)
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+
+diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
+index 18ca6a9..77b0e0d 100644
+--- a/arch/ia64/Kconfig
++++ b/arch/ia64/Kconfig
+@@ -519,6 +519,7 @@ config KEXEC
+ bool "kexec system call"
+ depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
+ select KEXEC_CORE
++ depends on !GRKERNSEC_KMEM
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
+index c100d78..c44d46d 100644
+--- a/arch/ia64/Makefile
++++ b/arch/ia64/Makefile
+@@ -98,5 +98,6 @@ endef
+ archprepare: make_nr_irqs_h
+ PHONY += make_nr_irqs_h
+
++GCC_PLUGINS_make_nr_irqs_h := n
+ make_nr_irqs_h:
+ $(Q)$(MAKE) $(build)=arch/ia64/kernel include/generated/nr-irqs.h
+diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
+index 65d4bb2..8b2e661 100644
+--- a/arch/ia64/include/asm/atomic.h
++++ b/arch/ia64/include/asm/atomic.h
+@@ -323,4 +323,14 @@ atomic64_add_negative (__s64 i, atomic64_t *v)
+ #define atomic64_inc(v) atomic64_add(1, (v))
+ #define atomic64_dec(v) atomic64_sub(1, (v))
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* _ASM_IA64_ATOMIC_H */
+diff --git a/arch/ia64/include/asm/cache.h b/arch/ia64/include/asm/cache.h
+index 988254a..e1ee885 100644
+--- a/arch/ia64/include/asm/cache.h
++++ b/arch/ia64/include/asm/cache.h
+@@ -1,6 +1,7 @@
+ #ifndef _ASM_IA64_CACHE_H
+ #define _ASM_IA64_CACHE_H
+
++#include <linux/const.h>
+
+ /*
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+@@ -9,7 +10,7 @@
+
+ /* Bytes per L1 (data) cache line. */
+ #define L1_CACHE_SHIFT CONFIG_IA64_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #ifdef CONFIG_SMP
+ # define SMP_CACHE_SHIFT L1_CACHE_SHIFT
+diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
+index 5a83c5c..4d7f553 100644
+--- a/arch/ia64/include/asm/elf.h
++++ b/arch/ia64/include/asm/elf.h
+@@ -42,6 +42,13 @@
+ */
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x800000000UL)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
++
++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
++#endif
++
+ #define PT_IA_64_UNWIND 0x70000001
+
+ /* IA-64 relocations: */
+diff --git a/arch/ia64/include/asm/pgalloc.h b/arch/ia64/include/asm/pgalloc.h
+index f5e70e9..624fad5 100644
+--- a/arch/ia64/include/asm/pgalloc.h
++++ b/arch/ia64/include/asm/pgalloc.h
+@@ -39,6 +39,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
+ pgd_val(*pgd_entry) = __pa(pud);
+ }
+
++static inline void
++pgd_populate_kernel(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)
++{
++ pgd_populate(mm, pgd_entry, pud);
++}
++
+ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
+@@ -57,6 +63,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
+ pud_val(*pud_entry) = __pa(pmd);
+ }
+
++static inline void
++pud_populate_kernel(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)
++{
++ pud_populate(mm, pud_entry, pmd);
++}
++
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+ {
+ return quicklist_alloc(0, GFP_KERNEL, NULL);
+diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
+index 9f3ed9e..c99b418 100644
+--- a/arch/ia64/include/asm/pgtable.h
++++ b/arch/ia64/include/asm/pgtable.h
+@@ -12,7 +12,7 @@
+ * David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+-
++#include <linux/const.h>
+ #include <asm/mman.h>
+ #include <asm/page.h>
+ #include <asm/processor.h>
+@@ -139,6 +139,17 @@
+ #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
+ #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
+ #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
++#else
++# define PAGE_SHARED_NOEXEC PAGE_SHARED
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++# define PAGE_COPY_NOEXEC PAGE_COPY
++#endif
++
+ #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
+ #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
+ #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
+diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
+index ca9e761..40dffaf 100644
+--- a/arch/ia64/include/asm/spinlock.h
++++ b/arch/ia64/include/asm/spinlock.h
+@@ -73,7 +73,7 @@ static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
+ unsigned short *p = (unsigned short *)&lock->lock + 1, tmp;
+
+ asm volatile ("ld2.bias %0=[%1]" : "=r"(tmp) : "r"(p));
+- ACCESS_ONCE(*p) = (tmp + 2) & ~1;
++ ACCESS_ONCE_RW(*p) = (tmp + 2) & ~1;
+ }
+
+ static __always_inline void __ticket_spin_unlock_wait(arch_spinlock_t *lock)
+diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h
+index bfe1319..da0014b 100644
+--- a/arch/ia64/include/asm/uaccess.h
++++ b/arch/ia64/include/asm/uaccess.h
+@@ -70,6 +70,7 @@
+ && ((segment).seg == KERNEL_DS.seg \
+ || likely(REGION_OFFSET((unsigned long) (addr)) < RGN_MAP_LIMIT))); \
+ })
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) __access_ok((addr), (size), get_fs())
+
+ /*
+@@ -241,17 +242,23 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use
+ static inline unsigned long
+ __copy_to_user (void __user *to, const void *from, unsigned long count)
+ {
++ if (count > INT_MAX)
++ return count;
++
+ check_object_size(from, count, true);
+
+- return __copy_user(to, (__force void __user *) from, count);
++ return __copy_user(to, (void __force_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;
++
+ check_object_size(to, count, false);
+
+- return __copy_user((__force void __user *) to, from, count);
++ return __copy_user((void __force_user *) to, from, count);
+ }
+
+ #define __copy_to_user_inatomic __copy_to_user
+@@ -260,11 +267,11 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
+ ({ \
+ void __user *__cu_to = (to); \
+ const void *__cu_from = (from); \
+- long __cu_len = (n); \
++ unsigned long __cu_len = (n); \
+ \
+- if (__access_ok(__cu_to, __cu_len, get_fs())) { \
+- check_object_size(__cu_from, __cu_len, true); \
+- __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
++ if (__cu_len <= INT_MAX && __access_ok(__cu_to, __cu_len, get_fs())) { \
++ check_object_size(__cu_from, __cu_len, true); \
++ __cu_len = __copy_user(__cu_to, (void __force_user *) __cu_from, __cu_len); \
+ } \
+ __cu_len; \
+ })
+@@ -272,10 +279,10 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
+ static inline unsigned long
+ copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+- check_object_size(to, n, false);
+- if (likely(__access_ok(from, n, get_fs())))
+- n = __copy_user((__force void __user *) to, from, n);
+- else
++ if (likely(__access_ok(from, n, get_fs()))) {
++ check_object_size(to, n, false);
++ n = __copy_user((void __force_user *) to, from, n);
++ } else if ((long)n > 0)
+ memset(to, 0, n);
+ return n;
+ }
+diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
+index c7c5144..7e31461 100644
+--- a/arch/ia64/kernel/kprobes.c
++++ b/arch/ia64/kernel/kprobes.c
+@@ -499,6 +499,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+ return 1;
+ }
+
++#ifdef CONFIG_KRETPROBES
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+ {
+@@ -507,6 +508,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ /* Replace the return addr with trampoline addr */
+ regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
+ }
++#endif
+
+ /* Check the instruction in the slot is break */
+ static int __kprobes __is_ia64_break_inst(bundle_t *bundle, uint slot)
+@@ -1119,6 +1121,7 @@ int __init arch_init_kprobes(void)
+ return register_kprobe(&trampoline_p);
+ }
+
++#ifdef CONFIG_KRETPROBES
+ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+ {
+ if (p->addr ==
+@@ -1127,3 +1130,4 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+
+ return 0;
+ }
++#endif
+diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
+index 6ab0ae7..88f1b60 100644
+--- a/arch/ia64/kernel/module.c
++++ b/arch/ia64/kernel/module.c
+@@ -486,13 +486,13 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
+ static inline int
+ in_init (const struct module *mod, uint64_t addr)
+ {
+- return addr - (uint64_t) mod->init_layout.base < mod->init_layout.size;
++ return within_module_init(addr, mod);
+ }
+
+ static inline int
+ in_core (const struct module *mod, uint64_t addr)
+ {
+- return addr - (uint64_t) mod->core_layout.base < mod->core_layout.size;
++ return within_module_core(addr, mod);
+ }
+
+ static inline int
+@@ -676,6 +676,14 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend,
+
+ case RV_BDREL:
+ val -= (uint64_t) (in_init(mod, val) ? mod->init_layout.base : mod->core_layout.base);
++ if (within_module_rx(val, &mod->init_layout))
++ val -= mod->init_layout.base_rx;
++ else if (within_module_rw(val, &mod->init_layout))
++ val -= mod->init_layout.base_rw;
++ else if (within_module_rx(val, &mod->core_layout))
++ val -= mod->core_layout.base_rx;
++ else if (within_module_rw(val, &mod->core_layout))
++ val -= mod->core_layout.base_rw;
+ break;
+
+ case RV_LTV:
+@@ -810,15 +818,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind
+ * addresses have been selected...
+ */
+ uint64_t gp;
+- if (mod->core_layout.size > MAX_LTOFF)
++ if (mod->core_layout.size_rx + mod->core_layout.size_rw > MAX_LTOFF)
+ /*
+ * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
+ * at the end of the module.
+ */
+- gp = mod->core_layout.size - MAX_LTOFF / 2;
++ gp = mod->core_layout.size_rx + mod->core_layout.size_rw - MAX_LTOFF / 2;
+ else
+- gp = mod->core_layout.size / 2;
+- gp = (uint64_t) mod->core_layout.base + ((gp + 7) & -8);
++ gp = (mod->core_layout.size_rx + mod->core_layout.size_rw) / 2;
++ gp = (uint64_t) mod->core_layout.base_rx + ((gp + 7) & -8);
+ mod->arch.gp = gp;
+ DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
+ }
+diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
+index c39c3cd..3c77738 100644
+--- a/arch/ia64/kernel/palinfo.c
++++ b/arch/ia64/kernel/palinfo.c
+@@ -980,7 +980,7 @@ static int palinfo_cpu_callback(struct notifier_block *nfb,
+ return NOTIFY_OK;
+ }
+
+-static struct notifier_block __refdata palinfo_cpu_notifier =
++static struct notifier_block palinfo_cpu_notifier =
+ {
+ .notifier_call = palinfo_cpu_callback,
+ .priority = 0,
+diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
+index 41e33f8..65180b2a 100644
+--- a/arch/ia64/kernel/sys_ia64.c
++++ b/arch/ia64/kernel/sys_ia64.c
+@@ -28,6 +28,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+ unsigned long align_mask = 0;
+ struct mm_struct *mm = current->mm;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+
+ if (len > RGN_MAP_LIMIT)
+ return -ENOMEM;
+@@ -43,6 +44,13 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+ if (REGION_NUMBER(addr) == RGN_HPAGE)
+ addr = 0;
+ #endif
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ addr = mm->free_area_cache;
++ else
++#endif
++
+ if (!addr)
+ addr = TASK_UNMAPPED_BASE;
+
+@@ -61,6 +69,7 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len
+ info.high_limit = TASK_SIZE;
+ info.align_mask = align_mask;
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ return vm_unmapped_area(&info);
+ }
+
+diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
+index f89d20c..410a1b1 100644
+--- a/arch/ia64/kernel/vmlinux.lds.S
++++ b/arch/ia64/kernel/vmlinux.lds.S
+@@ -172,7 +172,7 @@ SECTIONS {
+ /* Per-cpu data: */
+ . = ALIGN(PERCPU_PAGE_SIZE);
+ PERCPU_VADDR(SMP_CACHE_BYTES, PERCPU_ADDR, :percpu)
+- __phys_per_cpu_start = __per_cpu_load;
++ __phys_per_cpu_start = per_cpu_load;
+ /*
+ * ensure percpu data fits
+ * into percpu page size
+diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
+index fa6ad95..b46bd89 100644
+--- a/arch/ia64/mm/fault.c
++++ b/arch/ia64/mm/fault.c
+@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned long address)
+ return pte_present(pte);
+ }
+
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ unsigned long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 8; i++) {
++ unsigned int c;
++ if (get_user(c, (unsigned int *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08x ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ # define VM_READ_BIT 0
+ # define VM_WRITE_BIT 1
+ # define VM_EXEC_BIT 2
+@@ -151,8 +168,21 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
+ if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE))))
+ goto bad_area;
+
+- if ((vma->vm_flags & mask) != mask)
++ if ((vma->vm_flags & mask) != mask) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
++ goto bad_area;
++
++ up_read(&mm->mmap_sem);
++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ goto bad_area;
++ }
+
+ /*
+ * If for any reason at all we couldn't handle the fault, make
+diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
+index 85de86d..db7f6b8 100644
+--- a/arch/ia64/mm/hugetlbpage.c
++++ b/arch/ia64/mm/hugetlbpage.c
+@@ -138,6 +138,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
+ unsigned long pgoff, unsigned long flags)
+ {
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, file, flags);
+
+ if (len > RGN_MAP_LIMIT)
+ return -ENOMEM;
+@@ -161,6 +162,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u
+ info.high_limit = HPAGE_REGION_BASE + RGN_MAP_LIMIT;
+ info.align_mask = PAGE_MASK & (HPAGE_SIZE - 1);
+ info.align_offset = 0;
++ info.threadstack_offset = offset;
+ return vm_unmapped_area(&info);
+ }
+
+diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
+index 1841ef6..74d8330 100644
+--- a/arch/ia64/mm/init.c
++++ b/arch/ia64/mm/init.c
+@@ -119,6 +119,19 @@ ia64_init_addr_space (void)
+ vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
+ vma->vm_end = vma->vm_start + PAGE_SIZE;
+ vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
++ vma->vm_flags &= ~VM_EXEC;
++
++#ifdef CONFIG_PAX_MPROTECT
++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
++ vma->vm_flags &= ~VM_MAYEXEC;
++#endif
++
++ }
++#endif
++
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+ down_write(&current->mm->mmap_sem);
+ if (insert_vm_struct(current->mm, vma)) {
+@@ -279,7 +292,7 @@ static int __init gate_vma_init(void)
+ gate_vma.vm_start = FIXADDR_USER_START;
+ gate_vma.vm_end = FIXADDR_USER_END;
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
+- gate_vma.vm_page_prot = __P101;
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
+
+ return 0;
+ }
+diff --git a/arch/m32r/include/asm/cache.h b/arch/m32r/include/asm/cache.h
+index 40b3ee98..8c2c112 100644
+--- a/arch/m32r/include/asm/cache.h
++++ b/arch/m32r/include/asm/cache.h
+@@ -1,8 +1,10 @@
+ #ifndef _ASM_M32R_CACHE_H
+ #define _ASM_M32R_CACHE_H
+
++#include <linux/const.h>
++
+ /* L1 cache line size */
+ #define L1_CACHE_SHIFT 4
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #endif /* _ASM_M32R_CACHE_H */
+diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c
+index 82abd15..d95ae5d 100644
+--- a/arch/m32r/lib/usercopy.c
++++ b/arch/m32r/lib/usercopy.c
+@@ -14,6 +14,9 @@
+ unsigned long
+ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ prefetch(from);
+ if (access_ok(VERIFY_WRITE, to, n))
+ __copy_user(to,from,n);
+@@ -23,6 +26,9 @@ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
+ unsigned long
+ __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
++ if ((long)n < 0)
++ return n;
++
+ prefetchw(to);
+ if (access_ok(VERIFY_READ, from, n))
+ __copy_user_zeroing(to,from,n);
+diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
+index 0395c51..5f26031 100644
+--- a/arch/m68k/include/asm/cache.h
++++ b/arch/m68k/include/asm/cache.h
+@@ -4,9 +4,11 @@
+ #ifndef __ARCH_M68K_CACHE_H
+ #define __ARCH_M68K_CACHE_H
+
++#include <linux/const.h>
++
+ /* bytes per L1 cache line */
+ #define L1_CACHE_SHIFT 4
+-#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+
+diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
+index 4e5aa2f..172c469 100644
+--- a/arch/m68k/kernel/time.c
++++ b/arch/m68k/kernel/time.c
+@@ -107,6 +107,7 @@ static int rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+
+ switch (cmd) {
+ case RTC_PLL_GET:
++ memset(&pll, 0, sizeof(pll));
+ if (!mach_get_rtc_pll || mach_get_rtc_pll(&pll))
+ return -EINVAL;
+ return copy_to_user(argp, &pll, sizeof pll) ? -EFAULT : 0;
+diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
+index db1b7da..8e13684 100644
+--- a/arch/metag/mm/hugetlbpage.c
++++ b/arch/metag/mm/hugetlbpage.c
+@@ -189,6 +189,7 @@ hugetlb_get_unmapped_area_new_pmd(unsigned long len)
+ info.high_limit = TASK_SIZE;
+ info.align_mask = PAGE_MASK & HUGEPT_MASK;
+ info.align_offset = 0;
++ info.threadstack_offset = 0;
+ return vm_unmapped_area(&info);
+ }
+
+diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h
+index 4efe96a..60e8699 100644
+--- a/arch/microblaze/include/asm/cache.h
++++ b/arch/microblaze/include/asm/cache.h
+@@ -13,11 +13,12 @@
+ #ifndef _ASM_MICROBLAZE_CACHE_H
+ #define _ASM_MICROBLAZE_CACHE_H
+
++#include <linux/const.h>
+ #include <asm/registers.h>
+
+ #define L1_CACHE_SHIFT 5
+ /* word-granular cache in microblaze */
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+
+diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
+index 5c3f688..f8cc1b3 100644
+--- a/arch/mips/Kbuild
++++ b/arch/mips/Kbuild
+@@ -1,7 +1,7 @@
+ # Fail on warnings - also for files referenced in subdirs
+ # -Werror can be disabled for specific files using:
+ # CFLAGS_<file.o> := -Wno-error
+-subdir-ccflags-y := -Werror
++# subdir-ccflags-y := -Werror
+
+ # platform specific definitions
+ include arch/mips/Kbuild.platforms
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
+index b3c5bde..d6b5104 100644
+--- a/arch/mips/Kconfig
++++ b/arch/mips/Kconfig
+@@ -49,6 +49,7 @@ config MIPS
+ select HAVE_MOD_ARCH_SPECIFIC
+ select HAVE_NMI
+ select VIRT_TO_BUS
++ select HAVE_GCC_PLUGINS
+ select MODULES_USE_ELF_REL if MODULES
+ select MODULES_USE_ELF_RELA if MODULES && 64BIT
+ select CLONE_BACKWARDS
+@@ -2595,7 +2596,7 @@ config RELOCATION_TABLE_SIZE
+
+ config RANDOMIZE_BASE
+ bool "Randomize the address of the kernel image"
+- depends on RELOCATABLE
++ depends on RELOCATABLE && BROKEN_SECURITY
+ ---help---
+ Randomizes the physical and virtual address at which the
+ kernel image is loaded, as a security feature that
+@@ -2811,6 +2812,7 @@ source "kernel/Kconfig.preempt"
+ config KEXEC
+ bool "Kexec system call"
+ select KEXEC_CORE
++ depends on !GRKERNSEC_KMEM
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
+index 0ab176b..c4469a4 100644
+--- a/arch/mips/include/asm/atomic.h
++++ b/arch/mips/include/asm/atomic.h
+@@ -22,15 +22,39 @@
+ #include <asm/cmpxchg.h>
+ #include <asm/war.h>
+
++#ifdef CONFIG_GENERIC_ATOMIC64
++#include <asm-generic/atomic64.h>
++#endif
++
+ #define ATOMIC_INIT(i) { (i) }
+
++#ifdef CONFIG_64BIT
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++" .dword " #from ", " #to"\n" \
++" .previous\n"
++#else
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++" .word " #from ", " #to"\n" \
++" .previous\n"
++#endif
++
+ /*
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+-#define atomic_read(v) READ_ONCE((v)->counter)
++static inline int atomic_read(const atomic_t *v)
++{
++ return READ_ONCE(v->counter);
++}
++
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+
+ /*
+ * atomic_set - set atomic variable
+@@ -39,47 +63,77 @@
+ *
+ * Atomically sets the value of @v to @i.
+ */
+-#define atomic_set(v, i) WRITE_ONCE((v)->counter, (i))
++static inline void atomic_set(atomic_t *v, int i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+
+-#define ATOMIC_OP(op, c_op, asm_op) \
+-static __inline__ void atomic_##op(int i, atomic_t * v) \
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ WRITE_ONCE(v->counter, i);
++}
++
++#ifdef CONFIG_PAX_REFCOUNT
++#define __OVERFLOW_POST \
++ " b 4f \n" \
++ " .set noreorder \n" \
++ "3: b 5f \n" \
++ " move %0, %1 \n" \
++ " .set reorder \n"
++#define __OVERFLOW_EXTABLE \
++ "3:\n" \
++ _ASM_EXTABLE(2b, 3b)
++#else
++#define __OVERFLOW_POST
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, asm_op, extable) \
++static inline void atomic_##op##suffix(int i, atomic##suffix##_t * v) \
+ { \
+ if (kernel_uses_llsc && R10000_LLSC_WAR) { \
+ int temp; \
+ \
+ __asm__ __volatile__( \
+- " .set arch=r4000 \n" \
+- "1: ll %0, %1 # atomic_" #op " \n" \
+- " " #asm_op " %0, %2 \n" \
++ " .set mips3 \n" \
++ "1: ll %0, %1 # atomic_" #op #suffix "\n" \
++ "2: " #asm_op " %0, %2 \n" \
+ " sc %0, %1 \n" \
+ " beqzl %0, 1b \n" \
++ extable \
+ " .set mips0 \n" \
+ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
+ : "Ir" (i)); \
+ } else if (kernel_uses_llsc) { \
+ int temp; \
+ \
+- do { \
+- __asm__ __volatile__( \
+- " .set "MIPS_ISA_LEVEL" \n" \
+- " ll %0, %1 # atomic_" #op "\n" \
+- " " #asm_op " %0, %2 \n" \
+- " sc %0, %1 \n" \
+- " .set mips0 \n" \
+- : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
+- : "Ir" (i)); \
+- } while (unlikely(!temp)); \
++ __asm__ __volatile__( \
++ " .set "MIPS_ISA_LEVEL" \n" \
++ "1: ll %0, %1 # atomic_" #op #suffix "\n" \
++ "2: " #asm_op " %0, %2 \n" \
++ " sc %0, %1 \n" \
++ " beqz %0, 1b \n" \
++ extable \
++ " .set mips0 \n" \
++ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i)); \
+ } else { \
+ unsigned long flags; \
+ \
+ raw_local_irq_save(flags); \
+- v->counter c_op i; \
++ __asm__ __volatile__( \
++ "2: " #asm_op " %0, %1 \n" \
++ extable \
++ : "+r" (v->counter) : "Ir" (i)); \
+ raw_local_irq_restore(flags); \
+ } \
+ }
+
+-#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
+-static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
++#define ATOMIC_OP(op, asm_op) __ATOMIC_OP(op, _unchecked, asm_op##u, ) \
++ __ATOMIC_OP(op, , asm_op, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC_OP_RETURN(op, suffix, asm_op, post_op, extable) \
++static inline int atomic_##op##_return##suffix##_relaxed(int i, atomic##suffix##_t * v) \
+ { \
+ int result; \
+ \
+@@ -87,12 +141,15 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
+ int temp; \
+ \
+ __asm__ __volatile__( \
+- " .set arch=r4000 \n" \
+- "1: ll %1, %2 # atomic_" #op "_return \n" \
+- " " #asm_op " %0, %1, %3 \n" \
++ " .set mips3 \n" \
++ "1: ll %1, %2 # atomic_" #op "_return" #suffix"\n" \
++ "2: " #asm_op " %0, %1, %3 \n" \
+ " sc %0, %2 \n" \
+ " beqzl %0, 1b \n" \
+- " " #asm_op " %0, %1, %3 \n" \
++ post_op \
++ extable \
++ "4: " #asm_op " %0, %1, %3 \n" \
++ "5: \n" \
+ " .set mips0 \n" \
+ : "=&r" (result), "=&r" (temp), \
+ "+" GCC_OFF_SMALL_ASM() (v->counter) \
+@@ -100,32 +157,40 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v) \
+ } else if (kernel_uses_llsc) { \
+ int temp; \
+ \
+- do { \
+- __asm__ __volatile__( \
+- " .set "MIPS_ISA_LEVEL" \n" \
+- " ll %1, %2 # atomic_" #op "_return \n" \
+- " " #asm_op " %0, %1, %3 \n" \
+- " sc %0, %2 \n" \
+- " .set mips0 \n" \
+- : "=&r" (result), "=&r" (temp), \
+- "+" GCC_OFF_SMALL_ASM() (v->counter) \
+- : "Ir" (i)); \
+- } while (unlikely(!result)); \
+- \
+- result = temp; result c_op i; \
++ __asm__ __volatile__( \
++ " .set "MIPS_ISA_LEVEL" \n" \
++ "1: ll %1, %2 # atomic_" #op "_return" #suffix "\n" \
++ "2: " #asm_op " %0, %1, %3 \n" \
++ " sc %0, %2 \n" \
++ post_op \
++ extable \
++ "4: " #asm_op " %0, %1, %3 \n" \
++ "5: \n" \
++ " .set mips0 \n" \
++ : "=&r" (result), "=&r" (temp), \
++ "+" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i)); \
+ } else { \
+ unsigned long flags; \
+ \
+ raw_local_irq_save(flags); \
+- result = v->counter; \
+- result c_op i; \
+- v->counter = result; \
++ __asm__ __volatile__( \
++ " lw %0, %1 \n" \
++ "2: " #asm_op " %0, %1, %2 \n" \
++ " sw %0, %1 \n" \
++ "3: \n" \
++ extable \
++ : "=&r" (result), "+" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i)); \
+ raw_local_irq_restore(flags); \
+ } \
+ \
+ return result; \
+ }
+
++#define ATOMIC_OP_RETURN(op, asm_op) __ATOMIC_OP_RETURN(op, _unchecked, asm_op##u, , ) \
++ __ATOMIC_OP_RETURN(op, , asm_op, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC_FETCH_OP(op, c_op, asm_op) \
+ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
+ { \
+@@ -173,13 +238,13 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v) \
+ return result; \
+ }
+
+-#define ATOMIC_OPS(op, c_op, asm_op) \
+- ATOMIC_OP(op, c_op, asm_op) \
+- ATOMIC_OP_RETURN(op, c_op, asm_op) \
+- ATOMIC_FETCH_OP(op, c_op, asm_op)
++#define ATOMIC_OPS(op, asm_op) \
++ ATOMIC_OP(op, asm_op) \
++ ATOMIC_OP_RETURN(op, asm_op) \
++ ATOMIC_FETCH_OP(op, asm_op)
+
+-ATOMIC_OPS(add, +=, addu)
+-ATOMIC_OPS(sub, -=, subu)
++ATOMIC_OPS(add, addu)
++ATOMIC_OPS(sub, subu)
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
+ #define atomic_sub_return_relaxed atomic_sub_return_relaxed
+@@ -187,13 +252,13 @@ ATOMIC_OPS(sub, -=, subu)
+ #define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
+
+ #undef ATOMIC_OPS
+-#define ATOMIC_OPS(op, c_op, asm_op) \
+- ATOMIC_OP(op, c_op, asm_op) \
+- ATOMIC_FETCH_OP(op, c_op, asm_op)
++#define ATOMIC_OPS(op, asm_op) \
++ ATOMIC_OP(op, asm_op) \
++ ATOMIC_FETCH_OP(op, asm_op)
+
+-ATOMIC_OPS(and, &=, and)
+-ATOMIC_OPS(or, |=, or)
+-ATOMIC_OPS(xor, ^=, xor)
++ATOMIC_OPS(and, and)
++ATOMIC_OPS(or, or)
++ATOMIC_OPS(xor, xor)
+
+ #define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
+ #define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
+@@ -202,7 +267,9 @@ ATOMIC_OPS(xor, ^=, xor)
+ #undef ATOMIC_OPS
+ #undef ATOMIC_FETCH_OP
+ #undef ATOMIC_OP_RETURN
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+ /*
+ * atomic_sub_if_positive - conditionally subtract integer from atomic variable
+@@ -212,7 +279,7 @@ ATOMIC_OPS(xor, ^=, xor)
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+-static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
++static __inline__ int atomic_sub_if_positive(int i, atomic_t *v)
+ {
+ int result;
+
+@@ -222,7 +289,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+ int temp;
+
+ __asm__ __volatile__(
+- " .set arch=r4000 \n"
++ " .set "MIPS_ISA_LEVEL" \n"
+ "1: ll %1, %2 # atomic_sub_if_positive\n"
+ " subu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+@@ -271,8 +338,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+ return result;
+ }
+
+-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
++{
++ return cmpxchg(&v->counter, old, new);
++}
++
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old,
++ int new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++static inline int atomic_xchg(atomic_t *v, int new)
++{
++ return xchg(&v->counter, new);
++}
++
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++ return xchg(&(v->counter), new);
++}
+
+ /**
+ * __atomic_add_unless - add unless the number is a given value
+@@ -300,6 +385,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+
+ #define atomic_dec_return(v) atomic_sub_return(1, (v))
+ #define atomic_inc_return(v) atomic_add_return(1, (v))
++static __inline__ int atomic_inc_return_unchecked(atomic_unchecked_t *v)
++{
++ return atomic_add_return_unchecked(1, v);
++}
+
+ /*
+ * atomic_sub_and_test - subtract value from variable and test result
+@@ -321,6 +410,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * other cases.
+ */
+ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
++static __inline__ int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
++{
++ return atomic_add_return_unchecked(1, v) == 0;
++}
+
+ /*
+ * atomic_dec_and_test - decrement by 1 and test
+@@ -345,6 +438,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * Atomically increments @v by 1.
+ */
+ #define atomic_inc(v) atomic_add(1, (v))
++static __inline__ void atomic_inc_unchecked(atomic_unchecked_t *v)
++{
++ atomic_add_unchecked(1, v);
++}
+
+ /*
+ * atomic_dec - decrement and test
+@@ -353,6 +450,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * Atomically decrements @v by 1.
+ */
+ #define atomic_dec(v) atomic_sub(1, (v))
++static __inline__ void atomic_dec_unchecked(atomic_unchecked_t *v)
++{
++ atomic_sub_unchecked(1, v);
++}
+
+ /*
+ * atomic_add_negative - add and test if negative
+@@ -374,54 +475,77 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * @v: pointer of type atomic64_t
+ *
+ */
+-#define atomic64_read(v) READ_ONCE((v)->counter)
++static inline long atomic64_read(const atomic64_t *v)
++{
++ return READ_ONCE(v->counter);
++}
++
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ return READ_ONCE(v->counter);
++}
+
+ /*
+ * atomic64_set - set atomic variable
+ * @v: pointer of type atomic64_t
+ * @i: required value
+ */
+-#define atomic64_set(v, i) WRITE_ONCE((v)->counter, (i))
++static inline void atomic64_set(atomic64_t *v, long i)
++{
++ WRITE_ONCE(v->counter, i);
++}
+
+-#define ATOMIC64_OP(op, c_op, asm_op) \
+-static __inline__ void atomic64_##op(long i, atomic64_t * v) \
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++ WRITE_ONCE(v->counter, i);
++}
++
++#define __ATOMIC64_OP(op, suffix, asm_op, extable) \
++static inline void atomic64_##op##suffix(long i, atomic64##suffix##_t * v) \
+ { \
+ if (kernel_uses_llsc && R10000_LLSC_WAR) { \
+ long temp; \
+ \
+ __asm__ __volatile__( \
+- " .set arch=r4000 \n" \
+- "1: lld %0, %1 # atomic64_" #op " \n" \
+- " " #asm_op " %0, %2 \n" \
++ " .set "MIPS_ISA_LEVEL" \n" \
++ "1: lld %0, %1 # atomic64_" #op #suffix "\n" \
++ "2: " #asm_op " %0, %2 \n" \
+ " scd %0, %1 \n" \
+ " beqzl %0, 1b \n" \
++ extable \
+ " .set mips0 \n" \
+ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
+ : "Ir" (i)); \
+ } else if (kernel_uses_llsc) { \
+ long temp; \
+ \
+- do { \
+- __asm__ __volatile__( \
+- " .set "MIPS_ISA_LEVEL" \n" \
+- " lld %0, %1 # atomic64_" #op "\n" \
+- " " #asm_op " %0, %2 \n" \
+- " scd %0, %1 \n" \
+- " .set mips0 \n" \
+- : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
+- : "Ir" (i)); \
+- } while (unlikely(!temp)); \
++ __asm__ __volatile__( \
++ " .set "MIPS_ISA_LEVEL" \n" \
++ "1: lld %0, %1 # atomic64_" #op #suffix "\n" \
++ "2: " #asm_op " %0, %2 \n" \
++ " scd %0, %1 \n" \
++ " beqz %0, 1b \n" \
++ extable \
++ " .set mips0 \n" \
++ : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i)); \
+ } else { \
+ unsigned long flags; \
+ \
+ raw_local_irq_save(flags); \
+- v->counter c_op i; \
++ __asm__ __volatile__( \
++ "2: " #asm_op " %0, %1 \n" \
++ extable \
++ : "+" GCC_OFF_SMALL_ASM() (v->counter) : "Ir" (i)); \
+ raw_local_irq_restore(flags); \
+ } \
+ }
+
+-#define ATOMIC64_OP_RETURN(op, c_op, asm_op) \
+-static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
++#define ATOMIC64_OP(op, asm_op) __ATOMIC64_OP(op, _unchecked, asm_op##u, ) \
++ __ATOMIC64_OP(op, , asm_op, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC64_OP_RETURN(op, suffix, asm_op, post_op, extable) \
++static inline long atomic64_##op##_return##suffix##_relaxed(long i, atomic64##suffix##_t * v)\
+ { \
+ long result; \
+ \
+@@ -429,12 +553,15 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
+ long temp; \
+ \
+ __asm__ __volatile__( \
+- " .set arch=r4000 \n" \
++ " .set mips3 \n" \
+ "1: lld %1, %2 # atomic64_" #op "_return\n" \
+- " " #asm_op " %0, %1, %3 \n" \
++ "2: " #asm_op " %0, %1, %3 \n" \
+ " scd %0, %2 \n" \
+ " beqzl %0, 1b \n" \
+- " " #asm_op " %0, %1, %3 \n" \
++ post_op \
++ extable \
++ "4: " #asm_op " %0, %1, %3 \n" \
++ "5: \n" \
+ " .set mips0 \n" \
+ : "=&r" (result), "=&r" (temp), \
+ "+" GCC_OFF_SMALL_ASM() (v->counter) \
+@@ -442,33 +569,42 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
+ } else if (kernel_uses_llsc) { \
+ long temp; \
+ \
+- do { \
+- __asm__ __volatile__( \
+- " .set "MIPS_ISA_LEVEL" \n" \
+- " lld %1, %2 # atomic64_" #op "_return\n" \
+- " " #asm_op " %0, %1, %3 \n" \
+- " scd %0, %2 \n" \
+- " .set mips0 \n" \
+- : "=&r" (result), "=&r" (temp), \
+- "=" GCC_OFF_SMALL_ASM() (v->counter) \
+- : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter) \
+- : "memory"); \
+- } while (unlikely(!result)); \
+- \
+- result = temp; result c_op i; \
++ __asm__ __volatile__( \
++ " .set "MIPS_ISA_LEVEL" \n" \
++ "1: lld %1, %2 # atomic64_" #op "_return" #suffix "\n"\
++ "2: " #asm_op " %0, %1, %3 \n" \
++ " scd %0, %2 \n" \
++ " beqz %0, 1b \n" \
++ post_op \
++ extable \
++ "4: " #asm_op " %0, %1, %3 \n" \
++ "5: \n" \
++ " .set mips0 \n" \
++ : "=&r" (result), "=&r" (temp), \
++ "=" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter) \
++ : "memory"); \
+ } else { \
+ unsigned long flags; \
+ \
+ raw_local_irq_save(flags); \
+- result = v->counter; \
+- result c_op i; \
+- v->counter = result; \
++ __asm__ __volatile__( \
++ " ld %0, %1 \n" \
++ "2: " #asm_op " %0, %1, %2 \n" \
++ " sd %0, %1 \n" \
++ "3: \n" \
++ extable \
++ : "=&r" (result), "+" GCC_OFF_SMALL_ASM() (v->counter) \
++ : "Ir" (i)); \
+ raw_local_irq_restore(flags); \
+ } \
+ \
+ return result; \
+ }
+
++#define ATOMIC64_OP_RETURN(op, asm_op) __ATOMIC64_OP_RETURN(op, _unchecked, asm_op##u, , ) \
++ __ATOMIC64_OP_RETURN(op, , asm_op, __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC64_FETCH_OP(op, c_op, asm_op) \
+ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
+ { \
+@@ -517,13 +653,13 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
+ return result; \
+ }
+
+-#define ATOMIC64_OPS(op, c_op, asm_op) \
+- ATOMIC64_OP(op, c_op, asm_op) \
+- ATOMIC64_OP_RETURN(op, c_op, asm_op) \
+- ATOMIC64_FETCH_OP(op, c_op, asm_op)
++#define ATOMIC64_OPS(op, asm_op) \
++ ATOMIC64_OP(op, asm_op) \
++ ATOMIC64_OP_RETURN(op, asm_op) \
++ ATOMIC64_FETCH_OP(op, asm_op)
+
+-ATOMIC64_OPS(add, +=, daddu)
+-ATOMIC64_OPS(sub, -=, dsubu)
++ATOMIC64_OPS(add, daddu)
++ATOMIC64_OPS(sub, dsubu)
+
+ #define atomic64_add_return_relaxed atomic64_add_return_relaxed
+ #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+@@ -531,13 +667,13 @@ ATOMIC64_OPS(sub, -=, dsubu)
+ #define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
+
+ #undef ATOMIC64_OPS
+-#define ATOMIC64_OPS(op, c_op, asm_op) \
+- ATOMIC64_OP(op, c_op, asm_op) \
+- ATOMIC64_FETCH_OP(op, c_op, asm_op)
++#define ATOMIC64_OPS(op, asm_op) \
++ ATOMIC64_OP(op, asm_op) \
++ ATOMIC64_FETCH_OP(op, asm_op)
+
+-ATOMIC64_OPS(and, &=, and)
+-ATOMIC64_OPS(or, |=, or)
+-ATOMIC64_OPS(xor, ^=, xor)
++ATOMIC64_OPS(and, and)
++ATOMIC64_OPS(or, or)
++ATOMIC64_OPS(xor, xor)
+
+ #define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
+ #define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
+@@ -546,7 +682,11 @@ ATOMIC64_OPS(xor, ^=, xor)
+ #undef ATOMIC64_OPS
+ #undef ATOMIC64_FETCH_OP
+ #undef ATOMIC64_OP_RETURN
++#undef __ATOMIC64_OP_RETURN
+ #undef ATOMIC64_OP
++#undef __ATOMIC64_OP
++#undef __OVERFLOW_EXTABLE
++#undef __OVERFLOW_POST
+
+ /*
+ * atomic64_sub_if_positive - conditionally subtract integer from atomic
+@@ -557,7 +697,7 @@ ATOMIC64_OPS(xor, ^=, xor)
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+-static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
++static __inline__ long atomic64_sub_if_positive(long i, atomic64_t *v)
+ {
+ long result;
+
+@@ -567,7 +707,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+ long temp;
+
+ __asm__ __volatile__(
+- " .set arch=r4000 \n"
++ " .set "MIPS_ISA_LEVEL" \n"
+ "1: lld %1, %2 # atomic64_sub_if_positive\n"
+ " dsubu %0, %1, %3 \n"
+ " bltz %0, 1f \n"
+@@ -616,9 +756,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+ return result;
+ }
+
+-#define atomic64_cmpxchg(v, o, n) \
+- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
++{
++ return cmpxchg(&v->counter, old, new);
++}
++
++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old,
++ long new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++static inline long atomic64_xchg(atomic64_t *v, long new)
++{
++ return xchg(&v->counter, new);
++}
++
++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new)
++{
++ return xchg(&(v->counter), new);
++}
+
+ /**
+ * atomic64_add_unless - add unless the number is a given value
+@@ -648,6 +805,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_dec_return(v) atomic64_sub_return(1, (v))
+ #define atomic64_inc_return(v) atomic64_add_return(1, (v))
++#define atomic64_inc_return_unchecked(v) atomic64_add_return_unchecked(1, (v))
+
+ /*
+ * atomic64_sub_and_test - subtract value from variable and test result
+@@ -669,6 +827,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * other cases.
+ */
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
++#define atomic64_inc_and_test_unchecked(v) atomic64_add_return_unchecked(1, (v)) == 0)
+
+ /*
+ * atomic64_dec_and_test - decrement by 1 and test
+@@ -693,6 +852,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * Atomically increments @v by 1.
+ */
+ #define atomic64_inc(v) atomic64_add(1, (v))
++#define atomic64_inc_unchecked(v) atomic64_add_unchecked(1, (v))
+
+ /*
+ * atomic64_dec - decrement and test
+@@ -701,6 +861,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * Atomically decrements @v by 1.
+ */
+ #define atomic64_dec(v) atomic64_sub(1, (v))
++#define atomic64_dec_unchecked(v) atomic64_sub_unchecked(1, (v))
+
+ /*
+ * atomic64_add_negative - add and test if negative
+diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
+index b4db69f..8f3b093 100644
+--- a/arch/mips/include/asm/cache.h
++++ b/arch/mips/include/asm/cache.h
+@@ -9,10 +9,11 @@
+ #ifndef _ASM_CACHE_H
+ #define _ASM_CACHE_H
+
++#include <linux/const.h>
+ #include <kmalloc.h>
+
+ #define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT
+-#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #define SMP_CACHE_SHIFT L1_CACHE_SHIFT
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
+index 2b3dc29..1f7bdc4 100644
+--- a/arch/mips/include/asm/elf.h
++++ b/arch/mips/include/asm/elf.h
+@@ -458,6 +458,13 @@ extern const char *__elf_platform;
+ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
+ #endif
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
+ #define ARCH_DLINFO \
+ do { \
+diff --git a/arch/mips/include/asm/exec.h b/arch/mips/include/asm/exec.h
+index c1f6afa..38cc6e9 100644
+--- a/arch/mips/include/asm/exec.h
++++ b/arch/mips/include/asm/exec.h
+@@ -12,6 +12,6 @@
+ #ifndef _ASM_EXEC_H
+ #define _ASM_EXEC_H
+
+-extern unsigned long arch_align_stack(unsigned long sp);
++#define arch_align_stack(x) ((x) & ~0xfUL)
+
+ #endif /* _ASM_EXEC_H */
+diff --git a/arch/mips/include/asm/hw_irq.h b/arch/mips/include/asm/hw_irq.h
+index 9e8ef59..1139d6b 100644
+--- a/arch/mips/include/asm/hw_irq.h
++++ b/arch/mips/include/asm/hw_irq.h
+@@ -10,7 +10,7 @@
+
+ #include <linux/atomic.h>
+
+-extern atomic_t irq_err_count;
++extern atomic_unchecked_t irq_err_count;
+
+ /*
+ * interrupt-retrigger: NOP for now. This may not be appropriate for all
+diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
+index 6bf10e7..3c0b52f 100644
+--- a/arch/mips/include/asm/irq.h
++++ b/arch/mips/include/asm/irq.h
+@@ -11,7 +11,6 @@
+
+ #include <linux/linkage.h>
+ #include <linux/smp.h>
+-#include <linux/irqdomain.h>
+
+ #include <asm/mipsmtregs.h>
+
+diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
+index 8feaed6..1bd8a64 100644
+--- a/arch/mips/include/asm/local.h
++++ b/arch/mips/include/asm/local.h
+@@ -13,15 +13,25 @@ typedef struct
+ atomic_long_t a;
+ } local_t;
+
++typedef struct {
++ atomic_long_unchecked_t a;
++} local_unchecked_t;
++
+ #define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+
+ #define local_read(l) atomic_long_read(&(l)->a)
++#define local_read_unchecked(l) atomic_long_read_unchecked(&(l)->a)
+ #define local_set(l, i) atomic_long_set(&(l)->a, (i))
++#define local_set_unchecked(l, i) atomic_long_set_unchecked(&(l)->a, (i))
+
+ #define local_add(i, l) atomic_long_add((i), (&(l)->a))
++#define local_add_unchecked(i, l) atomic_long_add_unchecked((i), (&(l)->a))
+ #define local_sub(i, l) atomic_long_sub((i), (&(l)->a))
++#define local_sub_unchecked(i, l) atomic_long_sub_unchecked((i), (&(l)->a))
+ #define local_inc(l) atomic_long_inc(&(l)->a)
++#define local_inc_unchecked(l) atomic_long_inc_unchecked(&(l)->a)
+ #define local_dec(l) atomic_long_dec(&(l)->a)
++#define local_dec_unchecked(l) atomic_long_dec_unchecked(&(l)->a)
+
+ /*
+ * Same as above, but return the result value
+@@ -71,6 +81,51 @@ static __inline__ long local_add_return(long i, local_t * l)
+ return result;
+ }
+
++static __inline__ long local_add_return_unchecked(long i, local_unchecked_t * l)
++{
++ unsigned long result;
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ unsigned long temp;
++
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1:" __LL "%1, %2 # local_add_return \n"
++ " addu %0, %1, %3 \n"
++ __SC "%0, %2 \n"
++ " beqzl %0, 1b \n"
++ " addu %0, %1, %3 \n"
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++ : "Ir" (i), "m" (l->a.counter)
++ : "memory");
++ } else if (kernel_uses_llsc) {
++ unsigned long temp;
++
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1:" __LL "%1, %2 # local_add_return \n"
++ " addu %0, %1, %3 \n"
++ __SC "%0, %2 \n"
++ " beqz %0, 1b \n"
++ " addu %0, %1, %3 \n"
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
++ : "Ir" (i), "m" (l->a.counter)
++ : "memory");
++ } else {
++ unsigned long flags;
++
++ local_irq_save(flags);
++ result = l->a.counter;
++ result += i;
++ l->a.counter = result;
++ local_irq_restore(flags);
++ }
++
++ return result;
++}
++
+ static __inline__ long local_sub_return(long i, local_t * l)
+ {
+ unsigned long result;
+@@ -118,6 +173,8 @@ static __inline__ long local_sub_return(long i, local_t * l)
+
+ #define local_cmpxchg(l, o, n) \
+ ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
++#define local_cmpxchg_unchecked(l, o, n) \
++ ((long)cmpxchg_local(&((l)->a.counter), (o), (n)))
+ #define local_xchg(l, n) (atomic_long_xchg((&(l)->a), (n)))
+
+ /**
+diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
+index 5f98759..a3a7cb2 100644
+--- a/arch/mips/include/asm/page.h
++++ b/arch/mips/include/asm/page.h
+@@ -118,7 +118,7 @@ extern void copy_user_highpage(struct page *to, struct page *from,
+ #ifdef CONFIG_CPU_MIPS32
+ typedef struct { unsigned long pte_low, pte_high; } pte_t;
+ #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
+- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
+ #else
+ typedef struct { unsigned long long pte; } pte_t;
+ #define pte_val(x) ((x).pte)
+diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h
+index a03e869..e1928f5 100644
+--- a/arch/mips/include/asm/pgalloc.h
++++ b/arch/mips/include/asm/pgalloc.h
+@@ -37,6 +37,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
+ {
+ set_pud(pud, __pud((unsigned long)pmd));
+ }
++
++static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
++{
++ pud_populate(mm, pud, pmd);
++}
+ #endif
+
+ /*
+diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
+index 9e9e94415..43354f5 100644
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -20,6 +20,9 @@
+ #include <asm/io.h>
+ #include <asm/pgtable-bits.h>
+
++#define ktla_ktva(addr) (addr)
++#define ktva_ktla(addr) (addr)
++
+ struct mm_struct;
+ struct vm_area_struct;
+
+diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
+index e309d8f..20eefec 100644
+--- a/arch/mips/include/asm/thread_info.h
++++ b/arch/mips/include/asm/thread_info.h
+@@ -101,6 +101,9 @@ static inline struct thread_info *current_thread_info(void)
+ #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
+ #define TIF_UPROBE 6 /* breakpointed or singlestepping */
+ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
++/* li takes a 32bit immediate */
++#define TIF_GRSEC_SETXID 10 /* update credentials on syscall entry/exit */
++
+ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
+ #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+ #define TIF_NOHZ 19 /* in adaptive nohz mode */
+@@ -137,14 +140,16 @@ static inline struct thread_info *current_thread_info(void)
+ #define _TIF_USEDMSA (1<<TIF_USEDMSA)
+ #define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE)
+ #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT)
++#define _TIF_GRSEC_SETXID (1<<TIF_GRSEC_SETXID)
+
+ #define _TIF_WORK_SYSCALL_ENTRY (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \
+ _TIF_SYSCALL_AUDIT | \
+- _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
++ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
++ _TIF_GRSEC_SETXID)
+
+ /* work to do in syscall_trace_leave() */
+ #define _TIF_WORK_SYSCALL_EXIT (_TIF_NOHZ | _TIF_SYSCALL_TRACE | \
+- _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)
++ _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT | _TIF_GRSEC_SETXID)
+
+ /* work to do on interrupt/exception return */
+ #define _TIF_WORK_MASK \
+@@ -153,7 +158,7 @@ static inline struct thread_info *current_thread_info(void)
+ /* work to do on any return to u-space */
+ #define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
+ _TIF_WORK_SYSCALL_EXIT | \
+- _TIF_SYSCALL_TRACEPOINT)
++ _TIF_SYSCALL_TRACEPOINT | _TIF_GRSEC_SETXID)
+
+ /*
+ * We stash processor id into a COP0 register to retrieve it fast
+diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
+index 89fa5c0b..9409cea 100644
+--- a/arch/mips/include/asm/uaccess.h
++++ b/arch/mips/include/asm/uaccess.h
+@@ -148,6 +148,7 @@ static inline bool eva_kernel_access(void)
+ __ok == 0; \
+ })
+
++#define access_ok_noprefault(type, addr, size) access_ok((type), (addr), (size))
+ #define access_ok(type, addr, size) \
+ likely(__access_ok((addr), (size), __access_mask))
+
+diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
+index 9c7f3e1..ed42bda 100644
+--- a/arch/mips/kernel/binfmt_elfn32.c
++++ b/arch/mips/kernel/binfmt_elfn32.c
+@@ -37,6 +37,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #undef ELF_ET_DYN_BASE
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #include <asm/processor.h>
+ #include <linux/elfcore.h>
+ #include <linux/compat.h>
+diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
+index 1ab3432..0e66879 100644
+--- a/arch/mips/kernel/binfmt_elfo32.c
++++ b/arch/mips/kernel/binfmt_elfo32.c
+@@ -41,6 +41,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+ #undef ELF_ET_DYN_BASE
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE (TASK_IS_32BIT_ADDR ? 0x00400000UL : 0x00400000UL)
++
++#define PAX_DELTA_MMAP_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#define PAX_DELTA_STACK_LEN (TASK_IS_32BIT_ADDR ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
++#endif
++
+ #include <asm/processor.h>
+
+ #include <linux/elfcore.h>
+diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
+index 44a1f79..2bd6aa3 100644
+--- a/arch/mips/kernel/irq-gt641xx.c
++++ b/arch/mips/kernel/irq-gt641xx.c
+@@ -110,7 +110,7 @@ void gt641xx_irq_dispatch(void)
+ }
+ }
+
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ }
+
+ void __init gt641xx_irq_init(void)
+diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
+index f25f7ea..19e1c62 100644
+--- a/arch/mips/kernel/irq.c
++++ b/arch/mips/kernel/irq.c
+@@ -34,17 +34,17 @@ void ack_bad_irq(unsigned int irq)
+ printk("unexpected IRQ # %d\n", irq);
+ }
+
+-atomic_t irq_err_count;
++atomic_unchecked_t irq_err_count;
+
+ int arch_show_interrupts(struct seq_file *p, int prec)
+ {
+- seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
++ seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read_unchecked(&irq_err_count));
+ return 0;
+ }
+
+ asmlinkage void spurious_interrupt(void)
+ {
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ }
+
+ void __init init_IRQ(void)
+@@ -61,6 +61,8 @@ void __init init_IRQ(void)
+ }
+
+ #ifdef CONFIG_DEBUG_STACKOVERFLOW
++
++extern void gr_handle_kernel_exploit(void);
+ static inline void check_stack_overflow(void)
+ {
+ unsigned long sp;
+@@ -76,6 +78,7 @@ static inline void check_stack_overflow(void)
+ printk("do_IRQ: stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
++ gr_handle_kernel_exploit();
+ }
+ }
+ #else
+diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
+index f5c8bce..b06a560 100644
+--- a/arch/mips/kernel/kprobes.c
++++ b/arch/mips/kernel/kprobes.c
+@@ -535,6 +535,7 @@ static void __used kretprobe_trampoline_holder(void)
+
+ void kretprobe_trampoline(void);
+
++#ifdef CONFIG_KRETPROBES
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+ {
+@@ -543,6 +544,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ /* Replace the return addr with trampoline addr */
+ regs->regs[31] = (unsigned long)kretprobe_trampoline;
+ }
++#endif
+
+ /*
+ * Called when the probe at kretprobe trampoline is hit
+@@ -611,6 +613,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
+ return 1;
+ }
+
++#ifdef CONFIG_KRETPROBES
+ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+ {
+ if (p->addr == (kprobe_opcode_t *)kretprobe_trampoline)
+@@ -618,6 +621,7 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+
+ return 0;
+ }
++#endif
+
+ static struct kprobe trampoline_p = {
+ .addr = (kprobe_opcode_t *)kretprobe_trampoline,
+diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c
+index 7cf653e..7df52f6 100644
+--- a/arch/mips/kernel/pm-cps.c
++++ b/arch/mips/kernel/pm-cps.c
+@@ -168,7 +168,7 @@ int cps_pm_enter_state(enum cps_pm_state state)
+ nc_core_ready_count = nc_addr;
+
+ /* Ensure ready_count is zero-initialised before the assembly runs */
+- ACCESS_ONCE(*nc_core_ready_count) = 0;
++ ACCESS_ONCE_RW(*nc_core_ready_count) = 0;
+ coupled_barrier(&per_cpu(pm_barrier, core), online);
+
+ /* Run the generated entry code */
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index 1652f36..0e22377 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -590,18 +590,6 @@ unsigned long get_wchan(struct task_struct *task)
+ return pc;
+ }
+
+-/*
+- * Don't forget that the stack pointer must be aligned on a 8 bytes
+- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
+- */
+-unsigned long arch_align_stack(unsigned long sp)
+-{
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+- sp -= get_random_int() & ~PAGE_MASK;
+-
+- return sp & ALMASK;
+-}
+-
+ static void arch_dump_stack(void *info)
+ {
+ struct pt_regs *regs;
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+index a92994d..e389b11 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -882,6 +882,10 @@ long arch_ptrace(struct task_struct *child, long request,
+ return ret;
+ }
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++extern void gr_delayed_cred_worker(void);
++#endif
++
+ /*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+@@ -899,6 +903,11 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
+ if (secure_computing(NULL) == -1)
+ return -1;
+
++#ifdef CONFIG_GRKERNSEC_SETXID
++ if (unlikely(test_and_clear_thread_flag(TIF_GRSEC_SETXID)))
++ gr_delayed_cred_worker();
++#endif
++
+ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+ trace_sys_enter(regs, regs->regs[2]);
+
+diff --git a/arch/mips/kernel/sync-r4k.c b/arch/mips/kernel/sync-r4k.c
+index 4472a7f..c5905e6 100644
+--- a/arch/mips/kernel/sync-r4k.c
++++ b/arch/mips/kernel/sync-r4k.c
+@@ -18,8 +18,8 @@
+ #include <asm/mipsregs.h>
+
+ static unsigned int initcount = 0;
+-static atomic_t count_count_start = ATOMIC_INIT(0);
+-static atomic_t count_count_stop = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_start = ATOMIC_INIT(0);
++static atomic_unchecked_t count_count_stop = ATOMIC_INIT(0);
+
+ #define COUNTON 100
+ #define NR_LOOPS 3
+@@ -46,13 +46,13 @@ void synchronise_count_master(int cpu)
+
+ for (i = 0; i < NR_LOOPS; i++) {
+ /* slaves loop on '!= 2' */
+- while (atomic_read(&count_count_start) != 1)
++ while (atomic_read_unchecked(&count_count_start) != 1)
+ mb();
+- atomic_set(&count_count_stop, 0);
++ atomic_set_unchecked(&count_count_stop, 0);
+ smp_wmb();
+
+ /* Let the slave writes its count register */
+- atomic_inc(&count_count_start);
++ atomic_inc_unchecked(&count_count_start);
+
+ /* Count will be initialised to current timer */
+ if (i == 1)
+@@ -67,11 +67,11 @@ void synchronise_count_master(int cpu)
+ /*
+ * Wait for slave to leave the synchronization point:
+ */
+- while (atomic_read(&count_count_stop) != 1)
++ while (atomic_read_unchecked(&count_count_stop) != 1)
+ mb();
+- atomic_set(&count_count_start, 0);
++ atomic_set_unchecked(&count_count_start, 0);
+ smp_wmb();
+- atomic_inc(&count_count_stop);
++ atomic_inc_unchecked(&count_count_stop);
+ }
+ /* Arrange for an interrupt in a short while */
+ write_c0_compare(read_c0_count() + COUNTON);
+@@ -96,8 +96,8 @@ void synchronise_count_slave(int cpu)
+ */
+
+ for (i = 0; i < NR_LOOPS; i++) {
+- atomic_inc(&count_count_start);
+- while (atomic_read(&count_count_start) != 2)
++ atomic_inc_unchecked(&count_count_start);
++ while (atomic_read_unchecked(&count_count_start) != 2)
+ mb();
+
+ /*
+@@ -106,8 +106,8 @@ void synchronise_count_slave(int cpu)
+ if (i == NR_LOOPS-1)
+ write_c0_count(initcount);
+
+- atomic_inc(&count_count_stop);
+- while (atomic_read(&count_count_stop) != 2)
++ atomic_inc_unchecked(&count_count_stop);
++ while (atomic_read_unchecked(&count_count_stop) != 2)
+ mb();
+ }
+ /* Arrange for an interrupt in a short while */
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index 3905003..7c0cc88 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -702,7 +702,18 @@ asmlinkage void do_ov(struct pt_regs *regs)
+ };
+
+ prev_state = exception_enter();
+- die_if_kernel("Integer overflow", regs);
++ if (unlikely(!user_mode(regs))) {
++
++#ifdef CONFIG_PAX_REFCOUNT
++ if (fixup_exception(regs)) {
++ pax_report_refcount_error(regs, NULL);
++ exception_exit(prev_state);
++ return;
++ }
++#endif
++
++ die("Integer overflow", regs);
++ }
+
+ force_sig_info(SIGFPE, &info, current);
+ exception_exit(prev_state);
+diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c
+index c3e2205..b4302f8 100644
+--- a/arch/mips/lib/ashldi3.c
++++ b/arch/mips/lib/ashldi3.c
+@@ -2,7 +2,11 @@
+
+ #include "libgcc.h"
+
+-long long notrace __ashldi3(long long u, word_type b)
++#ifdef CONFIG_64BIT
++DWtype notrace __ashlti3(DWtype u, word_type b)
++#else
++DWtype notrace __ashldi3(DWtype u, word_type b)
++#endif
+ {
+ DWunion uu, w;
+ word_type bm;
+@@ -11,19 +15,22 @@ long long notrace __ashldi3(long long u, word_type b)
+ return u;
+
+ uu.ll = u;
+- bm = 32 - b;
++ bm = BITS_PER_LONG - b;
+
+ if (bm <= 0) {
+ w.s.low = 0;
+- w.s.high = (unsigned int) uu.s.low << -bm;
++ w.s.high = (unsigned long) uu.s.low << -bm;
+ } else {
+- const unsigned int carries = (unsigned int) uu.s.low >> bm;
++ const unsigned long carries = (unsigned long) uu.s.low >> bm;
+
+- w.s.low = (unsigned int) uu.s.low << b;
+- w.s.high = ((unsigned int) uu.s.high << b) | carries;
++ w.s.low = (unsigned long) uu.s.low << b;
++ w.s.high = ((unsigned long) uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+ }
+-
++#ifdef CONFIG_64BIT
++EXPORT_SYMBOL(__ashlti3);
++#else
+ EXPORT_SYMBOL(__ashldi3);
++#endif
+diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c
+index 1745602..d20aabf 100644
+--- a/arch/mips/lib/ashrdi3.c
++++ b/arch/mips/lib/ashrdi3.c
+@@ -2,7 +2,11 @@
+
+ #include "libgcc.h"
+
+-long long notrace __ashrdi3(long long u, word_type b)
++#ifdef CONFIG_64BIT
++DWtype notrace __ashrti3(DWtype u, word_type b)
++#else
++DWtype notrace __ashrdi3(DWtype u, word_type b)
++#endif
+ {
+ DWunion uu, w;
+ word_type bm;
+@@ -11,21 +15,24 @@ long long notrace __ashrdi3(long long u, word_type b)
+ return u;
+
+ uu.ll = u;
+- bm = 32 - b;
++ bm = BITS_PER_LONG - b;
+
+ if (bm <= 0) {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high =
+- uu.s.high >> 31;
++ uu.s.high >> (BITS_PER_LONG - 1);
+ w.s.low = uu.s.high >> -bm;
+ } else {
+- const unsigned int carries = (unsigned int) uu.s.high << bm;
++ const unsigned long carries = (unsigned long) uu.s.high << bm;
+
+ w.s.high = uu.s.high >> b;
+- w.s.low = ((unsigned int) uu.s.low >> b) | carries;
++ w.s.low = ((unsigned long) uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+ }
+-
++#ifdef CONFIG_64BIT
++EXPORT_SYMBOL(__ashrti3);
++#else
+ EXPORT_SYMBOL(__ashrdi3);
++#endif
+diff --git a/arch/mips/lib/libgcc.h b/arch/mips/lib/libgcc.h
+index 05909d58..b03284b 100644
+--- a/arch/mips/lib/libgcc.h
++++ b/arch/mips/lib/libgcc.h
+@@ -5,13 +5,19 @@
+
+ typedef int word_type __attribute__ ((mode (__word__)));
+
++#ifdef CONFIG_64BIT
++typedef int DWtype __attribute__((mode(TI)));
++#else
++typedef long long DWtype;
++#endif
++
+ #ifdef __BIG_ENDIAN
+ struct DWstruct {
+- int high, low;
++ long high, low;
+ };
+ #elif defined(__LITTLE_ENDIAN)
+ struct DWstruct {
+- int low, high;
++ long low, high;
+ };
+ #else
+ #error I feel sick.
+@@ -19,7 +25,7 @@ struct DWstruct {
+
+ typedef union {
+ struct DWstruct s;
+- long long ll;
++ DWtype ll;
+ } DWunion;
+
+ #endif /* __ASM_LIBGCC_H */
+diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
+index 3bef306..fcec133 100644
+--- a/arch/mips/mm/fault.c
++++ b/arch/mips/mm/fault.c
+@@ -30,6 +30,23 @@
+
+ int show_unhandled_signals = 1;
+
++#ifdef CONFIG_PAX_PAGEEXEC
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ unsigned long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 5; i++) {
++ unsigned int c;
++ if (get_user(c, (unsigned int *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08x ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ /*
+ * This routine handles page faults. It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+@@ -204,6 +221,14 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
+ bad_area_nosemaphore:
+ /* User mode accesses just cause a SIGSEGV */
+ if (user_mode(regs)) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if (cpu_has_rixi && (mm->pax_flags & MF_PAX_PAGEEXEC) && !write && address == instruction_pointer(regs)) {
++ pax_report_fault(regs, (void *)address, (void *)user_stack_pointer(regs));
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ tsk->thread.cp0_badvaddr = address;
+ tsk->thread.error_code = write;
+ if (show_unhandled_signals &&
+diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
+index e86ebcf..7a78a07 100644
+--- a/arch/mips/mm/init.c
++++ b/arch/mips/mm/init.c
+@@ -474,10 +474,10 @@ void __init mem_init(void)
+
+ #ifdef CONFIG_64BIT
+ if ((unsigned long) &_text > (unsigned long) CKSEG0)
+- /* The -4 is a hack so that user tools don't have to handle
++ /* The -0x2000-4 is a hack so that user tools don't have to handle
+ the overflow. */
+ kclist_add(&kcore_kseg0, (void *) CKSEG0,
+- 0x80000000 - 4, KCORE_TEXT);
++ 0x80000000 - 0x2000 - 4, KCORE_TEXT);
+ #endif
+ }
+ #endif /* !CONFIG_NEED_MULTIPLE_NODES */
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index d08ea3f..66bb13d 100644
+--- a/arch/mips/mm/mmap.c
++++ b/arch/mips/mm/mmap.c
+@@ -59,6 +59,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+ struct vm_area_struct *vma;
+ unsigned long addr = addr0;
+ int do_color_align;
++ unsigned long offset = gr_rand_threadstack_offset(mm, filp, flags);
+ struct vm_unmapped_area_info info;
+
+ if (unlikely(len > TASK_SIZE))
+@@ -84,6 +85,11 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+ do_color_align = 1;
+
+ /* requesting a specific address */
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+@@ -91,14 +97,14 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+- if (TASK_SIZE - len >= addr &&
+- (!vma || addr + len <= vma->vm_start))
++ if (TASK_SIZE - len >= addr && check_heap_stack_gap(vma, addr, len, offset))
+ return addr;
+ }
+
+ info.length = len;
+ info.align_mask = do_color_align ? (PAGE_MASK & shm_align_mask) : 0;
+ info.align_offset = pgoff << PAGE_SHIFT;
++ info.threadstack_offset = offset;
+
+ if (dir == DOWN) {
+ info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+@@ -160,14 +166,30 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
+ unsigned long random_factor = 0UL;
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = arch_mmap_rnd();
+
+ if (mmap_is_legacy()) {
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ mm->mmap_base += mm->delta_mmap;
++#endif
++
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ } else {
+ mm->mmap_base = mmap_base(random_factor);
++
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP)
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++#endif
++
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ }
+ }
+diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
+index cfceaea..65deeb4 100644
+--- a/arch/mips/sgi-ip27/ip27-nmi.c
++++ b/arch/mips/sgi-ip27/ip27-nmi.c
+@@ -187,9 +187,9 @@ void
+ cont_nmi_dump(void)
+ {
+ #ifndef REAL_NMI_SIGNAL
+- static atomic_t nmied_cpus = ATOMIC_INIT(0);
++ static atomic_unchecked_t nmied_cpus = ATOMIC_INIT(0);
+
+- atomic_inc(&nmied_cpus);
++ atomic_inc_unchecked(&nmied_cpus);
+ #endif
+ /*
+ * Only allow 1 cpu to proceed
+@@ -233,7 +233,7 @@ cont_nmi_dump(void)
+ udelay(10000);
+ }
+ #else
+- while (atomic_read(&nmied_cpus) != num_online_cpus());
++ while (atomic_read_unchecked(&nmied_cpus) != num_online_cpus());
+ #endif
+
+ /*
+diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
+index 160b880..3b53fdc 100644
+--- a/arch/mips/sni/rm200.c
++++ b/arch/mips/sni/rm200.c
+@@ -270,7 +270,7 @@ void sni_rm200_mask_and_ack_8259A(struct irq_data *d)
+ "spurious RM200 8259A interrupt: IRQ%d.\n", irq);
+ spurious_irq_mask |= irqmask;
+ }
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ /*
+ * Theoretically we do not have to handle this IRQ,
+ * but in Linux this does not cause problems and is
+diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
+index 41e873b..34d33a7 100644
+--- a/arch/mips/vr41xx/common/icu.c
++++ b/arch/mips/vr41xx/common/icu.c
+@@ -653,7 +653,7 @@ static int icu_get_irq(unsigned int irq)
+
+ printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2);
+
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+
+ return -1;
+ }
+diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
+index ae0e4ee..e8f0692 100644
+--- a/arch/mips/vr41xx/common/irq.c
++++ b/arch/mips/vr41xx/common/irq.c
+@@ -64,7 +64,7 @@ static void irq_dispatch(unsigned int irq)
+ irq_cascade_t *cascade;
+
+ if (irq >= NR_IRQS) {
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ return;
+ }
+
+@@ -84,7 +84,7 @@ static void irq_dispatch(unsigned int irq)
+ ret = cascade->get_irq(irq);
+ irq = ret;
+ if (ret < 0)
+- atomic_inc(&irq_err_count);
++ atomic_inc_unchecked(&irq_err_count);
+ else
+ irq_dispatch(irq);
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
+diff --git a/arch/mn10300/proc-mn103e010/include/proc/cache.h b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+index 967d144..db12197 100644
+--- a/arch/mn10300/proc-mn103e010/include/proc/cache.h
++++ b/arch/mn10300/proc-mn103e010/include/proc/cache.h
+@@ -11,12 +11,14 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+
++#include <linux/const.h>
++
+ /* L1 cache */
+
+ #define L1_CACHE_NWAYS 4 /* number of ways in caches */
+ #define L1_CACHE_NENTRIES 256 /* number of entries in each way */
+-#define L1_CACHE_BYTES 16 /* bytes per entry */
+ #define L1_CACHE_SHIFT 4 /* shift for bytes per entry */
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT) /* bytes per entry */
+ #define L1_CACHE_WAYDISP 0x1000 /* displacement of one way from the next */
+
+ #define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
+diff --git a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+index bcb5df2..84fabd2 100644
+--- a/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
++++ b/arch/mn10300/proc-mn2ws0050/include/proc/cache.h
+@@ -16,13 +16,15 @@
+ #ifndef _ASM_PROC_CACHE_H
+ #define _ASM_PROC_CACHE_H
+
++#include <linux/const.h>
++
+ /*
+ * L1 cache
+ */
+ #define L1_CACHE_NWAYS 4 /* number of ways in caches */
+ #define L1_CACHE_NENTRIES 128 /* number of entries in each way */
+-#define L1_CACHE_BYTES 32 /* bytes per entry */
+ #define L1_CACHE_SHIFT 5 /* shift for bytes per entry */
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT) /* bytes per entry */
+ #define L1_CACHE_WAYDISP 0x1000 /* distance from one way to the next */
+
+ #define L1_CACHE_TAG_VALID 0x00000001 /* cache tag valid bit */
+diff --git a/arch/openrisc/include/asm/cache.h b/arch/openrisc/include/asm/cache.h
+index 5f55da9..7ce9437 100644
+--- a/arch/openrisc/include/asm/cache.h
++++ b/arch/openrisc/include/asm/cache.h
+@@ -19,13 +19,15 @@
+ #ifndef __ASM_OPENRISC_CACHE_H
+ #define __ASM_OPENRISC_CACHE_H
+
++#include <linux/const.h>
++
+ /* FIXME: How can we replace these with values from the CPU...
+ * they shouldn't be hard-coded!
+ */
+
+ #define __ro_after_init __read_mostly
+
+-#define L1_CACHE_BYTES 16
+ #define L1_CACHE_SHIFT 4
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
+
+ #endif /* __ASM_OPENRISC_CACHE_H */
+diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
+index 5394b9c..e77a306 100644
+--- a/arch/parisc/include/asm/atomic.h
++++ b/arch/parisc/include/asm/atomic.h
+@@ -327,6 +327,16 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
+ return dec;
+ }
+
++#define atomic64_read_unchecked(v) atomic64_read(v)
++#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
++#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
++#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
++#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
++#define atomic64_inc_unchecked(v) atomic64_inc(v)
++#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
++#define atomic64_dec_unchecked(v) atomic64_dec(v)
++#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
++
+ #endif /* !CONFIG_64BIT */
+
+
+diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
+index df0f52b..810699b 100644
+--- a/arch/parisc/include/asm/cache.h
++++ b/arch/parisc/include/asm/cache.h
+@@ -5,6 +5,7 @@
+ #ifndef __ARCH_PARISC_CACHE_H
+ #define __ARCH_PARISC_CACHE_H
+
++#include <linux/const.h>
+
+ /*
+ * PA 2.0 processors have 64 and 128-byte L2 cachelines; PA 1.1 processors
+@@ -14,6 +15,8 @@
+ #define L1_CACHE_BYTES 16
+ #define L1_CACHE_SHIFT 4
+
++#define L1_CACHE_BYTES (_AC(1,UL) << L1_CACHE_SHIFT)
++
+ #ifndef __ASSEMBLY__
+
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
+index 78c9fd3..42fa66a 100644
+--- a/arch/parisc/include/asm/elf.h
++++ b/arch/parisc/include/asm/elf.h
+@@ -342,6 +342,13 @@ struct pt_regs; /* forward declaration... */
+
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
+
++#ifdef CONFIG_PAX_ASLR
++#define PAX_ELF_ET_DYN_BASE 0x10000UL
++
++#define PAX_DELTA_MMAP_LEN 16
++#define PAX_DELTA_STACK_LEN 16
++#endif
++
+ /* This yields a mask that user programs can use to figure out what
+ instruction set this CPU supports. This could be done in user space,
+ but it's not easy, and we've already done it here. */
+diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
+index f08dda3..ea6aa1b 100644
+--- a/arch/parisc/include/asm/pgalloc.h
++++ b/arch/parisc/include/asm/pgalloc.h
+@@ -61,6 +61,11 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+ (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT));
+ }
+
++static inline void pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
++{
++ pgd_populate(mm, pgd, pmd);
++}
++
+ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+ {
+ pmd_t *pmd = (pmd_t *)__get_free_pages(GFP_KERNEL, PMD_ORDER);
+@@ -96,6 +101,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+ #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
+ #define pmd_free(mm, x) do { } while (0)
+ #define pgd_populate(mm, pmd, pte) BUG()
++#define pgd_populate_kernel(mm, pmd, pte) BUG()
+
+ #endif
+
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index 3a4ed9f..29b7218 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -236,6 +236,17 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
+ #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
+ #define PAGE_COPY PAGE_EXECREAD
+ #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
++
++#ifdef CONFIG_PAX_PAGEEXEC
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
++#else
++# define PAGE_SHARED_NOEXEC PAGE_SHARED
++# define PAGE_COPY_NOEXEC PAGE_COPY
++# define PAGE_READONLY_NOEXEC PAGE_READONLY
++#endif
++
+ #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
+ #define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
+ #define PAGE_KERNEL_RWX __pgprot(_PAGE_KERNEL_RWX)
+diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h
+index 9a2aee1..a8e588f 100644
+--- a/arch/parisc/include/asm/uaccess.h
++++ b/arch/parisc/include/asm/uaccess.h
+@@ -223,10 +223,10 @@ static inline void copy_user_overflow(int size, unsigned long count)
+ static __always_inline unsigned long __must_check
+ copy_from_user(void *to, const void __user *from, unsigned long n)
+ {
+- int sz = __compiletime_object_size(to);
++ size_t sz = __compiletime_object_size(to);
+ unsigned long ret = n;
+
+- if (likely(sz < 0 || sz >= n)) {
++ if (likely(sz == (size_t)-1 || sz >= n)) {
+ check_object_size(to, n, false);
+ ret = __copy_from_user(to, from, n);
+ } else if (!__builtin_constant_p(n))
+@@ -234,7 +234,7 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
+ else
+ __bad_copy_user();
+
+- if (unlikely(ret))
++ if (unlikely(ret && (long)ret > 0))
+ memset(to + (n - ret), 0, ret);
+
+ return ret;
+@@ -243,9 +243,9 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
+ static __always_inline unsigned long __must_check
+ copy_to_user(void __user *to, const void *from, unsigned long n)
+ {
+- int sz = __compiletime_object_size(from);
++ size_t sz = __compiletime_object_size(to);
+
+- if (likely(sz < 0 || sz >= n)) {
++ if (likely(sz == (size_t)-1 || sz >= n)) {
+ check_object_size(from, n, true);
+ n = __copy_to_user(to, from, n);
+ } else if (!__builtin_constant_p(n))
+diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
+index a0ecdb4a..71d2069 100644
+--- a/arch/parisc/kernel/module.c
++++ b/arch/parisc/kernel/module.c
+@@ -100,14 +100,12 @@
+ * or init pieces the location is */
+ static inline int in_init(struct module *me, void *loc)
+ {
+- return (loc >= me->init_layout.base &&
+- loc <= (me->init_layout.base + me->init_layout.size));
++ within_module_init((unsigned long)loc, me);
+ }
+
+ static inline int in_core(struct module *me, void *loc)
+ {
+- return (loc >= me->core_layout.base &&
+- loc <= (me->core_layout.base + me->core_layout.size));
++ within_module_core((unsigned long)loc, me);
+ }
+
+ static inline int in_local(struct module *me, void *loc)
+@@ -367,13 +365,13 @@ int module_frob_arch_sections(CONST Elf_Ehdr *hdr,
+ }
+
+ /* align things a bit */
+- me->core_layout.size = ALIGN(me->core_layout.size, 16);
+- me->arch.got_offset = me->core_layout.size;
+- me->core_layout.size += gots * sizeof(struct got_entry);
++ me->core_layout.size_rw = ALIGN(me->core_layout.size_rw, 16);
++ me->arch.got_offset = me->core_layout.size_rw;
++ me->core_layout.size_rw += gots * sizeof(struct got_entry);
+
+- me->core_layout.size = ALIGN(me->core_layout.size, 16);
+- me->arch.fdesc_offset = me->core_layout.size;
+- me->core_layout.size += fdescs * sizeof(Elf_Fdesc);
++ me->core_layout.size_rw = ALIGN(me->core_layout.size_rw, 16);
++ me->arch.fdesc_offset = me->core_layout.size_rw;
++ me->core_layout.size_rw += fdescs * sizeof(Elf_Fdesc);
+
+ me->arch.got_max = gots;
+ me->arch.fdesc_max = fdescs;
+@@ -391,7 +389,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
+
+ BUG_ON(value == 0);
+
+- got = me->core_layout.base + me->arch.got_offset;
++ got = me->core_layout.base_rw + me->arch.got_offset;
+ for (i = 0; got[i].addr; i++)
+ if (got[i].addr == value)
+ goto out;
+@@ -409,7 +407,7 @@ static Elf64_Word get_got(struct module *me, unsigned long value, long addend)
+ #ifdef CONFIG_64BIT
+ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+ {
+- Elf_Fdesc *fdesc = me->core_layout.base + me->arch.fdesc_offset;
++ Elf_Fdesc *fdesc = me->core_layout.base_rw + me->arch.fdesc_offset;
+
+ if (!value) {
+ printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
+@@ -427,7 +425,7 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value)
+
+ /* Create new one */
+ fdesc->addr = value;
+- fdesc->gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
++ fdesc->gp = (Elf_Addr)me->core_layout.base_rw + me->arch.got_offset;
+ return (Elf_Addr)fdesc;
+ }
+ #endif /* CONFIG_64BIT */
+@@ -847,7 +845,7 @@ register_unwind_table(struct module *me,
+
+ table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
+ end = table + sechdrs[me->arch.unwind_section].sh_size;
+- gp = (Elf_Addr)me->core_layout.base + me->arch.got_offset;
++ gp = (Elf_Addr)me->core_layout.base_rw + me->arch.got_offset;
+
+ DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
+ me->arch.unwind_section, table, end, gp);
+diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
+index 0a393a0..5b3199e0 100644
+--- a/arch/parisc/kernel/sys_parisc.c
++++ b/arch/parisc/kernel/sys_parisc.c
+@@ -92,6 +92,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long task_size = TASK_SIZE;
+ int do_color_align, last_mmap;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ if (len > task_size)
+ return -ENOMEM;
+@@ -109,6 +110,10 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ goto found_addr;
+ }
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align && last_mmap)
+ addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+@@ -127,6 +132,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ info.high_limit = mmap_upper_limit();
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+ info.align_offset = shared_align_offset(last_mmap, pgoff);
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+
+ found_addr:
+@@ -146,6 +152,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ unsigned long addr = addr0;
+ int do_color_align, last_mmap;
+ struct vm_unmapped_area_info info;
++ unsigned long offset = gr_rand_threadstack_offset(current->mm, filp, flags);
+
+ #ifdef CONFIG_64BIT
+ /* This should only ever run for 32-bit processes. */
+@@ -170,6 +177,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ }
+
+ /* requesting a specific address */
++#ifdef CONFIG_PAX_RANDMMAP
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
++#endif
++
+ if (addr) {
+ if (do_color_align && last_mmap)
+ addr = COLOR_ALIGN(addr, last_mmap, pgoff);
+@@ -187,6 +198,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
+ info.high_limit = mm->mmap_base;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
+ info.align_offset = shared_align_offset(last_mmap, pgoff);
++ info.threadstack_offset = offset;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ goto found_addr;
+@@ -252,6 +264,13 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
+ mm->mmap_legacy_base = mmap_legacy_base();
+ mm->mmap_base = mmap_upper_limit();
+
++#ifdef CONFIG_PAX_RANDMMAP
++ if (mm->pax_flags & MF_PAX_RANDMMAP) {
++ mm->mmap_legacy_base += mm->delta_mmap;
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++ }
++#endif
++
+ if (mmap_is_legacy()) {
+ mm->mmap_base = mm->mmap_legacy_base;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
+index 378df92..9b2ab51 100644
+--- a/arch/parisc/kernel/traps.c
++++ b/arch/parisc/kernel/traps.c
+@@ -719,9 +719,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
+
+ down_read(&current->mm->mmap_sem);
+ vma = find_vma(current->mm,regs->iaoq[0]);
+- if (vma && (regs->iaoq[0] >= vma->vm_start)
+- && (vma->vm_flags & VM_EXEC)) {
+-
++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
+ fault_address = regs->iaoq[0];
+ fault_space = regs->iasq[0];
+
+diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
+index 1a0b4f6..f9d326d 100644
+--- a/arch/parisc/mm/fault.c
++++ b/arch/parisc/mm/fault.c
+@@ -16,6 +16,7 @@
+ #include <linux/interrupt.h>
+ #include <linux/extable.h>
+ #include <linux/uaccess.h>
++#include <linux/unistd.h>
+
+ #include <asm/traps.h>
+
+@@ -50,7 +51,7 @@ int show_unhandled_signals = 1;
+ static unsigned long
+ parisc_acctyp(unsigned long code, unsigned int inst)
+ {
+- if (code == 6 || code == 16)
++ if (code == 6 || code == 7 || code == 16)
+ return VM_EXEC;
+
+ switch (inst & 0xf0000000) {
+@@ -136,6 +137,116 @@ parisc_acctyp(unsigned long code, unsigned int inst)
+ }
+ #endif
+
++#ifdef CONFIG_PAX_PAGEEXEC
++/*
++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
++ *
++ * returns 1 when task should be killed
++ * 2 when rt_sigreturn trampoline was detected
++ * 3 when unpatched PLT trampoline was detected
++ */
++static int pax_handle_fetch_fault(struct pt_regs *regs)
++{
++
++#ifdef CONFIG_PAX_EMUPLT
++ int err;
++
++ do { /* PaX: unpatched PLT emulation */
++ unsigned int bl, depwi;
++
++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
++
++ if (err)
++ break;
++
++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
++
++ err = get_user(ldw, (unsigned int *)addr);
++ err |= get_user(bv, (unsigned int *)(addr+4));
++ err |= get_user(ldw2, (unsigned int *)(addr+8));
++
++ if (err)
++ break;
++
++ if (ldw == 0x0E801096U &&
++ bv == 0xEAC0C000U &&
++ ldw2 == 0x0E881095U)
++ {
++ unsigned int resolver, map;
++
++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
++ if (err)
++ break;
++
++ regs->gr[20] = instruction_pointer(regs)+8;
++ regs->gr[21] = map;
++ regs->gr[22] = resolver;
++ regs->iaoq[0] = resolver | 3UL;
++ regs->iaoq[1] = regs->iaoq[0] + 4;
++ return 3;
++ }
++ }
++ } while (0);
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++
++#ifndef CONFIG_PAX_EMUSIGRT
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
++ return 1;
++#endif
++
++ do { /* PaX: rt_sigreturn emulation */
++ unsigned int ldi1, ldi2, bel, nop;
++
++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
++
++ if (err)
++ break;
++
++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
++ ldi2 == 0x3414015AU &&
++ bel == 0xE4008200U &&
++ nop == 0x08000240U)
++ {
++ regs->gr[25] = (ldi1 & 2) >> 1;
++ regs->gr[20] = __NR_rt_sigreturn;
++ regs->gr[31] = regs->iaoq[1] + 16;
++ regs->sr[0] = regs->iasq[1];
++ regs->iaoq[0] = 0x100UL;
++ regs->iaoq[1] = regs->iaoq[0] + 4;
++ regs->iasq[0] = regs->sr[2];
++ regs->iasq[1] = regs->sr[2];
++ return 2;
++ }
++ } while (0);
++#endif
++
++ return 1;
++}
++
++void pax_report_insns(struct pt_regs *regs, void *pc, void *sp)
++{
++ unsigned long i;
++
++ printk(KERN_ERR "PAX: bytes at PC: ");
++ for (i = 0; i < 5; i++) {
++ unsigned int c;
++ if (get_user(c, (unsigned int *)pc+i))
++ printk(KERN_CONT "???????? ");
++ else
++ printk(KERN_CONT "%08x ", c);
++ }
++ printk("\n");
++}
++#endif
++
+ int fixup_exception(struct pt_regs *regs)
+ {
+ const struct exception_table_entry *fix;
+@@ -281,8 +392,33 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
+
+ good_area:
+
+- if ((vma->vm_flags & acc_type) != acc_type)
++ if ((vma->vm_flags & acc_type) != acc_type) {
++
++#ifdef CONFIG_PAX_PAGEEXEC
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
++ (address & ~3UL) == instruction_pointer(regs))
++ {
++ up_read(&mm->mmap_sem);
++ switch (pax_handle_fetch_fault(regs)) {
++
++#ifdef CONFIG_PAX_EMUPLT
++ case 3:
++ return;
++#endif
++
++#ifdef CONFIG_PAX_EMUTRAMP
++ case 2:
++ return;
++#endif
++
++ }
++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
++ do_group_exit(SIGKILL);
++ }
++#endif
++
+ goto bad_area;
++ }
+
+ /*
+ * If for any reason at all we couldn't handle the fault, make
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 65fba4c..3cfec12 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -140,6 +140,7 @@ config PPC
+ select ARCH_USE_BUILTIN_BSWAP
+ select OLD_SIGSUSPEND
+ select OLD_SIGACTION if PPC32
++ select HAVE_GCC_PLUGINS
+ select HAVE_DEBUG_STACKOVERFLOW
+ select HAVE_IRQ_EXIT_ON_IRQ_STACK
+ select ARCH_USE_CMPXCHG_LOCKREF if PPC64
+@@ -441,6 +442,7 @@ config KEXEC
+ bool "kexec system call"
+ depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E
+ select KEXEC_CORE
++ depends on !GRKERNSEC_KMEM
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
+index 2b90335..5e1a3d6 100644
+--- a/arch/powerpc/include/asm/atomic.h
++++ b/arch/powerpc/include/asm/atomic.h
+@@ -12,6 +12,11 @@
+
+ #define ATOMIC_INIT(i) { (i) }
+
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++ PPC_LONG" " #from ", " #to"\n" \
++" .previous\n"
++
+ /*
+ * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
+ * a "bne-" instruction at the end, so an isync is enough as a acquire barrier
+@@ -39,38 +44,79 @@ static __inline__ int atomic_read(const atomic_t *v)
+ return t;
+ }
+
++static __inline__ int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ int t;
++
++ __asm__ __volatile__("lwz%U1%X1 %0,%1" : "=r"(t) : "m"(v->counter));
++
++ return t;
++}
++
+ static __inline__ void atomic_set(atomic_t *v, int i)
+ {
+ __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
+ }
+
+-#define ATOMIC_OP(op, asm_op) \
+-static __inline__ void atomic_##op(int a, atomic_t *v) \
++static __inline__ void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i));
++}
++
++#ifdef CONFIG_PAX_REFCOUNT
++#define __REFCOUNT_OP(op) op##o.
++#define __OVERFLOW_PRE \
++ " mcrxr cr0\n"
++#define __OVERFLOW_POST \
++ " bf 4*cr0+so, 3f\n" \
++ "2: .long 0x00c00b00\n" \
++ "3:\n"
++#define __OVERFLOW_EXTABLE \
++ "\n4:\n" \
++ _ASM_EXTABLE(2b, 4b)
++#else
++#define __REFCOUNT_OP(op) op
++#define __OVERFLOW_PRE
++#define __OVERFLOW_POST
++#define __OVERFLOW_EXTABLE
++#endif
++
++#define __ATOMIC_OP(op, suffix, pre_op, asm_op, post_op, extable) \
++static inline void atomic_##op##suffix(int a, atomic##suffix##_t *v) \
+ { \
+ int t; \
+ \
+ __asm__ __volatile__( \
+-"1: lwarx %0,0,%3 # atomic_" #op "\n" \
++"1: lwarx %0,0,%3 # atomic_" #op #suffix "\n" \
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ PPC405_ERR77(0,%3) \
+ " stwcx. %0,0,%3 \n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+ } \
+
+-#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \
+-static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
++#define ATOMIC_OP(op, asm_op) __ATOMIC_OP(op, , , asm_op, , ) \
++ __ATOMIC_OP(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
++#define __ATOMIC_OP_RETURN(op, suffix, pre_op, asm_op, post_op, extable)\
++static inline int atomic_##op##_return##suffix##_relaxed(int a, atomic##suffix##_t *v)\
+ { \
+ int t; \
+ \
+ __asm__ __volatile__( \
+-"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \
++"1: lwarx %0,0,%2 # atomic_" #op "_return" #suffix "_relaxed\n"\
++ pre_op \
+ #asm_op " %0,%2,%0\n" \
++ post_op \
+ PPC405_ERR77(0, %3) \
+ " stwcx. %0,0,%3\n" \
+ " bne- 1b\n" \
++ extable \
+ : "=&r" (t), "+m" (v->counter) \
+ : "r" (a), "r" (&v->counter) \
+ : "cc"); \
+@@ -78,6 +124,9 @@ static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \
+ return t; \
+ }
+
++#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) __ATOMIC_OP_RETURN(op, , , asm_op, , )\
++ __ATOMIC_OP_RETURN(op, _unchecked, __OVERFLOW_PRE, __REFCOUNT_OP(asm_op), __OVERFLOW_POST, __OVERFLOW_EXTABLE)
++
+ #define ATOMIC_FETCH_OP_RELAXED(op, asm_op) \
+ static inline int atomic_fetch_##op##_relaxed(int a, atomic_t *v) \
+ { \
+@@ -105,6 +154,7 @@ ATOMIC_OPS(add, add)
+ ATOMIC_OPS(sub, subf)
+
+ #define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked_relaxed atomic_add_return_unchecked_relaxed
+ #define atomic_sub_return_relaxed atomic_sub_return_relaxed
+
+ #define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
+@@ -126,41 +176,22 @@ ATOMIC_OPS(xor, xor)
+ #undef ATOMIC_OPS
+ #undef ATOMIC_FETCH_OP_RELAXED
+ #undef ATOMIC_OP_RETURN_RELAXED
++#undef __ATOMIC_OP_RETURN
+ #undef ATOMIC_OP
++#undef __ATOMIC_OP
+
+ #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
+
+-static __inline__ void atomic_inc(atomic_t *v)
+-{
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_inc\n\
+- addic %0,%0,1\n"
+- PPC405_ERR77(0,%2)
+-" stwcx. %0,0,%2 \n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-}
+-
+-static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
+-{
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n"
+-" addic %0,%0,1\n"
+- PPC405_ERR77(0, %2)
+-" stwcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
+-}
++/*
++ * atomic_inc - increment atomic variable
++ * @v: pointer of type atomic_t
++ *
++ * Automatically increments @v by 1
++ */
++#define atomic_inc(v) atomic_add(1, (v))
++#define atomic_inc_unchecked(v) atomic_add_unchecked(1, (v))
++#define atomic_inc_return_relaxed(v) atomic_add_return_relaxed(1, (v))
++#define atomic_inc_return_unchecked_relaxed(v) atomic_add_return_unchecked_relaxed(1, (v))
+
+ /*
+ * atomic_inc_and_test - increment and test
+@@ -171,37 +202,20 @@ static __inline__ int atomic_inc_return_relaxed(atomic_t *v)
+ * other cases.
+ */
+ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+-
+-static __inline__ void atomic_dec(atomic_t *v)
+-{
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_dec\n\
+- addic %0,%0,-1\n"
+- PPC405_ERR77(0,%2)\
+-" stwcx. %0,0,%2\n\
+- bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-}
+-
+-static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
++#define atomic_inc_and_test_unchecked(v) (atomic_inc_return_unchecked(v) == 0)
++
++/*
++ * atomic_dec - decrement atomic variable
++ * @v: pointer of type atomic_t
++ *
++ * Atomically decrements @v by 1
++ */
++#define atomic_dec(v) atomic_sub(1, (v))
++#define atomic_dec_return_relaxed(v) atomic_sub_return_relaxed(1, (v))
++
++static __inline__ void atomic_dec_unchecked(atomic_unchecked_t *v)
+ {
+- int t;
+-
+- __asm__ __volatile__(
+-"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n"
+-" addic %0,%0,-1\n"
+- PPC405_ERR77(0, %2)
+-" stwcx. %0,0,%2\n"
+-" bne- 1b"
+- : "=&r" (t), "+m" (v->counter)
+- : "r" (&v->counter)
+- : "cc", "xer");
+-
+- return t;
++ atomic_sub_unchecked(1, v);
+ }
+
+ #define atomic_inc_return_relaxed atomic_inc_return_relaxed
+@@ -216,6 +230,16 @@ static __inline__ int atomic_dec_return_relaxed(atomic_t *v)
+ #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+ #define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
+
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old, int new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++ return xchg(&(v->counter), new);
++}
++
+ /**
+ * __atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+@@ -233,14 +257,21 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ PPC_ATOMIC_ENTRY_BARRIER
+ "1: lwarx %0,0,%1 # __atomic_add_unless\n\
+ cmpw 0,%0,%3 \n\
+- beq 2f \n\
+- add %0,%2,%0 \n"
++ beq 5f \n"
++
++