summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2016-07-12 14:59:29 -0400
committerAnthony G. Basile <blueness@gentoo.org>2016-07-12 14:59:29 -0400
commite541c2b69dd1103c5b8377a64ea8cb82d646558c (patch)
tree237a0604e3e155357abca9c357e791fe51afc353
parentgrsecurity-3.1-4.6.3-201607070721 (diff)
downloadhardened-patchset-20160711.tar.gz
hardened-patchset-20160711.tar.bz2
hardened-patchset-20160711.zip
grsecurity-3.1-4.6.4-20160711220520160711
-rw-r--r--4.6.3/1002_linux-4.6.3.patch4713
-rw-r--r--4.6.4/0000_README (renamed from 4.6.3/0000_README)6
-rw-r--r--4.6.4/4420_grsecurity-3.1-4.6.4-201607112205.patch (renamed from 4.6.3/4420_grsecurity-3.1-4.6.3-201607070721.patch)182
-rw-r--r--4.6.4/4425_grsec_remove_EI_PAX.patch (renamed from 4.6.3/4425_grsec_remove_EI_PAX.patch)0
-rw-r--r--4.6.4/4427_force_XATTR_PAX_tmpfs.patch (renamed from 4.6.3/4427_force_XATTR_PAX_tmpfs.patch)0
-rw-r--r--4.6.4/4430_grsec-remove-localversion-grsec.patch (renamed from 4.6.3/4430_grsec-remove-localversion-grsec.patch)0
-rw-r--r--4.6.4/4435_grsec-mute-warnings.patch (renamed from 4.6.3/4435_grsec-mute-warnings.patch)0
-rw-r--r--4.6.4/4440_grsec-remove-protected-paths.patch (renamed from 4.6.3/4440_grsec-remove-protected-paths.patch)0
-rw-r--r--4.6.4/4450_grsec-kconfig-default-gids.patch (renamed from 4.6.3/4450_grsec-kconfig-default-gids.patch)0
-rw-r--r--4.6.4/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 4.6.3/4465_selinux-avc_audit-log-curr_ip.patch)0
-rw-r--r--4.6.4/4470_disable-compat_vdso.patch (renamed from 4.6.3/4470_disable-compat_vdso.patch)0
-rw-r--r--4.6.4/4475_emutramp_default_on.patch (renamed from 4.6.3/4475_emutramp_default_on.patch)0
12 files changed, 152 insertions, 4749 deletions
diff --git a/4.6.3/1002_linux-4.6.3.patch b/4.6.3/1002_linux-4.6.3.patch
deleted file mode 100644
index f999198..0000000
--- a/4.6.3/1002_linux-4.6.3.patch
+++ /dev/null
@@ -1,4713 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 93068c2..c62b531 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 4
- PATCHLEVEL = 6
--SUBLEVEL = 2
-+SUBLEVEL = 3
- EXTRAVERSION =
- NAME = Charred Weasel
-
-diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
-index ef9119f..4d93758 100644
---- a/arch/arm/kernel/ptrace.c
-+++ b/arch/arm/kernel/ptrace.c
-@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
- if (ret)
- return ret;
-
-- vfp_flush_hwstate(thread);
- thread->vfpstate.hard = new_vfp;
-+ vfp_flush_hwstate(thread);
-
- return 0;
- }
-diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
-index 24ed037..83d48a5 100644
---- a/arch/arm64/include/asm/elf.h
-+++ b/arch/arm64/include/asm/elf.h
-@@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
- #define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
- #endif
-
--#ifdef CONFIG_COMPAT
--
- #ifdef __AARCH64EB__
- #define COMPAT_ELF_PLATFORM ("v8b")
- #else
- #define COMPAT_ELF_PLATFORM ("v8l")
- #endif
-
-+#ifdef CONFIG_COMPAT
-+
- #define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
-
- /* AArch32 registers. */
-diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
-index f0c3fb7..2d2d7cb 100644
---- a/arch/arm64/kernel/cpuinfo.c
-+++ b/arch/arm64/kernel/cpuinfo.c
-@@ -22,6 +22,8 @@
-
- #include <linux/bitops.h>
- #include <linux/bug.h>
-+#include <linux/compat.h>
-+#include <linux/elf.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/personality.h>
-@@ -104,6 +106,7 @@ static const char *const compat_hwcap2_str[] = {
- static int c_show(struct seq_file *m, void *v)
- {
- int i, j;
-+ bool compat = personality(current->personality) == PER_LINUX32;
-
- for_each_online_cpu(i) {
- struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
-@@ -115,6 +118,9 @@ static int c_show(struct seq_file *m, void *v)
- * "processor". Give glibc what it expects.
- */
- seq_printf(m, "processor\t: %d\n", i);
-+ if (compat)
-+ seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
-+ MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
-
- seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
- loops_per_jiffy / (500000UL/HZ),
-@@ -127,7 +133,7 @@ static int c_show(struct seq_file *m, void *v)
- * software which does already (at least for 32-bit).
- */
- seq_puts(m, "Features\t:");
-- if (personality(current->personality) == PER_LINUX32) {
-+ if (compat) {
- #ifdef CONFIG_COMPAT
- for (j = 0; compat_hwcap_str[j]; j++)
- if (compat_elf_hwcap & (1 << j))
-diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
-index fff7cd4..3129df9 100644
---- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
-+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
-@@ -190,12 +190,11 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
- if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
- continue;
-
-- if (cpu_if->vgic_elrsr & (1 << i)) {
-+ if (cpu_if->vgic_elrsr & (1 << i))
- cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
-- continue;
-- }
-+ else
-+ cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
-
-- cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
- __gic_v3_set_lr(0, i);
- }
-
-diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
-index 3ae4a28..10b79e9 100644
---- a/arch/arm64/mm/fault.c
-+++ b/arch/arm64/mm/fault.c
-@@ -109,7 +109,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
- * PTE_RDONLY is cleared by default in the asm below, so set it in
- * back if necessary (read-only or clean PTE).
- */
-- if (!pte_write(entry) || !dirty)
-+ if (!pte_write(entry) || !pte_sw_dirty(entry))
- pte_val(entry) |= PTE_RDONLY;
-
- /*
-diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
-index d7c0acb..8d49614 100644
---- a/arch/parisc/kernel/unaligned.c
-+++ b/arch/parisc/kernel/unaligned.c
-@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
- break;
- }
-
-- if (modify && R1(regs->iir))
-+ if (ret == 0 && modify && R1(regs->iir))
- regs->gr[R1(regs->iir)] = newbase;
-
-
-@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)
-
- if (ret)
- {
-+ /*
-+ * The unaligned handler failed.
-+ * If we were called by __get_user() or __put_user() jump
-+ * to it's exception fixup handler instead of crashing.
-+ */
-+ if (!user_mode(regs) && fixup_exception(regs))
-+ return;
-+
- printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
- die_if_kernel("Unaligned data reference", regs, 28);
-
-diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
-index f5f4c66..166d863 100644
---- a/arch/powerpc/include/asm/reg.h
-+++ b/arch/powerpc/include/asm/reg.h
-@@ -715,7 +715,7 @@
- #define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
- #define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
- #define SPRN_MMCR1 798
--#define SPRN_MMCR2 769
-+#define SPRN_MMCR2 785
- #define SPRN_MMCRA 0x312
- #define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
- #define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
-@@ -752,13 +752,13 @@
- #define SPRN_PMC6 792
- #define SPRN_PMC7 793
- #define SPRN_PMC8 794
--#define SPRN_SIAR 780
--#define SPRN_SDAR 781
- #define SPRN_SIER 784
- #define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
- #define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
- #define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
- #define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
-+#define SPRN_SIAR 796
-+#define SPRN_SDAR 797
- #define SPRN_TACR 888
- #define SPRN_TCSCR 889
- #define SPRN_CSIGR 890
-diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
-index da51925..ccd2037 100644
---- a/arch/powerpc/kernel/prom_init.c
-+++ b/arch/powerpc/kernel/prom_init.c
-@@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
- W(0xffff0000), W(0x003e0000), /* POWER6 */
- W(0xffff0000), W(0x003f0000), /* POWER7 */
- W(0xffff0000), W(0x004b0000), /* POWER8E */
-+ W(0xffff0000), W(0x004c0000), /* POWER8NVL */
- W(0xffff0000), W(0x004d0000), /* POWER8 */
- W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
- W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
-diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
-index 7635b1c..f4acba2 100644
---- a/arch/powerpc/mm/hash_utils_64.c
-+++ b/arch/powerpc/mm/hash_utils_64.c
-@@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
- },
- };
-
-+/*
-+ * 'R' and 'C' update notes:
-+ * - Under pHyp or KVM, the updatepp path will not set C, thus it *will*
-+ * create writeable HPTEs without C set, because the hcall H_PROTECT
-+ * that we use in that case will not update C
-+ * - The above is however not a problem, because we also don't do that
-+ * fancy "no flush" variant of eviction and we use H_REMOVE which will
-+ * do the right thing and thus we don't have the race I described earlier
-+ *
-+ * - Under bare metal, we do have the race, so we need R and C set
-+ * - We make sure R is always set and never lost
-+ * - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping
-+ */
- unsigned long htab_convert_pte_flags(unsigned long pteflags)
- {
- unsigned long rflags = 0;
-@@ -180,9 +193,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
- rflags |= 0x1;
- }
- /*
-- * Always add "C" bit for perf. Memory coherence is always enabled
-+ * We can't allow hardware to update hpte bits. Hence always
-+ * set 'R' bit and set 'C' if it is a write fault
-+ * Memory coherence is always enabled
- */
-- rflags |= HPTE_R_C | HPTE_R_M;
-+ rflags |= HPTE_R_R | HPTE_R_M;
-+
-+ if (pteflags & _PAGE_DIRTY)
-+ rflags |= HPTE_R_C;
- /*
- * Add in WIG bits
- */
-diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
-index ac3ffd9..405baaf 100644
---- a/arch/powerpc/platforms/pseries/eeh_pseries.c
-+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
-@@ -615,29 +615,50 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
- {
- int config_addr;
- int ret;
-+ /* Waiting 0.2s maximum before skipping configuration */
-+ int max_wait = 200;
-
- /* Figure out the PE address */
- config_addr = pe->config_addr;
- if (pe->addr)
- config_addr = pe->addr;
-
-- /* Use new configure-pe function, if supported */
-- if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
-- ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid));
-- } else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
-- ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
-- config_addr, BUID_HI(pe->phb->buid),
-- BUID_LO(pe->phb->buid));
-- } else {
-- return -EFAULT;
-- }
-+ while (max_wait > 0) {
-+ /* Use new configure-pe function, if supported */
-+ if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
-+ ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
-+ config_addr, BUID_HI(pe->phb->buid),
-+ BUID_LO(pe->phb->buid));
-+ } else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
-+ ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
-+ config_addr, BUID_HI(pe->phb->buid),
-+ BUID_LO(pe->phb->buid));
-+ } else {
-+ return -EFAULT;
-+ }
-
-- if (ret)
-- pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
-- __func__, pe->phb->global_number, pe->addr, ret);
-+ if (!ret)
-+ return ret;
-+
-+ /*
-+ * If RTAS returns a delay value that's above 100ms, cut it
-+ * down to 100ms in case firmware made a mistake. For more
-+ * on how these delay values work see rtas_busy_delay_time
-+ */
-+ if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
-+ ret <= RTAS_EXTENDED_DELAY_MAX)
-+ ret = RTAS_EXTENDED_DELAY_MIN+2;
-+
-+ max_wait -= rtas_busy_delay_time(ret);
-+
-+ if (max_wait < 0)
-+ break;
-+
-+ rtas_busy_delay(ret);
-+ }
-
-+ pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
-+ __func__, pe->phb->global_number, pe->addr, ret);
- return ret;
- }
-
-diff --git a/arch/s390/net/bpf_jit.h b/arch/s390/net/bpf_jit.h
-index f010c93..fda605d 100644
---- a/arch/s390/net/bpf_jit.h
-+++ b/arch/s390/net/bpf_jit.h
-@@ -37,7 +37,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
- * | | |
- * +---------------+ |
- * | 8 byte skbp | |
-- * R15+170 -> +---------------+ |
-+ * R15+176 -> +---------------+ |
- * | 8 byte hlen | |
- * R15+168 -> +---------------+ |
- * | 4 byte align | |
-@@ -58,7 +58,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
- #define STK_OFF (STK_SPACE - STK_160_UNUSED)
- #define STK_OFF_TMP 160 /* Offset of tmp buffer on stack */
- #define STK_OFF_HLEN 168 /* Offset of SKB header length on stack */
--#define STK_OFF_SKBP 170 /* Offset of SKB pointer on stack */
-+#define STK_OFF_SKBP 176 /* Offset of SKB pointer on stack */
-
- #define STK_OFF_R6 (160 - 11 * 8) /* Offset of r6 on stack */
- #define STK_OFF_TCCNT (160 - 12 * 8) /* Offset of tail_call_cnt on stack */
-diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
-index 3c0bfc1..2662fcc 100644
---- a/arch/s390/net/bpf_jit_comp.c
-+++ b/arch/s390/net/bpf_jit_comp.c
-@@ -45,7 +45,7 @@ struct bpf_jit {
- int labels[1]; /* Labels for local jumps */
- };
-
--#define BPF_SIZE_MAX 0x7ffff /* Max size for program (20 bit signed displ) */
-+#define BPF_SIZE_MAX 0xffff /* Max size for program (16 bit branches) */
-
- #define SEEN_SKB 1 /* skb access */
- #define SEEN_MEM 2 /* use mem[] for temporary storage */
-@@ -446,7 +446,7 @@ static void bpf_jit_prologue(struct bpf_jit *jit)
- emit_load_skb_data_hlen(jit);
- if (jit->seen & SEEN_SKB_CHANGE)
- /* stg %b1,ST_OFF_SKBP(%r0,%r15) */
-- EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, REG_15,
-+ EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
- STK_OFF_SKBP);
- }
-
-diff --git a/arch/sparc/include/asm/head_64.h b/arch/sparc/include/asm/head_64.h
-index 10e9dab..f0700cf 100644
---- a/arch/sparc/include/asm/head_64.h
-+++ b/arch/sparc/include/asm/head_64.h
-@@ -15,6 +15,10 @@
-
- #define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ)
-
-+#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
-+#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
-+#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
-+
- #define __CHEETAH_ID 0x003e0014
- #define __JALAPENO_ID 0x003e0016
- #define __SERRANO_ID 0x003e0022
-diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
-index f089cfa..5a189bf 100644
---- a/arch/sparc/include/asm/pgtable_64.h
-+++ b/arch/sparc/include/asm/pgtable_64.h
-@@ -375,7 +375,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
- #define pgprot_noncached pgprot_noncached
-
- #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
--static inline pte_t pte_mkhuge(pte_t pte)
-+static inline unsigned long __pte_huge_mask(void)
- {
- unsigned long mask;
-
-@@ -390,8 +390,19 @@ static inline pte_t pte_mkhuge(pte_t pte)
- : "=r" (mask)
- : "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
-
-- return __pte(pte_val(pte) | mask);
-+ return mask;
-+}
-+
-+static inline pte_t pte_mkhuge(pte_t pte)
-+{
-+ return __pte(pte_val(pte) | __pte_huge_mask());
-+}
-+
-+static inline bool is_hugetlb_pte(pte_t pte)
-+{
-+ return !!(pte_val(pte) & __pte_huge_mask());
- }
-+
- #ifdef CONFIG_TRANSPARENT_HUGEPAGE
- static inline pmd_t pmd_mkhuge(pmd_t pmd)
- {
-@@ -403,6 +414,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
- return __pmd(pte_val(pte));
- }
- #endif
-+#else
-+static inline bool is_hugetlb_pte(pte_t pte)
-+{
-+ return false;
-+}
- #endif
-
- static inline pte_t pte_mkdirty(pte_t pte)
-@@ -858,6 +874,19 @@ static inline unsigned long pud_pfn(pud_t pud)
- void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
- pte_t *ptep, pte_t orig, int fullmm);
-
-+static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
-+ pte_t *ptep, pte_t orig, int fullmm)
-+{
-+ /* It is more efficient to let flush_tlb_kernel_range()
-+ * handle init_mm tlb flushes.
-+ *
-+ * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
-+ * and SUN4V pte layout, so this inline test is fine.
-+ */
-+ if (likely(mm != &init_mm) && pte_accessible(mm, orig))
-+ tlb_batch_add(mm, vaddr, ptep, orig, fullmm);
-+}
-+
- #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
- static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
- unsigned long addr,
-@@ -874,15 +903,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t orig = *ptep;
-
- *ptep = pte;
--
-- /* It is more efficient to let flush_tlb_kernel_range()
-- * handle init_mm tlb flushes.
-- *
-- * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
-- * and SUN4V pte layout, so this inline test is fine.
-- */
-- if (likely(mm != &init_mm) && pte_accessible(mm, orig))
-- tlb_batch_add(mm, addr, ptep, orig, fullmm);
-+ maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm);
- }
-
- #define set_pte_at(mm,addr,ptep,pte) \
-diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
-index dea1cfa..a8e192e 100644
---- a/arch/sparc/include/asm/tlbflush_64.h
-+++ b/arch/sparc/include/asm/tlbflush_64.h
-@@ -8,6 +8,7 @@
- #define TLB_BATCH_NR 192
-
- struct tlb_batch {
-+ bool huge;
- struct mm_struct *mm;
- unsigned long tlb_nr;
- unsigned long active;
-@@ -16,7 +17,7 @@ struct tlb_batch {
-
- void flush_tsb_kernel_range(unsigned long start, unsigned long end);
- void flush_tsb_user(struct tlb_batch *tb);
--void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
-+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge);
-
- /* TLB flush operations. */
-
-diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
-index 71b5a67..781b9f1 100644
---- a/arch/sparc/include/asm/ttable.h
-+++ b/arch/sparc/include/asm/ttable.h
-@@ -589,8 +589,8 @@ user_rtt_fill_64bit: \
- restored; \
- nop; nop; nop; nop; nop; nop; \
- nop; nop; nop; nop; nop; \
-- ba,a,pt %xcc, user_rtt_fill_fixup; \
-- ba,a,pt %xcc, user_rtt_fill_fixup; \
-+ ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
-+ ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
- ba,a,pt %xcc, user_rtt_fill_fixup;
-
-
-@@ -652,8 +652,8 @@ user_rtt_fill_32bit: \
- restored; \
- nop; nop; nop; nop; nop; \
- nop; nop; nop; \
-- ba,a,pt %xcc, user_rtt_fill_fixup; \
-- ba,a,pt %xcc, user_rtt_fill_fixup; \
-+ ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
-+ ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
- ba,a,pt %xcc, user_rtt_fill_fixup;
-
-
-diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
-index 7cf9c6e..fdb1332 100644
---- a/arch/sparc/kernel/Makefile
-+++ b/arch/sparc/kernel/Makefile
-@@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
- CFLAGS_REMOVE_pcr.o := -pg
- endif
-
-+obj-$(CONFIG_SPARC64) += urtt_fill.o
- obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
- obj-$(CONFIG_SPARC32) += etrap_32.o
- obj-$(CONFIG_SPARC32) += rtrap_32.o
-diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
-index d08bdaf..216948c 100644
---- a/arch/sparc/kernel/rtrap_64.S
-+++ b/arch/sparc/kernel/rtrap_64.S
-@@ -14,10 +14,6 @@
- #include <asm/visasm.h>
- #include <asm/processor.h>
-
--#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
--#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
--#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
--
- #ifdef CONFIG_CONTEXT_TRACKING
- # define SCHEDULE_USER schedule_user
- #else
-@@ -242,52 +238,17 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
- wrpr %g1, %cwp
- ba,a,pt %xcc, user_rtt_fill_64bit
-
--user_rtt_fill_fixup:
-- rdpr %cwp, %g1
-- add %g1, 1, %g1
-- wrpr %g1, 0x0, %cwp
--
-- rdpr %wstate, %g2
-- sll %g2, 3, %g2
-- wrpr %g2, 0x0, %wstate
--
-- /* We know %canrestore and %otherwin are both zero. */
--
-- sethi %hi(sparc64_kern_pri_context), %g2
-- ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
-- mov PRIMARY_CONTEXT, %g1
--
--661: stxa %g2, [%g1] ASI_DMMU
-- .section .sun4v_1insn_patch, "ax"
-- .word 661b
-- stxa %g2, [%g1] ASI_MMU
-- .previous
--
-- sethi %hi(KERNBASE), %g1
-- flush %g1
-+user_rtt_fill_fixup_dax:
-+ ba,pt %xcc, user_rtt_fill_fixup_common
-+ mov 1, %g3
-
-- or %g4, FAULT_CODE_WINFIXUP, %g4
-- stb %g4, [%g6 + TI_FAULT_CODE]
-- stx %g5, [%g6 + TI_FAULT_ADDR]
-+user_rtt_fill_fixup_mna:
-+ ba,pt %xcc, user_rtt_fill_fixup_common
-+ mov 2, %g3
-
-- mov %g6, %l1
-- wrpr %g0, 0x0, %tl
--
--661: nop
-- .section .sun4v_1insn_patch, "ax"
-- .word 661b
-- SET_GL(0)
-- .previous
--
-- wrpr %g0, RTRAP_PSTATE, %pstate
--
-- mov %l1, %g6
-- ldx [%g6 + TI_TASK], %g4
-- LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
-- call do_sparc64_fault
-- add %sp, PTREGS_OFF, %o0
-- ba,pt %xcc, rtrap
-- nop
-+user_rtt_fill_fixup:
-+ ba,pt %xcc, user_rtt_fill_fixup_common
-+ clr %g3
-
- user_rtt_pre_restore:
- add %g1, 1, %g1
-diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
-index 3c25241..ebd0bfe 100644
---- a/arch/sparc/kernel/signal32.c
-+++ b/arch/sparc/kernel/signal32.c
-@@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
- return 0;
- }
-
-+/* Checks if the fp is valid. We always build signal frames which are
-+ * 16-byte aligned, therefore we can always enforce that the restore
-+ * frame has that property as well.
-+ */
-+static bool invalid_frame_pointer(void __user *fp, int fplen)
-+{
-+ if ((((unsigned long) fp) & 15) ||
-+ ((unsigned long)fp) > 0x100000000ULL - fplen)
-+ return true;
-+ return false;
-+}
-+
- void do_sigreturn32(struct pt_regs *regs)
- {
- struct signal_frame32 __user *sf;
- compat_uptr_t fpu_save;
- compat_uptr_t rwin_save;
-- unsigned int psr;
-+ unsigned int psr, ufp;
- unsigned int pc, npc;
- sigset_t set;
- compat_sigset_t seta;
-@@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs)
- sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
-
- /* 1. Make sure we are not getting garbage from the user */
-- if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-- (((unsigned long) sf) & 3))
-+ if (invalid_frame_pointer(sf, sizeof(*sf)))
-+ goto segv;
-+
-+ if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
-+ goto segv;
-+
-+ if (ufp & 0x7)
- goto segv;
-
-- if (get_user(pc, &sf->info.si_regs.pc) ||
-+ if (__get_user(pc, &sf->info.si_regs.pc) ||
- __get_user(npc, &sf->info.si_regs.npc))
- goto segv;
-
-@@ -227,7 +244,7 @@ segv:
- asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
- {
- struct rt_signal_frame32 __user *sf;
-- unsigned int psr, pc, npc;
-+ unsigned int psr, pc, npc, ufp;
- compat_uptr_t fpu_save;
- compat_uptr_t rwin_save;
- sigset_t set;
-@@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
- sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
-
- /* 1. Make sure we are not getting garbage from the user */
-- if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-- (((unsigned long) sf) & 3))
-+ if (invalid_frame_pointer(sf, sizeof(*sf)))
- goto segv;
-
-- if (get_user(pc, &sf->regs.pc) ||
-+ if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
-+ goto segv;
-+
-+ if (ufp & 0x7)
-+ goto segv;
-+
-+ if (__get_user(pc, &sf->regs.pc) ||
- __get_user(npc, &sf->regs.npc))
- goto segv;
-
-@@ -307,14 +329,6 @@ segv:
- force_sig(SIGSEGV, current);
- }
-
--/* Checks if the fp is valid */
--static int invalid_frame_pointer(void __user *fp, int fplen)
--{
-- if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
-- return 1;
-- return 0;
--}
--
- static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
- {
- unsigned long sp;
-diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
-index 52aa5e4..c3c12ef 100644
---- a/arch/sparc/kernel/signal_32.c
-+++ b/arch/sparc/kernel/signal_32.c
-@@ -60,10 +60,22 @@ struct rt_signal_frame {
- #define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
- #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
-
-+/* Checks if the fp is valid. We always build signal frames which are
-+ * 16-byte aligned, therefore we can always enforce that the restore
-+ * frame has that property as well.
-+ */
-+static inline bool invalid_frame_pointer(void __user *fp, int fplen)
-+{
-+ if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
-+ return true;
-+
-+ return false;
-+}
-+
- asmlinkage void do_sigreturn(struct pt_regs *regs)
- {
-+ unsigned long up_psr, pc, npc, ufp;
- struct signal_frame __user *sf;
-- unsigned long up_psr, pc, npc;
- sigset_t set;
- __siginfo_fpu_t __user *fpu_save;
- __siginfo_rwin_t __user *rwin_save;
-@@ -77,10 +89,13 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
- sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
-
- /* 1. Make sure we are not getting garbage from the user */
-- if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
-+ if (!invalid_frame_pointer(sf, sizeof(*sf)))
-+ goto segv_and_exit;
-+
-+ if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
- goto segv_and_exit;
-
-- if (((unsigned long) sf) & 3)
-+ if (ufp & 0x7)
- goto segv_and_exit;
-
- err = __get_user(pc, &sf->info.si_regs.pc);
-@@ -127,7 +142,7 @@ segv_and_exit:
- asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
- {
- struct rt_signal_frame __user *sf;
-- unsigned int psr, pc, npc;
-+ unsigned int psr, pc, npc, ufp;
- __siginfo_fpu_t __user *fpu_save;
- __siginfo_rwin_t __user *rwin_save;
- sigset_t set;
-@@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
-
- synchronize_user_stack();
- sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
-- if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
-- (((unsigned long) sf) & 0x03))
-+ if (!invalid_frame_pointer(sf, sizeof(*sf)))
-+ goto segv;
-+
-+ if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
-+ goto segv;
-+
-+ if (ufp & 0x7)
- goto segv;
-
- err = __get_user(pc, &sf->regs.pc);
-@@ -178,15 +198,6 @@ segv:
- force_sig(SIGSEGV, current);
- }
-
--/* Checks if the fp is valid */
--static inline int invalid_frame_pointer(void __user *fp, int fplen)
--{
-- if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
-- return 1;
--
-- return 0;
--}
--
- static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
- {
- unsigned long sp = regs->u_regs[UREG_FP];
-diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
-index 39aaec1..5ee930c 100644
---- a/arch/sparc/kernel/signal_64.c
-+++ b/arch/sparc/kernel/signal_64.c
-@@ -234,6 +234,17 @@ do_sigsegv:
- goto out;
- }
-
-+/* Checks if the fp is valid. We always build rt signal frames which
-+ * are 16-byte aligned, therefore we can always enforce that the
-+ * restore frame has that property as well.
-+ */
-+static bool invalid_frame_pointer(void __user *fp)
-+{
-+ if (((unsigned long) fp) & 15)
-+ return true;
-+ return false;
-+}
-+
- struct rt_signal_frame {
- struct sparc_stackf ss;
- siginfo_t info;
-@@ -246,8 +257,8 @@ struct rt_signal_frame {
-
- void do_rt_sigreturn(struct pt_regs *regs)
- {
-+ unsigned long tpc, tnpc, tstate, ufp;
- struct rt_signal_frame __user *sf;
-- unsigned long tpc, tnpc, tstate;
- __siginfo_fpu_t __user *fpu_save;
- __siginfo_rwin_t __user *rwin_save;
- sigset_t set;
-@@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *regs)
- (regs->u_regs [UREG_FP] + STACK_BIAS);
-
- /* 1. Make sure we are not getting garbage from the user */
-- if (((unsigned long) sf) & 3)
-+ if (invalid_frame_pointer(sf))
-+ goto segv;
-+
-+ if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
- goto segv;
-
-- err = get_user(tpc, &sf->regs.tpc);
-+ if ((ufp + STACK_BIAS) & 0x7)
-+ goto segv;
-+
-+ err = __get_user(tpc, &sf->regs.tpc);
- err |= __get_user(tnpc, &sf->regs.tnpc);
- if (test_thread_flag(TIF_32BIT)) {
- tpc &= 0xffffffff;
-@@ -308,14 +325,6 @@ segv:
- force_sig(SIGSEGV, current);
- }
-
--/* Checks if the fp is valid */
--static int invalid_frame_pointer(void __user *fp)
--{
-- if (((unsigned long) fp) & 15)
-- return 1;
-- return 0;
--}
--
- static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
- {
- unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
-diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
-index 0f6eebe..e5fe8ce 100644
---- a/arch/sparc/kernel/sigutil_32.c
-+++ b/arch/sparc/kernel/sigutil_32.c
-@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
- int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
- {
- int err;
-+
-+ if (((unsigned long) fpu) & 3)
-+ return -EFAULT;
-+
- #ifdef CONFIG_SMP
- if (test_tsk_thread_flag(current, TIF_USEDFPU))
- regs->psr &= ~PSR_EF;
-@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
- struct thread_info *t = current_thread_info();
- int i, wsaved, err;
-
-- __get_user(wsaved, &rp->wsaved);
-+ if (((unsigned long) rp) & 3)
-+ return -EFAULT;
-+
-+ get_user(wsaved, &rp->wsaved);
- if (wsaved > NSWINS)
- return -EFAULT;
-
-diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
-index 387834a..36aadcb 100644
---- a/arch/sparc/kernel/sigutil_64.c
-+++ b/arch/sparc/kernel/sigutil_64.c
-@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
- unsigned long fprs;
- int err;
-
-- err = __get_user(fprs, &fpu->si_fprs);
-+ if (((unsigned long) fpu) & 7)
-+ return -EFAULT;
-+
-+ err = get_user(fprs, &fpu->si_fprs);
- fprs_write(0);
- regs->tstate &= ~TSTATE_PEF;
- if (fprs & FPRS_DL)
-@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
- struct thread_info *t = current_thread_info();
- int i, wsaved, err;
-
-- __get_user(wsaved, &rp->wsaved);
-+ if (((unsigned long) rp) & 7)
-+ return -EFAULT;
-+
-+ get_user(wsaved, &rp->wsaved);
- if (wsaved > NSWINS)
- return -EFAULT;
-
-diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S
-new file mode 100644
-index 0000000..5604a2b
---- /dev/null
-+++ b/arch/sparc/kernel/urtt_fill.S
-@@ -0,0 +1,98 @@
-+#include <asm/thread_info.h>
-+#include <asm/trap_block.h>
-+#include <asm/spitfire.h>
-+#include <asm/ptrace.h>
-+#include <asm/head.h>
-+
-+ .text
-+ .align 8
-+ .globl user_rtt_fill_fixup_common
-+user_rtt_fill_fixup_common:
-+ rdpr %cwp, %g1
-+ add %g1, 1, %g1
-+ wrpr %g1, 0x0, %cwp
-+
-+ rdpr %wstate, %g2
-+ sll %g2, 3, %g2
-+ wrpr %g2, 0x0, %wstate
-+
-+ /* We know %canrestore and %otherwin are both zero. */
-+
-+ sethi %hi(sparc64_kern_pri_context), %g2
-+ ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
-+ mov PRIMARY_CONTEXT, %g1
-+
-+661: stxa %g2, [%g1] ASI_DMMU
-+ .section .sun4v_1insn_patch, "ax"
-+ .word 661b
-+ stxa %g2, [%g1] ASI_MMU
-+ .previous
-+
-+ sethi %hi(KERNBASE), %g1
-+ flush %g1
-+
-+ mov %g4, %l4
-+ mov %g5, %l5
-+ brnz,pn %g3, 1f
-+ mov %g3, %l3
-+
-+ or %g4, FAULT_CODE_WINFIXUP, %g4
-+ stb %g4, [%g6 + TI_FAULT_CODE]
-+ stx %g5, [%g6 + TI_FAULT_ADDR]
-+1:
-+ mov %g6, %l1
-+ wrpr %g0, 0x0, %tl
-+
-+661: nop
-+ .section .sun4v_1insn_patch, "ax"
-+ .word 661b
-+ SET_GL(0)
-+ .previous
-+
-+ wrpr %g0, RTRAP_PSTATE, %pstate
-+
-+ mov %l1, %g6
-+ ldx [%g6 + TI_TASK], %g4
-+ LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
-+
-+ brnz,pn %l3, 1f
-+ nop
-+
-+ call do_sparc64_fault
-+ add %sp, PTREGS_OFF, %o0
-+ ba,pt %xcc, rtrap
-+ nop
-+
-+1: cmp %g3, 2
-+ bne,pn %xcc, 2f
-+ nop
-+
-+ sethi %hi(tlb_type), %g1
-+ lduw [%g1 + %lo(tlb_type)], %g1
-+ cmp %g1, 3
-+ bne,pt %icc, 1f
-+ add %sp, PTREGS_OFF, %o0
-+ mov %l4, %o2
-+ call sun4v_do_mna
-+ mov %l5, %o1
-+ ba,a,pt %xcc, rtrap
-+1: mov %l4, %o1
-+ mov %l5, %o2
-+ call mem_address_unaligned
-+ nop
-+ ba,a,pt %xcc, rtrap
-+
-+2: sethi %hi(tlb_type), %g1
-+ mov %l4, %o1
-+ lduw [%g1 + %lo(tlb_type)], %g1
-+ mov %l5, %o2
-+ cmp %g1, 3
-+ bne,pt %icc, 1f
-+ add %sp, PTREGS_OFF, %o0
-+ call sun4v_data_access_exception
-+ nop
-+ ba,a,pt %xcc, rtrap
-+
-+1: call spitfire_data_access_exception
-+ nop
-+ ba,a,pt %xcc, rtrap
-diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
-index 4977800..ba52e64 100644
---- a/arch/sparc/mm/hugetlbpage.c
-+++ b/arch/sparc/mm/hugetlbpage.c
-@@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t entry)
- {
- int i;
-+ pte_t orig[2];
-+ unsigned long nptes;
-
- if (!pte_present(*ptep) && pte_present(entry))
- mm->context.huge_pte_count++;
-
- addr &= HPAGE_MASK;
-- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-- set_pte_at(mm, addr, ptep, entry);
-+
-+ nptes = 1 << HUGETLB_PAGE_ORDER;
-+ orig[0] = *ptep;
-+ orig[1] = *(ptep + nptes / 2);
-+ for (i = 0; i < nptes; i++) {
-+ *ptep = entry;
- ptep++;
- addr += PAGE_SIZE;
- pte_val(entry) += PAGE_SIZE;
- }
-+
-+ /* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
-+ addr -= REAL_HPAGE_SIZE;
-+ ptep -= nptes / 2;
-+ maybe_tlb_batch_add(mm, addr, ptep, orig[1], 0);
-+ addr -= REAL_HPAGE_SIZE;
-+ ptep -= nptes / 2;
-+ maybe_tlb_batch_add(mm, addr, ptep, orig[0], 0);
- }
-
- pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
-@@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
- {
- pte_t entry;
- int i;
-+ unsigned long nptes;
-
- entry = *ptep;
- if (pte_present(entry))
- mm->context.huge_pte_count--;
-
- addr &= HPAGE_MASK;
--
-- for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-- pte_clear(mm, addr, ptep);
-+ nptes = 1 << HUGETLB_PAGE_ORDER;
-+ for (i = 0; i < nptes; i++) {
-+ *ptep = __pte(0UL);
- addr += PAGE_SIZE;
- ptep++;
- }
-
-+ /* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
-+ addr -= REAL_HPAGE_SIZE;
-+ ptep -= nptes / 2;
-+ maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
-+ addr -= REAL_HPAGE_SIZE;
-+ ptep -= nptes / 2;
-+ maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
-+
- return entry;
- }
-
-diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
-index 09e8388..14bb0d5 100644
---- a/arch/sparc/mm/init_64.c
-+++ b/arch/sparc/mm/init_64.c
-@@ -324,18 +324,6 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
- tsb_insert(tsb, tag, tte);
- }
-
--#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
--static inline bool is_hugetlb_pte(pte_t pte)
--{
-- if ((tlb_type == hypervisor &&
-- (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
-- (tlb_type != hypervisor &&
-- (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
-- return true;
-- return false;
--}
--#endif
--
- void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
- {
- struct mm_struct *mm;
-@@ -2836,9 +2824,10 @@ void hugetlb_setup(struct pt_regs *regs)
- * the Data-TLB for huge pages.
- */
- if (tlb_type == cheetah_plus) {
-+ bool need_context_reload = false;
- unsigned long ctx;
-
-- spin_lock(&ctx_alloc_lock);
-+ spin_lock_irq(&ctx_alloc_lock);
- ctx = mm->context.sparc64_ctx_val;
- ctx &= ~CTX_PGSZ_MASK;
- ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
-@@ -2857,9 +2846,12 @@ void hugetlb_setup(struct pt_regs *regs)
- * also executing in this address space.
- */
- mm->context.sparc64_ctx_val = ctx;
-- on_each_cpu(context_reload, mm, 0);
-+ need_context_reload = true;
- }
-- spin_unlock(&ctx_alloc_lock);
-+ spin_unlock_irq(&ctx_alloc_lock);
-+
-+ if (need_context_reload)
-+ on_each_cpu(context_reload, mm, 0);
- }
- }
- #endif
-diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
-index 9df2190..f81cd97 100644
---- a/arch/sparc/mm/tlb.c
-+++ b/arch/sparc/mm/tlb.c
-@@ -67,7 +67,7 @@ void arch_leave_lazy_mmu_mode(void)
- }
-
- static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
-- bool exec)
-+ bool exec, bool huge)
- {
- struct tlb_batch *tb = &get_cpu_var(tlb_batch);
- unsigned long nr;
-@@ -84,13 +84,21 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
- }
-
- if (!tb->active) {
-- flush_tsb_user_page(mm, vaddr);
-+ flush_tsb_user_page(mm, vaddr, huge);
- global_flush_tlb_page(mm, vaddr);
- goto out;
- }
-
-- if (nr == 0)
-+ if (nr == 0) {
- tb->mm = mm;
-+ tb->huge = huge;
-+ }
-+
-+ if (tb->huge != huge) {
-+ flush_tlb_pending();
-+ tb->huge = huge;
-+ nr = 0;
-+ }
-
- tb->vaddrs[nr] = vaddr;
- tb->tlb_nr = ++nr;
-@@ -104,6 +112,8 @@ out:
- void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
- pte_t *ptep, pte_t orig, int fullmm)
- {
-+ bool huge = is_hugetlb_pte(orig);
-+
- if (tlb_type != hypervisor &&
- pte_dirty(orig)) {
- unsigned long paddr, pfn = pte_pfn(orig);
-@@ -129,7 +139,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
-
- no_cache_flush:
- if (!fullmm)
-- tlb_batch_add_one(mm, vaddr, pte_exec(orig));
-+ tlb_batch_add_one(mm, vaddr, pte_exec(orig), huge);
- }
-
- #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-@@ -145,7 +155,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
- if (pte_val(*pte) & _PAGE_VALID) {
- bool exec = pte_exec(*pte);
-
-- tlb_batch_add_one(mm, vaddr, exec);
-+ tlb_batch_add_one(mm, vaddr, exec, false);
- }
- pte++;
- vaddr += PAGE_SIZE;
-@@ -185,8 +195,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
- pte_t orig_pte = __pte(pmd_val(orig));
- bool exec = pte_exec(orig_pte);
-
-- tlb_batch_add_one(mm, addr, exec);
-- tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
-+ tlb_batch_add_one(mm, addr, exec, true);
-+ tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec,
-+ true);
- } else {
- tlb_batch_pmd_scan(mm, addr, orig);
- }
-diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
-index a065766..a0604a4 100644
---- a/arch/sparc/mm/tsb.c
-+++ b/arch/sparc/mm/tsb.c
-@@ -76,14 +76,15 @@ void flush_tsb_user(struct tlb_batch *tb)
-
- spin_lock_irqsave(&mm->context.lock, flags);
-
-- base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-- nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-- if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-- base = __pa(base);
-- __flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
--
-+ if (!tb->huge) {
-+ base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-+ nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-+ if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-+ base = __pa(base);
-+ __flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
-+ }
- #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-- if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
-+ if (tb->huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
- base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
- nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
- if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-@@ -94,20 +95,21 @@ void flush_tsb_user(struct tlb_batch *tb)
- spin_unlock_irqrestore(&mm->context.lock, flags);
- }
-
--void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr)
-+void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge)
- {
- unsigned long nentries, base, flags;
-
- spin_lock_irqsave(&mm->context.lock, flags);
-
-- base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-- nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-- if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-- base = __pa(base);
-- __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
--
-+ if (!huge) {
-+ base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
-+ nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
-+ if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-+ base = __pa(base);
-+ __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
-+ }
- #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
-- if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
-+ if (huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
- base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
- nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
- if (tlb_type == cheetah_plus || tlb_type == hypervisor)
-diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
-index 06cbe25..87bd6b6 100644
---- a/arch/x86/kernel/traps.c
-+++ b/arch/x86/kernel/traps.c
-@@ -95,6 +95,12 @@ static inline void cond_local_irq_disable(struct pt_regs *regs)
- local_irq_disable();
- }
-
-+/*
-+ * In IST context, we explicitly disable preemption. This serves two
-+ * purposes: it makes it much less likely that we would accidentally
-+ * schedule in IST context and it will force a warning if we somehow
-+ * manage to schedule by accident.
-+ */
- void ist_enter(struct pt_regs *regs)
- {
- if (user_mode(regs)) {
-@@ -109,13 +115,7 @@ void ist_enter(struct pt_regs *regs)
- rcu_nmi_enter();
- }
-
-- /*
-- * We are atomic because we're on the IST stack; or we're on
-- * x86_32, in which case we still shouldn't schedule; or we're
-- * on x86_64 and entered from user mode, in which case we're
-- * still atomic unless ist_begin_non_atomic is called.
-- */
-- preempt_count_add(HARDIRQ_OFFSET);
-+ preempt_disable();
-
- /* This code is a bit fragile. Test it. */
- RCU_LOCKDEP_WARN(!rcu_is_watching(), "ist_enter didn't work");
-@@ -123,7 +123,7 @@ void ist_enter(struct pt_regs *regs)
-
- void ist_exit(struct pt_regs *regs)
- {
-- preempt_count_sub(HARDIRQ_OFFSET);
-+ preempt_enable_no_resched();
-
- if (!user_mode(regs))
- rcu_nmi_exit();
-@@ -154,7 +154,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
- BUG_ON((unsigned long)(current_top_of_stack() -
- current_stack_pointer()) >= THREAD_SIZE);
-
-- preempt_count_sub(HARDIRQ_OFFSET);
-+ preempt_enable_no_resched();
- }
-
- /**
-@@ -164,7 +164,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
- */
- void ist_end_non_atomic(void)
- {
-- preempt_count_add(HARDIRQ_OFFSET);
-+ preempt_disable();
- }
-
- static nokprobe_inline int
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 9b7798c..6b9701b 100644
---- a/arch/x86/kvm/x86.c
-+++ b/arch/x86/kvm/x86.c
-@@ -3032,6 +3032,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
- if (dbgregs->flags)
- return -EINVAL;
-
-+ if (dbgregs->dr6 & ~0xffffffffull)
-+ return -EINVAL;
-+ if (dbgregs->dr7 & ~0xffffffffull)
-+ return -EINVAL;
-+
- memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
- kvm_update_dr0123(vcpu);
- vcpu->arch.dr6 = dbgregs->dr6;
-diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
-index 91a7e04..477cbf39 100644
---- a/crypto/asymmetric_keys/Kconfig
-+++ b/crypto/asymmetric_keys/Kconfig
-@@ -13,6 +13,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
- tristate "Asymmetric public-key crypto algorithm subtype"
- select MPILIB
- select CRYPTO_HASH_INFO
-+ select CRYPTO_AKCIPHER
- help
- This option provides support for asymmetric public key type handling.
- If signature generation and/or verification are to be used,
-diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
-index 52c7395..0d0d452 100644
---- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
-+++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
-@@ -122,6 +122,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
- struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
- struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
- unsigned int unit;
-+ u32 unit_size;
- int ret;
-
- if (!ctx->u.aes.key_len)
-@@ -133,11 +134,17 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
- if (!req->info)
- return -EINVAL;
-
-- for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++)
-- if (!(req->nbytes & (unit_size_map[unit].size - 1)))
-- break;
-+ unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
-+ if (req->nbytes <= unit_size_map[0].size) {
-+ for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
-+ if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
-+ unit_size = unit_size_map[unit].value;
-+ break;
-+ }
-+ }
-+ }
-
-- if ((unit_size_map[unit].value == CCP_XTS_AES_UNIT_SIZE__LAST) ||
-+ if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
- (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
- /* Use the fallback to process the request for any
- * unsupported unit sizes or key sizes
-@@ -158,7 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
- rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
- rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
- : CCP_AES_ACTION_DECRYPT;
-- rctx->cmd.u.xts.unit_size = unit_size_map[unit].value;
-+ rctx->cmd.u.xts.unit_size = unit_size;
- rctx->cmd.u.xts.key = &ctx->u.aes.key_sg;
- rctx->cmd.u.xts.key_len = ctx->u.aes.key_len;
- rctx->cmd.u.xts.iv = &rctx->iv_sg;
-diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
-index 2fd38d5..3c5e832 100644
---- a/drivers/gpio/gpio-bcm-kona.c
-+++ b/drivers/gpio/gpio-bcm-kona.c
-@@ -546,11 +546,11 @@ static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio)
- /* disable interrupts and clear status */
- for (i = 0; i < kona_gpio->num_bank; i++) {
- /* Unlock the entire bank first */
-- bcm_kona_gpio_write_lock_regs(kona_gpio, i, UNLOCK_CODE);
-+ bcm_kona_gpio_write_lock_regs(reg_base, i, UNLOCK_CODE);
- writel(0xffffffff, reg_base + GPIO_INT_MASK(i));
- writel(0xffffffff, reg_base + GPIO_INT_STATUS(i));
- /* Now re-lock the bank */
-- bcm_kona_gpio_write_lock_regs(kona_gpio, i, LOCK_CODE);
-+ bcm_kona_gpio_write_lock_regs(reg_base, i, LOCK_CODE);
- }
- }
-
-diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
-index 66d3d24..e72794e 100644
---- a/drivers/gpio/gpio-zynq.c
-+++ b/drivers/gpio/gpio-zynq.c
-@@ -709,11 +709,17 @@ static int zynq_gpio_probe(struct platform_device *pdev)
- dev_err(&pdev->dev, "input clock not found.\n");
- return PTR_ERR(gpio->clk);
- }
-+ ret = clk_prepare_enable(gpio->clk);
-+ if (ret) {
-+ dev_err(&pdev->dev, "Unable to enable clock.\n");
-+ return ret;
-+ }
-
-+ pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0)
-- return ret;
-+ goto err_pm_dis;
-
- /* report a bug if gpio chip registration fails */
- ret = gpiochip_add_data(chip, gpio);
-@@ -745,6 +751,9 @@ err_rm_gpiochip:
- gpiochip_remove(chip);
- err_pm_put:
- pm_runtime_put(&pdev->dev);
-+err_pm_dis:
-+ pm_runtime_disable(&pdev->dev);
-+ clk_disable_unprepare(gpio->clk);
-
- return ret;
- }
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index b747c76..cf3e712 100644
---- a/drivers/gpio/gpiolib.c
-+++ b/drivers/gpio/gpiolib.c
-@@ -438,7 +438,6 @@ static void gpiodevice_release(struct device *dev)
- {
- struct gpio_device *gdev = dev_get_drvdata(dev);
-
-- cdev_del(&gdev->chrdev);
- list_del(&gdev->list);
- ida_simple_remove(&gpio_ida, gdev->id);
- kfree(gdev->label);
-@@ -471,7 +470,6 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
-
- /* From this point, the .release() function cleans up gpio_device */
- gdev->dev.release = gpiodevice_release;
-- get_device(&gdev->dev);
- pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n",
- __func__, gdev->base, gdev->base + gdev->ngpio - 1,
- dev_name(&gdev->dev), gdev->chip->label ? : "generic");
-@@ -742,6 +740,8 @@ void gpiochip_remove(struct gpio_chip *chip)
- * be removed, else it will be dangling until the last user is
- * gone.
- */
-+ cdev_del(&gdev->chrdev);
-+ device_del(&gdev->dev);
- put_device(&gdev->dev);
- }
- EXPORT_SYMBOL_GPL(gpiochip_remove);
-@@ -841,7 +841,7 @@ struct gpio_chip *gpiochip_find(void *data,
-
- spin_lock_irqsave(&gpio_lock, flags);
- list_for_each_entry(gdev, &gpio_devices, list)
-- if (match(gdev->chip, data))
-+ if (gdev->chip && match(gdev->chip, data))
- break;
-
- /* No match? */
-@@ -1339,10 +1339,13 @@ done:
- /*
- * This descriptor validation needs to be inserted verbatim into each
- * function taking a descriptor, so we need to use a preprocessor
-- * macro to avoid endless duplication.
-+ * macro to avoid endless duplication. If the desc is NULL it is an
-+ * optional GPIO and calls should just bail out.
- */
- #define VALIDATE_DESC(desc) do { \
-- if (!desc || !desc->gdev) { \
-+ if (!desc) \
-+ return 0; \
-+ if (!desc->gdev) { \
- pr_warn("%s: invalid GPIO\n", __func__); \
- return -EINVAL; \
- } \
-@@ -1353,7 +1356,9 @@ done:
- } } while (0)
-
- #define VALIDATE_DESC_VOID(desc) do { \
-- if (!desc || !desc->gdev) { \
-+ if (!desc) \
-+ return; \
-+ if (!desc->gdev) { \
- pr_warn("%s: invalid GPIO\n", __func__); \
- return; \
- } \
-@@ -2001,7 +2006,14 @@ int gpiod_to_irq(const struct gpio_desc *desc)
- struct gpio_chip *chip;
- int offset;
-
-- VALIDATE_DESC(desc);
-+ /*
-+ * Cannot VALIDATE_DESC() here as gpiod_to_irq() consumer semantics
-+ * requires this function to not return zero on an invalid descriptor
-+ * but rather a negative error number.
-+ */
-+ if (!desc || !desc->gdev || !desc->gdev->chip)
-+ return -EINVAL;
-+
- chip = desc->gdev->chip;
- offset = gpio_chip_hwgpio(desc);
- return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO;
-diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
-index e08f962..f30de80 100644
---- a/drivers/gpu/drm/drm_crtc.c
-+++ b/drivers/gpu/drm/drm_crtc.c
-@@ -3434,6 +3434,24 @@ int drm_mode_addfb2(struct drm_device *dev,
- return 0;
- }
-
-+struct drm_mode_rmfb_work {
-+ struct work_struct work;
-+ struct list_head fbs;
-+};
-+
-+static void drm_mode_rmfb_work_fn(struct work_struct *w)
-+{
-+ struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
-+
-+ while (!list_empty(&arg->fbs)) {
-+ struct drm_framebuffer *fb =
-+ list_first_entry(&arg->fbs, typeof(*fb), filp_head);
-+
-+ list_del_init(&fb->filp_head);
-+ drm_framebuffer_remove(fb);
-+ }
-+}
-+
- /**
- * drm_mode_rmfb - remove an FB from the configuration
- * @dev: drm device for the ioctl
-@@ -3474,7 +3492,25 @@ int drm_mode_rmfb(struct drm_device *dev,
- mutex_unlock(&dev->mode_config.fb_lock);
- mutex_unlock(&file_priv->fbs_lock);
-
-- drm_framebuffer_unreference(fb);
-+ /*
-+ * we now own the reference that was stored in the fbs list
-+ *
-+ * drm_framebuffer_remove may fail with -EINTR on pending signals,
-+ * so run this in a separate stack as there's no way to correctly
-+ * handle this after the fb is already removed from the lookup table.
-+ */
-+ if (atomic_read(&fb->refcount.refcount) > 1) {
-+ struct drm_mode_rmfb_work arg;
-+
-+ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
-+ INIT_LIST_HEAD(&arg.fbs);
-+ list_add_tail(&fb->filp_head, &arg.fbs);
-+
-+ schedule_work(&arg.work);
-+ flush_work(&arg.work);
-+ destroy_work_on_stack(&arg.work);
-+ } else
-+ drm_framebuffer_unreference(fb);
-
- return 0;
-
-@@ -3627,7 +3663,6 @@ out_err1:
- return ret;
- }
-
--
- /**
- * drm_fb_release - remove and free the FBs on this file
- * @priv: drm file for the ioctl
-@@ -3642,6 +3677,9 @@ out_err1:
- void drm_fb_release(struct drm_file *priv)
- {
- struct drm_framebuffer *fb, *tfb;
-+ struct drm_mode_rmfb_work arg;
-+
-+ INIT_LIST_HEAD(&arg.fbs);
-
- /*
- * When the file gets released that means no one else can access the fb
-@@ -3654,10 +3692,22 @@ void drm_fb_release(struct drm_file *priv)
- * at it any more.
- */
- list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
-- list_del_init(&fb->filp_head);
-+ if (atomic_read(&fb->refcount.refcount) > 1) {
-+ list_move_tail(&fb->filp_head, &arg.fbs);
-+ } else {
-+ list_del_init(&fb->filp_head);
-
-- /* This drops the fpriv->fbs reference. */
-- drm_framebuffer_unreference(fb);
-+ /* This drops the fpriv->fbs reference. */
-+ drm_framebuffer_unreference(fb);
-+ }
-+ }
-+
-+ if (!list_empty(&arg.fbs)) {
-+ INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
-+
-+ schedule_work(&arg.work);
-+ flush_work(&arg.work);
-+ destroy_work_on_stack(&arg.work);
- }
- }
-
-diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
-index 1c21220..d1a46ef 100644
---- a/drivers/gpu/drm/i915/i915_irq.c
-+++ b/drivers/gpu/drm/i915/i915_irq.c
-@@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
- /* IRQs are synced during runtime_suspend, we don't require a wakeref */
- disable_rpm_wakeref_asserts(dev_priv);
-
-- do {
-+ for (;;) {
- master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
- iir = I915_READ(VLV_IIR);
-
-@@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
-
- I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
- POSTING_READ(GEN8_MASTER_IRQ);
-- } while (0);
-+ }
-
- enable_rpm_wakeref_asserts(dev_priv);
-
-diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h
-index 8fc93c5..d02c424 100644
---- a/drivers/net/ethernet/atheros/alx/alx.h
-+++ b/drivers/net/ethernet/atheros/alx/alx.h
-@@ -96,6 +96,10 @@ struct alx_priv {
- unsigned int rx_ringsz;
- unsigned int rxbuf_size;
-
-+ struct page *rx_page;
-+ unsigned int rx_page_offset;
-+ unsigned int rx_frag_size;
-+
- struct napi_struct napi;
- struct alx_tx_queue txq;
- struct alx_rx_queue rxq;
-diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
-index 55b118e..8611811 100644
---- a/drivers/net/ethernet/atheros/alx/main.c
-+++ b/drivers/net/ethernet/atheros/alx/main.c
-@@ -70,6 +70,35 @@ static void alx_free_txbuf(struct alx_priv *alx, int entry)
- }
- }
-
-+static struct sk_buff *alx_alloc_skb(struct alx_priv *alx, gfp_t gfp)
-+{
-+ struct sk_buff *skb;
-+ struct page *page;
-+
-+ if (alx->rx_frag_size > PAGE_SIZE)
-+ return __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
-+
-+ page = alx->rx_page;
-+ if (!page) {
-+ alx->rx_page = page = alloc_page(gfp);
-+ if (unlikely(!page))
-+ return NULL;
-+ alx->rx_page_offset = 0;
-+ }
-+
-+ skb = build_skb(page_address(page) + alx->rx_page_offset,
-+ alx->rx_frag_size);
-+ if (likely(skb)) {
-+ alx->rx_page_offset += alx->rx_frag_size;
-+ if (alx->rx_page_offset >= PAGE_SIZE)
-+ alx->rx_page = NULL;
-+ else
-+ get_page(page);
-+ }
-+ return skb;
-+}
-+
-+
- static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
- {
- struct alx_rx_queue *rxq = &alx->rxq;
-@@ -86,7 +115,7 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
- while (!cur_buf->skb && next != rxq->read_idx) {
- struct alx_rfd *rfd = &rxq->rfd[cur];
-
-- skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
-+ skb = alx_alloc_skb(alx, gfp);
- if (!skb)
- break;
- dma = dma_map_single(&alx->hw.pdev->dev,
-@@ -124,6 +153,7 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
- alx_write_mem16(&alx->hw, ALX_RFD_PIDX, cur);
- }
-
-+
- return count;
- }
-
-@@ -592,6 +622,11 @@ static void alx_free_rings(struct alx_priv *alx)
- kfree(alx->txq.bufs);
- kfree(alx->rxq.bufs);
-
-+ if (alx->rx_page) {
-+ put_page(alx->rx_page);
-+ alx->rx_page = NULL;
-+ }
-+
- dma_free_coherent(&alx->hw.pdev->dev,
- alx->descmem.size,
- alx->descmem.virt,
-@@ -646,6 +681,7 @@ static int alx_request_irq(struct alx_priv *alx)
- alx->dev->name, alx);
- if (!err)
- goto out;
-+
- /* fall back to legacy interrupt */
- pci_disable_msi(alx->hw.pdev);
- }
-@@ -689,6 +725,7 @@ static int alx_init_sw(struct alx_priv *alx)
- struct pci_dev *pdev = alx->hw.pdev;
- struct alx_hw *hw = &alx->hw;
- int err;
-+ unsigned int head_size;
-
- err = alx_identify_hw(alx);
- if (err) {
-@@ -704,7 +741,12 @@ static int alx_init_sw(struct alx_priv *alx)
-
- hw->smb_timer = 400;
- hw->mtu = alx->dev->mtu;
-+
- alx->rxbuf_size = ALX_MAX_FRAME_LEN(hw->mtu);
-+ head_size = SKB_DATA_ALIGN(alx->rxbuf_size + NET_SKB_PAD) +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+ alx->rx_frag_size = roundup_pow_of_two(head_size);
-+
- alx->tx_ringsz = 256;
- alx->rx_ringsz = 512;
- hw->imt = 200;
-@@ -806,6 +848,7 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
- {
- struct alx_priv *alx = netdev_priv(netdev);
- int max_frame = ALX_MAX_FRAME_LEN(mtu);
-+ unsigned int head_size;
-
- if ((max_frame < ALX_MIN_FRAME_SIZE) ||
- (max_frame > ALX_MAX_FRAME_SIZE))
-@@ -817,6 +860,9 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
- netdev->mtu = mtu;
- alx->hw.mtu = mtu;
- alx->rxbuf_size = max(max_frame, ALX_DEF_RXBUF_SIZE);
-+ head_size = SKB_DATA_ALIGN(alx->rxbuf_size + NET_SKB_PAD) +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+ alx->rx_frag_size = roundup_pow_of_two(head_size);
- netdev_update_features(netdev);
- if (netif_running(netdev))
- alx_reinit(alx);
-diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
-index 085f912..06f0317 100644
---- a/drivers/net/ethernet/ezchip/nps_enet.c
-+++ b/drivers/net/ethernet/ezchip/nps_enet.c
-@@ -205,8 +205,10 @@ static int nps_enet_poll(struct napi_struct *napi, int budget)
- * re-adding ourselves to the poll list.
- */
-
-- if (priv->tx_skb && !tx_ctrl_ct)
-+ if (priv->tx_skb && !tx_ctrl_ct) {
-+ nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, 0);
- napi_reschedule(napi);
-+ }
- }
-
- return work_done;
-diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c
-index 01fccec..466939f 100644
---- a/drivers/net/ethernet/marvell/mvneta_bm.c
-+++ b/drivers/net/ethernet/marvell/mvneta_bm.c
-@@ -189,6 +189,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- hwbm_pool->construct = mvneta_bm_construct;
- hwbm_pool->priv = new_pool;
-+ spin_lock_init(&hwbm_pool->lock);
-
- /* Create new pool */
- err = mvneta_bm_pool_create(priv, new_pool);
-diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
-index 0e758bc..1ca7963 100644
---- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
-+++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
-@@ -2727,7 +2727,7 @@ static int ofdpa_port_obj_fib4_add(struct rocker_port *rocker_port,
-
- return ofdpa_port_fib_ipv4(ofdpa_port, trans,
- htonl(fib4->dst), fib4->dst_len,
-- &fib4->fi, fib4->tb_id, 0);
-+ fib4->fi, fib4->tb_id, 0);
- }
-
- static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
-@@ -2737,7 +2737,7 @@ static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
-
- return ofdpa_port_fib_ipv4(ofdpa_port, NULL,
- htonl(fib4->dst), fib4->dst_len,
-- &fib4->fi, fib4->tb_id,
-+ fib4->fi, fib4->tb_id,
- OFDPA_OP_FLAG_REMOVE);
- }
-
-diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
-index 1681084..1f30912 100644
---- a/drivers/net/ethernet/sfc/ef10.c
-+++ b/drivers/net/ethernet/sfc/ef10.c
-@@ -619,6 +619,17 @@ fail:
- return rc;
- }
-
-+static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
-+{
-+ struct efx_channel *channel;
-+ struct efx_tx_queue *tx_queue;
-+
-+ /* All our existing PIO buffers went away */
-+ efx_for_each_channel(channel, efx)
-+ efx_for_each_channel_tx_queue(tx_queue, channel)
-+ tx_queue->piobuf = NULL;
-+}
-+
- #else /* !EFX_USE_PIO */
-
- static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
-@@ -635,6 +646,10 @@ static void efx_ef10_free_piobufs(struct efx_nic *efx)
- {
- }
-
-+static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
-+{
-+}
-+
- #endif /* EFX_USE_PIO */
-
- static void efx_ef10_remove(struct efx_nic *efx)
-@@ -1018,6 +1033,7 @@ static void efx_ef10_reset_mc_allocations(struct efx_nic *efx)
- nic_data->must_realloc_vis = true;
- nic_data->must_restore_filters = true;
- nic_data->must_restore_piobufs = true;
-+ efx_ef10_forget_old_piobufs(efx);
- nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
-
- /* Driver-created vswitches and vports must be re-created */
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-index 06704ca..8683a21 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
-@@ -209,7 +209,7 @@ int stmmac_mdio_register(struct net_device *ndev)
- return -ENOMEM;
-
- if (mdio_bus_data->irqs)
-- memcpy(new_bus->irq, mdio_bus_data, sizeof(new_bus->irq));
-+ memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
-
- #ifdef CONFIG_OF
- if (priv->device->of_node)
-diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
-index 7b0a644..9fcb489 100644
---- a/drivers/net/geneve.c
-+++ b/drivers/net/geneve.c
-@@ -336,15 +336,15 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
-
- /* Need Geneve and inner Ethernet header to be present */
- if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN)))
-- goto error;
-+ goto drop;
-
- /* Return packets with reserved bits set */
- geneveh = geneve_hdr(skb);
- if (unlikely(geneveh->ver != GENEVE_VER))
-- goto error;
-+ goto drop;
-
- if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
-- goto error;
-+ goto drop;
-
- gs = rcu_dereference_sk_user_data(sk);
- if (!gs)
-@@ -367,10 +367,6 @@ drop:
- /* Consume bad packet */
- kfree_skb(skb);
- return 0;
--
--error:
-- /* Let the UDP layer deal with the skb */
-- return 1;
- }
-
- static struct socket *geneve_create_sock(struct net *net, bool ipv6,
-diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
-index 92eaab95..9e803bb 100644
---- a/drivers/net/macsec.c
-+++ b/drivers/net/macsec.c
-@@ -1645,7 +1645,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
- if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
- rx_sa->active = !!nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
-
-- nla_memcpy(rx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEY], MACSEC_KEYID_LEN);
-+ nla_memcpy(rx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN);
- rx_sa->sc = rx_sc;
- rcu_assign_pointer(rx_sc->sa[assoc_num], rx_sa);
-
-@@ -1784,7 +1784,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
- return -ENOMEM;
- }
-
-- nla_memcpy(tx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEY], MACSEC_KEYID_LEN);
-+ nla_memcpy(tx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN);
-
- spin_lock_bh(&tx_sa->lock);
- tx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
-diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
-index a0f64cb..2ace126 100644
---- a/drivers/net/team/team.c
-+++ b/drivers/net/team/team.c
-@@ -990,7 +990,7 @@ static void team_port_disable(struct team *team,
- #define TEAM_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
- NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
-
--static void __team_compute_features(struct team *team)
-+static void ___team_compute_features(struct team *team)
- {
- struct team_port *port;
- u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
-@@ -1021,15 +1021,20 @@ static void __team_compute_features(struct team *team)
- team->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
- if (dst_release_flag == (IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM))
- team->dev->priv_flags |= IFF_XMIT_DST_RELEASE;
-+}
-
-+static void __team_compute_features(struct team *team)
-+{
-+ ___team_compute_features(team);
- netdev_change_features(team->dev);
- }
-
- static void team_compute_features(struct team *team)
- {
- mutex_lock(&team->lock);
-- __team_compute_features(team);
-+ ___team_compute_features(team);
- mutex_unlock(&team->lock);
-+ netdev_change_features(team->dev);
- }
-
- static int team_port_enter(struct team *team, struct team_port *port)
-diff --git a/drivers/net/tun.c b/drivers/net/tun.c
-index 2c9e45f5..dda4905 100644
---- a/drivers/net/tun.c
-+++ b/drivers/net/tun.c
-@@ -568,11 +568,13 @@ static void tun_detach_all(struct net_device *dev)
- for (i = 0; i < n; i++) {
- tfile = rtnl_dereference(tun->tfiles[i]);
- BUG_ON(!tfile);
-+ tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
- tfile->socket.sk->sk_data_ready(tfile->socket.sk);
- RCU_INIT_POINTER(tfile->tun, NULL);
- --tun->numqueues;
- }
- list_for_each_entry(tfile, &tun->disabled, next) {
-+ tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
- tfile->socket.sk->sk_data_ready(tfile->socket.sk);
- RCU_INIT_POINTER(tfile->tun, NULL);
- }
-@@ -628,6 +630,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte
- goto out;
- }
- tfile->queue_index = tun->numqueues;
-+ tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
- rcu_assign_pointer(tfile->tun, tun);
- rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
- tun->numqueues++;
-@@ -1425,9 +1428,6 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
- if (!iov_iter_count(to))
- return 0;
-
-- if (tun->dev->reg_state != NETREG_REGISTERED)
-- return -EIO;
--
- /* Read frames from queue */
- skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
- &peeked, &off, &err);
-diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
-index 8ac261a..7e29b55 100644
---- a/drivers/net/vxlan.c
-+++ b/drivers/net/vxlan.c
-@@ -1262,7 +1262,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
-
- /* Need Vxlan and inner Ethernet header to be present */
- if (!pskb_may_pull(skb, VXLAN_HLEN))
-- return 1;
-+ goto drop;
-
- unparsed = *vxlan_hdr(skb);
- /* VNI flag always required to be set */
-@@ -1271,7 +1271,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
- ntohl(vxlan_hdr(skb)->vx_flags),
- ntohl(vxlan_hdr(skb)->vx_vni));
- /* Return non vxlan pkt */
-- return 1;
-+ goto drop;
- }
- unparsed.vx_flags &= ~VXLAN_HF_VNI;
- unparsed.vx_vni &= ~VXLAN_VNI_MASK;
-@@ -2959,6 +2959,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
- if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
- conf.flags |= VXLAN_F_REMCSUM_NOPARTIAL;
-
-+ if (tb[IFLA_MTU])
-+ conf.mtu = nla_get_u32(tb[IFLA_MTU]);
-+
- err = vxlan_dev_configure(src_net, dev, &conf);
- switch (err) {
- case -ENODEV:
-diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
-index f700908..0e537fd 100644
---- a/drivers/perf/arm_pmu.c
-+++ b/drivers/perf/arm_pmu.c
-@@ -987,9 +987,6 @@ int arm_pmu_device_probe(struct platform_device *pdev,
-
- armpmu_init(pmu);
-
-- if (!__oprofile_cpu_pmu)
-- __oprofile_cpu_pmu = pmu;
--
- pmu->plat_device = pdev;
-
- if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) {
-@@ -1025,6 +1022,9 @@ int arm_pmu_device_probe(struct platform_device *pdev,
- if (ret)
- goto out_destroy;
-
-+ if (!__oprofile_cpu_pmu)
-+ __oprofile_cpu_pmu = pmu;
-+
- pr_info("enabled with %s PMU driver, %d counters available\n",
- pmu->name, pmu->num_events);
-
-diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
-index 6ab8c3c..fba2dd9 100644
---- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
-+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
-@@ -1256,9 +1256,10 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
- const struct mtk_desc_pin *pin;
-
- chained_irq_enter(chip, desc);
-- for (eint_num = 0; eint_num < pctl->devdata->ap_num; eint_num += 32) {
-+ for (eint_num = 0;
-+ eint_num < pctl->devdata->ap_num;
-+ eint_num += 32, reg += 4) {
- status = readl(reg);
-- reg += 4;
- while (status) {
- offset = __ffs(status);
- index = eint_num + offset;
-diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
-index 3408578..ff41c31 100644
---- a/drivers/scsi/scsi_devinfo.c
-+++ b/drivers/scsi/scsi_devinfo.c
-@@ -230,6 +230,7 @@ static struct {
- {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
- {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
- {"Promise", "", NULL, BLIST_SPARSELUN},
-+ {"QEMU", "QEMU CD-ROM", NULL, BLIST_SKIP_VPD_PAGES},
- {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
- {"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
- {"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
-diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
-index 8106515..f704d02 100644
---- a/drivers/scsi/scsi_lib.c
-+++ b/drivers/scsi/scsi_lib.c
-@@ -911,9 +911,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
- }
-
- /*
-- * If we finished all bytes in the request we are done now.
-+ * special case: failed zero length commands always need to
-+ * drop down into the retry code. Otherwise, if we finished
-+ * all bytes in the request we are done now.
- */
-- if (!scsi_end_request(req, error, good_bytes, 0))
-+ if (!(blk_rq_bytes(req) == 0 && error) &&
-+ !scsi_end_request(req, error, good_bytes, 0))
- return;
-
- /*
-diff --git a/fs/dcache.c b/fs/dcache.c
-index d5ecc6e..44008e3 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -1619,7 +1619,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
- struct dentry *dentry = __d_alloc(parent->d_sb, name);
- if (!dentry)
- return NULL;
--
-+ dentry->d_flags |= DCACHE_RCUACCESS;
- spin_lock(&parent->d_lock);
- /*
- * don't need child lock because it is not subject
-@@ -2338,7 +2338,6 @@ static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
- {
- BUG_ON(!d_unhashed(entry));
- hlist_bl_lock(b);
-- entry->d_flags |= DCACHE_RCUACCESS;
- hlist_bl_add_head_rcu(&entry->d_hash, b);
- hlist_bl_unlock(b);
- }
-@@ -2637,6 +2636,7 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
- /* ... and switch them in the tree */
- if (IS_ROOT(dentry)) {
- /* splicing a tree */
-+ dentry->d_flags |= DCACHE_RCUACCESS;
- dentry->d_parent = target->d_parent;
- target->d_parent = target;
- list_del_init(&target->d_child);
-diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
-index 866bb18..e818f5a 100644
---- a/fs/ecryptfs/kthread.c
-+++ b/fs/ecryptfs/kthread.c
-@@ -25,6 +25,7 @@
- #include <linux/slab.h>
- #include <linux/wait.h>
- #include <linux/mount.h>
-+#include <linux/file.h>
- #include "ecryptfs_kernel.h"
-
- struct ecryptfs_open_req {
-@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
- flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
- (*lower_file) = dentry_open(&req.path, flags, cred);
- if (!IS_ERR(*lower_file))
-- goto out;
-+ goto have_file;
- if ((flags & O_ACCMODE) == O_RDONLY) {
- rc = PTR_ERR((*lower_file));
- goto out;
-@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct file **lower_file,
- mutex_unlock(&ecryptfs_kthread_ctl.mux);
- wake_up(&ecryptfs_kthread_ctl.wait);
- wait_for_completion(&req.done);
-- if (IS_ERR(*lower_file))
-+ if (IS_ERR(*lower_file)) {
- rc = PTR_ERR(*lower_file);
-+ goto out;
-+ }
-+have_file:
-+ if ((*lower_file)->f_op->mmap == NULL) {
-+ fput(*lower_file);
-+ *lower_file = NULL;
-+ rc = -EMEDIUMTYPE;
-+ }
- out:
- return rc;
- }
-diff --git a/fs/proc/root.c b/fs/proc/root.c
-index 361ab4e..ec649c9 100644
---- a/fs/proc/root.c
-+++ b/fs/proc/root.c
-@@ -121,6 +121,13 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
- if (IS_ERR(sb))
- return ERR_CAST(sb);
-
-+ /*
-+ * procfs isn't actually a stacking filesystem; however, there is
-+ * too much magic going on inside it to permit stacking things on
-+ * top of it
-+ */
-+ sb->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
-+
- if (!proc_parse_options(options, ns)) {
- deactivate_locked_super(sb);
- return ERR_PTR(-EINVAL);
-diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
-index d5d798b..e984250 100644
---- a/include/linux/irqchip/arm-gic-v3.h
-+++ b/include/linux/irqchip/arm-gic-v3.h
-@@ -301,7 +301,7 @@
- #define ICC_SGI1R_AFFINITY_1_SHIFT 16
- #define ICC_SGI1R_AFFINITY_1_MASK (0xff << ICC_SGI1R_AFFINITY_1_SHIFT)
- #define ICC_SGI1R_SGI_ID_SHIFT 24
--#define ICC_SGI1R_SGI_ID_MASK (0xff << ICC_SGI1R_SGI_ID_SHIFT)
-+#define ICC_SGI1R_SGI_ID_MASK (0xfULL << ICC_SGI1R_SGI_ID_SHIFT)
- #define ICC_SGI1R_AFFINITY_2_SHIFT 32
- #define ICC_SGI1R_AFFINITY_2_MASK (0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)
- #define ICC_SGI1R_IRQ_ROUTING_MODE_BIT 40
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index 80a305b..4dd9306 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -242,11 +242,18 @@ void xt_unregister_match(struct xt_match *target);
- int xt_register_matches(struct xt_match *match, unsigned int n);
- void xt_unregister_matches(struct xt_match *match, unsigned int n);
-
-+int xt_check_entry_offsets(const void *base, const char *elems,
-+ unsigned int target_offset,
-+ unsigned int next_offset);
-+
- int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
- bool inv_proto);
- int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
- bool inv_proto);
-
-+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
-+ struct xt_counters_info *info, bool compat);
-+
- struct xt_table *xt_register_table(struct net *net,
- const struct xt_table *table,
- struct xt_table_info *bootstrap,
-@@ -480,7 +487,7 @@ void xt_compat_init_offsets(u_int8_t af, unsigned int number);
- int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
-
- int xt_compat_match_offset(const struct xt_match *match);
--int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
- unsigned int *size);
- int xt_compat_match_to_user(const struct xt_entry_match *m,
- void __user **dstptr, unsigned int *size);
-@@ -490,6 +497,9 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
- unsigned int *size);
- int xt_compat_target_to_user(const struct xt_entry_target *t,
- void __user **dstptr, unsigned int *size);
-+int xt_compat_check_entry_offsets(const void *base, const char *elems,
-+ unsigned int target_offset,
-+ unsigned int next_offset);
-
- #endif /* CONFIG_COMPAT */
- #endif /* _X_TABLES_H */
-diff --git a/include/net/switchdev.h b/include/net/switchdev.h
-index 51d77b2..985619a 100644
---- a/include/net/switchdev.h
-+++ b/include/net/switchdev.h
-@@ -97,7 +97,7 @@ struct switchdev_obj_ipv4_fib {
- struct switchdev_obj obj;
- u32 dst;
- int dst_len;
-- struct fib_info fi;
-+ struct fib_info *fi;
- u8 tos;
- u8 type;
- u32 nlflags;
-diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
-index d5e38c7..e4f048e 100644
---- a/include/uapi/linux/libc-compat.h
-+++ b/include/uapi/linux/libc-compat.h
-@@ -52,7 +52,7 @@
- #if defined(__GLIBC__)
-
- /* Coordinate with glibc net/if.h header. */
--#if defined(_NET_IF_H)
-+#if defined(_NET_IF_H) && defined(__USE_MISC)
-
- /* GLIBC headers included first so don't define anything
- * that would already be defined. */
-diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
-index 8f94ca1..b2aefa2 100644
---- a/kernel/bpf/inode.c
-+++ b/kernel/bpf/inode.c
-@@ -378,7 +378,7 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent)
- static struct dentry *bpf_mount(struct file_system_type *type, int flags,
- const char *dev_name, void *data)
- {
-- return mount_ns(type, flags, current->nsproxy->mnt_ns, bpf_fill_super);
-+ return mount_nodev(type, flags, data, bpf_fill_super);
- }
-
- static struct file_system_type bpf_fs_type = {
-@@ -386,7 +386,6 @@ static struct file_system_type bpf_fs_type = {
- .name = "bpf",
- .mount = bpf_mount,
- .kill_sb = kill_litter_super,
-- .fs_flags = FS_USERNS_MOUNT,
- };
-
- MODULE_ALIAS_FS("bpf");
-diff --git a/kernel/sched/core.c b/kernel/sched/core.c
-index d1f7149..11546a6 100644
---- a/kernel/sched/core.c
-+++ b/kernel/sched/core.c
-@@ -3047,7 +3047,8 @@ static noinline void __schedule_bug(struct task_struct *prev)
- static inline void schedule_debug(struct task_struct *prev)
- {
- #ifdef CONFIG_SCHED_STACK_END_CHECK
-- BUG_ON(task_stack_end_corrupted(prev));
-+ if (task_stack_end_corrupted(prev))
-+ panic("corrupted stack end detected inside scheduler\n");
- #endif
-
- if (unlikely(in_atomic_preempt_off())) {
-diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
-index 3e4ffb3..d028941 100644
---- a/kernel/trace/bpf_trace.c
-+++ b/kernel/trace/bpf_trace.c
-@@ -194,7 +194,7 @@ static u64 bpf_perf_event_read(u64 r1, u64 index, u64 r3, u64 r4, u64 r5)
- if (unlikely(index >= array->map.max_entries))
- return -E2BIG;
-
-- file = (struct file *)array->ptrs[index];
-+ file = READ_ONCE(array->ptrs[index]);
- if (unlikely(!file))
- return -ENOENT;
-
-@@ -238,7 +238,7 @@ static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
- if (unlikely(index >= array->map.max_entries))
- return -E2BIG;
-
-- file = (struct file *)array->ptrs[index];
-+ file = READ_ONCE(array->ptrs[index]);
- if (unlikely(!file))
- return -ENOENT;
-
-diff --git a/mm/memcontrol.c b/mm/memcontrol.c
-index fe787f5..a2e79b8 100644
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -2877,6 +2877,7 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
- * ordering is imposed by list_lru_node->lock taken by
- * memcg_drain_all_list_lrus().
- */
-+ rcu_read_lock(); /* can be called from css_free w/o cgroup_mutex */
- css_for_each_descendant_pre(css, &memcg->css) {
- child = mem_cgroup_from_css(css);
- BUG_ON(child->kmemcg_id != kmemcg_id);
-@@ -2884,6 +2885,8 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
- if (!memcg->use_hierarchy)
- break;
- }
-+ rcu_read_unlock();
-+
- memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);
-
- memcg_free_cache_id(kmemcg_id);
-diff --git a/mm/swap_state.c b/mm/swap_state.c
-index 366ce35..1155a68 100644
---- a/mm/swap_state.c
-+++ b/mm/swap_state.c
-@@ -252,7 +252,10 @@ static inline void free_swap_cache(struct page *page)
- void free_page_and_swap_cache(struct page *page)
- {
- free_swap_cache(page);
-- put_page(page);
-+ if (is_huge_zero_page(page))
-+ put_huge_zero_page();
-+ else
-+ put_page(page);
- }
-
- /*
-diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
-index dcea4f4..c18080a 100644
---- a/net/bridge/br_fdb.c
-+++ b/net/bridge/br_fdb.c
-@@ -279,6 +279,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
- * change from under us.
- */
- list_for_each_entry(v, &vg->vlan_list, vlist) {
-+ if (!br_vlan_should_use(v))
-+ continue;
- f = __br_fdb_get(br, br->dev->dev_addr, v->vid);
- if (f && f->is_local && !f->dst)
- fdb_delete_local(br, NULL, f);
-diff --git a/net/core/hwbm.c b/net/core/hwbm.c
-index 941c284..2cab489 100644
---- a/net/core/hwbm.c
-+++ b/net/core/hwbm.c
-@@ -55,18 +55,21 @@ int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
- spin_lock_irqsave(&bm_pool->lock, flags);
- if (bm_pool->buf_num == bm_pool->size) {
- pr_warn("pool already filled\n");
-+ spin_unlock_irqrestore(&bm_pool->lock, flags);
- return bm_pool->buf_num;
- }
-
- if (buf_num + bm_pool->buf_num > bm_pool->size) {
- pr_warn("cannot allocate %d buffers for pool\n",
- buf_num);
-+ spin_unlock_irqrestore(&bm_pool->lock, flags);
- return 0;
- }
-
- if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
- pr_warn("Adding %d buffers to the %d current buffers will overflow\n",
- buf_num, bm_pool->buf_num);
-+ spin_unlock_irqrestore(&bm_pool->lock, flags);
- return 0;
- }
-
-diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
-index 9e48199..7ad0e56 100644
---- a/net/ipv4/af_inet.c
-+++ b/net/ipv4/af_inet.c
-@@ -1660,6 +1660,14 @@ static __net_init int inet_init_net(struct net *net)
- */
- net->ipv4.ping_group_range.range[0] = make_kgid(&init_user_ns, 1);
- net->ipv4.ping_group_range.range[1] = make_kgid(&init_user_ns, 0);
-+
-+ /* Default values for sysctl-controlled parameters.
-+ * We set them here, in case sysctl is not compiled.
-+ */
-+ net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
-+ net->ipv4.sysctl_ip_dynaddr = 0;
-+ net->ipv4.sysctl_ip_early_demux = 1;
-+
- return 0;
- }
-
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 4133b0f..85d60c6 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -367,6 +367,18 @@ static inline bool unconditional(const struct arpt_entry *e)
- memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
- }
-
-+static bool find_jump_target(const struct xt_table_info *t,
-+ const struct arpt_entry *target)
-+{
-+ struct arpt_entry *iter;
-+
-+ xt_entry_foreach(iter, t->entries, t->size) {
-+ if (iter == target)
-+ return true;
-+ }
-+ return false;
-+}
-+
- /* Figures out from what hook each rule can be called: returns 0 if
- * there are loops. Puts hook bitmask in comefrom.
- */
-@@ -439,6 +451,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
- size = e->next_offset;
- e = (struct arpt_entry *)
- (entry0 + pos + size);
-+ if (pos + size >= newinfo->size)
-+ return 0;
- e->counters.pcnt = pos;
- pos += size;
- } else {
-@@ -458,9 +472,15 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-+ e = (struct arpt_entry *)
-+ (entry0 + newpos);
-+ if (!find_jump_target(newinfo, e))
-+ return 0;
- } else {
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
-+ if (newpos >= newinfo->size)
-+ return 0;
- }
- e = (struct arpt_entry *)
- (entry0 + newpos);
-@@ -474,23 +494,6 @@ next:
- return 1;
- }
-
--static inline int check_entry(const struct arpt_entry *e)
--{
-- const struct xt_entry_target *t;
--
-- if (!arp_checkentry(&e->arp))
-- return -EINVAL;
--
-- if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
-- return -EINVAL;
--
-- t = arpt_get_target_c(e);
-- if (e->target_offset + t->u.target_size > e->next_offset)
-- return -EINVAL;
--
-- return 0;
--}
--
- static inline int check_target(struct arpt_entry *e, const char *name)
- {
- struct xt_entry_target *t = arpt_get_target(e);
-@@ -586,7 +589,11 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
- return -EINVAL;
- }
-
-- err = check_entry(e);
-+ if (!arp_checkentry(&e->arp))
-+ return -EINVAL;
-+
-+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
-+ e->next_offset);
- if (err)
- return err;
-
-@@ -691,10 +698,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
- }
- }
-
-- if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
-- duprintf("Looping hook\n");
-+ if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
- return -ELOOP;
-- }
-
- /* Finally, each sanity check must pass */
- i = 0;
-@@ -1126,55 +1131,17 @@ static int do_add_counters(struct net *net, const void __user *user,
- unsigned int i;
- struct xt_counters_info tmp;
- struct xt_counters *paddc;
-- unsigned int num_counters;
-- const char *name;
-- int size;
-- void *ptmp;
- struct xt_table *t;
- const struct xt_table_info *private;
- int ret = 0;
- struct arpt_entry *iter;
- unsigned int addend;
--#ifdef CONFIG_COMPAT
-- struct compat_xt_counters_info compat_tmp;
-
-- if (compat) {
-- ptmp = &compat_tmp;
-- size = sizeof(struct compat_xt_counters_info);
-- } else
--#endif
-- {
-- ptmp = &tmp;
-- size = sizeof(struct xt_counters_info);
-- }
-+ paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
-+ if (IS_ERR(paddc))
-+ return PTR_ERR(paddc);
-
-- if (copy_from_user(ptmp, user, size) != 0)
-- return -EFAULT;
--
--#ifdef CONFIG_COMPAT
-- if (compat) {
-- num_counters = compat_tmp.num_counters;
-- name = compat_tmp.name;
-- } else
--#endif
-- {
-- num_counters = tmp.num_counters;
-- name = tmp.name;
-- }
--
-- if (len != size + num_counters * sizeof(struct xt_counters))
-- return -EINVAL;
--
-- paddc = vmalloc(len - size);
-- if (!paddc)
-- return -ENOMEM;
--
-- if (copy_from_user(paddc, user + size, len - size) != 0) {
-- ret = -EFAULT;
-- goto free;
-- }
--
-- t = xt_find_table_lock(net, NFPROTO_ARP, name);
-+ t = xt_find_table_lock(net, NFPROTO_ARP, tmp.name);
- if (IS_ERR_OR_NULL(t)) {
- ret = t ? PTR_ERR(t) : -ENOENT;
- goto free;
-@@ -1182,7 +1149,7 @@ static int do_add_counters(struct net *net, const void __user *user,
-
- local_bh_disable();
- private = t->private;
-- if (private->number != num_counters) {
-+ if (private->number != tmp.num_counters) {
- ret = -EINVAL;
- goto unlock_up_free;
- }
-@@ -1209,6 +1176,18 @@ static int do_add_counters(struct net *net, const void __user *user,
- }
-
- #ifdef CONFIG_COMPAT
-+struct compat_arpt_replace {
-+ char name[XT_TABLE_MAXNAMELEN];
-+ u32 valid_hooks;
-+ u32 num_entries;
-+ u32 size;
-+ u32 hook_entry[NF_ARP_NUMHOOKS];
-+ u32 underflow[NF_ARP_NUMHOOKS];
-+ u32 num_counters;
-+ compat_uptr_t counters;
-+ struct compat_arpt_entry entries[0];
-+};
-+
- static inline void compat_release_entry(struct compat_arpt_entry *e)
- {
- struct xt_entry_target *t;
-@@ -1217,20 +1196,17 @@ static inline void compat_release_entry(struct compat_arpt_entry *e)
- module_put(t->u.kernel.target->me);
- }
-
--static inline int
-+static int
- check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
- struct xt_table_info *newinfo,
- unsigned int *size,
- const unsigned char *base,
-- const unsigned char *limit,
-- const unsigned int *hook_entries,
-- const unsigned int *underflows,
-- const char *name)
-+ const unsigned char *limit)
- {
- struct xt_entry_target *t;
- struct xt_target *target;
- unsigned int entry_offset;
-- int ret, off, h;
-+ int ret, off;
-
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
- if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
-@@ -1247,8 +1223,11 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
- return -EINVAL;
- }
-
-- /* For purposes of check_entry casting the compat entry is fine */
-- ret = check_entry((struct arpt_entry *)e);
-+ if (!arp_checkentry(&e->arp))
-+ return -EINVAL;
-+
-+ ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
-+ e->next_offset);
- if (ret)
- return ret;
-
-@@ -1272,17 +1251,6 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
- if (ret)
- goto release_target;
-
-- /* Check hooks & underflows */
-- for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
-- if ((unsigned char *)e - base == hook_entries[h])
-- newinfo->hook_entry[h] = hook_entries[h];
-- if ((unsigned char *)e - base == underflows[h])
-- newinfo->underflow[h] = underflows[h];
-- }
--
-- /* Clear counters and comefrom */
-- memset(&e->counters, 0, sizeof(e->counters));
-- e->comefrom = 0;
- return 0;
-
- release_target:
-@@ -1291,18 +1259,17 @@ out:
- return ret;
- }
-
--static int
-+static void
- compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
-- unsigned int *size, const char *name,
-+ unsigned int *size,
- struct xt_table_info *newinfo, unsigned char *base)
- {
- struct xt_entry_target *t;
- struct xt_target *target;
- struct arpt_entry *de;
- unsigned int origsize;
-- int ret, h;
-+ int h;
-
-- ret = 0;
- origsize = *size;
- de = (struct arpt_entry *)*dstptr;
- memcpy(de, e, sizeof(struct arpt_entry));
-@@ -1323,148 +1290,82 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
- if ((unsigned char *)de - base < newinfo->underflow[h])
- newinfo->underflow[h] -= origsize - *size;
- }
-- return ret;
- }
-
--static int translate_compat_table(const char *name,
-- unsigned int valid_hooks,
-- struct xt_table_info **pinfo,
-+static int translate_compat_table(struct xt_table_info **pinfo,
- void **pentry0,
-- unsigned int total_size,
-- unsigned int number,
-- unsigned int *hook_entries,
-- unsigned int *underflows)
-+ const struct compat_arpt_replace *compatr)
- {
- unsigned int i, j;
- struct xt_table_info *newinfo, *info;
- void *pos, *entry0, *entry1;
- struct compat_arpt_entry *iter0;
-- struct arpt_entry *iter1;
-+ struct arpt_replace repl;
- unsigned int size;
- int ret = 0;
-
- info = *pinfo;
- entry0 = *pentry0;
-- size = total_size;
-- info->number = number;
--
-- /* Init all hooks to impossible value. */
-- for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-- info->hook_entry[i] = 0xFFFFFFFF;
-- info->underflow[i] = 0xFFFFFFFF;
-- }
-+ size = compatr->size;
-+ info->number = compatr->num_entries;
-
- duprintf("translate_compat_table: size %u\n", info->size);
- j = 0;
- xt_compat_lock(NFPROTO_ARP);
-- xt_compat_init_offsets(NFPROTO_ARP, number);
-+ xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
- /* Walk through entries, checking offsets. */
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = check_compat_entry_size_and_hooks(iter0, info, &size,
- entry0,
-- entry0 + total_size,
-- hook_entries,
-- underflows,
-- name);
-+ entry0 + compatr->size);
- if (ret != 0)
- goto out_unlock;
- ++j;
- }
-
- ret = -EINVAL;
-- if (j != number) {
-+ if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
-- j, number);
-+ j, compatr->num_entries);
- goto out_unlock;
- }
-
-- /* Check hooks all assigned */
-- for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-- /* Only hooks which are valid */
-- if (!(valid_hooks & (1 << i)))
-- continue;
-- if (info->hook_entry[i] == 0xFFFFFFFF) {
-- duprintf("Invalid hook entry %u %u\n",
-- i, hook_entries[i]);
-- goto out_unlock;
-- }
-- if (info->underflow[i] == 0xFFFFFFFF) {
-- duprintf("Invalid underflow %u %u\n",
-- i, underflows[i]);
-- goto out_unlock;
-- }
-- }
--
- ret = -ENOMEM;
- newinfo = xt_alloc_table_info(size);
- if (!newinfo)
- goto out_unlock;
-
-- newinfo->number = number;
-+ newinfo->number = compatr->num_entries;
- for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
- newinfo->hook_entry[i] = info->hook_entry[i];
- newinfo->underflow[i] = info->underflow[i];
- }
- entry1 = newinfo->entries;
- pos = entry1;
-- size = total_size;
-- xt_entry_foreach(iter0, entry0, total_size) {
-- ret = compat_copy_entry_from_user(iter0, &pos, &size,
-- name, newinfo, entry1);
-- if (ret != 0)
-- break;
-- }
-+ size = compatr->size;
-+ xt_entry_foreach(iter0, entry0, compatr->size)
-+ compat_copy_entry_from_user(iter0, &pos, &size,
-+ newinfo, entry1);
-+
-+ /* all module references in entry0 are now gone */
-+
- xt_compat_flush_offsets(NFPROTO_ARP);
- xt_compat_unlock(NFPROTO_ARP);
-- if (ret)
-- goto free_newinfo;
-
-- ret = -ELOOP;
-- if (!mark_source_chains(newinfo, valid_hooks, entry1))
-- goto free_newinfo;
-+ memcpy(&repl, compatr, sizeof(*compatr));
-
-- i = 0;
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- iter1->counters.pcnt = xt_percpu_counter_alloc();
-- if (IS_ERR_VALUE(iter1->counters.pcnt)) {
-- ret = -ENOMEM;
-- break;
-- }
--
-- ret = check_target(iter1, name);
-- if (ret != 0) {
-- xt_percpu_counter_free(iter1->counters.pcnt);
-- break;
-- }
-- ++i;
-- if (strcmp(arpt_get_target(iter1)->u.user.name,
-- XT_ERROR_TARGET) == 0)
-- ++newinfo->stacksize;
-- }
-- if (ret) {
-- /*
-- * The first i matches need cleanup_entry (calls ->destroy)
-- * because they had called ->check already. The other j-i
-- * entries need only release.
-- */
-- int skip = i;
-- j -= i;
-- xt_entry_foreach(iter0, entry0, newinfo->size) {
-- if (skip-- > 0)
-- continue;
-- if (j-- == 0)
-- break;
-- compat_release_entry(iter0);
-- }
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- if (i-- == 0)
-- break;
-- cleanup_entry(iter1);
-- }
-- xt_free_table_info(newinfo);
-- return ret;
-+ for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
-+ repl.hook_entry[i] = newinfo->hook_entry[i];
-+ repl.underflow[i] = newinfo->underflow[i];
- }
-
-+ repl.num_counters = 0;
-+ repl.counters = NULL;
-+ repl.size = newinfo->size;
-+ ret = translate_table(newinfo, entry1, &repl);
-+ if (ret)
-+ goto free_newinfo;
-+
- *pinfo = newinfo;
- *pentry0 = entry1;
- xt_free_table_info(info);
-@@ -1472,31 +1373,18 @@ static int translate_compat_table(const char *name,
-
- free_newinfo:
- xt_free_table_info(newinfo);
--out:
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ return ret;
-+out_unlock:
-+ xt_compat_flush_offsets(NFPROTO_ARP);
-+ xt_compat_unlock(NFPROTO_ARP);
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- if (j-- == 0)
- break;
- compat_release_entry(iter0);
- }
- return ret;
--out_unlock:
-- xt_compat_flush_offsets(NFPROTO_ARP);
-- xt_compat_unlock(NFPROTO_ARP);
-- goto out;
- }
-
--struct compat_arpt_replace {
-- char name[XT_TABLE_MAXNAMELEN];
-- u32 valid_hooks;
-- u32 num_entries;
-- u32 size;
-- u32 hook_entry[NF_ARP_NUMHOOKS];
-- u32 underflow[NF_ARP_NUMHOOKS];
-- u32 num_counters;
-- compat_uptr_t counters;
-- struct compat_arpt_entry entries[0];
--};
--
- static int compat_do_replace(struct net *net, void __user *user,
- unsigned int len)
- {
-@@ -1529,10 +1417,7 @@ static int compat_do_replace(struct net *net, void __user *user,
- goto free_newinfo;
- }
-
-- ret = translate_compat_table(tmp.name, tmp.valid_hooks,
-- &newinfo, &loc_cpu_entry, tmp.size,
-- tmp.num_entries, tmp.hook_entry,
-- tmp.underflow);
-+ ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
- if (ret != 0)
- goto free_newinfo;
-
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 631c100..0984ea3 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -443,6 +443,18 @@ ipt_do_table(struct sk_buff *skb,
- #endif
- }
-
-+static bool find_jump_target(const struct xt_table_info *t,
-+ const struct ipt_entry *target)
-+{
-+ struct ipt_entry *iter;
-+
-+ xt_entry_foreach(iter, t->entries, t->size) {
-+ if (iter == target)
-+ return true;
-+ }
-+ return false;
-+}
-+
- /* Figures out from what hook each rule can be called: returns 0 if
- there are loops. Puts hook bitmask in comefrom. */
- static int
-@@ -520,6 +532,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
- size = e->next_offset;
- e = (struct ipt_entry *)
- (entry0 + pos + size);
-+ if (pos + size >= newinfo->size)
-+ return 0;
- e->counters.pcnt = pos;
- pos += size;
- } else {
-@@ -538,9 +552,15 @@ mark_source_chains(const struct xt_table_info *newinfo,
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-+ e = (struct ipt_entry *)
-+ (entry0 + newpos);
-+ if (!find_jump_target(newinfo, e))
-+ return 0;
- } else {
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
-+ if (newpos >= newinfo->size)
-+ return 0;
- }
- e = (struct ipt_entry *)
- (entry0 + newpos);
-@@ -568,25 +588,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
- }
-
- static int
--check_entry(const struct ipt_entry *e)
--{
-- const struct xt_entry_target *t;
--
-- if (!ip_checkentry(&e->ip))
-- return -EINVAL;
--
-- if (e->target_offset + sizeof(struct xt_entry_target) >
-- e->next_offset)
-- return -EINVAL;
--
-- t = ipt_get_target_c(e);
-- if (e->target_offset + t->u.target_size > e->next_offset)
-- return -EINVAL;
--
-- return 0;
--}
--
--static int
- check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
- {
- const struct ipt_ip *ip = par->entryinfo;
-@@ -750,7 +751,11 @@ check_entry_size_and_hooks(struct ipt_entry *e,
- return -EINVAL;
- }
-
-- err = check_entry(e);
-+ if (!ip_checkentry(&e->ip))
-+ return -EINVAL;
-+
-+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
-+ e->next_offset);
- if (err)
- return err;
-
-@@ -1309,55 +1314,17 @@ do_add_counters(struct net *net, const void __user *user,
- unsigned int i;
- struct xt_counters_info tmp;
- struct xt_counters *paddc;
-- unsigned int num_counters;
-- const char *name;
-- int size;
-- void *ptmp;
- struct xt_table *t;
- const struct xt_table_info *private;
- int ret = 0;
- struct ipt_entry *iter;
- unsigned int addend;
--#ifdef CONFIG_COMPAT
-- struct compat_xt_counters_info compat_tmp;
-
-- if (compat) {
-- ptmp = &compat_tmp;
-- size = sizeof(struct compat_xt_counters_info);
-- } else
--#endif
-- {
-- ptmp = &tmp;
-- size = sizeof(struct xt_counters_info);
-- }
--
-- if (copy_from_user(ptmp, user, size) != 0)
-- return -EFAULT;
--
--#ifdef CONFIG_COMPAT
-- if (compat) {
-- num_counters = compat_tmp.num_counters;
-- name = compat_tmp.name;
-- } else
--#endif
-- {
-- num_counters = tmp.num_counters;
-- name = tmp.name;
-- }
-+ paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
-+ if (IS_ERR(paddc))
-+ return PTR_ERR(paddc);
-
-- if (len != size + num_counters * sizeof(struct xt_counters))
-- return -EINVAL;
--
-- paddc = vmalloc(len - size);
-- if (!paddc)
-- return -ENOMEM;
--
-- if (copy_from_user(paddc, user + size, len - size) != 0) {
-- ret = -EFAULT;
-- goto free;
-- }
--
-- t = xt_find_table_lock(net, AF_INET, name);
-+ t = xt_find_table_lock(net, AF_INET, tmp.name);
- if (IS_ERR_OR_NULL(t)) {
- ret = t ? PTR_ERR(t) : -ENOENT;
- goto free;
-@@ -1365,7 +1332,7 @@ do_add_counters(struct net *net, const void __user *user,
-
- local_bh_disable();
- private = t->private;
-- if (private->number != num_counters) {
-+ if (private->number != tmp.num_counters) {
- ret = -EINVAL;
- goto unlock_up_free;
- }
-@@ -1444,7 +1411,6 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
-
- static int
- compat_find_calc_match(struct xt_entry_match *m,
-- const char *name,
- const struct ipt_ip *ip,
- int *size)
- {
-@@ -1479,17 +1445,14 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
- struct xt_table_info *newinfo,
- unsigned int *size,
- const unsigned char *base,
-- const unsigned char *limit,
-- const unsigned int *hook_entries,
-- const unsigned int *underflows,
-- const char *name)
-+ const unsigned char *limit)
- {
- struct xt_entry_match *ematch;
- struct xt_entry_target *t;
- struct xt_target *target;
- unsigned int entry_offset;
- unsigned int j;
-- int ret, off, h;
-+ int ret, off;
-
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
- if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
-@@ -1506,8 +1469,11 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
- return -EINVAL;
- }
-
-- /* For purposes of check_entry casting the compat entry is fine */
-- ret = check_entry((struct ipt_entry *)e);
-+ if (!ip_checkentry(&e->ip))
-+ return -EINVAL;
-+
-+ ret = xt_compat_check_entry_offsets(e, e->elems,
-+ e->target_offset, e->next_offset);
- if (ret)
- return ret;
-
-@@ -1515,7 +1481,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
- entry_offset = (void *)e - (void *)base;
- j = 0;
- xt_ematch_foreach(ematch, e) {
-- ret = compat_find_calc_match(ematch, name, &e->ip, &off);
-+ ret = compat_find_calc_match(ematch, &e->ip, &off);
- if (ret != 0)
- goto release_matches;
- ++j;
-@@ -1538,17 +1504,6 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
- if (ret)
- goto out;
-
-- /* Check hooks & underflows */
-- for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-- if ((unsigned char *)e - base == hook_entries[h])
-- newinfo->hook_entry[h] = hook_entries[h];
-- if ((unsigned char *)e - base == underflows[h])
-- newinfo->underflow[h] = underflows[h];
-- }
--
-- /* Clear counters and comefrom */
-- memset(&e->counters, 0, sizeof(e->counters));
-- e->comefrom = 0;
- return 0;
-
- out:
-@@ -1562,19 +1517,18 @@ release_matches:
- return ret;
- }
-
--static int
-+static void
- compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
-- unsigned int *size, const char *name,
-+ unsigned int *size,
- struct xt_table_info *newinfo, unsigned char *base)
- {
- struct xt_entry_target *t;
- struct xt_target *target;
- struct ipt_entry *de;
- unsigned int origsize;
-- int ret, h;
-+ int h;
- struct xt_entry_match *ematch;
-
-- ret = 0;
- origsize = *size;
- de = (struct ipt_entry *)*dstptr;
- memcpy(de, e, sizeof(struct ipt_entry));
-@@ -1583,201 +1537,105 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
- *dstptr += sizeof(struct ipt_entry);
- *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
-
-- xt_ematch_foreach(ematch, e) {
-- ret = xt_compat_match_from_user(ematch, dstptr, size);
-- if (ret != 0)
-- return ret;
-- }
-+ xt_ematch_foreach(ematch, e)
-+ xt_compat_match_from_user(ematch, dstptr, size);
-+
- de->target_offset = e->target_offset - (origsize - *size);
- t = compat_ipt_get_target(e);
- target = t->u.kernel.target;
- xt_compat_target_from_user(t, dstptr, size);
-
- de->next_offset = e->next_offset - (origsize - *size);
-+
- for (h = 0; h < NF_INET_NUMHOOKS; h++) {
- if ((unsigned char *)de - base < newinfo->hook_entry[h])
- newinfo->hook_entry[h] -= origsize - *size;
- if ((unsigned char *)de - base < newinfo->underflow[h])
- newinfo->underflow[h] -= origsize - *size;
- }
-- return ret;
--}
--
--static int
--compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
--{
-- struct xt_entry_match *ematch;
-- struct xt_mtchk_param mtpar;
-- unsigned int j;
-- int ret = 0;
--
-- e->counters.pcnt = xt_percpu_counter_alloc();
-- if (IS_ERR_VALUE(e->counters.pcnt))
-- return -ENOMEM;
--
-- j = 0;
-- mtpar.net = net;
-- mtpar.table = name;
-- mtpar.entryinfo = &e->ip;
-- mtpar.hook_mask = e->comefrom;
-- mtpar.family = NFPROTO_IPV4;
-- xt_ematch_foreach(ematch, e) {
-- ret = check_match(ematch, &mtpar);
-- if (ret != 0)
-- goto cleanup_matches;
-- ++j;
-- }
--
-- ret = check_target(e, net, name);
-- if (ret)
-- goto cleanup_matches;
-- return 0;
--
-- cleanup_matches:
-- xt_ematch_foreach(ematch, e) {
-- if (j-- == 0)
-- break;
-- cleanup_match(ematch, net);
-- }
--
-- xt_percpu_counter_free(e->counters.pcnt);
--
-- return ret;
- }
-
- static int
- translate_compat_table(struct net *net,
-- const char *name,
-- unsigned int valid_hooks,
- struct xt_table_info **pinfo,
- void **pentry0,
-- unsigned int total_size,
-- unsigned int number,
-- unsigned int *hook_entries,
-- unsigned int *underflows)
-+ const struct compat_ipt_replace *compatr)
- {
- unsigned int i, j;
- struct xt_table_info *newinfo, *info;
- void *pos, *entry0, *entry1;
- struct compat_ipt_entry *iter0;
-- struct ipt_entry *iter1;
-+ struct ipt_replace repl;
- unsigned int size;
- int ret;
-
- info = *pinfo;
- entry0 = *pentry0;
-- size = total_size;
-- info->number = number;
--
-- /* Init all hooks to impossible value. */
-- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- info->hook_entry[i] = 0xFFFFFFFF;
-- info->underflow[i] = 0xFFFFFFFF;
-- }
-+ size = compatr->size;
-+ info->number = compatr->num_entries;
-
- duprintf("translate_compat_table: size %u\n", info->size);
- j = 0;
- xt_compat_lock(AF_INET);
-- xt_compat_init_offsets(AF_INET, number);
-+ xt_compat_init_offsets(AF_INET, compatr->num_entries);
- /* Walk through entries, checking offsets. */
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = check_compat_entry_size_and_hooks(iter0, info, &size,
- entry0,
-- entry0 + total_size,
-- hook_entries,
-- underflows,
-- name);
-+ entry0 + compatr->size);
- if (ret != 0)
- goto out_unlock;
- ++j;
- }
-
- ret = -EINVAL;
-- if (j != number) {
-+ if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
-- j, number);
-+ j, compatr->num_entries);
- goto out_unlock;
- }
-
-- /* Check hooks all assigned */
-- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- /* Only hooks which are valid */
-- if (!(valid_hooks & (1 << i)))
-- continue;
-- if (info->hook_entry[i] == 0xFFFFFFFF) {
-- duprintf("Invalid hook entry %u %u\n",
-- i, hook_entries[i]);
-- goto out_unlock;
-- }
-- if (info->underflow[i] == 0xFFFFFFFF) {
-- duprintf("Invalid underflow %u %u\n",
-- i, underflows[i]);
-- goto out_unlock;
-- }
-- }
--
- ret = -ENOMEM;
- newinfo = xt_alloc_table_info(size);
- if (!newinfo)
- goto out_unlock;
-
-- newinfo->number = number;
-+ newinfo->number = compatr->num_entries;
- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- newinfo->hook_entry[i] = info->hook_entry[i];
-- newinfo->underflow[i] = info->underflow[i];
-+ newinfo->hook_entry[i] = compatr->hook_entry[i];
-+ newinfo->underflow[i] = compatr->underflow[i];
- }
- entry1 = newinfo->entries;
- pos = entry1;
-- size = total_size;
-- xt_entry_foreach(iter0, entry0, total_size) {
-- ret = compat_copy_entry_from_user(iter0, &pos, &size,
-- name, newinfo, entry1);
-- if (ret != 0)
-- break;
-- }
-+ size = compatr->size;
-+ xt_entry_foreach(iter0, entry0, compatr->size)
-+ compat_copy_entry_from_user(iter0, &pos, &size,
-+ newinfo, entry1);
-+
-+ /* all module references in entry0 are now gone.
-+ * entry1/newinfo contains a 64bit ruleset that looks exactly as
-+ * generated by 64bit userspace.
-+ *
-+ * Call standard translate_table() to validate all hook_entrys,
-+ * underflows, check for loops, etc.
-+ */
- xt_compat_flush_offsets(AF_INET);
- xt_compat_unlock(AF_INET);
-- if (ret)
-- goto free_newinfo;
-
-- ret = -ELOOP;
-- if (!mark_source_chains(newinfo, valid_hooks, entry1))
-- goto free_newinfo;
-+ memcpy(&repl, compatr, sizeof(*compatr));
-
-- i = 0;
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- ret = compat_check_entry(iter1, net, name);
-- if (ret != 0)
-- break;
-- ++i;
-- if (strcmp(ipt_get_target(iter1)->u.user.name,
-- XT_ERROR_TARGET) == 0)
-- ++newinfo->stacksize;
-- }
-- if (ret) {
-- /*
-- * The first i matches need cleanup_entry (calls ->destroy)
-- * because they had called ->check already. The other j-i
-- * entries need only release.
-- */
-- int skip = i;
-- j -= i;
-- xt_entry_foreach(iter0, entry0, newinfo->size) {
-- if (skip-- > 0)
-- continue;
-- if (j-- == 0)
-- break;
-- compat_release_entry(iter0);
-- }
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- if (i-- == 0)
-- break;
-- cleanup_entry(iter1, net);
-- }
-- xt_free_table_info(newinfo);
-- return ret;
-+ for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-+ repl.hook_entry[i] = newinfo->hook_entry[i];
-+ repl.underflow[i] = newinfo->underflow[i];
- }
-
-+ repl.num_counters = 0;
-+ repl.counters = NULL;
-+ repl.size = newinfo->size;
-+ ret = translate_table(net, newinfo, entry1, &repl);
-+ if (ret)
-+ goto free_newinfo;
-+
- *pinfo = newinfo;
- *pentry0 = entry1;
- xt_free_table_info(info);
-@@ -1785,17 +1643,16 @@ translate_compat_table(struct net *net,
-
- free_newinfo:
- xt_free_table_info(newinfo);
--out:
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ return ret;
-+out_unlock:
-+ xt_compat_flush_offsets(AF_INET);
-+ xt_compat_unlock(AF_INET);
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- if (j-- == 0)
- break;
- compat_release_entry(iter0);
- }
- return ret;
--out_unlock:
-- xt_compat_flush_offsets(AF_INET);
-- xt_compat_unlock(AF_INET);
-- goto out;
- }
-
- static int
-@@ -1831,10 +1688,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
- goto free_newinfo;
- }
-
-- ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-- &newinfo, &loc_cpu_entry, tmp.size,
-- tmp.num_entries, tmp.hook_entry,
-- tmp.underflow);
-+ ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
- if (ret != 0)
- goto free_newinfo;
-
-diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
-index 1e1fe60..03112a3 100644
---- a/net/ipv4/sysctl_net_ipv4.c
-+++ b/net/ipv4/sysctl_net_ipv4.c
-@@ -988,10 +988,6 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
- if (!net->ipv4.sysctl_local_reserved_ports)
- goto err_ports;
-
-- net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
-- net->ipv4.sysctl_ip_dynaddr = 0;
-- net->ipv4.sysctl_ip_early_demux = 1;
--
- return 0;
-
- err_ports:
-diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
-index a2e7f55..e9853df 100644
---- a/net/ipv4/udp.c
-+++ b/net/ipv4/udp.c
-@@ -1616,7 +1616,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
-
- /* if we're overly short, let UDP handle it */
- encap_rcv = ACCESS_ONCE(up->encap_rcv);
-- if (skb->len > sizeof(struct udphdr) && encap_rcv) {
-+ if (encap_rcv) {
- int ret;
-
- /* Verify checksum before giving to encap */
-diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
-index bc972e7..da88de8 100644
---- a/net/ipv6/ip6_output.c
-+++ b/net/ipv6/ip6_output.c
-@@ -1071,17 +1071,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
- const struct in6_addr *final_dst)
- {
- struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
-- int err;
-
- dst = ip6_sk_dst_check(sk, dst, fl6);
-+ if (!dst)
-+ dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
-
-- err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6);
-- if (err)
-- return ERR_PTR(err);
-- if (final_dst)
-- fl6->daddr = *final_dst;
--
-- return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
-+ return dst;
- }
- EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
-
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 86b67b7..9021b43 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -455,6 +455,18 @@ ip6t_do_table(struct sk_buff *skb,
- #endif
- }
-
-+static bool find_jump_target(const struct xt_table_info *t,
-+ const struct ip6t_entry *target)
-+{
-+ struct ip6t_entry *iter;
-+
-+ xt_entry_foreach(iter, t->entries, t->size) {
-+ if (iter == target)
-+ return true;
-+ }
-+ return false;
-+}
-+
- /* Figures out from what hook each rule can be called: returns 0 if
- there are loops. Puts hook bitmask in comefrom. */
- static int
-@@ -532,6 +544,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
- size = e->next_offset;
- e = (struct ip6t_entry *)
- (entry0 + pos + size);
-+ if (pos + size >= newinfo->size)
-+ return 0;
- e->counters.pcnt = pos;
- pos += size;
- } else {
-@@ -550,9 +564,15 @@ mark_source_chains(const struct xt_table_info *newinfo,
- /* This a jump; chase it. */
- duprintf("Jump rule %u -> %u\n",
- pos, newpos);
-+ e = (struct ip6t_entry *)
-+ (entry0 + newpos);
-+ if (!find_jump_target(newinfo, e))
-+ return 0;
- } else {
- /* ... this is a fallthru */
- newpos = pos + e->next_offset;
-+ if (newpos >= newinfo->size)
-+ return 0;
- }
- e = (struct ip6t_entry *)
- (entry0 + newpos);
-@@ -579,25 +599,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
- module_put(par.match->me);
- }
-
--static int
--check_entry(const struct ip6t_entry *e)
--{
-- const struct xt_entry_target *t;
--
-- if (!ip6_checkentry(&e->ipv6))
-- return -EINVAL;
--
-- if (e->target_offset + sizeof(struct xt_entry_target) >
-- e->next_offset)
-- return -EINVAL;
--
-- t = ip6t_get_target_c(e);
-- if (e->target_offset + t->u.target_size > e->next_offset)
-- return -EINVAL;
--
-- return 0;
--}
--
- static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
- {
- const struct ip6t_ip6 *ipv6 = par->entryinfo;
-@@ -762,7 +763,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
- return -EINVAL;
- }
-
-- err = check_entry(e);
-+ if (!ip6_checkentry(&e->ipv6))
-+ return -EINVAL;
-+
-+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
-+ e->next_offset);
- if (err)
- return err;
-
-@@ -1321,55 +1326,16 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
- unsigned int i;
- struct xt_counters_info tmp;
- struct xt_counters *paddc;
-- unsigned int num_counters;
-- char *name;
-- int size;
-- void *ptmp;
- struct xt_table *t;
- const struct xt_table_info *private;
- int ret = 0;
- struct ip6t_entry *iter;
- unsigned int addend;
--#ifdef CONFIG_COMPAT
-- struct compat_xt_counters_info compat_tmp;
--
-- if (compat) {
-- ptmp = &compat_tmp;
-- size = sizeof(struct compat_xt_counters_info);
-- } else
--#endif
-- {
-- ptmp = &tmp;
-- size = sizeof(struct xt_counters_info);
-- }
--
-- if (copy_from_user(ptmp, user, size) != 0)
-- return -EFAULT;
--
--#ifdef CONFIG_COMPAT
-- if (compat) {
-- num_counters = compat_tmp.num_counters;
-- name = compat_tmp.name;
-- } else
--#endif
-- {
-- num_counters = tmp.num_counters;
-- name = tmp.name;
-- }
--
-- if (len != size + num_counters * sizeof(struct xt_counters))
-- return -EINVAL;
--
-- paddc = vmalloc(len - size);
-- if (!paddc)
-- return -ENOMEM;
-
-- if (copy_from_user(paddc, user + size, len - size) != 0) {
-- ret = -EFAULT;
-- goto free;
-- }
--
-- t = xt_find_table_lock(net, AF_INET6, name);
-+ paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
-+ if (IS_ERR(paddc))
-+ return PTR_ERR(paddc);
-+ t = xt_find_table_lock(net, AF_INET6, tmp.name);
- if (IS_ERR_OR_NULL(t)) {
- ret = t ? PTR_ERR(t) : -ENOENT;
- goto free;
-@@ -1377,7 +1343,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
-
- local_bh_disable();
- private = t->private;
-- if (private->number != num_counters) {
-+ if (private->number != tmp.num_counters) {
- ret = -EINVAL;
- goto unlock_up_free;
- }
-@@ -1456,7 +1422,6 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
-
- static int
- compat_find_calc_match(struct xt_entry_match *m,
-- const char *name,
- const struct ip6t_ip6 *ipv6,
- int *size)
- {
-@@ -1491,17 +1456,14 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
- struct xt_table_info *newinfo,
- unsigned int *size,
- const unsigned char *base,
-- const unsigned char *limit,
-- const unsigned int *hook_entries,
-- const unsigned int *underflows,
-- const char *name)
-+ const unsigned char *limit)
- {
- struct xt_entry_match *ematch;
- struct xt_entry_target *t;
- struct xt_target *target;
- unsigned int entry_offset;
- unsigned int j;
-- int ret, off, h;
-+ int ret, off;
-
- duprintf("check_compat_entry_size_and_hooks %p\n", e);
- if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
-@@ -1518,8 +1480,11 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
- return -EINVAL;
- }
-
-- /* For purposes of check_entry casting the compat entry is fine */
-- ret = check_entry((struct ip6t_entry *)e);
-+ if (!ip6_checkentry(&e->ipv6))
-+ return -EINVAL;
-+
-+ ret = xt_compat_check_entry_offsets(e, e->elems,
-+ e->target_offset, e->next_offset);
- if (ret)
- return ret;
-
-@@ -1527,7 +1492,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
- entry_offset = (void *)e - (void *)base;
- j = 0;
- xt_ematch_foreach(ematch, e) {
-- ret = compat_find_calc_match(ematch, name, &e->ipv6, &off);
-+ ret = compat_find_calc_match(ematch, &e->ipv6, &off);
- if (ret != 0)
- goto release_matches;
- ++j;
-@@ -1550,17 +1515,6 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
- if (ret)
- goto out;
-
-- /* Check hooks & underflows */
-- for (h = 0; h < NF_INET_NUMHOOKS; h++) {
-- if ((unsigned char *)e - base == hook_entries[h])
-- newinfo->hook_entry[h] = hook_entries[h];
-- if ((unsigned char *)e - base == underflows[h])
-- newinfo->underflow[h] = underflows[h];
-- }
--
-- /* Clear counters and comefrom */
-- memset(&e->counters, 0, sizeof(e->counters));
-- e->comefrom = 0;
- return 0;
-
- out:
-@@ -1574,18 +1528,17 @@ release_matches:
- return ret;
- }
-
--static int
-+static void
- compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
-- unsigned int *size, const char *name,
-+ unsigned int *size,
- struct xt_table_info *newinfo, unsigned char *base)
- {
- struct xt_entry_target *t;
- struct ip6t_entry *de;
- unsigned int origsize;
-- int ret, h;
-+ int h;
- struct xt_entry_match *ematch;
-
-- ret = 0;
- origsize = *size;
- de = (struct ip6t_entry *)*dstptr;
- memcpy(de, e, sizeof(struct ip6t_entry));
-@@ -1594,11 +1547,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
- *dstptr += sizeof(struct ip6t_entry);
- *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
-
-- xt_ematch_foreach(ematch, e) {
-- ret = xt_compat_match_from_user(ematch, dstptr, size);
-- if (ret != 0)
-- return ret;
-- }
-+ xt_ematch_foreach(ematch, e)
-+ xt_compat_match_from_user(ematch, dstptr, size);
-+
- de->target_offset = e->target_offset - (origsize - *size);
- t = compat_ip6t_get_target(e);
- xt_compat_target_from_user(t, dstptr, size);
-@@ -1610,183 +1561,83 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
- if ((unsigned char *)de - base < newinfo->underflow[h])
- newinfo->underflow[h] -= origsize - *size;
- }
-- return ret;
--}
--
--static int compat_check_entry(struct ip6t_entry *e, struct net *net,
-- const char *name)
--{
-- unsigned int j;
-- int ret = 0;
-- struct xt_mtchk_param mtpar;
-- struct xt_entry_match *ematch;
--
-- e->counters.pcnt = xt_percpu_counter_alloc();
-- if (IS_ERR_VALUE(e->counters.pcnt))
-- return -ENOMEM;
-- j = 0;
-- mtpar.net = net;
-- mtpar.table = name;
-- mtpar.entryinfo = &e->ipv6;
-- mtpar.hook_mask = e->comefrom;
-- mtpar.family = NFPROTO_IPV6;
-- xt_ematch_foreach(ematch, e) {
-- ret = check_match(ematch, &mtpar);
-- if (ret != 0)
-- goto cleanup_matches;
-- ++j;
-- }
--
-- ret = check_target(e, net, name);
-- if (ret)
-- goto cleanup_matches;
-- return 0;
--
-- cleanup_matches:
-- xt_ematch_foreach(ematch, e) {
-- if (j-- == 0)
-- break;
-- cleanup_match(ematch, net);
-- }
--
-- xt_percpu_counter_free(e->counters.pcnt);
--
-- return ret;
- }
-
- static int
- translate_compat_table(struct net *net,
-- const char *name,
-- unsigned int valid_hooks,
- struct xt_table_info **pinfo,
- void **pentry0,
-- unsigned int total_size,
-- unsigned int number,
-- unsigned int *hook_entries,
-- unsigned int *underflows)
-+ const struct compat_ip6t_replace *compatr)
- {
- unsigned int i, j;
- struct xt_table_info *newinfo, *info;
- void *pos, *entry0, *entry1;
- struct compat_ip6t_entry *iter0;
-- struct ip6t_entry *iter1;
-+ struct ip6t_replace repl;
- unsigned int size;
- int ret = 0;
-
- info = *pinfo;
- entry0 = *pentry0;
-- size = total_size;
-- info->number = number;
--
-- /* Init all hooks to impossible value. */
-- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- info->hook_entry[i] = 0xFFFFFFFF;
-- info->underflow[i] = 0xFFFFFFFF;
-- }
-+ size = compatr->size;
-+ info->number = compatr->num_entries;
-
- duprintf("translate_compat_table: size %u\n", info->size);
- j = 0;
- xt_compat_lock(AF_INET6);
-- xt_compat_init_offsets(AF_INET6, number);
-+ xt_compat_init_offsets(AF_INET6, compatr->num_entries);
- /* Walk through entries, checking offsets. */
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = check_compat_entry_size_and_hooks(iter0, info, &size,
- entry0,
-- entry0 + total_size,
-- hook_entries,
-- underflows,
-- name);
-+ entry0 + compatr->size);
- if (ret != 0)
- goto out_unlock;
- ++j;
- }
-
- ret = -EINVAL;
-- if (j != number) {
-+ if (j != compatr->num_entries) {
- duprintf("translate_compat_table: %u not %u entries\n",
-- j, number);
-+ j, compatr->num_entries);
- goto out_unlock;
- }
-
-- /* Check hooks all assigned */
-- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- /* Only hooks which are valid */
-- if (!(valid_hooks & (1 << i)))
-- continue;
-- if (info->hook_entry[i] == 0xFFFFFFFF) {
-- duprintf("Invalid hook entry %u %u\n",
-- i, hook_entries[i]);
-- goto out_unlock;
-- }
-- if (info->underflow[i] == 0xFFFFFFFF) {
-- duprintf("Invalid underflow %u %u\n",
-- i, underflows[i]);
-- goto out_unlock;
-- }
-- }
--
- ret = -ENOMEM;
- newinfo = xt_alloc_table_info(size);
- if (!newinfo)
- goto out_unlock;
-
-- newinfo->number = number;
-+ newinfo->number = compatr->num_entries;
- for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-- newinfo->hook_entry[i] = info->hook_entry[i];
-- newinfo->underflow[i] = info->underflow[i];
-+ newinfo->hook_entry[i] = compatr->hook_entry[i];
-+ newinfo->underflow[i] = compatr->underflow[i];
- }
- entry1 = newinfo->entries;
- pos = entry1;
-- size = total_size;
-- xt_entry_foreach(iter0, entry0, total_size) {
-- ret = compat_copy_entry_from_user(iter0, &pos, &size,
-- name, newinfo, entry1);
-- if (ret != 0)
-- break;
-- }
-+ size = compatr->size;
-+ xt_entry_foreach(iter0, entry0, compatr->size)
-+ compat_copy_entry_from_user(iter0, &pos, &size,
-+ newinfo, entry1);
-+
-+ /* all module references in entry0 are now gone. */
- xt_compat_flush_offsets(AF_INET6);
- xt_compat_unlock(AF_INET6);
-- if (ret)
-- goto free_newinfo;
-
-- ret = -ELOOP;
-- if (!mark_source_chains(newinfo, valid_hooks, entry1))
-- goto free_newinfo;
-+ memcpy(&repl, compatr, sizeof(*compatr));
-
-- i = 0;
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- ret = compat_check_entry(iter1, net, name);
-- if (ret != 0)
-- break;
-- ++i;
-- if (strcmp(ip6t_get_target(iter1)->u.user.name,
-- XT_ERROR_TARGET) == 0)
-- ++newinfo->stacksize;
-- }
-- if (ret) {
-- /*
-- * The first i matches need cleanup_entry (calls ->destroy)
-- * because they had called ->check already. The other j-i
-- * entries need only release.
-- */
-- int skip = i;
-- j -= i;
-- xt_entry_foreach(iter0, entry0, newinfo->size) {
-- if (skip-- > 0)
-- continue;
-- if (j-- == 0)
-- break;
-- compat_release_entry(iter0);
-- }
-- xt_entry_foreach(iter1, entry1, newinfo->size) {
-- if (i-- == 0)
-- break;
-- cleanup_entry(iter1, net);
-- }
-- xt_free_table_info(newinfo);
-- return ret;
-+ for (i = 0; i < NF_INET_NUMHOOKS; i++) {
-+ repl.hook_entry[i] = newinfo->hook_entry[i];
-+ repl.underflow[i] = newinfo->underflow[i];
- }
-
-+ repl.num_counters = 0;
-+ repl.counters = NULL;
-+ repl.size = newinfo->size;
-+ ret = translate_table(net, newinfo, entry1, &repl);
-+ if (ret)
-+ goto free_newinfo;
-+
- *pinfo = newinfo;
- *pentry0 = entry1;
- xt_free_table_info(info);
-@@ -1794,17 +1645,16 @@ translate_compat_table(struct net *net,
-
- free_newinfo:
- xt_free_table_info(newinfo);
--out:
-- xt_entry_foreach(iter0, entry0, total_size) {
-+ return ret;
-+out_unlock:
-+ xt_compat_flush_offsets(AF_INET6);
-+ xt_compat_unlock(AF_INET6);
-+ xt_entry_foreach(iter0, entry0, compatr->size) {
- if (j-- == 0)
- break;
- compat_release_entry(iter0);
- }
- return ret;
--out_unlock:
-- xt_compat_flush_offsets(AF_INET6);
-- xt_compat_unlock(AF_INET6);
-- goto out;
- }
-
- static int
-@@ -1840,10 +1690,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
- goto free_newinfo;
- }
-
-- ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
-- &newinfo, &loc_cpu_entry, tmp.size,
-- tmp.num_entries, tmp.hook_entry,
-- tmp.underflow);
-+ ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
- if (ret != 0)
- goto free_newinfo;
-
-diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
-index f443c6b..f6d7516 100644
---- a/net/ipv6/tcp_ipv6.c
-+++ b/net/ipv6/tcp_ipv6.c
-@@ -1717,7 +1717,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
- destp = ntohs(inet->inet_dport);
- srcp = ntohs(inet->inet_sport);
-
-- if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
-+ if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
-+ icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
-+ icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
- timer_active = 1;
- timer_expires = icsk->icsk_timeout;
- } else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index 6bc5c66..f96831d9 100644
---- a/net/ipv6/udp.c
-+++ b/net/ipv6/udp.c
-@@ -653,7 +653,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
-
- /* if we're overly short, let UDP handle it */
- encap_rcv = ACCESS_ONCE(up->encap_rcv);
-- if (skb->len > sizeof(struct udphdr) && encap_rcv) {
-+ if (encap_rcv) {
- int ret;
-
- /* Verify checksum before giving to encap */
-diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
-index 6edfa99..1e40dac 100644
---- a/net/l2tp/l2tp_core.c
-+++ b/net/l2tp/l2tp_core.c
-@@ -1581,7 +1581,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
- /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
- tunnel->encap = encap;
- if (encap == L2TP_ENCAPTYPE_UDP) {
-- struct udp_tunnel_sock_cfg udp_cfg;
-+ struct udp_tunnel_sock_cfg udp_cfg = { };
-
- udp_cfg.sk_user_data = tunnel;
- udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP;
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 582c9cf..2675d58 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -416,6 +416,47 @@ int xt_check_match(struct xt_mtchk_param *par,
- }
- EXPORT_SYMBOL_GPL(xt_check_match);
-
-+/** xt_check_entry_match - check that matches end before start of target
-+ *
-+ * @match: beginning of xt_entry_match
-+ * @target: beginning of this rules target (alleged end of matches)
-+ * @alignment: alignment requirement of match structures
-+ *
-+ * Validates that all matches add up to the beginning of the target,
-+ * and that each match covers at least the base structure size.
-+ *
-+ * Return: 0 on success, negative errno on failure.
-+ */
-+static int xt_check_entry_match(const char *match, const char *target,
-+ const size_t alignment)
-+{
-+ const struct xt_entry_match *pos;
-+ int length = target - match;
-+
-+ if (length == 0) /* no matches */
-+ return 0;
-+
-+ pos = (struct xt_entry_match *)match;
-+ do {
-+ if ((unsigned long)pos % alignment)
-+ return -EINVAL;
-+
-+ if (length < (int)sizeof(struct xt_entry_match))
-+ return -EINVAL;
-+
-+ if (pos->u.match_size < sizeof(struct xt_entry_match))
-+ return -EINVAL;
-+
-+ if (pos->u.match_size > length)
-+ return -EINVAL;
-+
-+ length -= pos->u.match_size;
-+ pos = ((void *)((char *)(pos) + (pos)->u.match_size));
-+ } while (length > 0);
-+
-+ return 0;
-+}
-+
- #ifdef CONFIG_COMPAT
- int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
- {
-@@ -485,13 +526,14 @@ int xt_compat_match_offset(const struct xt_match *match)
- }
- EXPORT_SYMBOL_GPL(xt_compat_match_offset);
-
--int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-- unsigned int *size)
-+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-+ unsigned int *size)
- {
- const struct xt_match *match = m->u.kernel.match;
- struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
- int pad, off = xt_compat_match_offset(match);
- u_int16_t msize = cm->u.user.match_size;
-+ char name[sizeof(m->u.user.name)];
-
- m = *dstptr;
- memcpy(m, cm, sizeof(*cm));
-@@ -505,10 +547,12 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-
- msize += off;
- m->u.user.match_size = msize;
-+ strlcpy(name, match->name, sizeof(name));
-+ module_put(match->me);
-+ strncpy(m->u.user.name, name, sizeof(m->u.user.name));
-
- *size += off;
- *dstptr += msize;
-- return 0;
- }
- EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
-
-@@ -539,8 +583,125 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
- return 0;
- }
- EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
-+
-+/* non-compat version may have padding after verdict */
-+struct compat_xt_standard_target {
-+ struct compat_xt_entry_target t;
-+ compat_uint_t verdict;
-+};
-+
-+int xt_compat_check_entry_offsets(const void *base, const char *elems,
-+ unsigned int target_offset,
-+ unsigned int next_offset)
-+{
-+ long size_of_base_struct = elems - (const char *)base;
-+ const struct compat_xt_entry_target *t;
-+ const char *e = base;
-+
-+ if (target_offset < size_of_base_struct)
-+ return -EINVAL;
-+
-+ if (target_offset + sizeof(*t) > next_offset)
-+ return -EINVAL;
-+
-+ t = (void *)(e + target_offset);
-+ if (t->u.target_size < sizeof(*t))
-+ return -EINVAL;
-+
-+ if (target_offset + t->u.target_size > next_offset)
-+ return -EINVAL;
-+
-+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
-+ COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
-+ return -EINVAL;
-+
-+ /* compat_xt_entry match has less strict aligment requirements,
-+ * otherwise they are identical. In case of padding differences
-+ * we need to add compat version of xt_check_entry_match.
-+ */
-+ BUILD_BUG_ON(sizeof(struct compat_xt_entry_match) != sizeof(struct xt_entry_match));
-+
-+ return xt_check_entry_match(elems, base + target_offset,
-+ __alignof__(struct compat_xt_entry_match));
-+}
-+EXPORT_SYMBOL(xt_compat_check_entry_offsets);
- #endif /* CONFIG_COMPAT */
-
-+/**
-+ * xt_check_entry_offsets - validate arp/ip/ip6t_entry
-+ *
-+ * @base: pointer to arp/ip/ip6t_entry
-+ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
-+ * @target_offset: the arp/ip/ip6_t->target_offset
-+ * @next_offset: the arp/ip/ip6_t->next_offset
-+ *
-+ * validates that target_offset and next_offset are sane and that all
-+ * match sizes (if any) align with the target offset.
-+ *
-+ * This function does not validate the targets or matches themselves, it
-+ * only tests that all the offsets and sizes are correct, that all
-+ * match structures are aligned, and that the last structure ends where
-+ * the target structure begins.
-+ *
-+ * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
-+ *
-+ * The arp/ip/ip6t_entry structure @base must have passed following tests:
-+ * - it must point to a valid memory location
-+ * - base to base + next_offset must be accessible, i.e. not exceed allocated
-+ * length.
-+ *
-+ * A well-formed entry looks like this:
-+ *
-+ * ip(6)t_entry match [mtdata] match [mtdata] target [tgdata] ip(6)t_entry
-+ * e->elems[]-----' | |
-+ * matchsize | |
-+ * matchsize | |
-+ * | |
-+ * target_offset---------------------------------' |
-+ * next_offset---------------------------------------------------'
-+ *
-+ * elems[]: flexible array member at end of ip(6)/arpt_entry struct.
-+ * This is where matches (if any) and the target reside.
-+ * target_offset: beginning of target.
-+ * next_offset: start of the next rule; also: size of this rule.
-+ * Since targets have a minimum size, target_offset + minlen <= next_offset.
-+ *
-+ * Every match stores its size, sum of sizes must not exceed target_offset.
-+ *
-+ * Return: 0 on success, negative errno on failure.
-+ */
-+int xt_check_entry_offsets(const void *base,
-+ const char *elems,
-+ unsigned int target_offset,
-+ unsigned int next_offset)
-+{
-+ long size_of_base_struct = elems - (const char *)base;
-+ const struct xt_entry_target *t;
-+ const char *e = base;
-+
-+ /* target start is within the ip/ip6/arpt_entry struct */
-+ if (target_offset < size_of_base_struct)
-+ return -EINVAL;
-+
-+ if (target_offset + sizeof(*t) > next_offset)
-+ return -EINVAL;
-+
-+ t = (void *)(e + target_offset);
-+ if (t->u.target_size < sizeof(*t))
-+ return -EINVAL;
-+
-+ if (target_offset + t->u.target_size > next_offset)
-+ return -EINVAL;
-+
-+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
-+ XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
-+ return -EINVAL;
-+
-+ return xt_check_entry_match(elems, base + target_offset,
-+ __alignof__(struct xt_entry_match));
-+}
-+EXPORT_SYMBOL(xt_check_entry_offsets);
-+
- int xt_check_target(struct xt_tgchk_param *par,
- unsigned int size, u_int8_t proto, bool inv_proto)
- {
-@@ -591,6 +752,80 @@ int xt_check_target(struct xt_tgchk_param *par,
- }
- EXPORT_SYMBOL_GPL(xt_check_target);
-
-+/**
-+ * xt_copy_counters_from_user - copy counters and metadata from userspace
-+ *
-+ * @user: src pointer to userspace memory
-+ * @len: alleged size of userspace memory
-+ * @info: where to store the xt_counters_info metadata
-+ * @compat: true if we setsockopt call is done by 32bit task on 64bit kernel
-+ *
-+ * Copies counter meta data from @user and stores it in @info.
-+ *
-+ * vmallocs memory to hold the counters, then copies the counter data
-+ * from @user to the new memory and returns a pointer to it.
-+ *
-+ * If @compat is true, @info gets converted automatically to the 64bit
-+ * representation.
-+ *
-+ * The metadata associated with the counters is stored in @info.
-+ *
-+ * Return: returns pointer that caller has to test via IS_ERR().
-+ * If IS_ERR is false, caller has to vfree the pointer.
-+ */
-+void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
-+ struct xt_counters_info *info, bool compat)
-+{
-+ void *mem;
-+ u64 size;
-+
-+#ifdef CONFIG_COMPAT
-+ if (compat) {
-+ /* structures only differ in size due to alignment */
-+ struct compat_xt_counters_info compat_tmp;
-+
-+ if (len <= sizeof(compat_tmp))
-+ return ERR_PTR(-EINVAL);
-+
-+ len -= sizeof(compat_tmp);
-+ if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
-+ return ERR_PTR(-EFAULT);
-+
-+ strlcpy(info->name, compat_tmp.name, sizeof(info->name));
-+ info->num_counters = compat_tmp.num_counters;
-+ user += sizeof(compat_tmp);
-+ } else
-+#endif
-+ {
-+ if (len <= sizeof(*info))
-+ return ERR_PTR(-EINVAL);
-+
-+ len -= sizeof(*info);
-+ if (copy_from_user(info, user, sizeof(*info)) != 0)
-+ return ERR_PTR(-EFAULT);
-+
-+ info->name[sizeof(info->name) - 1] = '\0';
-+ user += sizeof(*info);
-+ }
-+
-+ size = sizeof(struct xt_counters);
-+ size *= info->num_counters;
-+
-+ if (size != (u64)len)
-+ return ERR_PTR(-EINVAL);
-+
-+ mem = vmalloc(len);
-+ if (!mem)
-+ return ERR_PTR(-ENOMEM);
-+
-+ if (copy_from_user(mem, user, len) == 0)
-+ return mem;
-+
-+ vfree(mem);
-+ return ERR_PTR(-EFAULT);
-+}
-+EXPORT_SYMBOL_GPL(xt_copy_counters_from_user);
-+
- #ifdef CONFIG_COMPAT
- int xt_compat_target_offset(const struct xt_target *target)
- {
-@@ -606,6 +841,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
- struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
- int pad, off = xt_compat_target_offset(target);
- u_int16_t tsize = ct->u.user.target_size;
-+ char name[sizeof(t->u.user.name)];
-
- t = *dstptr;
- memcpy(t, ct, sizeof(*ct));
-@@ -619,6 +855,9 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
-
- tsize += off;
- t->u.user.target_size = tsize;
-+ strlcpy(name, target->name, sizeof(name));
-+ module_put(target->me);
-+ strncpy(t->u.user.name, name, sizeof(t->u.user.name));
-
- *size += off;
- *dstptr += tsize;
-diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
-index 330ebd6..f48e3b3 100644
---- a/net/netlink/af_netlink.c
-+++ b/net/netlink/af_netlink.c
-@@ -2059,6 +2059,7 @@ static int netlink_dump(struct sock *sk)
- struct netlink_callback *cb;
- struct sk_buff *skb = NULL;
- struct nlmsghdr *nlh;
-+ struct module *module;
- int len, err = -ENOBUFS;
- int alloc_min_size;
- int alloc_size;
-@@ -2134,9 +2135,11 @@ static int netlink_dump(struct sock *sk)
- cb->done(cb);
-
- nlk->cb_running = false;
-+ module = cb->module;
-+ skb = cb->skb;
- mutex_unlock(nlk->cb_mutex);
-- module_put(cb->module);
-- consume_skb(cb->skb);
-+ module_put(module);
-+ consume_skb(skb);
- return 0;
-
- errout_skb:
-diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
-index b7e01d8..59658b2 100644
---- a/net/switchdev/switchdev.c
-+++ b/net/switchdev/switchdev.c
-@@ -1188,6 +1188,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
- .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
- .dst = dst,
- .dst_len = dst_len,
-+ .fi = fi,
- .tos = tos,
- .type = type,
- .nlflags = nlflags,
-@@ -1196,8 +1197,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
- struct net_device *dev;
- int err = 0;
-
-- memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
--
- /* Don't offload route if using custom ip rules or if
- * IPv4 FIB offloading has been disabled completely.
- */
-@@ -1242,6 +1241,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
- .obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
- .dst = dst,
- .dst_len = dst_len,
-+ .fi = fi,
- .tos = tos,
- .type = type,
- .nlflags = 0,
-@@ -1250,8 +1250,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
- struct net_device *dev;
- int err = 0;
-
-- memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
--
- if (!(fi->fib_flags & RTNH_F_OFFLOAD))
- return 0;
-
-diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
-index d7d050f..4dfc5c1 100644
---- a/net/tipc/netlink_compat.c
-+++ b/net/tipc/netlink_compat.c
-@@ -802,7 +802,7 @@ static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg,
- goto out;
-
- tipc_tlv_sprintf(msg->rep, "%-10u %s",
-- nla_get_u32(publ[TIPC_NLA_PUBL_REF]),
-+ nla_get_u32(publ[TIPC_NLA_PUBL_KEY]),
- scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
- out:
- tipc_tlv_sprintf(msg->rep, "\n");
-diff --git a/net/tipc/socket.c b/net/tipc/socket.c
-index 3eeb50a..5f80d3f 100644
---- a/net/tipc/socket.c
-+++ b/net/tipc/socket.c
-@@ -2807,6 +2807,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
- if (err)
- return err;
-
-+ if (!attrs[TIPC_NLA_SOCK])
-+ return -EINVAL;
-+
- err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
- attrs[TIPC_NLA_SOCK],
- tipc_nl_sock_policy);
-diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
-index b50ee5d..c753211 100644
---- a/net/wireless/wext-core.c
-+++ b/net/wireless/wext-core.c
-@@ -955,8 +955,29 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
- return private(dev, iwr, cmd, info, handler);
- }
- /* Old driver API : call driver ioctl handler */
-- if (dev->netdev_ops->ndo_do_ioctl)
-- return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
-+ if (dev->netdev_ops->ndo_do_ioctl) {
-+#ifdef CONFIG_COMPAT
-+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
-+ int ret = 0;
-+ struct iwreq iwr_lcl;
-+ struct compat_iw_point *iwp_compat = (void *) &iwr->u.data;
-+
-+ memcpy(&iwr_lcl, iwr, sizeof(struct iwreq));
-+ iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer);
-+ iwr_lcl.u.data.length = iwp_compat->length;
-+ iwr_lcl.u.data.flags = iwp_compat->flags;
-+
-+ ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd);
-+
-+ iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer);
-+ iwp_compat->length = iwr_lcl.u.data.length;
-+ iwp_compat->flags = iwr_lcl.u.data.flags;
-+
-+ return ret;
-+ } else
-+#endif
-+ return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
-+ }
- return -EOPNOTSUPP;
- }
-
-diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
-index 9a0d144..94089fc 100644
---- a/sound/pci/hda/hda_intel.c
-+++ b/sound/pci/hda/hda_intel.c
-@@ -365,8 +365,11 @@ enum {
-
- #define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
- #define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
-+#define IS_KBL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171)
-+#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
- #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
--#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
-+#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
-+ IS_KBL(pci) || IS_KBL_LP(pci)
-
- static char *driver_short_names[] = {
- [AZX_DRIVER_ICH] = "HDA Intel",
-@@ -2181,6 +2184,12 @@ static const struct pci_device_id azx_ids[] = {
- /* Sunrise Point-LP */
- { PCI_DEVICE(0x8086, 0x9d70),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
-+ /* Kabylake */
-+ { PCI_DEVICE(0x8086, 0xa171),
-+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
-+ /* Kabylake-LP */
-+ { PCI_DEVICE(0x8086, 0x9d71),
-+ .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
- /* Broxton-P(Apollolake) */
- { PCI_DEVICE(0x8086, 0x5a98),
- .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
-diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
-index d53c25e..0fe18ed 100644
---- a/sound/pci/hda/patch_realtek.c
-+++ b/sound/pci/hda/patch_realtek.c
-@@ -346,6 +346,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
- case 0x10ec0234:
- case 0x10ec0274:
- case 0x10ec0294:
-+ case 0x10ec0700:
-+ case 0x10ec0701:
-+ case 0x10ec0703:
- alc_update_coef_idx(codec, 0x10, 1<<15, 0);
- break;
- case 0x10ec0662:
-@@ -2655,6 +2658,7 @@ enum {
- ALC269_TYPE_ALC256,
- ALC269_TYPE_ALC225,
- ALC269_TYPE_ALC294,
-+ ALC269_TYPE_ALC700,
- };
-
- /*
-@@ -2686,6 +2690,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
- case ALC269_TYPE_ALC256:
- case ALC269_TYPE_ALC225:
- case ALC269_TYPE_ALC294:
-+ case ALC269_TYPE_ALC700:
- ssids = alc269_ssids;
- break;
- default:
-@@ -3618,13 +3623,20 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
- static void alc_headset_mode_unplugged(struct hda_codec *codec)
- {
- static struct coef_fw coef0255[] = {
-- WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
- WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
- UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
- WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
- WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
- {}
- };
-+ static struct coef_fw coef0255_1[] = {
-+ WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
-+ {}
-+ };
-+ static struct coef_fw coef0256[] = {
-+ WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
-+ {}
-+ };
- static struct coef_fw coef0233[] = {
- WRITE_COEF(0x1b, 0x0c0b),
- WRITE_COEF(0x45, 0xc429),
-@@ -3677,7 +3689,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
-
- switch (codec->core.vendor_id) {
- case 0x10ec0255:
-+ alc_process_coef_fw(codec, coef0255_1);
-+ alc_process_coef_fw(codec, coef0255);
-+ break;
- case 0x10ec0256:
-+ alc_process_coef_fw(codec, coef0256);
- alc_process_coef_fw(codec, coef0255);
- break;
- case 0x10ec0233:
-@@ -3896,6 +3912,12 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
- WRITE_COEFEX(0x57, 0x03, 0x8ea6),
- {}
- };
-+ static struct coef_fw coef0256[] = {
-+ WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
-+ WRITE_COEF(0x1b, 0x0c6b),
-+ WRITE_COEFEX(0x57, 0x03, 0x8ea6),
-+ {}
-+ };
- static struct coef_fw coef0233[] = {
- WRITE_COEF(0x45, 0xd429),
- WRITE_COEF(0x1b, 0x0c2b),
-@@ -3936,9 +3958,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
-
- switch (codec->core.vendor_id) {
- case 0x10ec0255:
-- case 0x10ec0256:
- alc_process_coef_fw(codec, coef0255);
- break;
-+ case 0x10ec0256:
-+ alc_process_coef_fw(codec, coef0256);
-+ break;
- case 0x10ec0233:
- case 0x10ec0283:
- alc_process_coef_fw(codec, coef0233);
-@@ -3978,6 +4002,12 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
- WRITE_COEFEX(0x57, 0x03, 0x8ea6),
- {}
- };
-+ static struct coef_fw coef0256[] = {
-+ WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
-+ WRITE_COEF(0x1b, 0x0c6b),
-+ WRITE_COEFEX(0x57, 0x03, 0x8ea6),
-+ {}
-+ };
- static struct coef_fw coef0233[] = {
- WRITE_COEF(0x45, 0xe429),
- WRITE_COEF(0x1b, 0x0c2b),
-@@ -4018,9 +4048,11 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
-
- switch (codec->core.vendor_id) {
- case 0x10ec0255:
-- case 0x10ec0256:
- alc_process_coef_fw(codec, coef0255);
- break;
-+ case 0x10ec0256:
-+ alc_process_coef_fw(codec, coef0256);
-+ break;
- case 0x10ec0233:
- case 0x10ec0283:
- alc_process_coef_fw(codec, coef0233);
-@@ -4266,7 +4298,7 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
- static void alc255_set_default_jack_type(struct hda_codec *codec)
- {
- /* Set to iphone type */
-- static struct coef_fw fw[] = {
-+ static struct coef_fw alc255fw[] = {
- WRITE_COEF(0x1b, 0x880b),
- WRITE_COEF(0x45, 0xd089),
- WRITE_COEF(0x1b, 0x080b),
-@@ -4274,7 +4306,22 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
- WRITE_COEF(0x1b, 0x0c0b),
- {}
- };
-- alc_process_coef_fw(codec, fw);
-+ static struct coef_fw alc256fw[] = {
-+ WRITE_COEF(0x1b, 0x884b),
-+ WRITE_COEF(0x45, 0xd089),
-+ WRITE_COEF(0x1b, 0x084b),
-+ WRITE_COEF(0x46, 0x0004),
-+ WRITE_COEF(0x1b, 0x0c4b),
-+ {}
-+ };
-+ switch (codec->core.vendor_id) {
-+ case 0x10ec0255:
-+ alc_process_coef_fw(codec, alc255fw);
-+ break;
-+ case 0x10ec0256:
-+ alc_process_coef_fw(codec, alc256fw);
-+ break;
-+ }
- msleep(30);
- }
-
-@@ -5587,6 +5634,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
- SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
- SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
- SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
-+ SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
- 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),
-@@ -5775,6 +5823,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
- {0x12, 0x90a60180},
- {0x14, 0x90170130},
- {0x21, 0x02211040}),
-+ SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
-+ {0x12, 0x90a60180},
-+ {0x14, 0x90170120},
-+ {0x21, 0x02211030}),
- SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
- {0x12, 0x90a60160},
- {0x14, 0x90170120},
-@@ -6053,6 +6105,14 @@ static int patch_alc269(struct hda_codec *codec)
- case 0x10ec0294:
- spec->codec_variant = ALC269_TYPE_ALC294;
- break;
-+ case 0x10ec0700:
-+ case 0x10ec0701:
-+ case 0x10ec0703:
-+ spec->codec_variant = ALC269_TYPE_ALC700;
-+ spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
-+ alc_update_coef_idx(codec, 0x4a, 0, 1 << 15); /* Combo jack auto trigger control */
-+ break;
-+
- }
-
- if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
-@@ -7008,6 +7068,9 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
- HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
- HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
- HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
-+ HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
-+ HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
-+ HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
- HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc882),
- HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
- HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
-diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
-index 674bdf8..501849a 100644
---- a/virt/kvm/arm/hyp/vgic-v2-sr.c
-+++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
-@@ -93,12 +93,11 @@ static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
- if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
- continue;
-
-- if (cpu_if->vgic_elrsr & (1UL << i)) {
-+ if (cpu_if->vgic_elrsr & (1UL << i))
- cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
-- continue;
-- }
-+ else
-+ cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
-
-- cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
- writel_relaxed(0, base + GICH_LR0 + (i * 4));
- }
- }
-diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
-index fe84e1a..8db197b 100644
---- a/virt/kvm/irqchip.c
-+++ b/virt/kvm/irqchip.c
-@@ -40,7 +40,7 @@ int kvm_irq_map_gsi(struct kvm *kvm,
-
- irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
- lockdep_is_held(&kvm->irq_lock));
-- if (gsi < irq_rt->nr_rt_entries) {
-+ if (irq_rt && gsi < irq_rt->nr_rt_entries) {
- hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
- entries[n] = *e;
- ++n;
diff --git a/4.6.3/0000_README b/4.6.4/0000_README
index 585f483..55247f8 100644
--- a/4.6.3/0000_README
+++ b/4.6.4/0000_README
@@ -2,11 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1002_linux-4.6.3.patch
-From: http://www.kernel.org
-Desc: Linux 4.6.3
-
-Patch: 4420_grsecurity-3.1-4.6.3-201607070721.patch
+Patch: 4420_grsecurity-3.1-4.6.4-201607112205.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.6.3/4420_grsecurity-3.1-4.6.3-201607070721.patch b/4.6.4/4420_grsecurity-3.1-4.6.4-201607112205.patch
index b3964cb..95ffa2d 100644
--- a/4.6.3/4420_grsecurity-3.1-4.6.3-201607070721.patch
+++ b/4.6.4/4420_grsecurity-3.1-4.6.4-201607112205.patch
@@ -420,7 +420,7 @@ index fcddfd5..71afd6b 100644
A toggle value indicating if modules are allowed to be loaded
diff --git a/Makefile b/Makefile
-index c62b531..e158b54 100644
+index cd37442..4c8e887 100644
--- a/Makefile
+++ b/Makefile
@@ -298,7 +298,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -39799,10 +39799,10 @@ index 7921251..ba86330 100644
static void cryptd_queue_worker(struct work_struct *work);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
-index 43fe85f..215a174 100644
+index 7097a33..e946ace 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
-@@ -504,7 +504,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+@@ -505,7 +505,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
dump_alloc += CRYPTO_REPORT_MAXSIZE;
{
@@ -42021,7 +42021,7 @@ index 92d6fc0..e4e1e27 100644
}
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
-index 7a1cf7e..538f666 100644
+index 7a1cf7e..0330e12 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -382,7 +382,7 @@ struct drbd_epoch {
@@ -42033,6 +42033,17 @@ index 7a1cf7e..538f666 100644
atomic_t active; /* increased on every req. added, and dec on every finished. */
unsigned long flags;
};
+@@ -586,8 +586,8 @@ struct drbd_md {
+ u32 flags;
+ u32 md_size_sect;
+
+- s32 al_offset; /* signed relative sector offset to activity log */
+- s32 bm_offset; /* signed relative sector offset to bitmap */
++ s32 al_offset __intentional_overflow(0); /* signed relative sector offset to activity log */
++ s32 bm_offset __intentional_overflow(0); /* signed relative sector offset to bitmap */
+
+ /* cached value of bdev->disk_conf->meta_dev_idx (see below) */
+ s32 meta_dev_idx;
@@ -951,7 +951,7 @@ struct drbd_device {
unsigned int al_tr_number;
int al_tr_cycle;
@@ -70517,7 +70528,7 @@ index 1e7e139..c2031dd 100644
/*
diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h
-index 06dc215..543c5aa 100644
+index 06dc215..543c5aaa 100644
--- a/drivers/scsi/bfa/bfa_fcs.h
+++ b/drivers/scsi/bfa/bfa_fcs.h
@@ -67,8 +67,10 @@ struct bfa_fcs_s;
@@ -78569,7 +78580,7 @@ index a7de8e8..e1ef134 100644
spin_lock_init(&uhci->lock);
setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout,
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
-index 48672fa..9245081 100644
+index c10972f..7a2d5db5 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -32,7 +32,7 @@
@@ -78582,10 +78593,10 @@ index 48672fa..9245081 100644
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
-index 99b4ff4..83b36b4 100644
+index 8b5b2ac..052a44e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
-@@ -1861,9 +1861,9 @@ td_cleanup:
+@@ -1878,9 +1878,9 @@ td_cleanup:
* unsigned). Play it safe and say we didn't transfer anything.
*/
if (urb->actual_length > urb->transfer_buffer_length) {
@@ -78597,7 +78608,7 @@ index 99b4ff4..83b36b4 100644
urb->actual_length = 0;
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
*status = -EREMOTEIO;
-@@ -1942,10 +1942,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -1959,10 +1959,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
return finish_td(xhci, td, event_trb, event, ep, status, false);
case COMP_STOP:
/* Did we stop at data stage? */
@@ -78617,7 +78628,7 @@ index 99b4ff4..83b36b4 100644
/* fall through */
case COMP_STOP_INVAL:
return finish_td(xhci, td, event_trb, event, ep, status, false);
-@@ -1959,12 +1964,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -1976,12 +1981,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* else fall through */
case COMP_STALL:
/* Did we transfer part of the data (middle) phase? */
@@ -78639,7 +78650,7 @@ index 99b4ff4..83b36b4 100644
td->urb->actual_length = 0;
return finish_td(xhci, td, event_trb, event, ep, status, false);
-@@ -1997,9 +2005,12 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -2014,9 +2022,12 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
* the last TRB.
*/
td->urb_length_set = true;
@@ -78655,7 +78666,7 @@ index 99b4ff4..83b36b4 100644
xhci_dbg(xhci, "Waiting for status "
"stage event\n");
return 0;
-@@ -2194,11 +2205,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -2211,11 +2222,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* Fast path - was this the last TRB in the TD for this URB? */
} else if (event_trb == td->last_trb) {
if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
@@ -78668,7 +78679,7 @@ index 99b4ff4..83b36b4 100644
xhci_warn(xhci, "HC gave bad length "
"of %d bytes left\n",
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
-@@ -2207,7 +2214,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
+@@ -2224,7 +2231,10 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
*status = -EREMOTEIO;
else
*status = 0;
@@ -78681,10 +78692,10 @@ index 99b4ff4..83b36b4 100644
if (*status == -EINPROGRESS) {
if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
-index 9e71c96..f9b2333 100644
+index 3272805..a3f7895 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -4875,7 +4875,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
+@@ -4878,7 +4878,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
int retval;
/* Accept arbitrarily long scatter-gather lists */
@@ -98514,6 +98525,39 @@ index 8580831..36166e5 100644
retval = sysfs_create_mount_point(kernel_kobj, "debug");
if (retval)
return retval;
+diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
+index f024040..27794b1 100644
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -169,6 +169,19 @@ out:
+ return rc;
+ }
+
++static int ecryptfs_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct file *lower_file = ecryptfs_file_to_lower(file);
++ /*
++ * Don't allow mmap on top of file systems that don't support it
++ * natively. If FILESYSTEM_MAX_STACK_DEPTH > 2 or ecryptfs
++ * allows recursive mounting, this will need to be extended.
++ */
++ if (!lower_file->f_op->mmap)
++ return -ENODEV;
++ return generic_file_mmap(file, vma);
++}
++
+ /**
+ * ecryptfs_open
+ * @inode: inode speciying file to open
+@@ -403,7 +416,7 @@ const struct file_operations ecryptfs_main_fops = {
+ #ifdef CONFIG_COMPAT
+ .compat_ioctl = ecryptfs_compat_ioctl,
+ #endif
+- .mmap = generic_file_mmap,
++ .mmap = ecryptfs_mmap,
+ .open = ecryptfs_open,
+ .flush = ecryptfs_flush,
+ .release = ecryptfs_release,
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 224b49e..980370c 100644
--- a/fs/ecryptfs/inode.c
@@ -133239,7 +133283,7 @@ index f3f302f..a001305 100644
/* Helper routines for sys_msgsnd and sys_msgrcv */
extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
diff --git a/include/linux/net.h b/include/linux/net.h
-index f840d77..f7a95d98 100644
+index 9d90efe6..55eeb64 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -195,7 +195,7 @@ struct net_proto_family {
@@ -135063,7 +135107,7 @@ index c441407..f487b83 100644
/*
* Callback to arch code if there's nosmp or maxcpus=0 on the
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
-index 4018b48..68baf26 100644
+index a0596ca0..6c9245f 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -16,7 +16,7 @@ struct sock_diag_handler {
@@ -139598,7 +139642,7 @@ index 2a20c0d..3eb7d03 100644
#ifdef CONFIG_MODULE_UNLOAD
{
diff --git a/kernel/events/core.c b/kernel/events/core.c
-index c0ded24..9a8ef89 100644
+index a69c90c..9344bfe 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -350,8 +350,15 @@ static struct srcu_struct pmus_srcu;
@@ -154052,7 +154096,7 @@ index 3937b1b..b18d1cb 100644
fle->object = flo;
else
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
-index f18ae91..f033693 100644
+index 769cece..425d3bd 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -860,7 +860,7 @@ static void neigh_probe(struct neighbour *neigh)
@@ -154118,7 +154162,7 @@ index f18ae91..f033693 100644
nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
goto nla_put_failure;
-@@ -2870,7 +2870,7 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write,
+@@ -2874,7 +2874,7 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int size, ret;
@@ -154127,7 +154171,7 @@ index f18ae91..f033693 100644
tmp.extra1 = &zero;
tmp.extra2 = &unres_qlen_max;
-@@ -2932,7 +2932,7 @@ static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
+@@ -2936,7 +2936,7 @@ static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write,
void __user *buffer,
size_t *lenp, loff_t *ppos)
{
@@ -157090,7 +157134,7 @@ index 6f32944..03cad65 100644
table = kmemdup(ipv6_route_table_template,
sizeof(ipv6_route_table_template),
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
-index 8338430..602490e 100644
+index 6c53e4e..6e83866 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -74,7 +74,7 @@ static void ipip6_tunnel_setup(struct net_device *dev);
@@ -184835,10 +184879,10 @@ index 0000000..00c7430
+}
diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data
new file mode 100644
-index 0000000..bdcfd9a
+index 0000000..e6b58b6
--- /dev/null
+++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data
-@@ -0,0 +1,21989 @@
+@@ -0,0 +1,21990 @@
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL
+enable_so_v9fs_xattr_get_acl_fndecl_4 v9fs_xattr_get_acl fndecl 5 4 NULL
@@ -184976,6 +185020,7 @@ index 0000000..bdcfd9a
+enable_so_fcp_resid_bnx2fc_cmd_412 fcp_resid bnx2fc_cmd 0 412 NULL
+enable_so_base_cbuf_417 base cbuf 0 417 NULL
+enable_so_mp_config_acpi_gsi_fndecl_419 mp_config_acpi_gsi fndecl 2 419 NULL
++enable_so_apparmor_setprocattr_fndecl_421 apparmor_setprocattr fndecl 4 421 NULL
+enable_so_fat_short2uni_fndecl_423 fat_short2uni fndecl 0 423 NULL
+enable_so_vol_reg_size_tas571x_chip_426 vol_reg_size tas571x_chip 0 426 NULL
+enable_so_status_netdev_desc_430 status netdev_desc 0 430 NULL
@@ -212148,7 +212193,7 @@ index f72f48f..769a657 100755
# Find all available archs
find_all_archs()
diff --git a/security/Kconfig b/security/Kconfig
-index e452378..e634654 100644
+index e4523789..e634654 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -4,6 +4,994 @@
@@ -213184,7 +213229,7 @@ index c28b0f2..3b9fee0 100644
struct dentry *dents[AAFS_NS_SIZEOF];
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
-index dec607c..37fe357 100644
+index dec607c..53d479f 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -176,7 +176,7 @@ static int common_perm_dir_dentry(int op, struct path *dir,
@@ -213216,7 +213261,82 @@ index dec607c..37fe357 100644
struct path_cond cond = { d_backing_inode(old_dentry)->i_uid,
d_backing_inode(old_dentry)->i_mode
};
-@@ -677,11 +677,11 @@ static const struct kernel_param_ops param_ops_aalockpolicy = {
+@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
+ {
+ struct common_audit_data sa;
+ struct apparmor_audit_data aad = {0,};
+- char *command, *args = value;
++ char *command, *largs = NULL, *args = value;
+ size_t arg_size;
+ int error;
+
+ if (size == 0)
+ return -EINVAL;
+- /* args points to a PAGE_SIZE buffer, AppArmor requires that
+- * the buffer must be null terminated or have size <= PAGE_SIZE -1
+- * so that AppArmor can null terminate them
+- */
+- if (args[size - 1] != '\0') {
+- if (size == PAGE_SIZE)
+- return -EINVAL;
+- args[size] = '\0';
+- }
+-
+ /* task can only write its own attributes */
+ if (current != task)
+ return -EACCES;
+
+- args = value;
++ /* AppArmor requires that the buffer must be null terminated atm */
++ if (args[size - 1] != '\0') {
++ /* null terminate */
++ largs = args = kmalloc(size + 1, GFP_KERNEL);
++ if (!args)
++ return -ENOMEM;
++ memcpy(args, value, size);
++ args[size] = '\0';
++ }
++
++ error = -EINVAL;
+ args = strim(args);
+ command = strsep(&args, " ");
+ if (!args)
+- return -EINVAL;
++ goto out;
+ args = skip_spaces(args);
+ if (!*args)
+- return -EINVAL;
++ goto out;
+
+ arg_size = size - (args - (char *) value);
+ if (strcmp(name, "current") == 0) {
+@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
+ goto fail;
+ } else
+ /* only support the "current" and "exec" process attributes */
+- return -EINVAL;
++ goto fail;
+
+ if (!error)
+ error = size;
++out:
++ kfree(largs);
+ return error;
+
+ fail:
+@@ -588,9 +590,9 @@ fail:
+ aad.profile = aa_current_profile();
+ aad.op = OP_SETPROCATTR;
+ aad.info = name;
+- aad.error = -EINVAL;
++ aad.error = error = -EINVAL;
+ aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
+- return -EINVAL;
++ goto out;
+ }
+
+ static int apparmor_task_setrlimit(struct task_struct *task,
+@@ -677,11 +679,11 @@ static const struct kernel_param_ops param_ops_aalockpolicy = {
.get = param_get_aalockpolicy
};
@@ -213232,7 +213352,7 @@ index dec607c..37fe357 100644
/* Flag values, also controllable via /sys/module/apparmor/parameters
* We define special types as we want to do additional mediation.
-@@ -791,7 +791,7 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp)
+@@ -791,7 +793,7 @@ static int param_get_aauint(char *buffer, const struct kernel_param *kp)
return param_get_uint(buffer, kp);
}
@@ -213241,7 +213361,7 @@ index dec607c..37fe357 100644
{
if (!capable(CAP_MAC_ADMIN))
return -EPERM;
-@@ -802,7 +802,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
+@@ -802,7 +804,7 @@ static int param_get_audit(char *buffer, struct kernel_param *kp)
return sprintf(buffer, "%s", audit_mode_names[aa_g_audit]);
}
@@ -213250,7 +213370,7 @@ index dec607c..37fe357 100644
{
int i;
if (!capable(CAP_MAC_ADMIN))
-@@ -824,7 +824,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
+@@ -824,7 +826,7 @@ static int param_set_audit(const char *val, struct kernel_param *kp)
return -EINVAL;
}
@@ -213259,7 +213379,7 @@ index dec607c..37fe357 100644
{
if (!capable(CAP_MAC_ADMIN))
return -EPERM;
-@@ -835,7 +835,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
+@@ -835,7 +837,7 @@ static int param_get_mode(char *buffer, struct kernel_param *kp)
return sprintf(buffer, "%s", aa_profile_mode_names[aa_g_profile_mode]);
}
diff --git a/4.6.3/4425_grsec_remove_EI_PAX.patch b/4.6.4/4425_grsec_remove_EI_PAX.patch
index c988c9a..c988c9a 100644
--- a/4.6.3/4425_grsec_remove_EI_PAX.patch
+++ b/4.6.4/4425_grsec_remove_EI_PAX.patch
diff --git a/4.6.3/4427_force_XATTR_PAX_tmpfs.patch b/4.6.4/4427_force_XATTR_PAX_tmpfs.patch
index 4ee3f0c..4ee3f0c 100644
--- a/4.6.3/4427_force_XATTR_PAX_tmpfs.patch
+++ b/4.6.4/4427_force_XATTR_PAX_tmpfs.patch
diff --git a/4.6.3/4430_grsec-remove-localversion-grsec.patch b/4.6.4/4430_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/4.6.3/4430_grsec-remove-localversion-grsec.patch
+++ b/4.6.4/4430_grsec-remove-localversion-grsec.patch
diff --git a/4.6.3/4435_grsec-mute-warnings.patch b/4.6.4/4435_grsec-mute-warnings.patch
index b7564e4..b7564e4 100644
--- a/4.6.3/4435_grsec-mute-warnings.patch
+++ b/4.6.4/4435_grsec-mute-warnings.patch
diff --git a/4.6.3/4440_grsec-remove-protected-paths.patch b/4.6.4/4440_grsec-remove-protected-paths.patch
index 741546d..741546d 100644
--- a/4.6.3/4440_grsec-remove-protected-paths.patch
+++ b/4.6.4/4440_grsec-remove-protected-paths.patch
diff --git a/4.6.3/4450_grsec-kconfig-default-gids.patch b/4.6.4/4450_grsec-kconfig-default-gids.patch
index ccf0abd..ccf0abd 100644
--- a/4.6.3/4450_grsec-kconfig-default-gids.patch
+++ b/4.6.4/4450_grsec-kconfig-default-gids.patch
diff --git a/4.6.3/4465_selinux-avc_audit-log-curr_ip.patch b/4.6.4/4465_selinux-avc_audit-log-curr_ip.patch
index 7248385..7248385 100644
--- a/4.6.3/4465_selinux-avc_audit-log-curr_ip.patch
+++ b/4.6.4/4465_selinux-avc_audit-log-curr_ip.patch
diff --git a/4.6.3/4470_disable-compat_vdso.patch b/4.6.4/4470_disable-compat_vdso.patch
index fd822fe..fd822fe 100644
--- a/4.6.3/4470_disable-compat_vdso.patch
+++ b/4.6.4/4470_disable-compat_vdso.patch
diff --git a/4.6.3/4475_emutramp_default_on.patch b/4.6.4/4475_emutramp_default_on.patch
index feb8c7b..feb8c7b 100644
--- a/4.6.3/4475_emutramp_default_on.patch
+++ b/4.6.4/4475_emutramp_default_on.patch