diff options
Diffstat (limited to 'arch/x86/net')
| -rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 79c216aa0e2b..516593e1ce33 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c | |||
| @@ -772,13 +772,21 @@ out: | |||
| 772 | return; | 772 | return; |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | static void bpf_jit_free_deferred(struct work_struct *work) | ||
| 776 | { | ||
| 777 | struct sk_filter *fp = container_of(work, struct sk_filter, work); | ||
| 778 | unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; | ||
| 779 | struct bpf_binary_header *header = (void *)addr; | ||
| 780 | |||
| 781 | set_memory_rw(addr, header->pages); | ||
| 782 | module_free(NULL, header); | ||
| 783 | kfree(fp); | ||
| 784 | } | ||
| 785 | |||
| 775 | void bpf_jit_free(struct sk_filter *fp) | 786 | void bpf_jit_free(struct sk_filter *fp) |
| 776 | { | 787 | { |
| 777 | if (fp->bpf_func != sk_run_filter) { | 788 | if (fp->bpf_func != sk_run_filter) { |
| 778 | unsigned long addr = (unsigned long)fp->bpf_func & PAGE_MASK; | 789 | INIT_WORK(&fp->work, bpf_jit_free_deferred); |
| 779 | struct bpf_binary_header *header = (void *)addr; | 790 | schedule_work(&fp->work); |
| 780 | |||
| 781 | set_memory_rw(addr, header->pages); | ||
| 782 | module_free(NULL, header); | ||
| 783 | } | 791 | } |
| 784 | } | 792 | } |
