apply_range_set_cb() maps the pages for a new arena allocation. It returned -EBUSY when the target PTE was already populated. Kernel-fault recovery can leave the per-arena scratch page in an otherwise unallocated arena PTE: a BPF program that touched an unallocated address gets the scratch page installed there. A later bpf_arena_alloc_pages() covering that page then finds the PTE populated, returns -EBUSY, and leaves the scratch page in place. Every subsequent allocation of that page fails the same way. Drop the must-be-empty check so set_pte_at() installs the real page unconditionally, overwriting a scratch (or empty) PTE. Suggested-by: Alexei Starovoitov Signed-off-by: Tejun Heo Cc: David Hildenbrand --- kernel/bpf/arena.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -131,15 +131,13 @@ static int apply_range_set_cb(pte_t *pte if (!data) return 0; - /* sanity check */ - if (unlikely(!pte_none(ptep_get(pte)))) - return -EBUSY; page = d->pages[d->i]; /* paranoia, similar to vmap_pages_pte_range() */ if (WARN_ON_ONCE(!pfn_valid(page_to_pfn(page)))) return -EINVAL; + /* May be none or the scratch page, overwrite either way */ set_pte_at(&init_mm, addr, pte, mk_pte(page, PAGE_KERNEL)); d->i++; return 0;