diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2015-07-29 09:22:32 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2015-07-29 09:22:32 -0400 |
commit | d8f474ed8b41ce8c105ac603af9afbba9f60181d (patch) | |
tree | 26d2c457160e770322dd8969574f46f2e1714f51 | |
parent | grsecurity-{3.14.48,4.1.3}-201507261932 (diff) | |
download | hardened-patchset-d8f474ed8b41ce8c105ac603af9afbba9f60181d.tar.gz hardened-patchset-d8f474ed8b41ce8c105ac603af9afbba9f60181d.tar.bz2 hardened-patchset-d8f474ed8b41ce8c105ac603af9afbba9f60181d.zip |
grsecurity-3.1-4.1.3-20150728194320150728
-rw-r--r-- | 4.1.3/0000_README | 2 | ||||
-rw-r--r-- | 4.1.3/4420_grsecurity-3.1-4.1.3-201507281943.patch (renamed from 4.1.3/4420_grsecurity-3.1-4.1.3-201507261932.patch) | 770 |
2 files changed, 686 insertions, 86 deletions
diff --git a/4.1.3/0000_README b/4.1.3/0000_README index cbe10c3..68a3992 100644 --- a/4.1.3/0000_README +++ b/4.1.3/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-3.1-4.1.3-201507261932.patch +Patch: 4420_grsecurity-3.1-4.1.3-201507281943.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.1.3/4420_grsecurity-3.1-4.1.3-201507261932.patch b/4.1.3/4420_grsecurity-3.1-4.1.3-201507281943.patch index c2c4ded..fc096b0 100644 --- a/4.1.3/4420_grsecurity-3.1-4.1.3-201507261932.patch +++ b/4.1.3/4420_grsecurity-3.1-4.1.3-201507281943.patch @@ -16525,20 +16525,19 @@ index acdee09..a553db3 100644 struct compat_timespec { compat_time_t tv_sec; diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h -index 3d6606f..5e22255 100644 +index 3d6606f..91703f1 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h -@@ -214,7 +214,8 @@ +@@ -214,7 +214,7 @@ #define X86_FEATURE_PAUSEFILTER ( 8*32+13) /* AMD filtered pause intercept */ #define X86_FEATURE_PFTHRESHOLD ( 8*32+14) /* AMD pause filter threshold */ #define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ - -+#define X86_FEATURE_PCIDUDEREF ( 8*32+30) /* PaX PCID based UDEREF */ +#define X86_FEATURE_STRONGUDEREF (8*32+31) /* PaX PCID based strong UDEREF */ /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ #define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ -@@ -222,7 +223,7 @@ +@@ -222,7 +222,7 @@ #define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ #define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ #define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ @@ -16547,7 +16546,7 @@ index 3d6606f..5e22255 100644 #define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ #define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ #define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ -@@ -401,6 +402,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; +@@ -401,6 +401,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) #define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) #define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) @@ -16555,7 +16554,7 @@ index 3d6606f..5e22255 100644 #if __GNUC__ >= 4 extern void warn_pre_alternatives(void); -@@ -454,7 +456,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) +@@ -454,7 +455,8 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) #ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS t_warn: @@ -16565,7 +16564,7 @@ index 3d6606f..5e22255 100644 return false; #endif -@@ -475,7 +478,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) +@@ -475,7 +477,7 @@ static __always_inline __pure bool __static_cpu_has(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ ".previous\n" @@ -16574,7 +16573,7 @@ index 3d6606f..5e22255 100644 "3: movb $1,%0\n" "4:\n" ".previous\n" -@@ -510,7 +513,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -510,7 +512,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) " .byte 5f - 4f\n" /* repl len */ " .byte 3b - 2b\n" /* pad len */ ".previous\n" @@ -16583,7 +16582,7 @@ index 3d6606f..5e22255 100644 "4: jmp %l[t_no]\n" "5:\n" ".previous\n" -@@ -545,7 +548,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -545,7 +547,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ ".previous\n" @@ -16592,7 +16591,7 @@ index 3d6606f..5e22255 100644 "3: movb $0,%0\n" "4:\n" ".previous\n" -@@ -560,7 +563,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) +@@ -560,7 +562,7 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) ".section .discard,\"aw\",@progbits\n" " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */ ".previous\n" @@ -17439,7 +17438,7 @@ index 09b9620..923aecd 100644 atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */ } mm_context_t; diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h -index 883f6b93..5184058 100644 +index 883f6b93..bb405b5 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -42,6 +42,20 @@ void destroy_context(struct mm_struct *mm); @@ -17448,7 +17447,7 @@ index 883f6b93..5184058 100644 { + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (!(static_cpu_has(X86_FEATURE_PCIDUDEREF))) { ++ if (!(static_cpu_has(X86_FEATURE_PCID))) { + unsigned int i; + pgd_t *pgd; + @@ -17486,7 +17485,7 @@ index 883f6b93..5184058 100644 + pax_open_kernel(); + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) ++ if (static_cpu_has(X86_FEATURE_PCID)) + __clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd); + else +#endif @@ -17497,7 +17496,7 @@ index 883f6b93..5184058 100644 + BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & __PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & __PHYSICAL_MASK)); + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) { ++ if (static_cpu_has(X86_FEATURE_PCID)) { + if (static_cpu_has(X86_FEATURE_INVPCID)) { + u64 descriptor[2]; + descriptor[0] = PCID_USER; @@ -17554,7 +17553,7 @@ index 883f6b93..5184058 100644 + pax_open_kernel(); + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) ++ if (static_cpu_has(X86_FEATURE_PCID)) + __clone_user_pgds(get_cpu_pgd(cpu, user), next->pgd); + else +#endif @@ -17565,7 +17564,7 @@ index 883f6b93..5184058 100644 + BUG_ON((__pa(get_cpu_pgd(cpu, kernel)) | PCID_KERNEL) != (read_cr3() & __PHYSICAL_MASK) && (__pa(get_cpu_pgd(cpu, user)) | PCID_USER) != (read_cr3() & __PHYSICAL_MASK)); + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) { ++ if (static_cpu_has(X86_FEATURE_PCID)) { + if (static_cpu_has(X86_FEATURE_INVPCID)) { + u64 descriptor[2]; + descriptor[0] = PCID_USER; @@ -19402,7 +19401,7 @@ index b4bdec3..e8af9bc 100644 #endif #endif /* _ASM_X86_THREAD_INFO_H */ diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h -index cd79194..6a9956f 100644 +index cd79194..e7a9491 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -86,18 +86,44 @@ static inline void cr4_set_bits_and_update_boot(unsigned long mask) @@ -19418,7 +19417,7 @@ index cd79194..6a9956f 100644 + } + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) { ++ if (static_cpu_has(X86_FEATURE_PCID)) { + unsigned int cpu = raw_get_cpu(); + + native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER); @@ -19456,7 +19455,7 @@ index cd79194..6a9956f 100644 } static inline void __native_flush_tlb_global(void) -@@ -118,6 +144,43 @@ static inline void __native_flush_tlb_global(void) +@@ -118,6 +144,41 @@ static inline void __native_flush_tlb_global(void) static inline void __native_flush_tlb_single(unsigned long addr) { @@ -19467,16 +19466,14 @@ index cd79194..6a9956f 100644 + descriptor[1] = addr; + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) { -+ if (!static_cpu_has(X86_FEATURE_STRONGUDEREF) || addr >= TASK_SIZE_MAX) { -+ if (addr < TASK_SIZE_MAX) -+ descriptor[1] += pax_user_shadow_base; -+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : "memory"); -+ } -+ -+ descriptor[0] = PCID_USER; -+ descriptor[1] = addr; ++ if (!static_cpu_has(X86_FEATURE_STRONGUDEREF) || addr >= TASK_SIZE_MAX) { ++ if (addr < TASK_SIZE_MAX) ++ descriptor[1] += pax_user_shadow_base; ++ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : "memory"); + } ++ ++ descriptor[0] = PCID_USER; ++ descriptor[1] = addr; +#endif + + asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_SINGLE_ADDRESS) : "memory"); @@ -19484,7 +19481,7 @@ index cd79194..6a9956f 100644 + } + +#if defined(CONFIG_X86_64) && defined(CONFIG_PAX_MEMORY_UDEREF) -+ if (static_cpu_has(X86_FEATURE_PCIDUDEREF)) { ++ if (static_cpu_has(X86_FEATURE_PCID)) { + unsigned int cpu = raw_get_cpu(); + + native_write_cr3(__pa(get_cpu_pgd(cpu, user)) | PCID_USER | PCID_NOFLUSH); @@ -21131,7 +21128,7 @@ index e4cf633..941f450 100644 if (c->x86_model == 3 && c->x86_mask == 0) size = 64; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c -index a62cf04..56afd65 100644 +index a62cf04..041e39c 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -91,60 +91,6 @@ static const struct cpu_dev default_cpu = { @@ -21195,7 +21192,7 @@ index a62cf04..56afd65 100644 static int __init x86_xsave_setup(char *s) { if (strlen(s)) -@@ -306,6 +252,62 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) +@@ -306,6 +252,59 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) } } @@ -21216,31 +21213,26 @@ index a62cf04..56afd65 100644 + +static void setup_pcid(struct cpuinfo_x86 *c) +{ -+ if (cpu_has(c, X86_FEATURE_PCID)) { -+ printk("PAX: PCID detected\n"); -+ cr4_set_bits(X86_CR4_PCIDE); -+ } else ++ if (!cpu_has(c, X86_FEATURE_PCID)) { + clear_cpu_cap(c, X86_FEATURE_INVPCID); + -+ if (cpu_has(c, X86_FEATURE_INVPCID)) -+ printk("PAX: INVPCID detected\n"); -+ +#ifdef CONFIG_PAX_MEMORY_UDEREF -+ if (clone_pgd_mask == ~(pgdval_t)0UL) { -+ printk("PAX: UDEREF disabled\n"); -+ return; -+ } ++ if (clone_pgd_mask != ~(pgdval_t)0UL) { ++ pax_open_kernel(); ++ pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT; ++ pax_close_kernel(); ++ printk("PAX: slow and weak UDEREF enabled\n"); ++ } else ++ printk("PAX: UDEREF disabled\n"); ++#endif + -+ if (!cpu_has(c, X86_FEATURE_PCID)) { -+ pax_open_kernel(); -+ pax_user_shadow_base = 1UL << TASK_SIZE_MAX_SHIFT; -+ pax_close_kernel(); -+ printk("PAX: slow and weak UDEREF enabled\n"); + return; + } + -+ set_cpu_cap(c, X86_FEATURE_PCIDUDEREF); ++ printk("PAX: PCID detected\n"); ++ cr4_set_bits(X86_CR4_PCIDE); + ++#ifdef CONFIG_PAX_MEMORY_UDEREF + pax_open_kernel(); + clone_pgd_mask = ~(pgdval_t)0UL; + pax_close_kernel(); @@ -21252,13 +21244,15 @@ index a62cf04..56afd65 100644 + } +#endif + ++ if (cpu_has(c, X86_FEATURE_INVPCID)) ++ printk("PAX: INVPCID detected\n"); +} +#endif + /* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization -@@ -406,7 +408,7 @@ void switch_to_new_gdt(int cpu) +@@ -406,7 +405,7 @@ void switch_to_new_gdt(int cpu) { struct desc_ptr gdt_descr; @@ -21267,7 +21261,7 @@ index a62cf04..56afd65 100644 gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); /* Reload the per-cpu base */ -@@ -935,6 +937,20 @@ static void identify_cpu(struct cpuinfo_x86 *c) +@@ -935,6 +934,20 @@ static void identify_cpu(struct cpuinfo_x86 *c) setup_smep(c); setup_smap(c); @@ -21288,7 +21282,7 @@ index a62cf04..56afd65 100644 /* * The vendor-specific functions might have changed features. * Now we do "generic changes." -@@ -1009,7 +1025,7 @@ void enable_sep_cpu(void) +@@ -1009,7 +1022,7 @@ void enable_sep_cpu(void) int cpu; cpu = get_cpu(); @@ -21297,7 +21291,7 @@ index a62cf04..56afd65 100644 if (!boot_cpu_has(X86_FEATURE_SEP)) goto out; -@@ -1155,14 +1171,16 @@ static __init int setup_disablecpuid(char *arg) +@@ -1155,14 +1168,16 @@ static __init int setup_disablecpuid(char *arg) } __setup("clearcpuid=", setup_disablecpuid); @@ -21318,7 +21312,7 @@ index a62cf04..56afd65 100644 DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union) __aligned(PAGE_SIZE) __visible; -@@ -1367,7 +1385,7 @@ void cpu_init(void) +@@ -1367,7 +1382,7 @@ void cpu_init(void) */ load_ucode_ap(); @@ -21327,7 +21321,7 @@ index a62cf04..56afd65 100644 oist = &per_cpu(orig_ist, cpu); #ifdef CONFIG_NUMA -@@ -1399,7 +1417,6 @@ void cpu_init(void) +@@ -1399,7 +1414,6 @@ void cpu_init(void) wrmsrl(MSR_KERNEL_GS_BASE, 0); barrier(); @@ -21335,7 +21329,7 @@ index a62cf04..56afd65 100644 x2apic_setup(); /* -@@ -1451,7 +1468,7 @@ void cpu_init(void) +@@ -1451,7 +1465,7 @@ void cpu_init(void) { int cpu = smp_processor_id(); struct task_struct *curr = current; @@ -21745,10 +21739,25 @@ index 7795f3f..3535b76 100644 __bts_event_stop(event); diff --git a/arch/x86/kernel/cpu/perf_event_intel_cqm.c b/arch/x86/kernel/cpu/perf_event_intel_cqm.c -index e4d1b8b..2c6ffa0 100644 +index e4d1b8b..8867302 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_cqm.c +++ b/arch/x86/kernel/cpu/perf_event_intel_cqm.c -@@ -1352,7 +1352,9 @@ static int __init intel_cqm_init(void) +@@ -934,6 +934,14 @@ static u64 intel_cqm_event_count(struct perf_event *event) + return 0; + + /* ++ * Getting up-to-date values requires an SMP IPI which is not ++ * possible if we're being called in interrupt context. Return ++ * the cached values instead. ++ */ ++ if (unlikely(in_interrupt())) ++ goto out; ++ ++ /* + * Notice that we don't perform the reading of an RMID + * atomically, because we can't hold a spin lock across the + * IPIs. +@@ -1352,7 +1360,9 @@ static int __init intel_cqm_init(void) goto out; } @@ -33559,10 +33568,10 @@ index 9ca35fc..4b2b7b7 100644 return (void *)vaddr; diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c -index 70e7444..75b9a13 100644 +index 70e7444..e9904fd 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c -@@ -56,8 +56,8 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, +@@ -56,12 +56,10 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, unsigned long i; for (i = 0; i < nr_pages; ++i) @@ -33572,8 +33581,50 @@ index 70e7444..75b9a13 100644 + !PageReserved(pfn_to_page(start_pfn + i)))) return 1; - WARN_ONCE(1, "ioremap on RAM pfn 0x%lx\n", start_pfn); -@@ -288,7 +288,7 @@ EXPORT_SYMBOL(ioremap_prot); +- WARN_ONCE(1, "ioremap on RAM pfn 0x%lx\n", start_pfn); +- + return 0; + } + +@@ -91,7 +89,6 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, + pgprot_t prot; + int retval; + void __iomem *ret_addr; +- int ram_region; + + /* Don't allow wraparound or zero size */ + last_addr = phys_addr + size - 1; +@@ -114,23 +111,15 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr, + /* + * Don't allow anybody to remap normal RAM that we're using.. + */ +- /* First check if whole region can be identified as RAM or not */ +- ram_region = region_is_ram(phys_addr, size); +- if (ram_region > 0) { +- WARN_ONCE(1, "ioremap on RAM at 0x%lx - 0x%lx\n", +- (unsigned long int)phys_addr, +- (unsigned long int)last_addr); ++ pfn = phys_addr >> PAGE_SHIFT; ++ last_pfn = last_addr >> PAGE_SHIFT; ++ if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, ++ __ioremap_check_ram) == 1) { ++ WARN_ONCE(1, "ioremap on RAM at 0x%llx - 0x%llx\n", ++ phys_addr, last_addr); + return NULL; + } + +- /* If could not be identified(-1), check page by page */ +- if (ram_region < 0) { +- pfn = phys_addr >> PAGE_SHIFT; +- last_pfn = last_addr >> PAGE_SHIFT; +- if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, +- __ioremap_check_ram) == 1) +- return NULL; +- } + /* + * Mappings have to be page-aligned + */ +@@ -288,7 +277,7 @@ EXPORT_SYMBOL(ioremap_prot); * * Caller must ensure there is only one unmapping for the same pointer. */ @@ -33582,7 +33633,7 @@ index 70e7444..75b9a13 100644 { struct vm_struct *p, *o; -@@ -351,32 +351,36 @@ int arch_ioremap_pmd_supported(void) +@@ -351,32 +340,36 @@ int arch_ioremap_pmd_supported(void) */ void *xlate_dev_mem_ptr(phys_addr_t phys) { @@ -33635,7 +33686,7 @@ index 70e7444..75b9a13 100644 static inline pmd_t * __init early_ioremap_pmd(unsigned long addr) { -@@ -412,8 +416,7 @@ void __init early_ioremap_init(void) +@@ -412,8 +405,7 @@ void __init early_ioremap_init(void) early_ioremap_setup(); pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)); @@ -34407,7 +34458,7 @@ index 90555bf..f5f1828 100644 } diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c -index 3250f23..7a97ba2 100644 +index 3250f23..4197ac2 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -45,7 +45,11 @@ void leave_mm(int cpu) @@ -34422,6 +34473,15 @@ index 3250f23..7a97ba2 100644 /* * This gets called in the idle path where RCU * functions differently. Tracing normally +@@ -117,7 +121,7 @@ static void flush_tlb_func(void *info) + } else { + unsigned long addr; + unsigned long nr_pages = +- f->flush_end - f->flush_start / PAGE_SIZE; ++ (f->flush_end - f->flush_start) / PAGE_SIZE; + addr = f->flush_start; + while (addr < f->flush_end) { + __flush_tlb_single(addr); diff --git a/arch/x86/mm/uderef_64.c b/arch/x86/mm/uderef_64.c new file mode 100644 index 0000000..3fda3f3 @@ -47683,6 +47743,19 @@ index c439c82..1f20f57 100644 union axis_conversion ac; /* hw -> logical axis */ int mapped_btns[3]; +diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c +index 3e29681..e40bcd03 100644 +--- a/drivers/misc/mei/main.c ++++ b/drivers/misc/mei/main.c +@@ -685,7 +685,7 @@ int mei_register(struct mei_device *dev, struct device *parent) + /* Fill in the data structures */ + devno = MKDEV(MAJOR(mei_devt), dev->minor); + cdev_init(&dev->cdev, &mei_fops); +- dev->cdev.owner = mei_fops.owner; ++ dev->cdev.owner = parent->driver->owner; + + /* Add the device */ + ret = cdev_add(&dev->cdev, devno, 1); diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c index 2f30bad..c4c13d0 100644 --- a/drivers/misc/sgi-gru/gruhandles.c @@ -96084,6 +96157,34 @@ index 7ee1774..72505b8 100644 } /* +diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h +index 1da6029..6cd8c0e 100644 +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -116,6 +116,7 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops); + * SAVE_REGS. If another ops with this flag set is already registered + * for any of the functions that this ops will be registered for, then + * this ops will fail to register or set_filter_ip. ++ * PID - Is affected by set_ftrace_pid (allows filtering on those pids) + */ + enum { + FTRACE_OPS_FL_ENABLED = 1 << 0, +@@ -132,6 +133,7 @@ enum { + FTRACE_OPS_FL_MODIFYING = 1 << 11, + FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12, + FTRACE_OPS_FL_IPMODIFY = 1 << 13, ++ FTRACE_OPS_FL_PID = 1 << 14, + }; + + #ifdef CONFIG_DYNAMIC_FTRACE +@@ -159,6 +161,7 @@ struct ftrace_ops { + struct ftrace_ops *next; + unsigned long flags; + void *private; ++ ftrace_func_t saved_func; + int __percpu *disabled; + #ifdef CONFIG_DYNAMIC_FTRACE + int nr_trampolines; diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ec274e0..e678159 100644 --- a/include/linux/genhd.h @@ -101287,6 +101388,71 @@ index 0320bbb..938789c 100644 /** inet_connection_sock - INET connection oriented sock * +diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h +index 8d17655..2f3246d 100644 +--- a/include/net/inet_frag.h ++++ b/include/net/inet_frag.h +@@ -21,13 +21,11 @@ struct netns_frags { + * @INET_FRAG_FIRST_IN: first fragment has arrived + * @INET_FRAG_LAST_IN: final fragment has arrived + * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction +- * @INET_FRAG_EVICTED: frag queue is being evicted + */ + enum { + INET_FRAG_FIRST_IN = BIT(0), + INET_FRAG_LAST_IN = BIT(1), + INET_FRAG_COMPLETE = BIT(2), +- INET_FRAG_EVICTED = BIT(3) + }; + + /** +@@ -45,6 +43,7 @@ enum { + * @flags: fragment queue flags + * @max_size: (ipv4 only) maximum received fragment size with IP_DF set + * @net: namespace that this frag belongs to ++ * @list_evictor: list of queues to forcefully evict (e.g. due to low memory) + */ + struct inet_frag_queue { + spinlock_t lock; +@@ -59,6 +58,7 @@ struct inet_frag_queue { + __u8 flags; + u16 max_size; + struct netns_frags *net; ++ struct hlist_node list_evictor; + }; + + #define INETFRAGS_HASHSZ 1024 +@@ -125,6 +125,11 @@ static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f + inet_frag_destroy(q, f); + } + ++static inline bool inet_frag_evicting(struct inet_frag_queue *q) ++{ ++ return !hlist_unhashed(&q->list_evictor); ++} ++ + /* Memory Tracking Functions. */ + + /* The default percpu_counter batch size is not big enough to scale to +@@ -139,14 +144,14 @@ static inline int frag_mem_limit(struct netns_frags *nf) + return percpu_counter_read(&nf->mem); + } + +-static inline void sub_frag_mem_limit(struct inet_frag_queue *q, int i) ++static inline void sub_frag_mem_limit(struct netns_frags *nf, int i) + { +- __percpu_counter_add(&q->net->mem, -i, frag_percpu_counter_batch); ++ __percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch); + } + +-static inline void add_frag_mem_limit(struct inet_frag_queue *q, int i) ++static inline void add_frag_mem_limit(struct netns_frags *nf, int i) + { +- __percpu_counter_add(&q->net->mem, i, frag_percpu_counter_batch); ++ __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch); + } + + static inline void init_frag_mem_limit(struct netns_frags *nf) diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index d5332dd..10a5c3c 100644 --- a/include/net/inetpeer.h @@ -102761,7 +102927,7 @@ index ad1bd77..dca2c1b 100644 next_state = Reset; return 0; diff --git a/init/main.c b/init/main.c -index 2a89545..eb9203f 100644 +index 2a89545..449eca2 100644 --- a/init/main.c +++ b/init/main.c @@ -97,6 +97,8 @@ extern void radix_tree_init(void); @@ -102773,7 +102939,7 @@ index 2a89545..eb9203f 100644 /* * Debug helper: via this flag we know that we are in 'early bootup code' * where only the boot processor is running with IRQ disabled. This means -@@ -158,6 +160,84 @@ static int __init set_reset_devices(char *str) +@@ -158,6 +160,85 @@ static int __init set_reset_devices(char *str) __setup("reset_devices", set_reset_devices); @@ -102826,7 +102992,8 @@ index 2a89545..eb9203f 100644 + memcpy(pax_exit_kernel_user, (unsigned char []){0xc3}, 1); + clone_pgd_mask = ~(pgdval_t)0UL; + pax_user_shadow_base = 0UL; -+ setup_clear_cpu_cap(X86_FEATURE_PCIDUDEREF); ++ setup_clear_cpu_cap(X86_FEATURE_PCID); ++ setup_clear_cpu_cap(X86_FEATURE_INVPCID); +#endif + + return 0; @@ -102858,7 +103025,7 @@ index 2a89545..eb9203f 100644 static const char *argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; const char *envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; static const char *panic_later, *panic_param; -@@ -726,7 +806,7 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) +@@ -726,7 +807,7 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn) struct blacklist_entry *entry; char *fn_name; @@ -102867,7 +103034,7 @@ index 2a89545..eb9203f 100644 if (!fn_name) return false; -@@ -778,7 +858,7 @@ int __init_or_module do_one_initcall(initcall_t fn) +@@ -778,7 +859,7 @@ int __init_or_module do_one_initcall(initcall_t fn) { int count = preempt_count(); int ret; @@ -102876,7 +103043,7 @@ index 2a89545..eb9203f 100644 if (initcall_blacklisted(fn)) return -EPERM; -@@ -788,18 +868,17 @@ int __init_or_module do_one_initcall(initcall_t fn) +@@ -788,18 +869,17 @@ int __init_or_module do_one_initcall(initcall_t fn) else ret = fn(); @@ -102899,7 +103066,7 @@ index 2a89545..eb9203f 100644 return ret; } -@@ -905,8 +984,8 @@ static int run_init_process(const char *init_filename) +@@ -905,8 +985,8 @@ static int run_init_process(const char *init_filename) { argv_init[0] = init_filename; return do_execve(getname_kernel(init_filename), @@ -102910,7 +103077,7 @@ index 2a89545..eb9203f 100644 } static int try_to_run_init_process(const char *init_filename) -@@ -923,6 +1002,10 @@ static int try_to_run_init_process(const char *init_filename) +@@ -923,6 +1003,10 @@ static int try_to_run_init_process(const char *init_filename) return ret; } @@ -102921,7 +103088,7 @@ index 2a89545..eb9203f 100644 static noinline void __init kernel_init_freeable(void); static int __ref kernel_init(void *unused) -@@ -947,6 +1030,11 @@ static int __ref kernel_init(void *unused) +@@ -947,6 +1031,11 @@ static int __ref kernel_init(void *unused) ramdisk_execute_command, ret); } @@ -102933,7 +103100,7 @@ index 2a89545..eb9203f 100644 /* * We try each of these until one succeeds. * -@@ -1002,7 +1090,7 @@ static noinline void __init kernel_init_freeable(void) +@@ -1002,7 +1091,7 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); /* Open the /dev/console on the rootfs, this should never fail */ @@ -102942,7 +103109,7 @@ index 2a89545..eb9203f 100644 pr_err("Warning: unable to open an initial console.\n"); (void) sys_dup(0); -@@ -1015,11 +1103,13 @@ static noinline void __init kernel_init_freeable(void) +@@ -1015,11 +1104,13 @@ static noinline void __init kernel_init_freeable(void) if (!ramdisk_execute_command) ramdisk_execute_command = "/init"; @@ -107685,7 +107852,7 @@ index 1f13335..77ebb7f 100644 } diff --git a/kernel/resource.c b/kernel/resource.c -index 90552aa..8c02098 100644 +index 90552aa..ad13346 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -162,8 +162,18 @@ static const struct file_operations proc_iomem_operations = { @@ -107707,6 +107874,31 @@ index 90552aa..8c02098 100644 return 0; } __initcall(ioresources_init); +@@ -504,13 +514,13 @@ int region_is_ram(resource_size_t start, unsigned long size) + { + struct resource *p; + resource_size_t end = start + size - 1; +- int flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY; + const char *name = "System RAM"; + int ret = -1; + + read_lock(&resource_lock); + for (p = iomem_resource.child; p ; p = p->sibling) { +- if (end < p->start) ++ if (p->end < start) + continue; + + if (p->start <= start && end <= p->end) { +@@ -521,7 +531,7 @@ int region_is_ram(resource_size_t start, unsigned long size) + ret = 1; + break; + } +- if (p->end < start) ++ if (end < p->start) + break; /* not found */ + } + read_unlock(&resource_lock); diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c index eae160d..c9aa22e 100644 --- a/kernel/sched/auto_group.c @@ -109195,10 +109387,108 @@ index 483cecf..ac46091 100644 ret = -EIO; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c -index 02bece4..f9b05af 100644 +index 02bece4..43adc29 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c -@@ -2395,12 +2395,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) +@@ -98,6 +98,13 @@ struct ftrace_pid { + struct pid *pid; + }; + ++static bool ftrace_pids_enabled(void) ++{ ++ return !list_empty(&ftrace_pids); ++} ++ ++static void ftrace_update_trampoline(struct ftrace_ops *ops); ++ + /* + * ftrace_disabled is set when an anomaly is discovered. + * ftrace_disabled is much stronger than ftrace_enabled. +@@ -109,7 +116,6 @@ static DEFINE_MUTEX(ftrace_lock); + static struct ftrace_ops *ftrace_control_list __read_mostly = &ftrace_list_end; + static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end; + ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub; +-ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub; + static struct ftrace_ops global_ops; + static struct ftrace_ops control_ops; + +@@ -183,14 +189,7 @@ static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, + if (!test_tsk_trace_trace(current)) + return; + +- ftrace_pid_function(ip, parent_ip, op, regs); +-} +- +-static void set_ftrace_pid_function(ftrace_func_t func) +-{ +- /* do not set ftrace_pid_function to itself! */ +- if (func != ftrace_pid_func) +- ftrace_pid_function = func; ++ op->saved_func(ip, parent_ip, op, regs); + } + + /** +@@ -202,7 +201,6 @@ static void set_ftrace_pid_function(ftrace_func_t func) + void clear_ftrace_function(void) + { + ftrace_trace_function = ftrace_stub; +- ftrace_pid_function = ftrace_stub; + } + + static void control_ops_disable_all(struct ftrace_ops *ops) +@@ -436,6 +434,12 @@ static int __register_ftrace_function(struct ftrace_ops *ops) + } else + add_ftrace_ops(&ftrace_ops_list, ops); + ++ /* Always save the function, and reset at unregistering */ ++ ops->saved_func = ops->func; ++ ++ if (ops->flags & FTRACE_OPS_FL_PID && ftrace_pids_enabled()) ++ ops->func = ftrace_pid_func; ++ + ftrace_update_trampoline(ops); + + if (ftrace_enabled) +@@ -463,15 +467,28 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) + if (ftrace_enabled) + update_ftrace_function(); + ++ ops->func = ops->saved_func; ++ + return 0; + } + + static void ftrace_update_pid_func(void) + { ++ bool enabled = ftrace_pids_enabled(); ++ struct ftrace_ops *op; ++ + /* Only do something if we are tracing something */ + if (ftrace_trace_function == ftrace_stub) + return; + ++ do_for_each_ftrace_op(op, ftrace_ops_list) { ++ if (op->flags & FTRACE_OPS_FL_PID) { ++ op->func = enabled ? ftrace_pid_func : ++ op->saved_func; ++ ftrace_update_trampoline(op); ++ } ++ } while_for_each_ftrace_op(op); ++ + update_ftrace_function(); + } + +@@ -1133,7 +1150,8 @@ static struct ftrace_ops global_ops = { + .local_hash.filter_hash = EMPTY_HASH, + INIT_OPS_HASH(global_ops) + .flags = FTRACE_OPS_FL_RECURSION_SAFE | +- FTRACE_OPS_FL_INITIALIZED, ++ FTRACE_OPS_FL_INITIALIZED | ++ FTRACE_OPS_FL_PID, + }; + + /* +@@ -2395,12 +2413,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) if (unlikely(ftrace_disabled)) return 0; @@ -109218,7 +109508,7 @@ index 02bece4..f9b05af 100644 } /* -@@ -4789,8 +4794,10 @@ static int ftrace_process_locs(struct module *mod, +@@ -4789,8 +4812,10 @@ static int ftrace_process_locs(struct module *mod, if (!count) return 0; @@ -109229,7 +109519,47 @@ index 02bece4..f9b05af 100644 start_pg = ftrace_allocate_pages(count); if (!start_pg) -@@ -5659,7 +5666,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) +@@ -5023,7 +5048,9 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops) + + static struct ftrace_ops global_ops = { + .func = ftrace_stub, +- .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, ++ .flags = FTRACE_OPS_FL_RECURSION_SAFE | ++ FTRACE_OPS_FL_INITIALIZED | ++ FTRACE_OPS_FL_PID, + }; + + static int __init ftrace_nodyn_init(void) +@@ -5080,11 +5107,6 @@ void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func) + if (WARN_ON(tr->ops->func != ftrace_stub)) + printk("ftrace ops had %pS for function\n", + tr->ops->func); +- /* Only the top level instance does pid tracing */ +- if (!list_empty(&ftrace_pids)) { +- set_ftrace_pid_function(func); +- func = ftrace_pid_func; +- } + } + tr->ops->func = func; + tr->ops->private = tr; +@@ -5371,7 +5393,7 @@ static void *fpid_start(struct seq_file *m, loff_t *pos) + { + mutex_lock(&ftrace_lock); + +- if (list_empty(&ftrace_pids) && (!*pos)) ++ if (!ftrace_pids_enabled() && (!*pos)) + return (void *) 1; + + return seq_list_start(&ftrace_pids, *pos); +@@ -5610,6 +5632,7 @@ static struct ftrace_ops graph_ops = { + .func = ftrace_stub, + .flags = FTRACE_OPS_FL_RECURSION_SAFE | + FTRACE_OPS_FL_INITIALIZED | ++ FTRACE_OPS_FL_PID | + FTRACE_OPS_FL_STUB, + #ifdef FTRACE_GRAPH_TRAMP_ADDR + .trampoline = FTRACE_GRAPH_TRAMP_ADDR, +@@ -5659,7 +5682,7 @@ static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) if (t->ret_stack == NULL) { atomic_set(&t->tracing_graph_pause, 0); @@ -109238,7 +109568,7 @@ index 02bece4..f9b05af 100644 t->curr_ret_stack = -1; /* Make sure the tasks see the -1 first: */ smp_wmb(); -@@ -5882,7 +5889,7 @@ static void +@@ -5882,7 +5905,7 @@ static void graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack) { atomic_set(&t->tracing_graph_pause, 0); @@ -116603,6 +116933,21 @@ index 8e385a0..a5bdd8e 100644 tty_port_close(&dev->port, tty, filp); } +diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c +index 1ab3dc9..7b815bc 100644 +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -2295,6 +2295,10 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) + return 1; + + chan = conn->smp; ++ if (!chan) { ++ BT_ERR("SMP security requested but not available"); ++ return 1; ++ } + + if (!hci_dev_test_flag(hcon->hdev, HCI_LE_ENABLED)) + return 1; diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index e29ad70b..cc00066 100644 --- a/net/bridge/br_mdb.c @@ -117842,9 +118187,36 @@ index 0ae5822..3fe3627 100644 .priv_size = sizeof(struct lowpan_dev_info), .setup = lowpan_setup, diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c -index f46e4d1..30231f1 100644 +index f46e4d1..dcb7f86 100644 --- a/net/ieee802154/6lowpan/reassembly.c +++ b/net/ieee802154/6lowpan/reassembly.c +@@ -207,7 +207,7 @@ found: + } else { + fq->q.meat += skb->len; + } +- add_frag_mem_limit(&fq->q, skb->truesize); ++ add_frag_mem_limit(fq->q.net, skb->truesize); + + if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && + fq->q.meat == fq->q.len) { +@@ -287,7 +287,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev, + clone->data_len = clone->len; + head->data_len -= clone->len; + head->len -= clone->len; +- add_frag_mem_limit(&fq->q, clone->truesize); ++ add_frag_mem_limit(fq->q.net, clone->truesize); + } + + WARN_ON(head == NULL); +@@ -310,7 +310,7 @@ static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, struct sk_buff *prev, + } + fp = next; + } +- sub_frag_mem_limit(&fq->q, sum_truesize); ++ sub_frag_mem_limit(fq->q.net, sum_truesize); + + head->next = NULL; + head->dev = dev; @@ -435,14 +435,13 @@ static struct ctl_table lowpan_frags_ctl_table[] = { static int __net_init lowpan_frags_ns_sysctl_register(struct net *net) @@ -118030,6 +118402,117 @@ index 8d695b6..752d427a 100644 return nh->nh_saddr; } +diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c +index 5e346a0..d0a7c03 100644 +--- a/net/ipv4/inet_fragment.c ++++ b/net/ipv4/inet_fragment.c +@@ -131,34 +131,22 @@ inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb) + unsigned int evicted = 0; + HLIST_HEAD(expired); + +-evict_again: + spin_lock(&hb->chain_lock); + + hlist_for_each_entry_safe(fq, n, &hb->chain, list) { + if (!inet_fragq_should_evict(fq)) + continue; + +- if (!del_timer(&fq->timer)) { +- /* q expiring right now thus increment its refcount so +- * it won't be freed under us and wait until the timer +- * has finished executing then destroy it +- */ +- atomic_inc(&fq->refcnt); +- spin_unlock(&hb->chain_lock); +- del_timer_sync(&fq->timer); +- inet_frag_put(fq, f); +- goto evict_again; +- } ++ if (!del_timer(&fq->timer)) ++ continue; + +- fq->flags |= INET_FRAG_EVICTED; +- hlist_del(&fq->list); +- hlist_add_head(&fq->list, &expired); ++ hlist_add_head(&fq->list_evictor, &expired); + ++evicted; + } + + spin_unlock(&hb->chain_lock); + +- hlist_for_each_entry_safe(fq, n, &expired, list) ++ hlist_for_each_entry_safe(fq, n, &expired, list_evictor) + f->frag_expire((unsigned long) fq); + + return evicted; +@@ -240,19 +228,21 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) + int i; + + nf->low_thresh = 0; +- local_bh_disable(); + + evict_again: ++ local_bh_disable(); + seq = read_seqbegin(&f->rnd_seqlock); + + for (i = 0; i < INETFRAGS_HASHSZ ; i++) + inet_evict_bucket(f, &f->hash[i]); + +- if (read_seqretry(&f->rnd_seqlock, seq)) ++ local_bh_enable(); ++ cond_resched(); ++ ++ if (read_seqretry(&f->rnd_seqlock, seq) || ++ percpu_counter_sum(&nf->mem)) + goto evict_again; + +- local_bh_enable(); +- + percpu_counter_destroy(&nf->mem); + } + EXPORT_SYMBOL(inet_frags_exit_net); +@@ -284,8 +274,8 @@ static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f) + struct inet_frag_bucket *hb; + + hb = get_frag_bucket_locked(fq, f); +- if (!(fq->flags & INET_FRAG_EVICTED)) +- hlist_del(&fq->list); ++ hlist_del(&fq->list); ++ fq->flags |= INET_FRAG_COMPLETE; + spin_unlock(&hb->chain_lock); + } + +@@ -297,7 +287,6 @@ void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f) + if (!(fq->flags & INET_FRAG_COMPLETE)) { + fq_unlink(fq, f); + atomic_dec(&fq->refcnt); +- fq->flags |= INET_FRAG_COMPLETE; + } + } + EXPORT_SYMBOL(inet_frag_kill); +@@ -330,11 +319,12 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f) + fp = xp; + } + sum = sum_truesize + f->qsize; +- sub_frag_mem_limit(q, sum); + + if (f->destructor) + f->destructor(q); + kmem_cache_free(f->frags_cachep, q); ++ ++ sub_frag_mem_limit(nf, sum); + } + EXPORT_SYMBOL(inet_frag_destroy); + +@@ -390,7 +380,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, + + q->net = nf; + f->constructor(q, arg); +- add_frag_mem_limit(q, f->qsize); ++ add_frag_mem_limit(nf, f->qsize); + + setup_timer(&q->timer, f->frag_expire, (unsigned long)q); + spin_lock_init(&q->lock); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index c6fb80b..8705495 100644 --- a/net/ipv4/inet_hashtables.c @@ -118074,9 +118557,18 @@ index 241afd7..31b95d5 100644 p->rate_tokens = 0; /* 60*HZ is arbitrary, but chosen enough high so that the first diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c -index cc1da6d..64b1534 100644 +index cc1da6d..593fc73 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c +@@ -192,7 +192,7 @@ static void ip_expire(unsigned long arg) + ipq_kill(qp); + IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); + +- if (!(qp->q.flags & INET_FRAG_EVICTED)) { ++ if (!inet_frag_evicting(&qp->q)) { + struct sk_buff *head = qp->q.fragments; + const struct iphdr *iph; + int err; @@ -268,7 +268,7 @@ static int ip_frag_too_far(struct ipq *qp) return 0; @@ -118086,6 +118578,51 @@ index cc1da6d..64b1534 100644 qp->rid = end; rc = qp->q.fragments && (end - start) > max; +@@ -301,7 +301,7 @@ static int ip_frag_reinit(struct ipq *qp) + kfree_skb(fp); + fp = xp; + } while (fp); +- sub_frag_mem_limit(&qp->q, sum_truesize); ++ sub_frag_mem_limit(qp->q.net, sum_truesize); + + qp->q.flags = 0; + qp->q.len = 0; +@@ -446,7 +446,7 @@ found: + qp->q.fragments = next; + + qp->q.meat -= free_it->len; +- sub_frag_mem_limit(&qp->q, free_it->truesize); ++ sub_frag_mem_limit(qp->q.net, free_it->truesize); + kfree_skb(free_it); + } + } +@@ -470,7 +470,7 @@ found: + qp->q.stamp = skb->tstamp; + qp->q.meat += skb->len; + qp->ecn |= ecn; +- add_frag_mem_limit(&qp->q, skb->truesize); ++ add_frag_mem_limit(qp->q.net, skb->truesize); + if (offset == 0) + qp->q.flags |= INET_FRAG_FIRST_IN; + +@@ -573,7 +573,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, + head->len -= clone->len; + clone->csum = 0; + clone->ip_summed = head->ip_summed; +- add_frag_mem_limit(&qp->q, clone->truesize); ++ add_frag_mem_limit(qp->q.net, clone->truesize); + } + + skb_push(head, head->data - skb_network_header(head)); +@@ -601,7 +601,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, + } + fp = next; + } +- sub_frag_mem_limit(&qp->q, sum_truesize); ++ sub_frag_mem_limit(qp->q.net, sum_truesize); + + head->next = NULL; + head->dev = dev; @@ -750,12 +750,11 @@ static struct ctl_table ip4_frags_ctl_table[] = { static int __net_init ip4_frags_ns_ctl_register(struct net *net) @@ -119380,7 +119917,7 @@ index 62f5b0d..331fdb1 100644 case IP6T_SO_GET_ENTRIES: diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c -index 6f187c8..34b367f 100644 +index 6f187c8..55e564f 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -96,12 +96,11 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { @@ -119421,6 +119958,33 @@ index 6f187c8..34b367f 100644 err_alloc: return -ENOMEM; } +@@ -348,7 +346,7 @@ found: + fq->ecn |= ecn; + if (payload_len > fq->q.max_size) + fq->q.max_size = payload_len; +- add_frag_mem_limit(&fq->q, skb->truesize); ++ add_frag_mem_limit(fq->q.net, skb->truesize); + + /* The first fragment. + * nhoffset is obtained from the first fragment, of course. +@@ -430,7 +428,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev) + clone->ip_summed = head->ip_summed; + + NFCT_FRAG6_CB(clone)->orig = NULL; +- add_frag_mem_limit(&fq->q, clone->truesize); ++ add_frag_mem_limit(fq->q.net, clone->truesize); + } + + /* We have to remove fragment header from datagram and to relocate +@@ -454,7 +452,7 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev) + head->csum = csum_add(head->csum, fp->csum); + head->truesize += fp->truesize; + } +- sub_frag_mem_limit(&fq->q, head->truesize); ++ sub_frag_mem_limit(fq->q.net, head->truesize); + + head->ignore_df = 1; + head->next = NULL; diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 263a516..692f738 100644 --- a/net/ipv6/ping.c @@ -119570,9 +120134,45 @@ index 8072bd4..1629245 100644 return 0; default: diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c -index 8ffa2c8..5968612 100644 +index 8ffa2c8..0db5dad 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c +@@ -144,7 +144,7 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, + + IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); + +- if (fq->q.flags & INET_FRAG_EVICTED) ++ if (inet_frag_evicting(&fq->q)) + goto out_rcu_unlock; + + IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); +@@ -330,7 +330,7 @@ found: + fq->q.stamp = skb->tstamp; + fq->q.meat += skb->len; + fq->ecn |= ecn; +- add_frag_mem_limit(&fq->q, skb->truesize); ++ add_frag_mem_limit(fq->q.net, skb->truesize); + + /* The first fragment. + * nhoffset is obtained from the first fragment, of course. +@@ -443,7 +443,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, + head->len -= clone->len; + clone->csum = 0; + clone->ip_summed = head->ip_summed; +- add_frag_mem_limit(&fq->q, clone->truesize); ++ add_frag_mem_limit(fq->q.net, clone->truesize); + } + + /* We have to remove fragment header from datagram and to relocate +@@ -481,7 +481,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, + } + fp = next; + } +- sub_frag_mem_limit(&fq->q, sum_truesize); ++ sub_frag_mem_limit(fq->q.net, sum_truesize); + + head->next = NULL; + head->dev = dev; @@ -626,12 +626,11 @@ static struct ctl_table ip6_frags_ctl_table[] = { static int __net_init ip6_frags_ns_sysctl_register(struct net *net) |