aboutsummaryrefslogtreecommitdiffstats
path: root/main/linux-grsec
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2012-11-21 12:43:49 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2012-11-21 12:43:49 +0000
commit41a35763c0368d6db691f8289906d0d28375f0b2 (patch)
tree314e20e180d223985169a93313375f111777d02e /main/linux-grsec
parent5885deea0e02085296082c33f5e5ed0208a9c741 (diff)
downloadaports-41a35763c0368d6db691f8289906d0d28375f0b2.tar.bz2
aports-41a35763c0368d6db691f8289906d0d28375f0b2.tar.xz
main/linux-grsec: upgrade to 3.6.7 kernel
Diffstat (limited to 'main/linux-grsec')
-rw-r--r--main/linux-grsec/APKBUILD10
-rw-r--r--main/linux-grsec/grsecurity-2.9.1-3.6.7-201211181105.patch (renamed from main/linux-grsec/grsecurity-2.9.1-3.6.6-201211122213.patch)1067
2 files changed, 550 insertions, 527 deletions
diff --git a/main/linux-grsec/APKBUILD b/main/linux-grsec/APKBUILD
index ec1f358aad..ec40286cac 100644
--- a/main/linux-grsec/APKBUILD
+++ b/main/linux-grsec/APKBUILD
@@ -2,9 +2,9 @@
_flavor=grsec
pkgname=linux-${_flavor}
-pkgver=3.6.6
+pkgver=3.6.7
_kernver=3.6
-pkgrel=2
+pkgrel=0
pkgdesc="Linux kernel with grsecurity"
url=http://grsecurity.net
depends="mkinitfs linux-firmware"
@@ -14,7 +14,7 @@ _config=${config:-kernelconfig.${CARCH}}
install=
source="http://ftp.kernel.org/pub/linux/kernel/v3.x/linux-$_kernver.tar.xz
http://ftp.kernel.org/pub/linux/kernel/v3.x/patch-$pkgver.xz
- grsecurity-2.9.1-3.6.6-201211122213.patch
+ grsecurity-2.9.1-3.6.7-201211181105.patch
0004-arp-flush-arp-cache-on-device-change.patch
@@ -139,8 +139,8 @@ dev() {
}
md5sums="1a1760420eac802c541a20ab51a093d1 linux-3.6.tar.xz
-11d6d8749d4612a77f43f0531c0f2824 patch-3.6.6.xz
-eeadecd13caac8e41b567b21b5d42c80 grsecurity-2.9.1-3.6.6-201211122213.patch
+134936c362d8812b5cafcf3c67afdce0 patch-3.6.7.xz
+af1f2097a6e26d36801188193d3eb185 grsecurity-2.9.1-3.6.7-201211181105.patch
776adeeb5272093574f8836c5037dd7d 0004-arp-flush-arp-cache-on-device-change.patch
0b4abb6b3e32cc7ba656c24e30581349 kernelconfig.x86
0971129c59c7fe0011b3ec46982d9f5c kernelconfig.x86_64"
diff --git a/main/linux-grsec/grsecurity-2.9.1-3.6.6-201211122213.patch b/main/linux-grsec/grsecurity-2.9.1-3.6.7-201211181105.patch
index 164e8e9168..6f0229a48a 100644
--- a/main/linux-grsec/grsecurity-2.9.1-3.6.6-201211122213.patch
+++ b/main/linux-grsec/grsecurity-2.9.1-3.6.7-201211181105.patch
@@ -251,7 +251,7 @@ index ad7e2e5..199f49e 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 471b83c..a290aa2 100644
+index 07f2308..7271d99 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -5692,6 +5692,26 @@ index 6cf591b..b49e65a 100644
extra-y := head_$(BITS).o
+diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
+index f8b6eee..87f60ee 100644
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu)
+ static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
+ {
+ unsigned int eirq;
++ struct irq_bucket *p;
+ int cpu = sparc_leon3_cpuid();
+
+ eirq = leon_eirq_get(cpu);
+- if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
+- generic_handle_irq(irq_map[eirq]->irq);
++ p = irq_map[eirq];
++ if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */
++ generic_handle_irq(p->irq);
+ }
+
+ /* The extended IRQ controller has been found, this function registers it */
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 14006d8..8146238 100644
--- a/arch/sparc/kernel/process_32.c
@@ -15787,7 +15807,7 @@ index 8f8e8ee..3617d6e 100644
/*
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
-index dcdd0ea..de0bb2d 100644
+index dcdd0ea..8f32835 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -57,6 +57,8 @@
@@ -15863,7 +15883,7 @@ index dcdd0ea..de0bb2d 100644
jmp *%rdi
#endif
-@@ -180,6 +188,280 @@ ENTRY(native_usergs_sysret64)
+@@ -180,6 +188,273 @@ ENTRY(native_usergs_sysret64)
ENDPROC(native_usergs_sysret64)
#endif /* CONFIG_PARAVIRT */
@@ -15949,13 +15969,6 @@ index dcdd0ea..de0bb2d 100644
+ ljmpq __KERNEL_CS,3f
+3: SET_RDI_INTO_CR0
+ jmp 1b
-+#ifdef CONFIG_PARAVIRT
-+ PV_RESTORE_REGS(CLBR_RDI);
-+#endif
-+
-+ popq %rdi
-+ pax_force_retaddr
-+ retq
+ENDPROC(pax_exit_kernel)
+#endif
+
@@ -16144,7 +16157,7 @@ index dcdd0ea..de0bb2d 100644
.macro TRACE_IRQS_IRETQ offset=ARGOFFSET
#ifdef CONFIG_TRACE_IRQFLAGS
-@@ -271,8 +553,8 @@ ENDPROC(native_usergs_sysret64)
+@@ -271,8 +546,8 @@ ENDPROC(native_usergs_sysret64)
.endm
.macro UNFAKE_STACK_FRAME
@@ -16155,7 +16168,7 @@ index dcdd0ea..de0bb2d 100644
.endm
/*
-@@ -359,7 +641,7 @@ ENDPROC(native_usergs_sysret64)
+@@ -359,7 +634,7 @@ ENDPROC(native_usergs_sysret64)
movq %rsp, %rsi
leaq -RBP(%rsp),%rdi /* arg1 for handler */
@@ -16164,7 +16177,7 @@ index dcdd0ea..de0bb2d 100644
je 1f
SWAPGS
/*
-@@ -394,9 +676,10 @@ ENTRY(save_rest)
+@@ -394,9 +669,10 @@ ENTRY(save_rest)
movq_cfi r15, R15+16
movq %r11, 8(%rsp) /* return address */
FIXUP_TOP_OF_STACK %r11, 16
@@ -16176,7 +16189,7 @@ index dcdd0ea..de0bb2d 100644
/* save complete stack frame */
.pushsection .kprobes.text, "ax"
-@@ -425,9 +708,10 @@ ENTRY(save_paranoid)
+@@ -425,9 +701,10 @@ ENTRY(save_paranoid)
js 1f /* negative -> in kernel */
SWAPGS
xorl %ebx,%ebx
@@ -16189,7 +16202,7 @@ index dcdd0ea..de0bb2d 100644
.popsection
/*
-@@ -449,7 +733,7 @@ ENTRY(ret_from_fork)
+@@ -449,7 +726,7 @@ ENTRY(ret_from_fork)
RESTORE_REST
@@ -16198,7 +16211,7 @@ index dcdd0ea..de0bb2d 100644
jz retint_restore_args
testl $_TIF_IA32, TI_flags(%rcx) # 32-bit compat task needs IRET
-@@ -459,7 +743,7 @@ ENTRY(ret_from_fork)
+@@ -459,7 +736,7 @@ ENTRY(ret_from_fork)
jmp ret_from_sys_call # go to the SYSRET fastpath
CFI_ENDPROC
@@ -16207,7 +16220,7 @@ index dcdd0ea..de0bb2d 100644
/*
* System call entry. Up to 6 arguments in registers are supported.
-@@ -495,7 +779,7 @@ END(ret_from_fork)
+@@ -495,7 +772,7 @@ END(ret_from_fork)
ENTRY(system_call)
CFI_STARTPROC simple
CFI_SIGNAL_FRAME
@@ -16216,7 +16229,7 @@ index dcdd0ea..de0bb2d 100644
CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK
-@@ -508,16 +792,23 @@ GLOBAL(system_call_after_swapgs)
+@@ -508,16 +785,23 @@ GLOBAL(system_call_after_swapgs)
movq %rsp,PER_CPU_VAR(old_rsp)
movq PER_CPU_VAR(kernel_stack),%rsp
@@ -16242,7 +16255,7 @@ index dcdd0ea..de0bb2d 100644
jnz tracesys
system_call_fastpath:
#if __SYSCALL_MASK == ~0
-@@ -527,7 +818,7 @@ system_call_fastpath:
+@@ -527,7 +811,7 @@ system_call_fastpath:
cmpl $__NR_syscall_max,%eax
#endif
ja badsys
@@ -16251,7 +16264,7 @@ index dcdd0ea..de0bb2d 100644
call *sys_call_table(,%rax,8) # XXX: rip relative
movq %rax,RAX-ARGOFFSET(%rsp)
/*
-@@ -541,10 +832,13 @@ sysret_check:
+@@ -541,10 +825,13 @@ sysret_check:
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
@@ -16266,7 +16279,7 @@ index dcdd0ea..de0bb2d 100644
/*
* sysretq will re-enable interrupts:
*/
-@@ -596,14 +890,18 @@ badsys:
+@@ -596,14 +883,18 @@ badsys:
* jump back to the normal fast path.
*/
auditsys:
@@ -16286,7 +16299,7 @@ index dcdd0ea..de0bb2d 100644
jmp system_call_fastpath
/*
-@@ -624,7 +922,7 @@ sysret_audit:
+@@ -624,7 +915,7 @@ sysret_audit:
/* Do syscall tracing */
tracesys:
#ifdef CONFIG_AUDITSYSCALL
@@ -16295,7 +16308,7 @@ index dcdd0ea..de0bb2d 100644
jz auditsys
#endif
SAVE_REST
-@@ -632,12 +930,16 @@ tracesys:
+@@ -632,12 +923,16 @@ tracesys:
FIXUP_TOP_OF_STACK %rdi
movq %rsp,%rdi
call syscall_trace_enter
@@ -16312,7 +16325,7 @@ index dcdd0ea..de0bb2d 100644
RESTORE_REST
#if __SYSCALL_MASK == ~0
cmpq $__NR_syscall_max,%rax
-@@ -646,7 +948,7 @@ tracesys:
+@@ -646,7 +941,7 @@ tracesys:
cmpl $__NR_syscall_max,%eax
#endif
ja int_ret_from_sys_call /* RAX(%rsp) set to -ENOSYS above */
@@ -16321,7 +16334,7 @@ index dcdd0ea..de0bb2d 100644
call *sys_call_table(,%rax,8)
movq %rax,RAX-ARGOFFSET(%rsp)
/* Use IRET because user could have changed frame */
-@@ -667,7 +969,9 @@ GLOBAL(int_with_check)
+@@ -667,7 +962,9 @@ GLOBAL(int_with_check)
andl %edi,%edx
jnz int_careful
andl $~TS_COMPAT,TI_status(%rcx)
@@ -16332,7 +16345,7 @@ index dcdd0ea..de0bb2d 100644
/* Either reschedule or signal or syscall exit tracking needed. */
/* First do a reschedule test. */
-@@ -713,7 +1017,7 @@ int_restore_rest:
+@@ -713,7 +1010,7 @@ int_restore_rest:
TRACE_IRQS_OFF
jmp int_with_check
CFI_ENDPROC
@@ -16341,7 +16354,7 @@ index dcdd0ea..de0bb2d 100644
/*
* Certain special system calls that need to save a complete full stack frame.
-@@ -729,7 +1033,7 @@ ENTRY(\label)
+@@ -729,7 +1026,7 @@ ENTRY(\label)
call \func
jmp ptregscall_common
CFI_ENDPROC
@@ -16350,7 +16363,7 @@ index dcdd0ea..de0bb2d 100644
.endm
PTREGSCALL stub_clone, sys_clone, %r8
-@@ -747,9 +1051,10 @@ ENTRY(ptregscall_common)
+@@ -747,9 +1044,10 @@ ENTRY(ptregscall_common)
movq_cfi_restore R12+8, r12
movq_cfi_restore RBP+8, rbp
movq_cfi_restore RBX+8, rbx
@@ -16362,7 +16375,7 @@ index dcdd0ea..de0bb2d 100644
ENTRY(stub_execve)
CFI_STARTPROC
-@@ -764,7 +1069,7 @@ ENTRY(stub_execve)
+@@ -764,7 +1062,7 @@ ENTRY(stub_execve)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -16371,7 +16384,7 @@ index dcdd0ea..de0bb2d 100644
/*
* sigreturn is special because it needs to restore all registers on return.
-@@ -782,7 +1087,7 @@ ENTRY(stub_rt_sigreturn)
+@@ -782,7 +1080,7 @@ ENTRY(stub_rt_sigreturn)
RESTORE_REST
jmp int_ret_from_sys_call
CFI_ENDPROC
@@ -16380,7 +16393,7 @@ index dcdd0ea..de0bb2d 100644
#ifdef CONFIG_X86_X32_ABI
PTREGSCALL stub_x32_sigaltstack, sys32_sigaltstack, %rdx
-@@ -851,7 +1156,7 @@ vector=vector+1
+@@ -851,7 +1149,7 @@ vector=vector+1
2: jmp common_interrupt
.endr
CFI_ENDPROC
@@ -16389,7 +16402,7 @@ index dcdd0ea..de0bb2d 100644
.previous
END(interrupt)
-@@ -871,6 +1176,16 @@ END(interrupt)
+@@ -871,6 +1169,16 @@ END(interrupt)
subq $ORIG_RAX-RBP, %rsp
CFI_ADJUST_CFA_OFFSET ORIG_RAX-RBP
SAVE_ARGS_IRQ
@@ -16406,7 +16419,7 @@ index dcdd0ea..de0bb2d 100644
call \func
.endm
-@@ -902,7 +1217,7 @@ ret_from_intr:
+@@ -902,7 +1210,7 @@ ret_from_intr:
exit_intr:
GET_THREAD_INFO(%rcx)
@@ -16415,7 +16428,7 @@ index dcdd0ea..de0bb2d 100644
je retint_kernel
/* Interrupt came from user space */
-@@ -924,12 +1239,16 @@ retint_swapgs: /* return to user-space */
+@@ -924,12 +1232,16 @@ retint_swapgs: /* return to user-space */
* The iretq could re-enable interrupts:
*/
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -16432,7 +16445,7 @@ index dcdd0ea..de0bb2d 100644
/*
* The iretq could re-enable interrupts:
*/
-@@ -1012,7 +1331,7 @@ ENTRY(retint_kernel)
+@@ -1012,7 +1324,7 @@ ENTRY(retint_kernel)
#endif
CFI_ENDPROC
@@ -16441,7 +16454,7 @@ index dcdd0ea..de0bb2d 100644
/*
* End of kprobes section
*/
-@@ -1029,7 +1348,7 @@ ENTRY(\sym)
+@@ -1029,7 +1341,7 @@ ENTRY(\sym)
interrupt \do_sym
jmp ret_from_intr
CFI_ENDPROC
@@ -16450,7 +16463,7 @@ index dcdd0ea..de0bb2d 100644
.endm
#ifdef CONFIG_SMP
-@@ -1084,12 +1403,22 @@ ENTRY(\sym)
+@@ -1084,12 +1396,22 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
@@ -16474,7 +16487,7 @@ index dcdd0ea..de0bb2d 100644
.endm
.macro paranoidzeroentry sym do_sym
-@@ -1101,15 +1430,25 @@ ENTRY(\sym)
+@@ -1101,15 +1423,25 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF
@@ -16502,7 +16515,7 @@ index dcdd0ea..de0bb2d 100644
.macro paranoidzeroentry_ist sym do_sym ist
ENTRY(\sym)
INTR_FRAME
-@@ -1119,14 +1458,30 @@ ENTRY(\sym)
+@@ -1119,14 +1451,30 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call save_paranoid
TRACE_IRQS_OFF_DEBUG
@@ -16534,7 +16547,7 @@ index dcdd0ea..de0bb2d 100644
.endm
.macro errorentry sym do_sym
-@@ -1137,13 +1492,23 @@ ENTRY(\sym)
+@@ -1137,13 +1485,23 @@ ENTRY(\sym)
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
call error_entry
DEFAULT_FRAME 0
@@ -16559,7 +16572,7 @@ index dcdd0ea..de0bb2d 100644
.endm
/* error code is on the stack already */
-@@ -1156,13 +1521,23 @@ ENTRY(\sym)
+@@ -1156,13 +1514,23 @@ ENTRY(\sym)
call save_paranoid
DEFAULT_FRAME 0
TRACE_IRQS_OFF
@@ -16584,7 +16597,7 @@ index dcdd0ea..de0bb2d 100644
.endm
zeroentry divide_error do_divide_error
-@@ -1192,9 +1567,10 @@ gs_change:
+@@ -1192,9 +1560,10 @@ gs_change:
2: mfence /* workaround */
SWAPGS
popfq_cfi
@@ -16596,7 +16609,7 @@ index dcdd0ea..de0bb2d 100644
_ASM_EXTABLE(gs_change,bad_gs)
.section .fixup,"ax"
-@@ -1213,13 +1589,14 @@ ENTRY(kernel_thread_helper)
+@@ -1213,13 +1582,14 @@ ENTRY(kernel_thread_helper)
* Here we are in the child and the registers are set as they were
* at kernel_thread() invocation in the parent.
*/
@@ -16612,7 +16625,7 @@ index dcdd0ea..de0bb2d 100644
/*
* execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
-@@ -1246,11 +1623,11 @@ ENTRY(kernel_execve)
+@@ -1246,11 +1616,11 @@ ENTRY(kernel_execve)
RESTORE_REST
testq %rax,%rax
je int_ret_from_sys_call
@@ -16626,7 +16639,7 @@ index dcdd0ea..de0bb2d 100644
/* Call softirq on interrupt stack. Interrupts are off. */
ENTRY(call_softirq)
-@@ -1268,9 +1645,10 @@ ENTRY(call_softirq)
+@@ -1268,9 +1638,10 @@ ENTRY(call_softirq)
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
decl PER_CPU_VAR(irq_count)
@@ -16638,7 +16651,7 @@ index dcdd0ea..de0bb2d 100644
#ifdef CONFIG_XEN
zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
-@@ -1308,7 +1686,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
+@@ -1308,7 +1679,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
decl PER_CPU_VAR(irq_count)
jmp error_exit
CFI_ENDPROC
@@ -16647,7 +16660,7 @@ index dcdd0ea..de0bb2d 100644
/*
* Hypervisor uses this for application faults while it executes.
-@@ -1367,7 +1745,7 @@ ENTRY(xen_failsafe_callback)
+@@ -1367,7 +1738,7 @@ ENTRY(xen_failsafe_callback)
SAVE_ALL
jmp error_exit
CFI_ENDPROC
@@ -16656,7 +16669,7 @@ index dcdd0ea..de0bb2d 100644
apicinterrupt XEN_HVM_EVTCHN_CALLBACK \
xen_hvm_callback_vector xen_evtchn_do_upcall
-@@ -1416,16 +1794,31 @@ ENTRY(paranoid_exit)
+@@ -1416,16 +1787,31 @@ ENTRY(paranoid_exit)
TRACE_IRQS_OFF_DEBUG
testl %ebx,%ebx /* swapgs needed? */
jnz paranoid_restore
@@ -16689,7 +16702,7 @@ index dcdd0ea..de0bb2d 100644
jmp irq_return
paranoid_userspace:
GET_THREAD_INFO(%rcx)
-@@ -1454,7 +1847,7 @@ paranoid_schedule:
+@@ -1454,7 +1840,7 @@ paranoid_schedule:
TRACE_IRQS_OFF
jmp paranoid_userspace
CFI_ENDPROC
@@ -16698,7 +16711,7 @@ index dcdd0ea..de0bb2d 100644
/*
* Exception entry point. This expects an error code/orig_rax on the stack.
-@@ -1481,12 +1874,13 @@ ENTRY(error_entry)
+@@ -1481,12 +1867,13 @@ ENTRY(error_entry)
movq_cfi r14, R14+8
movq_cfi r15, R15+8
xorl %ebx,%ebx
@@ -16713,7 +16726,7 @@ index dcdd0ea..de0bb2d 100644
ret
/*
-@@ -1513,7 +1907,7 @@ bstep_iret:
+@@ -1513,7 +1900,7 @@ bstep_iret:
movq %rcx,RIP+8(%rsp)
jmp error_swapgs
CFI_ENDPROC
@@ -16722,7 +16735,7 @@ index dcdd0ea..de0bb2d 100644
/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
-@@ -1533,7 +1927,7 @@ ENTRY(error_exit)
+@@ -1533,7 +1920,7 @@ ENTRY(error_exit)
jnz retint_careful
jmp retint_swapgs
CFI_ENDPROC
@@ -16731,7 +16744,7 @@ index dcdd0ea..de0bb2d 100644
/*
* Test if a given stack is an NMI stack or not.
-@@ -1591,9 +1985,11 @@ ENTRY(nmi)
+@@ -1591,9 +1978,11 @@ ENTRY(nmi)
* If %cs was not the kernel segment, then the NMI triggered in user
* space, which means it is definitely not nested.
*/
@@ -16744,7 +16757,7 @@ index dcdd0ea..de0bb2d 100644
/*
* Check the special variable on the stack to see if NMIs are
* executing.
-@@ -1752,6 +2148,17 @@ end_repeat_nmi:
+@@ -1752,6 +2141,17 @@ end_repeat_nmi:
*/
movq %cr2, %r12
@@ -16762,7 +16775,7 @@ index dcdd0ea..de0bb2d 100644
/* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
movq %rsp,%rdi
movq $-1,%rsi
-@@ -1767,21 +2174,32 @@ end_repeat_nmi:
+@@ -1767,21 +2167,32 @@ end_repeat_nmi:
testl %ebx,%ebx /* swapgs needed? */
jnz nmi_restore
nmi_swapgs:
@@ -20427,6 +20440,20 @@ index 0595f13..b544fa3 100644
return 0;
out:
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index a10e460..58fc514 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_cpuid_entry2 *best;
+
++ if (!static_cpu_has(X86_FEATURE_XSAVE))
++ return 0;
++
+ best = kvm_find_cpuid_entry(vcpu, 1, 0);
+ return best && (best->ecx & bit(X86_FEATURE_XSAVE));
+ }
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index a3b57a2..ebbe732 100644
--- a/arch/x86/kvm/emulate.c
@@ -20626,7 +20653,7 @@ index b1eb202..254e292 100644
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 2966c84..207d0cb 100644
+index 2966c84..9ac0c3c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1379,8 +1379,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data)
@@ -20667,6 +20694,16 @@ index 2966c84..207d0cb 100644
{
int r;
struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
+@@ -5762,6 +5764,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+ int pending_vec, max_bits, idx;
+ struct desc_ptr dt;
+
++ if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE))
++ return -EINVAL;
++
+ dt.size = sregs->idt.limit;
+ dt.address = sregs->idt.base;
+ kvm_x86_ops->set_idt(vcpu, &dt);
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 642d880..cc9ebac 100644
--- a/arch/x86/lguest/boot.c
@@ -27411,10 +27448,10 @@ index c1461de..355f120 100644
#ifdef CONFIG_ACPI_NUMA
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
-index 5141d80..6c9fb41 100644
+index dde1a3f..6b663e6 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
-@@ -1765,6 +1765,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1784,6 +1784,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
convert_pfn_mfn(init_level4_pgt);
convert_pfn_mfn(level3_ident_pgt);
convert_pfn_mfn(level3_kernel_pgt);
@@ -27424,7 +27461,7 @@ index 5141d80..6c9fb41 100644
l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
-@@ -1783,7 +1786,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
+@@ -1802,7 +1805,11 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
@@ -27436,7 +27473,7 @@ index 5141d80..6c9fb41 100644
set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
-@@ -1967,6 +1974,7 @@ static void __init xen_post_allocator_init(void)
+@@ -1986,6 +1993,7 @@ static void __init xen_post_allocator_init(void)
pv_mmu_ops.set_pud = xen_set_pud;
#if PAGETABLE_LEVELS == 4
pv_mmu_ops.set_pgd = xen_set_pgd;
@@ -27444,7 +27481,7 @@ index 5141d80..6c9fb41 100644
#endif
/* This will work as long as patching hasn't happened yet
-@@ -2048,6 +2056,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
+@@ -2067,6 +2075,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
.pud_val = PV_CALLEE_SAVE(xen_pud_val),
.make_pud = PV_CALLEE_SAVE(xen_make_pud),
.set_pgd = xen_set_pgd_hyper,
@@ -27785,7 +27822,7 @@ index 9a87daa..fb17486 100644
goto error;
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
-index 671d4d6..5f24030 100644
+index 671d4d6..afec999 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -63,7 +63,7 @@ struct cryptd_blkcipher_ctx {
@@ -27806,6 +27843,28 @@ index 671d4d6..5f24030 100644
static void cryptd_queue_worker(struct work_struct *work);
+@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work)
+ struct crypto_async_request *req, *backlog;
+
+ cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+- /* Only handle one request at a time to avoid hogging crypto
+- * workqueue. preempt_disable/enable is used to prevent
+- * being preempted by cryptd_enqueue_request() */
++ /*
++ * Only handle one request at a time to avoid hogging crypto workqueue.
++ * preempt_disable/enable is used to prevent being preempted by
++ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
++ * cryptd_enqueue_request() being accessed from software interrupts.
++ */
++ local_bh_disable();
+ preempt_disable();
+ backlog = crypto_get_backlog(&cpu_queue->queue);
+ req = crypto_dequeue_request(&cpu_queue->queue);
+ preempt_enable();
++ local_bh_enable();
+
+ if (!req)
+ return;
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index e6defd8..c26a225 100644
--- a/drivers/acpi/apei/cper.c
@@ -30368,7 +30427,7 @@ index 9238de4..a27c72a 100644
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
-index 5062eec..4e3e51f 100644
+index 7aff5c7..bee6c27 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -71,7 +71,7 @@ static int drm_setup(struct drm_device * dev)
@@ -30380,18 +30439,34 @@ index 5062eec..4e3e51f 100644
dev->sigdata.lock = NULL;
-@@ -134,8 +134,8 @@ int drm_open(struct inode *inode, struct file *filp)
+@@ -134,7 +134,7 @@ int drm_open(struct inode *inode, struct file *filp)
+ if (drm_device_is_unplugged(dev))
+ return -ENODEV;
+- if (!dev->open_count++)
++ if (local_inc_return(&dev->open_count) == 1)
+ need_setup = 1;
+ mutex_lock(&dev->struct_mutex);
+ old_mapping = dev->dev_mapping;
+@@ -149,7 +149,7 @@ int drm_open(struct inode *inode, struct file *filp)
retcode = drm_open_helper(inode, filp, dev);
- if (!retcode) {
-- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
-- if (!dev->open_count++)
-+ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
-+ if (local_inc_return(&dev->open_count) == 1)
- retcode = drm_setup(dev);
- }
- if (!retcode) {
-@@ -422,7 +422,7 @@ int drm_release(struct inode *inode, struct file *filp)
+ if (retcode)
+ goto err_undo;
+- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
++ atomic_inc_unchecked(&dev->counts[_DRM_STAT_OPENS]);
+ if (need_setup) {
+ retcode = drm_setup(dev);
+ if (retcode)
+@@ -164,7 +164,7 @@ err_undo:
+ iput(container_of(dev->dev_mapping, struct inode, i_data));
+ dev->dev_mapping = old_mapping;
+ mutex_unlock(&dev->struct_mutex);
+- dev->open_count--;
++ local_dec(&dev->open_count);
+ return retcode;
+ }
+ EXPORT_SYMBOL(drm_open);
+@@ -438,7 +438,7 @@ int drm_release(struct inode *inode, struct file *filp)
mutex_lock(&drm_global_mutex);
@@ -30400,7 +30475,7 @@ index 5062eec..4e3e51f 100644
if (dev->driver->preclose)
dev->driver->preclose(dev, file_priv);
-@@ -431,10 +431,10 @@ int drm_release(struct inode *inode, struct file *filp)
+@@ -447,10 +447,10 @@ int drm_release(struct inode *inode, struct file *filp)
* Begin inline drm_release
*/
@@ -30413,7 +30488,7 @@ index 5062eec..4e3e51f 100644
/* Release any auth tokens that might point to this file_priv,
(do that under the drm_global_mutex) */
-@@ -530,8 +530,8 @@ int drm_release(struct inode *inode, struct file *filp)
+@@ -546,8 +546,8 @@ int drm_release(struct inode *inode, struct file *filp)
* End inline drm_release
*/
@@ -30654,7 +30729,7 @@ index 359f6e8..ada68fd 100644
if (IS_GEN6(dev) || IS_GEN7(dev)) {
seq_printf(m, "Graphics Interrupt mask (%s): %08x\n",
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
-index 914c0df..d47d380 100644
+index 0969a7c..b9ffa45 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1269,7 +1269,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
@@ -35325,18 +35400,6 @@ index 4a518a3..936b334 100644
#define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath) \
((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next)
-diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
-index 53743f7..af8b414 100644
---- a/drivers/net/ethernet/nxp/lpc_eth.c
-+++ b/drivers/net/ethernet/nxp/lpc_eth.c
-@@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
- pldat->dma_buff_base_p);
- free_irq(ndev->irq, ndev);
- iounmap(pldat->net_base);
-+ mdiobus_unregister(pldat->mii_bus);
- mdiobus_free(pldat->mii_bus);
- clk_disable(pldat->clk);
- clk_put(pldat->clk);
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index b47d5b3..273a516 100644
--- a/drivers/net/ethernet/realtek/r8169.c
@@ -37943,40 +38006,6 @@ index 0d4aa82..f7832d4 100644
extern void tmem_register_hostops(struct tmem_hostops *m);
/* core tmem accessor functions */
-diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
-index 9fc9a60..68d4c10 100644
---- a/drivers/target/target_core_device.c
-+++ b/drivers/target/target_core_device.c
-@@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev)
-
- static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
- {
-- u32 tmp, aligned_max_sectors;
-+ u32 aligned_max_sectors;
-+ u32 alignment;
- /*
- * Limit max_sectors to a PAGE_SIZE aligned value for modern
- * transport_allocate_data_tasks() operation.
- */
-- tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
-- aligned_max_sectors = (tmp / block_size);
-- if (max_sectors != aligned_max_sectors) {
-- printk(KERN_INFO "Rounding down aligned max_sectors from %u"
-- " to %u\n", max_sectors, aligned_max_sectors);
-- return aligned_max_sectors;
-- }
-+ alignment = max(1ul, PAGE_SIZE / block_size);
-+ aligned_max_sectors = rounddown(max_sectors, alignment);
-
-- return max_sectors;
-+ if (max_sectors != aligned_max_sectors)
-+ pr_info("Rounding down aligned max_sectors from %u to %u\n",
-+ max_sectors, aligned_max_sectors);
-+
-+ return aligned_max_sectors;
- }
-
- void se_dev_set_default_attribs(
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 7502660..f214d9f 100644
--- a/drivers/target/target_core_transport.c
@@ -42708,6 +42737,22 @@ index 88714ae..16c2e11 100644
static inline u32 get_pll_internal_frequency(u32 ref_freq,
+diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
+index c3b3f7f..abd47c7 100644
+--- a/drivers/virtio/virtio.c
++++ b/drivers/virtio/virtio.c
+@@ -225,8 +225,10 @@ EXPORT_SYMBOL_GPL(register_virtio_device);
+
+ void unregister_virtio_device(struct virtio_device *dev)
+ {
++ int index = dev->index; /* save for after device release */
++
+ device_unregister(&dev->dev);
+- ida_simple_remove(&virtio_index_ida, dev->index);
++ ida_simple_remove(&virtio_index_ida, index);
+ }
+ EXPORT_SYMBOL_GPL(unregister_virtio_device);
+
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 453db0c..604973e 100644
--- a/drivers/virtio/virtio_mmio.c
@@ -42989,7 +43034,7 @@ index d146e18..12d1bd1 100644
fd_offset + ex.a_text);
if (error != N_DATADDR(ex)) {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
-index 0225fdd..08bda99 100644
+index 0225fdd..0c0d35d 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -32,6 +32,7 @@
@@ -43135,7 +43180,7 @@ index 0225fdd..08bda99 100644
error = -ENOMEM;
goto out_close;
}
-@@ -523,6 +544,311 @@ out:
+@@ -523,6 +544,315 @@ out:
return error;
}
@@ -43369,7 +43414,7 @@ index 0225fdd..08bda99 100644
+ unsigned long pax_flags_hardmode = 0UL, pax_flags_softmode = 0UL;
+
+ xattr_size = vfs_getxattr(file->f_path.dentry, XATTR_NAME_PAX_FLAGS, xattr_value, sizeof xattr_value);
-+ if (xattr_size <= 0)
++ if (xattr_size <= 0 || xattr_size > 5)
+ return ~0UL;
+
+ for (i = 0; i < xattr_size; i++)
@@ -43379,9 +43424,13 @@ index 0225fdd..08bda99 100644
+
+#define parse_flag(option1, option2, flag) \
+ case option1: \
++ if (pax_flags_hardmode & MF_PAX_##flag) \
++ return ~0UL; \
+ pax_flags_hardmode |= MF_PAX_##flag; \
+ break; \
+ case option2: \
++ if (pax_flags_softmode & MF_PAX_##flag) \
++ return ~0UL; \
+ pax_flags_softmode |= MF_PAX_##flag; \
+ break;
+
@@ -43447,7 +43496,7 @@ index 0225fdd..08bda99 100644
/*
* These are the functions used to load ELF style executables and shared
* libraries. There is no binary dependent code anywhere else.
-@@ -539,6 +865,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
+@@ -539,6 +869,11 @@ static unsigned long randomize_stack_top(unsigned long stack_top)
{
unsigned int random_variable = 0;
@@ -43459,7 +43508,7 @@ index 0225fdd..08bda99 100644
if ((current->flags & PF_RANDOMIZE) &&
!(current->personality & ADDR_NO_RANDOMIZE)) {
random_variable = get_random_int() & STACK_RND_MASK;
-@@ -557,7 +888,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -557,7 +892,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
unsigned long load_addr = 0, load_bias = 0;
int load_addr_set = 0;
char * elf_interpreter = NULL;
@@ -43468,7 +43517,7 @@ index 0225fdd..08bda99 100644
struct elf_phdr *elf_ppnt, *elf_phdata;
unsigned long elf_bss, elf_brk;
int retval, i;
-@@ -567,11 +898,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -567,11 +902,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
unsigned long start_code, end_code, start_data, end_data;
unsigned long reloc_func_desc __maybe_unused = 0;
int executable_stack = EXSTACK_DEFAULT;
@@ -43481,7 +43530,7 @@ index 0225fdd..08bda99 100644
loc = kmalloc(sizeof(*loc), GFP_KERNEL);
if (!loc) {
-@@ -707,11 +1038,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -707,11 +1042,81 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto out_free_dentry;
/* OK, This is the point of no return */
@@ -43564,7 +43613,7 @@ index 0225fdd..08bda99 100644
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
current->personality |= READ_IMPLIES_EXEC;
-@@ -802,6 +1203,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -802,6 +1207,20 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
#else
load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
#endif
@@ -43585,7 +43634,7 @@ index 0225fdd..08bda99 100644
}
error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
-@@ -834,9 +1249,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -834,9 +1253,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
* allowed task size. Note that p_filesz must always be
* <= p_memsz so it is only necessary to check p_memsz.
*/
@@ -43598,7 +43647,7 @@ index 0225fdd..08bda99 100644
/* set_brk can never work. Avoid overflows. */
send_sig(SIGKILL, current, 0);
retval = -EINVAL;
-@@ -875,17 +1290,44 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
+@@ -875,17 +1294,44 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto out_free_dentry;
}
if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
@@ -43649,7 +43698,7 @@ index 0225fdd..08bda99 100644
load_bias);
if (!IS_ERR((void *)elf_entry)) {
/*
-@@ -1107,7 +1549,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
+@@ -1107,7 +1553,7 @@ static bool always_dump_vma(struct vm_area_struct *vma)
* Decide what to dump of a segment, part, all or none.
*/
static unsigned long vma_dump_size(struct vm_area_struct *vma,
@@ -43658,7 +43707,7 @@ index 0225fdd..08bda99 100644
{
#define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
-@@ -1144,7 +1586,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
+@@ -1144,7 +1590,7 @@ static unsigned long vma_dump_size(struct vm_area_struct *vma,
if (vma->vm_file == NULL)
return 0;
@@ -43667,7 +43716,7 @@ index 0225fdd..08bda99 100644
goto whole;
/*
-@@ -1366,9 +1808,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
+@@ -1366,9 +1812,9 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
{
elf_addr_t *auxv = (elf_addr_t *) mm->saved_auxv;
int i = 0;
@@ -43679,7 +43728,7 @@ index 0225fdd..08bda99 100644
fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
}
-@@ -1879,14 +2321,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
+@@ -1879,14 +2325,14 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
}
static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
@@ -43696,7 +43745,7 @@ index 0225fdd..08bda99 100644
return size;
}
-@@ -1980,7 +2422,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -1980,7 +2426,7 @@ static int elf_core_dump(struct coredump_params *cprm)
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
@@ -43705,7 +43754,7 @@ index 0225fdd..08bda99 100644
offset += elf_core_extra_data_size();
e_shoff = offset;
-@@ -1994,10 +2436,12 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -1994,10 +2440,12 @@ static int elf_core_dump(struct coredump_params *cprm)
offset = dataoff;
size += sizeof(*elf);
@@ -43718,7 +43767,7 @@ index 0225fdd..08bda99 100644
if (size > cprm->limit
|| !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
goto end_coredump;
-@@ -2011,7 +2455,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2011,7 +2459,7 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_offset = offset;
phdr.p_vaddr = vma->vm_start;
phdr.p_paddr = 0;
@@ -43727,7 +43776,7 @@ index 0225fdd..08bda99 100644
phdr.p_memsz = vma->vm_end - vma->vm_start;
offset += phdr.p_filesz;
phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
-@@ -2022,6 +2466,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2022,6 +2470,7 @@ static int elf_core_dump(struct coredump_params *cprm)
phdr.p_align = ELF_EXEC_PAGESIZE;
size += sizeof(phdr);
@@ -43735,7 +43784,7 @@ index 0225fdd..08bda99 100644
if (size > cprm->limit
|| !dump_write(cprm->file, &phdr, sizeof(phdr)))
goto end_coredump;
-@@ -2046,7 +2491,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2046,7 +2495,7 @@ static int elf_core_dump(struct coredump_params *cprm)
unsigned long addr;
unsigned long end;
@@ -43744,7 +43793,7 @@ index 0225fdd..08bda99 100644
for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
struct page *page;
-@@ -2055,6 +2500,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2055,6 +2504,7 @@ static int elf_core_dump(struct coredump_params *cprm)
page = get_dump_page(addr);
if (page) {
void *kaddr = kmap(page);
@@ -43752,7 +43801,7 @@ index 0225fdd..08bda99 100644
stop = ((size += PAGE_SIZE) > cprm->limit) ||
!dump_write(cprm->file, kaddr,
PAGE_SIZE);
-@@ -2072,6 +2518,7 @@ static int elf_core_dump(struct coredump_params *cprm)
+@@ -2072,6 +2522,7 @@ static int elf_core_dump(struct coredump_params *cprm)
if (e_phnum == PN_XNUM) {
size += sizeof(*shdr4extnum);
@@ -43760,7 +43809,7 @@ index 0225fdd..08bda99 100644
if (size > cprm->limit
|| !dump_write(cprm->file, shdr4extnum,
sizeof(*shdr4extnum)))
-@@ -2092,6 +2539,97 @@ out:
+@@ -2092,6 +2543,97 @@ out:
#endif /* CONFIG_ELF_CORE */
@@ -47589,6 +47638,54 @@ index 753af3d..f7b021a 100644
if (!IS_ERR(s))
kfree(s);
}
+diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
+index a3bde91..2524579 100644
+--- a/fs/gfs2/quota.c
++++ b/fs/gfs2/quota.c
+@@ -497,8 +497,11 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
+ struct gfs2_quota_data **qd;
+ int error;
+
+- if (ip->i_res == NULL)
+- gfs2_rs_alloc(ip);
++ if (ip->i_res == NULL) {
++ error = gfs2_rs_alloc(ip);
++ if (error)
++ return error;
++ }
+
+ qd = ip->i_res->rs_qa_qd;
+
+diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
+index c9ed814..4a45d5f 100644
+--- a/fs/gfs2/rgrp.c
++++ b/fs/gfs2/rgrp.c
+@@ -477,7 +477,6 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd)
+ */
+ int gfs2_rs_alloc(struct gfs2_inode *ip)
+ {
+- int error = 0;
+ struct gfs2_blkreserv *res;
+
+ if (ip->i_res)
+@@ -485,7 +484,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
+
+ res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
+ if (!res)
+- error = -ENOMEM;
++ return -ENOMEM;
+
+ down_write(&ip->i_rw_mutex);
+ if (ip->i_res)
+@@ -493,7 +492,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
+ else
+ ip->i_res = res;
+ up_write(&ip->i_rw_mutex);
+- return error;
++ return 0;
+ }
+
+ static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8349a89..51a0254 100644
--- a/fs/hugetlbfs/inode.c
@@ -48448,6 +48545,18 @@ index a9269f1..5490437 100644
set_fs(oldfs);
if (host_err < 0)
+diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
+index f35794b..a506360 100644
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
+ if ((old->path.mnt == new->path.mnt) &&
+ (old->path.dentry == new->path.dentry))
+ return true;
++ break;
+ case (FSNOTIFY_EVENT_NONE):
+ return true;
+ default:
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index d438036..0ecadde 100644
--- a/fs/notify/fanotify/fanotify_user.c
@@ -50078,6 +50187,25 @@ index 1ccfa53..0848f95 100644
} else if (mm) {
pid_t tid = vm_is_stack(priv->task, vma, is_pid);
+diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
+index 29996e8..2d1e0f3 100644
+--- a/fs/pstore/platform.c
++++ b/fs/pstore/platform.c
+@@ -161,12 +161,13 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
+
+ while (s < e) {
+ unsigned long flags;
++ u64 id;
+
+ if (c > psinfo->bufsize)
+ c = psinfo->bufsize;
+ spin_lock_irqsave(&psinfo->buf_lock, flags);
+ memcpy(psinfo->buf, s, c);
+- psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo);
++ psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo);
+ spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+ s += c;
+ c = e - s;
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index d67908b..d13f6a6 100644
--- a/fs/quota/netlink.c
@@ -65250,26 +65378,6 @@ index 9e5425b..8136ffc 100644
struct list_head list;
/* Protects from simultaneous access to first_req list */
spinlock_t info_list_lock;
-diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
-index f10553c..fb5204b 100644
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -2633,6 +2633,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
- unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
-
- /**
-+ * ieee80211_get_mesh_hdrlen - get mesh extension header length
-+ * @meshhdr: the mesh extension header, only the flags field
-+ * (first byte) will be accessed
-+ * Returns the length of the extension header, which is always at
-+ * least 6 bytes and at most 18 if address 5 and 6 are present.
-+ */
-+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
-+
-+/**
- * DOC: Data path helpers
- *
- * In addition to generic utilities, cfg80211 also offers
diff --git a/include/net/flow.h b/include/net/flow.h
index 628e11b..4c475df 100644
--- a/include/net/flow.h
@@ -67668,7 +67776,7 @@ index 2c8857e..288c9c7 100644
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index 3717e7b..473c750 100644
+index 20ef219..b3a0cb2 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
@@ -67691,7 +67799,7 @@ index 3717e7b..473c750 100644
/*
* The futex address must be "naturally" aligned.
*/
-@@ -2714,6 +2720,7 @@ static int __init futex_init(void)
+@@ -2717,6 +2723,7 @@ static int __init futex_init(void)
{
u32 curval;
int i;
@@ -67699,7 +67807,7 @@ index 3717e7b..473c750 100644
/*
* This will fail and we want it. Some arch implementations do
-@@ -2725,8 +2732,11 @@ static int __init futex_init(void)
+@@ -2728,8 +2735,11 @@ static int __init futex_init(void)
* implementation, the non-functional ones will return
* -ENOSYS.
*/
@@ -68223,7 +68331,7 @@ index 91c32a0..7b88d63 100644
seq_printf(m, "%40s %14lu %29s %pS\n",
name, stats->contending_point[i],
diff --git a/kernel/module.c b/kernel/module.c
-index 9ad9ee9..f6e05c2 100644
+index 9ad9ee9..731c128 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -58,6 +58,7 @@
@@ -68512,7 +68620,7 @@ index 9ad9ee9..f6e05c2 100644
}
}
-@@ -2266,7 +2284,7 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+@@ -2266,28 +2284,33 @@ static void layout_symtab(struct module *mod, struct load_info *info)
/* Put symbol section at end of init part of module. */
symsect->sh_flags |= SHF_ALLOC;
@@ -68521,8 +68629,23 @@ index 9ad9ee9..f6e05c2 100644
info->index.sym) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
-@@ -2281,13 +2299,13 @@ static void layout_symtab(struct module *mod, struct load_info *info)
+ src = (void *)info->hdr + symsect->sh_offset;
+ nsrc = symsect->sh_size / sizeof(*src);
+
++ /* strtab always starts with a nul, so offset 0 is the empty string. */
++ strtab_size = 1;
++
+ /* Compute total space required for the core symbols' strtab. */
+- for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
+- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
+- strtab_size += strlen(&info->strtab[src->st_name]) + 1;
++ for (ndst = i = 0; i < nsrc; i++) {
++ if (i == 0 ||
++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++ strtab_size += strlen(&info->strtab[src[i].st_name])+1;
+ ndst++;
}
++ }
/* Append room for core symbols at end of core part. */
- info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
@@ -68539,7 +68662,7 @@ index 9ad9ee9..f6e05c2 100644
info->index.str) | INIT_OFFSET_MASK;
pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
}
-@@ -2305,12 +2323,14 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
+@@ -2305,24 +2328,28 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
/* Make sure we get permanent strtab: don't use info->strtab. */
mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
@@ -68554,10 +68677,23 @@ index 9ad9ee9..f6e05c2 100644
+ mod->core_symtab = dst = mod->module_core_rx + info->symoffs;
+ mod->core_strtab = s = mod->module_core_rx + info->stroffs;
src = mod->symtab;
- *dst = *src;
+- *dst = *src;
*s++ = 0;
-@@ -2323,6 +2343,8 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
- s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
+- for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
+- if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
+- continue;
+-
+- dst[ndst] = *src;
+- dst[ndst++].st_name = s - mod->core_strtab;
+- s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
++ for (ndst = i = 0; i < mod->num_symtab; i++) {
++ if (i == 0 ||
++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++ dst[ndst] = src[i];
++ dst[ndst++].st_name = s - mod->core_strtab;
++ s += strlcpy(s, &mod->strtab[src[i].st_name],
++ KSYM_NAME_LEN) + 1;
++ }
}
mod->core_num_syms = ndst;
+
@@ -68565,7 +68701,7 @@ index 9ad9ee9..f6e05c2 100644
}
#else
static inline void layout_symtab(struct module *mod, struct load_info *info)
-@@ -2356,17 +2378,33 @@ void * __weak module_alloc(unsigned long size)
+@@ -2356,17 +2383,33 @@ void * __weak module_alloc(unsigned long size)
return size == 0 ? NULL : vmalloc_exec(size);
}
@@ -68604,7 +68740,7 @@ index 9ad9ee9..f6e05c2 100644
mutex_unlock(&module_mutex);
}
return ret;
-@@ -2544,8 +2582,14 @@ static struct module *setup_load_info(struct load_info *info)
+@@ -2544,8 +2587,14 @@ static struct module *setup_load_info(struct load_info *info)
static int check_modinfo(struct module *mod, struct load_info *info)
{
const char *modmagic = get_modinfo(info, "vermagic");
@@ -68619,7 +68755,7 @@ index 9ad9ee9..f6e05c2 100644
/* This is allowed: modprobe --force will invalidate it. */
if (!modmagic) {
err = try_to_force_load(mod, "bad vermagic");
-@@ -2568,7 +2612,7 @@ static int check_modinfo(struct module *mod, struct load_info *info)
+@@ -2568,7 +2617,7 @@ static int check_modinfo(struct module *mod, struct load_info *info)
}
/* Set up license info based on the info section */
@@ -68628,7 +68764,7 @@ index 9ad9ee9..f6e05c2 100644
return 0;
}
-@@ -2662,7 +2706,7 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2662,7 +2711,7 @@ static int move_module(struct module *mod, struct load_info *info)
void *ptr;
/* Do the allocs. */
@@ -68637,7 +68773,7 @@ index 9ad9ee9..f6e05c2 100644
/*
* The pointer to this block is stored in the module structure
* which is inside the block. Just mark it as not being a
-@@ -2672,23 +2716,50 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2672,23 +2721,50 @@ static int move_module(struct module *mod, struct load_info *info)
if (!ptr)
return -ENOMEM;
@@ -68696,7 +68832,7 @@ index 9ad9ee9..f6e05c2 100644
/* Transfer each section which specifies SHF_ALLOC */
pr_debug("final section addresses:\n");
-@@ -2699,16 +2770,45 @@ static int move_module(struct module *mod, struct load_info *info)
+@@ -2699,16 +2775,45 @@ static int move_module(struct module *mod, struct load_info *info)
if (!(shdr->sh_flags & SHF_ALLOC))
continue;
@@ -68749,7 +68885,7 @@ index 9ad9ee9..f6e05c2 100644
pr_debug("\t0x%lx %s\n",
(long)shdr->sh_addr, info->secstrings + shdr->sh_name);
}
-@@ -2763,12 +2863,12 @@ static void flush_module_icache(const struct module *mod)
+@@ -2763,12 +2868,12 @@ static void flush_module_icache(const struct module *mod)
* Do it before processing of module parameters, so the module
* can provide parameter accessor functions of its own.
*/
@@ -68768,7 +68904,7 @@ index 9ad9ee9..f6e05c2 100644
set_fs(old_fs);
}
-@@ -2838,8 +2938,10 @@ out:
+@@ -2838,8 +2943,10 @@ out:
static void module_deallocate(struct module *mod, struct load_info *info)
{
percpu_modfree(mod);
@@ -68781,7 +68917,7 @@ index 9ad9ee9..f6e05c2 100644
}
int __weak module_finalize(const Elf_Ehdr *hdr,
-@@ -2852,7 +2954,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
+@@ -2852,7 +2959,9 @@ int __weak module_finalize(const Elf_Ehdr *hdr,
static int post_relocation(struct module *mod, const struct load_info *info)
{
/* Sort exception table now relocations are done. */
@@ -68791,7 +68927,7 @@ index 9ad9ee9..f6e05c2 100644
/* Copy relocated percpu area over. */
percpu_modcopy(mod, (void *)info->sechdrs[info->index.pcpu].sh_addr,
-@@ -2903,9 +3007,38 @@ static struct module *load_module(void __user *umod,
+@@ -2903,9 +3012,38 @@ static struct module *load_module(void __user *umod,
if (err)
goto free_unload;
@@ -68830,7 +68966,7 @@ index 9ad9ee9..f6e05c2 100644
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(mod, &info);
if (err < 0)
-@@ -2921,13 +3054,6 @@ static struct module *load_module(void __user *umod,
+@@ -2921,13 +3059,6 @@ static struct module *load_module(void __user *umod,
flush_module_icache(mod);
@@ -68844,7 +68980,7 @@ index 9ad9ee9..f6e05c2 100644
/* Mark state as coming so strong_try_module_get() ignores us. */
mod->state = MODULE_STATE_COMING;
-@@ -2985,11 +3111,10 @@ static struct module *load_module(void __user *umod,
+@@ -2985,11 +3116,10 @@ static struct module *load_module(void __user *umod,
unlock:
mutex_unlock(&module_mutex);
synchronize_sched();
@@ -68857,7 +68993,7 @@ index 9ad9ee9..f6e05c2 100644
free_unload:
module_unload_free(mod);
free_module:
-@@ -3030,16 +3155,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
+@@ -3030,16 +3160,16 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
MODULE_STATE_COMING, mod);
/* Set RO and NX regions for core */
@@ -68882,7 +69018,7 @@ index 9ad9ee9..f6e05c2 100644
do_mod_ctors(mod);
/* Start the module */
-@@ -3085,11 +3210,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
+@@ -3085,11 +3215,12 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
mod->strtab = mod->core_strtab;
#endif
unset_module_init_ro_nx(mod);
@@ -68900,7 +69036,7 @@ index 9ad9ee9..f6e05c2 100644
mutex_unlock(&module_mutex);
return 0;
-@@ -3120,10 +3246,16 @@ static const char *get_ksymbol(struct module *mod,
+@@ -3120,10 +3251,16 @@ static const char *get_ksymbol(struct module *mod,
unsigned long nextval;
/* At worse, next value is at end of module */
@@ -68920,7 +69056,7 @@ index 9ad9ee9..f6e05c2 100644
/* Scan for closest preceding symbol, and next symbol. (ELF
starts real symbols at 1). */
-@@ -3358,7 +3490,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3358,7 +3495,7 @@ static int m_show(struct seq_file *m, void *p)
char buf[8];
seq_printf(m, "%s %u",
@@ -68929,7 +69065,7 @@ index 9ad9ee9..f6e05c2 100644
print_unload_info(m, mod);
/* Informative for users. */
-@@ -3367,7 +3499,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3367,7 +3504,7 @@ static int m_show(struct seq_file *m, void *p)
mod->state == MODULE_STATE_COMING ? "Loading":
"Live");
/* Used by oprofile and other similar tools. */
@@ -68938,7 +69074,7 @@ index 9ad9ee9..f6e05c2 100644
/* Taints info */
if (mod->taints)
-@@ -3403,7 +3535,17 @@ static const struct file_operations proc_modules_operations = {
+@@ -3403,7 +3540,17 @@ static const struct file_operations proc_modules_operations = {
static int __init proc_modules_init(void)
{
@@ -68956,7 +69092,7 @@ index 9ad9ee9..f6e05c2 100644
return 0;
}
module_init(proc_modules_init);
-@@ -3462,12 +3604,12 @@ struct module *__module_address(unsigned long addr)
+@@ -3462,12 +3609,12 @@ struct module *__module_address(unsigned long addr)
{
struct module *mod;
@@ -68972,7 +69108,7 @@ index 9ad9ee9..f6e05c2 100644
return mod;
return NULL;
}
-@@ -3501,11 +3643,20 @@ bool is_module_text_address(unsigned long addr)
+@@ -3501,11 +3648,20 @@ bool is_module_text_address(unsigned long addr)
*/
struct module *__module_text_address(unsigned long addr)
{
@@ -71437,6 +71573,55 @@ index bd2bea9..6b3c95e 100644
if (atomic_read(&task->signal->live) != 1)
return false;
+diff --git a/lib/list_debug.c b/lib/list_debug.c
+index c24c2f7..bef49ee 100644
+--- a/lib/list_debug.c
++++ b/lib/list_debug.c
+@@ -23,17 +23,19 @@ void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+ {
+- WARN(next->prev != prev,
++ if (WARN(next->prev != prev,
+ "list_add corruption. next->prev should be "
+ "prev (%p), but was %p. (next=%p).\n",
+- prev, next->prev, next);
+- WARN(prev->next != next,
++ prev, next->prev, next) ||
++ WARN(prev->next != next,
+ "list_add corruption. prev->next should be "
+ "next (%p), but was %p. (prev=%p).\n",
+- next, prev->next, prev);
+- WARN(new == prev || new == next,
++ next, prev->next, prev) ||
++ WARN(new == prev || new == next,
+ "list_add double add: new=%p, prev=%p, next=%p.\n",
+- new, prev, next);
++ new, prev, next))
++ return;
++
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+@@ -86,12 +88,14 @@ EXPORT_SYMBOL(list_del);
+ void __list_add_rcu(struct list_head *new,
+ struct list_head *prev, struct list_head *next)
+ {
+- WARN(next->prev != prev,
++ if (WARN(next->prev != prev,
+ "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n",
+- prev, next->prev, next);
+- WARN(prev->next != next,
++ prev, next->prev, next) ||
++ WARN(prev->next != next,
+ "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n",
+- next, prev->next, prev);
++ next, prev->next, prev))
++ return;
++
+ new->next = next;
+ new->prev = prev;
+ rcu_assign_pointer(list_next_rcu(prev), new);
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index e796429..6e38f9f 100644
--- a/lib/radix-tree.c
@@ -74702,7 +74887,7 @@ index aa95e59..b681a63 100644
struct anon_vma_chain *avc;
struct anon_vma *anon_vma;
diff --git a/mm/shmem.c b/mm/shmem.c
-index d2eeca1..3f160be 100644
+index d2eeca1..92f3123 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -31,7 +31,7 @@
@@ -74723,7 +74908,35 @@ index d2eeca1..3f160be 100644
struct shmem_xattr {
struct list_head list; /* anchored by shmem_inode_info->xattr_list */
-@@ -2594,8 +2594,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
+@@ -2207,6 +2207,11 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ static int shmem_xattr_validate(const char *name)
+ {
+ struct { const char *prefix; size_t len; } arr[] = {
++
++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS
++ { XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN},
++#endif
++
+ { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN },
+ { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN }
+ };
+@@ -2260,6 +2265,15 @@ static int shmem_setxattr(struct dentry *dentry, const char *name,
+ if (err)
+ return err;
+
++#ifdef CONFIG_PAX_XATTR_PAX_FLAGS
++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
++ if (strcmp(name, XATTR_NAME_PAX_FLAGS))
++ return -EOPNOTSUPP;
++ if (size > 8)
++ return -EINVAL;
++ }
++#endif
++
+ if (size == 0)
+ value = ""; /* empty EA, do not remove */
+
+@@ -2594,8 +2608,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
int err = -ENOMEM;
/* Round up to L1_CACHE_BYTES to resist false sharing */
@@ -75718,7 +75931,7 @@ index 8c7265a..c96d884 100644
mm->unmap_area = arch_unmap_area;
}
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
-index 2bb90b1..ed47e53 100644
+index 2bb90b1..3795e47 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -39,8 +39,19 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
@@ -75743,15 +75956,7 @@ index 2bb90b1..ed47e53 100644
} while (pte++, addr += PAGE_SIZE, addr != end);
}
-@@ -91,6 +102,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
- unsigned long end, pgprot_t prot, struct page **pages, int *nr)
- {
- pte_t *pte;
-+ int ret = -ENOMEM;
-
- /*
- * nr is a running index into the array which helps higher level
-@@ -100,17 +112,30 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
+@@ -100,16 +111,29 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
@@ -75761,33 +75966,29 @@ index 2bb90b1..ed47e53 100644
struct page *page = pages[*nr];
- if (WARN_ON(!pte_none(*pte)))
-- return -EBUSY;
-- if (WARN_ON(!page))
-- return -ENOMEM;
+#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
+ if (pgprot_val(prot) & _PAGE_NX)
+#endif
+
-+ if (WARN_ON(!pte_none(*pte))) {
-+ ret = -EBUSY;
-+ goto out;
++ if (!pte_none(*pte)) {
++ pax_close_kernel();
++ WARN_ON(1);
+ return -EBUSY;
+- if (WARN_ON(!page))
+ }
-+ if (WARN_ON(!page)) {
-+ ret = -ENOMEM;
-+ goto out;
++ if (!page) {
++ pax_close_kernel();
++ WARN_ON(1);
+ return -ENOMEM;
+ }
set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
(*nr)++;
} while (pte++, addr += PAGE_SIZE, addr != end);
-- return 0;
-+ ret = 0;
-+out:
+ pax_close_kernel();
-+ return ret;
+ return 0;
}
- static int vmap_pmd_range(pud_t *pud, unsigned long addr,
-@@ -119,7 +144,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr,
+@@ -119,7 +143,7 @@ static int vmap_pmd_range(pud_t *pud, unsigned long addr,
pmd_t *pmd;
unsigned long next;
@@ -75796,7 +75997,7 @@ index 2bb90b1..ed47e53 100644
if (!pmd)
return -ENOMEM;
do {
-@@ -136,7 +161,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr,
+@@ -136,7 +160,7 @@ static int vmap_pud_range(pgd_t *pgd, unsigned long addr,
pud_t *pud;
unsigned long next;
@@ -75805,7 +76006,7 @@ index 2bb90b1..ed47e53 100644
if (!pud)
return -ENOMEM;
do {
-@@ -191,11 +216,20 @@ int is_vmalloc_or_module_addr(const void *x)
+@@ -191,11 +215,20 @@ int is_vmalloc_or_module_addr(const void *x)
* and fall back on vmalloc() if that fails. Others
* just put it in the vmalloc space.
*/
@@ -75827,7 +76028,7 @@ index 2bb90b1..ed47e53 100644
return is_vmalloc_addr(x);
}
-@@ -216,8 +250,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
+@@ -216,8 +249,14 @@ struct page *vmalloc_to_page(const void *vmalloc_addr)
if (!pgd_none(*pgd)) {
pud_t *pud = pud_offset(pgd, addr);
@@ -75842,7 +76043,7 @@ index 2bb90b1..ed47e53 100644
if (!pmd_none(*pmd)) {
pte_t *ptep, pte;
-@@ -329,7 +369,7 @@ static void purge_vmap_area_lazy(void);
+@@ -329,7 +368,7 @@ static void purge_vmap_area_lazy(void);
* Allocate a region of KVA of the specified size and alignment, within the
* vstart and vend.
*/
@@ -75851,7 +76052,7 @@ index 2bb90b1..ed47e53 100644
unsigned long align,
unsigned long vstart, unsigned long vend,
int node, gfp_t gfp_mask)
-@@ -1328,6 +1368,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
+@@ -1328,6 +1367,16 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
struct vm_struct *area;
BUG_ON(in_interrupt());
@@ -75868,7 +76069,7 @@ index 2bb90b1..ed47e53 100644
if (flags & VM_IOREMAP) {
int bit = fls(size);
-@@ -1568,6 +1618,11 @@ void *vmap(struct page **pages, unsigned int count,
+@@ -1568,6 +1617,11 @@ void *vmap(struct page **pages, unsigned int count,
if (count > totalram_pages)
return NULL;
@@ -75880,7 +76081,7 @@ index 2bb90b1..ed47e53 100644
area = get_vm_area_caller((count << PAGE_SHIFT), flags,
__builtin_return_address(0));
if (!area)
-@@ -1669,6 +1724,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
+@@ -1669,6 +1723,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
if (!size || (size >> PAGE_SHIFT) > totalram_pages)
goto fail;
@@ -75894,7 +76095,7 @@ index 2bb90b1..ed47e53 100644
area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST,
start, end, node, gfp_mask, caller);
if (!area)
-@@ -1842,10 +1904,9 @@ EXPORT_SYMBOL(vzalloc_node);
+@@ -1842,10 +1903,9 @@ EXPORT_SYMBOL(vzalloc_node);
* For tight control over page level allocator and protection flags
* use __vmalloc() instead.
*/
@@ -75906,7 +76107,7 @@ index 2bb90b1..ed47e53 100644
-1, __builtin_return_address(0));
}
-@@ -2136,6 +2197,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
+@@ -2136,6 +2196,8 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
unsigned long uaddr = vma->vm_start;
unsigned long usize = vma->vm_end - vma->vm_start;
@@ -75915,7 +76116,7 @@ index 2bb90b1..ed47e53 100644
if ((PAGE_SIZE-1) & (unsigned long)addr)
return -EINVAL;
-@@ -2572,7 +2635,7 @@ static int s_show(struct seq_file *m, void *p)
+@@ -2572,7 +2634,7 @@ static int s_show(struct seq_file *m, void *p)
{
struct vm_struct *v = p;
@@ -75924,6 +76125,19 @@ index 2bb90b1..ed47e53 100644
v->addr, v->addr + v->size, v->size);
if (v->caller)
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 99b434b..a018dfc 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2953,6 +2953,8 @@ static int kswapd(void *p)
+ &balanced_classzone_idx);
+ }
+ }
++
++ current->reclaim_state = NULL;
+ return 0;
+ }
+
diff --git a/mm/vmstat.c b/mm/vmstat.c
index df7a674..8b4a4f3 100644
--- a/mm/vmstat.c
@@ -76609,7 +76823,7 @@ index 0337e2b..47914a0 100644
return err;
diff --git a/net/core/dev.c b/net/core/dev.c
-index 2fb9f59..d9a07df 100644
+index aed87a4..72cc526 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1138,9 +1138,13 @@ void dev_load(struct net *net, const char *name)
@@ -77303,10 +77517,10 @@ index d23c657..cb69cc2 100644
static int raw_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index 2a1383c..ff99572 100644
+index c017cb1..9eb15b7d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
-@@ -2523,7 +2523,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
+@@ -2526,7 +2526,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
static __net_init int rt_genid_init(struct net *net)
{
@@ -77315,42 +77529,11 @@ index 2a1383c..ff99572 100644
get_random_bytes(&net->ipv4.dev_addr_genid,
sizeof(net->ipv4.dev_addr_genid));
return 0;
-diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c
-index 813b43a..834857f 100644
---- a/net/ipv4/tcp_illinois.c
-+++ b/net/ipv4/tcp_illinois.c
-@@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext,
- .tcpv_rttcnt = ca->cnt_rtt,
- .tcpv_minrtt = ca->base_rtt,
- };
-- u64 t = ca->sum_rtt;
-
-- do_div(t, ca->cnt_rtt);
-- info.tcpv_rtt = t;
-+ if (info.tcpv_rttcnt > 0) {
-+ u64 t = ca->sum_rtt;
-
-+ do_div(t, info.tcpv_rttcnt);
-+ info.tcpv_rtt = t;
-+ }
- nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
- }
- }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index d377f48..f19e3ec 100644
+index c92c4da..f19e3ec 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
-@@ -4556,6 +4556,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
- struct tcphdr *th;
- bool fragstolen;
-
-+ if (size == 0)
-+ return 0;
-+
- skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
- if (!skb)
- goto err;
-@@ -4728,7 +4731,7 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
+@@ -4731,7 +4731,7 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
* simplifies code)
*/
static void
@@ -78148,31 +78331,6 @@ index 34e4185..8823368 100644
} while (!res);
return res;
}
-diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
-index 3bfb34a..69bf48d 100644
---- a/net/l2tp/l2tp_eth.c
-+++ b/net/l2tp/l2tp_eth.c
-@@ -290,6 +290,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p
-
- out_del_dev:
- free_netdev(dev);
-+ spriv->dev = NULL;
- out_del_session:
- l2tp_session_delete(session);
- out:
-diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
-index 5746d62..327aa07 100644
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -1074,7 +1074,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
- sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
- sdata->u.ibss.ibss_join_req = jiffies;
-
-- memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
-+ memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
- sdata->u.ibss.ssid_len = params->ssid_len;
-
- mutex_unlock(&sdata->u.ibss.mtx);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index bb61f77..3788d63 100644
--- a/net/mac80211/ieee80211_i.h
@@ -78331,111 +78489,11 @@ index c97a065..ff61928 100644
return -EFAULT;
return p;
-diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index 0cb4ede..884155d 100644
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -491,6 +491,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
-
- if (ieee80211_is_action(hdr->frame_control)) {
- u8 category;
-+
-+ /* make sure category field is present */
-+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
-+ return RX_DROP_MONITOR;
-+
- mgmt = (struct ieee80211_mgmt *)hdr;
- category = mgmt->u.action.category;
- if (category != WLAN_CATEGORY_MESH_ACTION &&
-@@ -1426,7 +1431,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
- frag = sc & IEEE80211_SCTL_FRAG;
-
- if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
-- (rx->skb)->len < 24 ||
- is_multicast_ether_addr(hdr->addr1))) {
- /* not fragmented */
- goto out;
-@@ -1849,6 +1853,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
-
- hdr = (struct ieee80211_hdr *) skb->data;
- hdrlen = ieee80211_hdrlen(hdr->frame_control);
-+
-+ /* make sure fixed part of mesh header is there, also checks skb len */
-+ if (!pskb_may_pull(rx->skb, hdrlen + 6))
-+ return RX_DROP_MONITOR;
-+
-+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-+
-+ /* make sure full mesh header is there, also checks skb len */
-+ if (!pskb_may_pull(rx->skb,
-+ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
-+ return RX_DROP_MONITOR;
-+
-+ /* reload pointers */
-+ hdr = (struct ieee80211_hdr *) skb->data;
- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
-
- /* frame is in RMC, don't forward */
-@@ -1871,9 +1889,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
- if (is_multicast_ether_addr(hdr->addr1)) {
- mpp_addr = hdr->addr3;
- proxied_addr = mesh_hdr->eaddr1;
-- } else {
-+ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
-+ /* has_a4 already checked in ieee80211_rx_mesh_check */
- mpp_addr = hdr->addr4;
- proxied_addr = mesh_hdr->eaddr2;
-+ } else {
-+ return RX_DROP_MONITOR;
- }
-
- rcu_read_lock();
-@@ -2313,6 +2334,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
- }
- break;
- case WLAN_CATEGORY_SELF_PROTECTED:
-+ if (len < (IEEE80211_MIN_ACTION_SIZE +
-+ sizeof(mgmt->u.action.u.self_prot.action_code)))
-+ break;
-+
- switch (mgmt->u.action.u.self_prot.action_code) {
- case WLAN_SP_MESH_PEERING_OPEN:
- case WLAN_SP_MESH_PEERING_CLOSE:
-@@ -2331,6 +2356,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
- }
- break;
- case WLAN_CATEGORY_MESH_ACTION:
-+ if (len < (IEEE80211_MIN_ACTION_SIZE +
-+ sizeof(mgmt->u.action.u.mesh_action.action_code)))
-+ break;
-+
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- if (mesh_action_is_path_sel(mgmt) &&
-@@ -2865,10 +2894,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
- if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
- local->dot11ReceivedFragmentCount++;
-
-- if (ieee80211_is_mgmt(fc))
-- err = skb_linearize(skb);
-- else
-+ if (ieee80211_is_mgmt(fc)) {
-+ /* drop frame if too short for header */
-+ if (skb->len < ieee80211_hdrlen(fc))
-+ err = -ENOBUFS;
-+ else
-+ err = skb_linearize(skb);
-+ } else {
- err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
-+ }
-
- if (err) {
- dev_kfree_skb(skb);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-index c9b52f7..4da1014 100644
+index 1cfe6d5..c428ba3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
-@@ -1251,7 +1251,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
+@@ -1279,7 +1279,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
}
#endif
/* everything else happens only if HW was up & running */
@@ -78773,10 +78831,10 @@ index 4fe4fb4..87a89e5 100644
return 0;
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
-index 9172179..a4035c4 100644
+index 0426b67..d6ddaca 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
-@@ -769,7 +769,7 @@ static void netlink_overrun(struct sock *sk)
+@@ -780,7 +780,7 @@ static void netlink_overrun(struct sock *sk)
sk->sk_error_report(sk);
}
}
@@ -78785,7 +78843,7 @@ index 9172179..a4035c4 100644
}
static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
-@@ -2059,7 +2059,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
+@@ -2070,7 +2070,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
sk_wmem_alloc_get(s),
nlk->cb,
atomic_read(&s->sk_refcnt),
@@ -80023,27 +80081,6 @@ index bc7430b..35349de 100644
struct rfkill *rfkill;
struct work_struct rfkill_sync;
-diff --git a/net/wireless/util.c b/net/wireless/util.c
-index 994e2f0..f67aeb1 100644
---- a/net/wireless/util.c
-+++ b/net/wireless/util.c
-@@ -309,7 +309,7 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
- }
- EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
-
--static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
-+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
- {
- int ae = meshhdr->flags & MESH_FLAGS_AE;
- /* 7.1.3.5a.2 */
-@@ -326,6 +326,7 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
- return 6;
- }
- }
-+EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen);
-
- int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
- enum nl80211_iftype iftype)
diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
index b0eb7aa..7d73e82 100644
--- a/net/wireless/wext-core.c
@@ -81829,7 +81866,7 @@ index ffd2025..df062c9 100644
/* PCM3052 register definitions */
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
-index 08fde00..0bf641a 100644
+index 4c1cc51..16040040 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1189,10 +1189,10 @@ snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const
@@ -81917,10 +81954,10 @@ index 91cdf94..4085161 100644
if (err < 0)
return err;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
-index 53b5ada..2db94c8 100644
+index bf3bf43..3826cbc 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
-@@ -2780,11 +2780,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
+@@ -2803,11 +2803,11 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
switch (substream->stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
@@ -87665,10 +87702,10 @@ index 0000000..9332f17
+_003896_hash nfs_parse_server_name 2 1899 _003896_hash NULL
diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c
new file mode 100644
-index 0000000..244559e
+index 0000000..1aa0dce
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin.c
-@@ -0,0 +1,1879 @@
+@@ -0,0 +1,1865 @@
+/*
+ * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
@@ -87746,10 +87783,10 @@ index 0000000..244559e
+static unsigned int handle_function(void);
+static void check_size_overflow(gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before);
+static tree get_size_overflow_type(gimple stmt, const_tree node);
-+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3);
++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3);
+
+static struct plugin_info size_overflow_plugin_info = {
-+ .version = "20120930beta",
++ .version = "20121113beta",
+ .help = "no-size-overflow\tturn off size overflow checking\n",
+};
+
@@ -88068,6 +88105,7 @@ index 0000000..244559e
+ tree type = TREE_TYPE(rhs1);
+ tree lhs = create_new_var(type);
+
++ gcc_assert(types_compatible_p(type, TREE_TYPE(rhs2)));
+ assign = gimple_build_assign_with_ops(code, lhs, rhs1, rhs2);
+ gimple_set_lhs(assign, make_ssa_name(lhs, assign));
+
@@ -88133,42 +88171,41 @@ index 0000000..244559e
+ return assign;
+}
+
-+static tree cast_to_new_size_overflow_type(gimple stmt, tree new_rhs1, tree size_overflow_type, bool before)
++static tree cast_to_new_size_overflow_type(gimple stmt, tree rhs, tree size_overflow_type, bool before)
+{
-+ const_gimple assign;
++ gimple assign;
+ gimple_stmt_iterator gsi;
+
-+ if (new_rhs1 == NULL_TREE)
++ if (rhs == NULL_TREE)
+ return NULL_TREE;
+
-+ if (!useless_type_conversion_p(TREE_TYPE(new_rhs1), size_overflow_type)) {
-+ gsi = gsi_for_stmt(stmt);
-+ assign = build_cast_stmt(size_overflow_type, new_rhs1, CREATE_NEW_VAR, &gsi, before);
-+ return gimple_get_lhs(assign);
-+ }
-+ return new_rhs1;
++ if (types_compatible_p(TREE_TYPE(rhs), size_overflow_type) && gimple_plf(stmt, MY_STMT))
++ return rhs;
++
++ gsi = gsi_for_stmt(stmt);
++ assign = build_cast_stmt(size_overflow_type, rhs, CREATE_NEW_VAR, &gsi, before);
++ gimple_set_plf(assign, MY_STMT, true);
++ return gimple_get_lhs(assign);
+}
+
-+static tree follow_overflow_type_and_dup(struct pointer_set_t *visited, gimple stmt, const_tree node, tree new_rhs1, tree new_rhs2, tree new_rhs3)
++static tree cast_to_TI_type(gimple stmt, tree node)
+{
-+ tree size_overflow_type = get_size_overflow_type(stmt, node);
-+
-+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
-+
-+ if (new_rhs2 != NULL_TREE)
-+ new_rhs2 = cast_to_new_size_overflow_type(stmt, new_rhs2, size_overflow_type, BEFORE_STMT);
++ gimple_stmt_iterator gsi;
++ gimple cast_stmt;
++ tree type = TREE_TYPE(node);
+
-+ if (new_rhs3 != NULL_TREE)
-+ new_rhs3 = cast_to_new_size_overflow_type(stmt, new_rhs3, size_overflow_type, BEFORE_STMT);
++ if (types_compatible_p(type, intTI_type_node))
++ return node;
+
-+ return dup_assign(visited, stmt, size_overflow_type, new_rhs1, new_rhs2, new_rhs3);
++ gsi = gsi_for_stmt(stmt);
++ cast_stmt = build_cast_stmt(intTI_type_node, node, CREATE_NEW_VAR, &gsi, BEFORE_STMT);
++ gimple_set_plf(cast_stmt, MY_STMT, true);
++ return gimple_get_lhs(cast_stmt);
+}
+
-+
+static tree create_assign(struct pointer_set_t *visited, gimple oldstmt, tree rhs1, bool before)
+{
-+ tree size_overflow_type, lhs;
-+ gimple stmt;
++ tree lhs;
+ gimple_stmt_iterator gsi;
+
+ if (rhs1 == NULL_TREE) {
@@ -88206,18 +88243,14 @@ index 0000000..244559e
+ oldstmt = gsi_stmt(gsi);
+ }
+
-+ size_overflow_type = get_size_overflow_type(oldstmt, lhs);
-+
-+ stmt = build_cast_stmt(size_overflow_type, rhs1, CREATE_NEW_VAR, &gsi, before);
-+ gimple_set_plf(stmt, MY_STMT, true);
-+ return gimple_get_lhs(stmt);
++ return cast_to_new_size_overflow_type(oldstmt, rhs1, get_size_overflow_type(oldstmt, lhs), before);
+}
+
-+static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, tree size_overflow_type, tree rhs1, tree rhs2, tree __unused rhs3)
++static tree dup_assign(struct pointer_set_t *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3)
+{
+ gimple stmt;
+ gimple_stmt_iterator gsi;
-+ tree new_var, lhs = gimple_get_lhs(oldstmt);
++ tree size_overflow_type, new_var, lhs = gimple_get_lhs(oldstmt);
+
+ if (gimple_plf(oldstmt, MY_STMT))
+ return lhs;
@@ -88238,6 +88271,8 @@ index 0000000..244559e
+ if (gimple_assign_rhs_code(oldstmt) == WIDEN_MULT_EXPR)
+ gimple_assign_set_rhs_code(stmt, MULT_EXPR);
+
++ size_overflow_type = get_size_overflow_type(oldstmt, node);
++
+ if (is_bool(lhs))
+ new_var = SSA_NAME_VAR(lhs);
+ else
@@ -88246,7 +88281,7 @@ index 0000000..244559e
+ gimple_set_lhs(stmt, new_var);
+
+ if (rhs1 != NULL_TREE) {
-+ if (!gimple_assign_cast_p(oldstmt))
++ if (!gimple_assign_cast_p(oldstmt) && TREE_CODE_CLASS(gimple_assign_rhs_code(oldstmt)) != tcc_comparison)
+ rhs1 = cast_a_tree(size_overflow_type, rhs1);
+ gimple_assign_set_rhs1(stmt, rhs1);
+ }
@@ -88498,7 +88533,7 @@ index 0000000..244559e
+ return lhs;
+
+ if (gimple_plf(stmt, NO_CAST_CHECK))
-+ return follow_overflow_type_and_dup(visited, stmt, rhs1, new_rhs1, NULL_TREE, NULL_TREE);
++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE);
+
+ if (gimple_assign_rhs_code(stmt) == BIT_NOT_EXPR) {
+ size_overflow_type = get_size_overflow_type(stmt, rhs1);
@@ -88508,7 +88543,7 @@ index 0000000..244559e
+ }
+
+ if (!gimple_assign_cast_p(stmt) || check_undefined_integer_operation(stmt))
-+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE);
++ return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE);
+
+ size_overflow_type = get_size_overflow_type(stmt, rhs1);
+ new_rhs1 = cast_to_new_size_overflow_type(stmt, new_rhs1, size_overflow_type, BEFORE_STMT);
@@ -88693,8 +88728,8 @@ index 0000000..244559e
+ cast_rhs_type = TREE_TYPE(cast_rhs);
+ type_max_type = TREE_TYPE(type_max);
+ type_min_type = TREE_TYPE(type_min);
-+ gcc_assert(useless_type_conversion_p(cast_rhs_type, type_max_type));
-+ gcc_assert(useless_type_conversion_p(type_max_type, type_min_type));
++ gcc_assert(types_compatible_p(cast_rhs_type, type_max_type));
++ gcc_assert(types_compatible_p(type_max_type, type_min_type));
+
+ insert_check_size_overflow(stmt, GT_EXPR, cast_rhs, type_max, before, false);
+ insert_check_size_overflow(stmt, LT_EXPR, cast_rhs, type_min, before, true);
@@ -88722,7 +88757,7 @@ index 0000000..244559e
+ if (gimple_assign_rhs_code(def_stmt) == RSHIFT_EXPR)
+ return get_size_overflow_type(change_rhs_def_stmt, change_rhs);
+
-+ if (!useless_type_conversion_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) {
++ if (!types_compatible_p(lhs_type, rhs1_type) || !useless_type_conversion_p(rhs1_type, rhs2_type)) {
+ debug_gimple_stmt(def_stmt);
+ gcc_unreachable();
+ }
@@ -88739,64 +88774,20 @@ index 0000000..244559e
+ return true;
+}
+
-+static tree get_cast_def_stmt_rhs(const_tree new_rhs)
-+{
-+ gimple def_stmt;
-+
-+ def_stmt = get_def_stmt(new_rhs);
-+ // get_size_overflow_type
-+ if (LONG_TYPE_SIZE != GET_MODE_BITSIZE(SImode))
-+ gcc_assert(gimple_assign_cast_p(def_stmt));
-+ return gimple_assign_rhs1(def_stmt);
-+}
-+
-+static tree cast_to_int_TI_type_and_check(gimple stmt, tree new_rhs)
-+{
-+ gimple_stmt_iterator gsi;
-+ const_gimple cast_stmt;
-+ gimple def_stmt;
-+ enum machine_mode mode = TYPE_MODE(TREE_TYPE(new_rhs));
-+
-+ if (mode != TImode && mode != DImode) {
-+ def_stmt = get_def_stmt(new_rhs);
-+ gcc_assert(gimple_assign_cast_p(def_stmt));
-+ new_rhs = gimple_assign_rhs1(def_stmt);
-+ mode = TYPE_MODE(TREE_TYPE(new_rhs));
-+ }
-+
-+ gcc_assert(mode == TImode || mode == DImode);
-+
-+ if (mode == TYPE_MODE(intTI_type_node) && useless_type_conversion_p(TREE_TYPE(new_rhs), intTI_type_node))
-+ return new_rhs;
-+
-+ gsi = gsi_for_stmt(stmt);
-+ cast_stmt = build_cast_stmt(intTI_type_node, new_rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT);
-+ new_rhs = gimple_get_lhs(cast_stmt);
-+
-+ if (mode == DImode)
-+ return new_rhs;
-+
-+ check_size_overflow(stmt, intTI_type_node, new_rhs, new_rhs, BEFORE_STMT);
-+
-+ return new_rhs;
-+}
-+
-+static bool is_an_integer_trunction(const_gimple stmt)
++static bool is_subtraction_special(const_gimple stmt)
+{
+ gimple rhs1_def_stmt, rhs2_def_stmt;
-+ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1;
-+ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode;
++ const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1, rhs1_def_stmt_lhs, rhs2_def_stmt_lhs;
++ enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode, rhs1_def_stmt_lhs_mode, rhs2_def_stmt_lhs_mode;
+ const_tree rhs1 = gimple_assign_rhs1(stmt);
+ const_tree rhs2 = gimple_assign_rhs2(stmt);
-+ enum machine_mode rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1));
-+ enum machine_mode rhs2_mode = TYPE_MODE(TREE_TYPE(rhs2));
+
+ if (is_gimple_constant(rhs1) || is_gimple_constant(rhs2))
+ return false;
+
+ gcc_assert(TREE_CODE(rhs1) == SSA_NAME && TREE_CODE(rhs2) == SSA_NAME);
+
-+ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR || rhs1_mode != SImode || rhs2_mode != SImode)
++ if (gimple_assign_rhs_code(stmt) != MINUS_EXPR)
+ return false;
+
+ rhs1_def_stmt = get_def_stmt(rhs1);
@@ -88806,9 +88797,15 @@ index 0000000..244559e
+
+ rhs1_def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt);
+ rhs2_def_stmt_rhs1 = gimple_assign_rhs1(rhs2_def_stmt);
++ rhs1_def_stmt_lhs = gimple_get_lhs(rhs1_def_stmt);
++ rhs2_def_stmt_lhs = gimple_get_lhs(rhs2_def_stmt);
+ rhs1_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_rhs1));
+ rhs2_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_rhs1));
-+ if (rhs1_def_stmt_rhs1_mode != DImode || rhs2_def_stmt_rhs1_mode != DImode)
++ rhs1_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_lhs));
++ rhs2_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_lhs));
++ if (GET_MODE_BITSIZE(rhs1_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs1_def_stmt_lhs_mode))
++ return false;
++ if (GET_MODE_BITSIZE(rhs2_def_stmt_rhs1_mode) <= GET_MODE_BITSIZE(rhs2_def_stmt_lhs_mode))
+ return false;
+
+ gimple_set_plf(rhs1_def_stmt, NO_CAST_CHECK, true);
@@ -88816,37 +88813,63 @@ index 0000000..244559e
+ return true;
+}
+
++static tree get_def_stmt_rhs(const_tree var)
++{
++ tree rhs1, def_stmt_rhs1;
++ gimple rhs1_def_stmt, def_stmt_rhs1_def_stmt, def_stmt;
++
++ def_stmt = get_def_stmt(var);
++ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP && gimple_plf(def_stmt, MY_STMT) && gimple_assign_cast_p(def_stmt));
++
++ rhs1 = gimple_assign_rhs1(def_stmt);
++ rhs1_def_stmt = get_def_stmt(rhs1);
++ gcc_assert(gimple_code(rhs1_def_stmt) != GIMPLE_NOP);
++ if (!gimple_assign_cast_p(rhs1_def_stmt))
++ return rhs1;
++
++ def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt);
++ def_stmt_rhs1_def_stmt = get_def_stmt(def_stmt_rhs1);
++
++ switch (gimple_code(def_stmt_rhs1_def_stmt)) {
++ case GIMPLE_CALL:
++ case GIMPLE_NOP:
++ case GIMPLE_ASM:
++ return def_stmt_rhs1;
++ case GIMPLE_ASSIGN:
++ return rhs1;
++ default:
++ debug_gimple_stmt(def_stmt_rhs1_def_stmt);
++ gcc_unreachable();
++ }
++}
++
+static tree handle_integer_truncation(struct pointer_set_t *visited, const_tree lhs)
+{
+ tree new_rhs1, new_rhs2;
+ tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs;
-+ tree new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type;
+ gimple assign, stmt = get_def_stmt(lhs);
+ tree rhs1 = gimple_assign_rhs1(stmt);
+ tree rhs2 = gimple_assign_rhs2(stmt);
+
-+ if (!is_an_integer_trunction(stmt))
++ if (!is_subtraction_special(stmt))
+ return NULL_TREE;
+
+ new_rhs1 = expand(visited, rhs1);
+ new_rhs2 = expand(visited, rhs2);
+
-+ new_rhs1_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs1);
-+ new_rhs2_def_stmt_rhs1 = get_cast_def_stmt_rhs(new_rhs2);
-+
-+ new_rhs1_def_stmt_rhs1_type = TREE_TYPE(new_rhs1_def_stmt_rhs1);
-+ new_rhs2_def_stmt_rhs1_type = TREE_TYPE(new_rhs2_def_stmt_rhs1);
++ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs1);
++ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs2);
+
-+ if (!useless_type_conversion_p(new_rhs1_def_stmt_rhs1_type, new_rhs2_def_stmt_rhs1_type)) {
-+ new_rhs1_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs1_def_stmt_rhs1);
-+ new_rhs2_def_stmt_rhs1 = cast_to_int_TI_type_and_check(stmt, new_rhs2_def_stmt_rhs1);
++ if (!types_compatible_p(TREE_TYPE(new_rhs1_def_stmt_rhs1), TREE_TYPE(new_rhs2_def_stmt_rhs1))) {
++ new_rhs1_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs1_def_stmt_rhs1);
++ new_rhs2_def_stmt_rhs1 = cast_to_TI_type(stmt, new_rhs2_def_stmt_rhs1);
+ }
+
+ assign = create_binary_assign(MINUS_EXPR, stmt, new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1);
+ new_lhs = gimple_get_lhs(assign);
+ check_size_overflow(assign, TREE_TYPE(new_lhs), new_lhs, rhs1, AFTER_STMT);
+
-+ return follow_overflow_type_and_dup(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
++ return dup_assign(visited, stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
+}
+
+static bool is_a_neg_overflow(const_gimple stmt, const_tree rhs)
@@ -88949,7 +88972,7 @@ index 0000000..244559e
+ if (is_a_constant_overflow(def_stmt, rhs1))
+ return handle_intentional_overflow(visited, !is_a_cast_and_const_overflow(rhs2), def_stmt, new_rhs2, NULL_TREE, new_rhs2);
+
-+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE);
+}
+
+#if BUILDING_GCC_VERSION >= 4007
@@ -88976,7 +88999,7 @@ index 0000000..244559e
+ new_rhs2 = get_new_rhs(visited, size_overflow_type, rhs2);
+ new_rhs3 = get_new_rhs(visited, size_overflow_type, rhs3);
+
-+ return follow_overflow_type_and_dup(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3);
++ return dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, new_rhs3);
+}
+#endif
+