mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-29 14:05:19 +08:00
9c82ce5936
commitb89ddf4cca
upstream. Commit91fc957c9b
("arm64/bpf: don't allocate BPF JIT programs in module memory") restricts BPF JIT program allocation to a 128MB region to ensure BPF programs are still in branching range of each other. However this restriction should not apply to the aarch64 JIT, since BPF_JMP | BPF_CALL are implemented as a 64-bit move into a register and then a BLR instruction - which has the effect of being able to call anything without proximity limitation. The practical reason to relax this restriction on JIT memory is that 128MB of JIT memory can be quickly exhausted, especially where PAGE_SIZE is 64KB - one page is needed per program. In cases where seccomp filters are applied to multiple VMs on VM launch - such filters are classic BPF but converted to BPF - this can severely limit the number of VMs that can be launched. In a world where we support BPF JIT always on, turning off the JIT isn't always an option either. Fixes:91fc957c9b
("arm64/bpf: don't allocate BPF JIT programs in module memory") Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Russell King <russell.king@oracle.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Alan Maguire <alan.maguire@oracle.com> Link: https://lore.kernel.org/bpf/1636131046-5982-2-git-send-email-alan.maguire@oracle.com Reviewed-by: Tom Saeger <tom.saeger@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 lines
581 B
C
28 lines
581 B
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Based on arch/arm/mm/extable.c
|
|
*/
|
|
|
|
#include <linux/extable.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
int fixup_exception(struct pt_regs *regs)
|
|
{
|
|
const struct exception_table_entry *fixup;
|
|
unsigned long addr;
|
|
|
|
addr = instruction_pointer(regs);
|
|
|
|
/* Search the BPF tables first, these are formatted differently */
|
|
fixup = search_bpf_extables(addr);
|
|
if (fixup)
|
|
return arm64_bpf_fixup_exception(fixup, regs);
|
|
|
|
fixup = search_exception_tables(addr);
|
|
if (!fixup)
|
|
return 0;
|
|
|
|
regs->pc = (unsigned long)&fixup->fixup + fixup->fixup;
|
|
return 1;
|
|
}
|