Skip to content

Commit f54dcaf

Browse files
Xu KuohaiKernel Patches Daemon
Xu Kuohai
authored and
Kernel Patches Daemon
committed
bpf, arm64: Impelment bpf_arch_text_poke() for arm64
Impelment bpf_arch_text_poke() for arm64, so bpf trampoline code can use it to replace nop with jump, or replace jump with nop. Signed-off-by: Xu Kuohai <[email protected]> Acked-by: Song Liu <[email protected]>
1 parent 030713a commit f54dcaf

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <linux/bitfield.h>
1111
#include <linux/bpf.h>
12+
#include <linux/memory.h>
1213
#include <linux/filter.h>
1314
#include <linux/printk.h>
1415
#include <linux/slab.h>
@@ -18,6 +19,7 @@
1819
#include <asm/cacheflush.h>
1920
#include <asm/debug-monitors.h>
2021
#include <asm/insn.h>
22+
#include <asm/patching.h>
2123
#include <asm/set_memory.h>
2224

2325
#include "bpf_jit.h"
@@ -1529,3 +1531,53 @@ void bpf_jit_free_exec(void *addr)
15291531
{
15301532
return vfree(addr);
15311533
}
1534+
1535+
static int gen_branch_or_nop(enum aarch64_insn_branch_type type, void *ip,
1536+
void *addr, u32 *insn)
1537+
{
1538+
if (!addr)
1539+
*insn = aarch64_insn_gen_nop();
1540+
else
1541+
*insn = aarch64_insn_gen_branch_imm((unsigned long)ip,
1542+
(unsigned long)addr,
1543+
type);
1544+
1545+
return *insn != AARCH64_BREAK_FAULT ? 0 : -EFAULT;
1546+
}
1547+
1548+
int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type poke_type,
1549+
void *old_addr, void *new_addr)
1550+
{
1551+
int ret;
1552+
u32 old_insn;
1553+
u32 new_insn;
1554+
u32 replaced;
1555+
enum aarch64_insn_branch_type branch_type;
1556+
1557+
if (poke_type == BPF_MOD_CALL)
1558+
branch_type = AARCH64_INSN_BRANCH_LINK;
1559+
else
1560+
branch_type = AARCH64_INSN_BRANCH_NOLINK;
1561+
1562+
if (gen_branch_or_nop(branch_type, ip, old_addr, &old_insn) < 0)
1563+
return -EFAULT;
1564+
1565+
if (gen_branch_or_nop(branch_type, ip, new_addr, &new_insn) < 0)
1566+
return -EFAULT;
1567+
1568+
mutex_lock(&text_mutex);
1569+
if (aarch64_insn_read(ip, &replaced)) {
1570+
ret = -EFAULT;
1571+
goto out;
1572+
}
1573+
1574+
if (replaced != old_insn) {
1575+
ret = -EFAULT;
1576+
goto out;
1577+
}
1578+
1579+
ret = aarch64_insn_patch_text_nosync((void *)ip, new_insn);
1580+
out:
1581+
mutex_unlock(&text_mutex);
1582+
return ret;
1583+
}

0 commit comments

Comments
 (0)