}
 
 #ifdef CONFIG_BPF_JIT
+# define BPF_JIT_LIMIT_DEFAULT (PAGE_SIZE * 40000)
+
 /* All BPF JIT sysctl knobs here. */
 int bpf_jit_enable   __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
 int bpf_jit_harden   __read_mostly;
 int bpf_jit_kallsyms __read_mostly;
+int bpf_jit_limit    __read_mostly = BPF_JIT_LIMIT_DEFAULT;
 
 static __always_inline void
 bpf_get_prog_addr_region(const struct bpf_prog *prog,
        return ret;
 }
 
+static atomic_long_t bpf_jit_current;
+
+#if defined(MODULES_VADDR)
+static int __init bpf_jit_charge_init(void)
+{
+       /* Only used as heuristic here to derive limit. */
+       bpf_jit_limit = min_t(u64, round_up((MODULES_END - MODULES_VADDR) >> 2,
+                                           PAGE_SIZE), INT_MAX);
+       return 0;
+}
+pure_initcall(bpf_jit_charge_init);
+#endif
+
+static int bpf_jit_charge_modmem(u32 pages)
+{
+       if (atomic_long_add_return(pages, &bpf_jit_current) >
+           (bpf_jit_limit >> PAGE_SHIFT)) {
+               if (!capable(CAP_SYS_ADMIN)) {
+                       atomic_long_sub(pages, &bpf_jit_current);
+                       return -EPERM;
+               }
+       }
+
+       return 0;
+}
+
+static void bpf_jit_uncharge_modmem(u32 pages)
+{
+       atomic_long_sub(pages, &bpf_jit_current);
+}
+
 struct bpf_binary_header *
 bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
                     unsigned int alignment,
                     bpf_jit_fill_hole_t bpf_fill_ill_insns)
 {
        struct bpf_binary_header *hdr;
-       unsigned int size, hole, start;
+       u32 size, hole, start, pages;
 
        /* Most of BPF filters are really small, but if some of them
         * fill a page, allow at least 128 extra bytes to insert a
         * random section of illegal instructions.
         */
        size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE);
+       pages = size / PAGE_SIZE;
+
+       if (bpf_jit_charge_modmem(pages))
+               return NULL;
        hdr = module_alloc(size);
-       if (hdr == NULL)
+       if (!hdr) {
+               bpf_jit_uncharge_modmem(pages);
                return NULL;
+       }
 
        /* Fill space with illegal/arch-dep instructions. */
        bpf_fill_ill_insns(hdr, size);
 
-       hdr->pages = size / PAGE_SIZE;
+       hdr->pages = pages;
        hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)),
                     PAGE_SIZE - sizeof(*hdr));
        start = (get_random_int() % hole) & ~(alignment - 1);
 
 void bpf_jit_binary_free(struct bpf_binary_header *hdr)
 {
+       u32 pages = hdr->pages;
+
        module_memfree(hdr);
+       bpf_jit_uncharge_modmem(pages);
 }
 
 /* This symbol is only overridden by archs that have different
 
        return ret;
 }
 
-# ifdef CONFIG_HAVE_EBPF_JIT
 static int
 proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
                                    void __user *buffer, size_t *lenp,
 
        return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
 }
-# endif
 #endif
 
 static struct ctl_table net_core_table[] = {
                .extra2         = &one,
        },
 # endif
+       {
+               .procname       = "bpf_jit_limit",
+               .data           = &bpf_jit_limit,
+               .maxlen         = sizeof(int),
+               .mode           = 0600,
+               .proc_handler   = proc_dointvec_minmax_bpf_restricted,
+               .extra1         = &one,
+       },
 #endif
        {
                .procname       = "netdev_tstamp_prequeue",