Skip to content

Commit 0e06b40

Browse files
liu-song-6Alexei Starovoitov
authored andcommitted
x86/alternative: Introduce text_poke_copy
This will be used by BPF jit compiler to dump JITed binary to a RX huge page, and thus allow multiple BPF programs sharing the a huge (2MB) page. Signed-off-by: Song Liu <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent d00c647 commit 0e06b40

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

arch/x86/include/asm/text-patching.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern void text_poke_early(void *addr, const void *opcode, size_t len);
4444
extern void *text_poke(void *addr, const void *opcode, size_t len);
4545
extern void text_poke_sync(void);
4646
extern void *text_poke_kgdb(void *addr, const void *opcode, size_t len);
47+
extern void *text_poke_copy(void *addr, const void *opcode, size_t len);
4748
extern int poke_int3_handler(struct pt_regs *regs);
4849
extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void *emulate);
4950

arch/x86/kernel/alternative.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,40 @@ void *text_poke_kgdb(void *addr, const void *opcode, size_t len)
11021102
return __text_poke(addr, opcode, len);
11031103
}
11041104

1105+
/**
1106+
* text_poke_copy - Copy instructions into (an unused part of) RX memory
1107+
* @addr: address to modify
1108+
* @opcode: source of the copy
1109+
* @len: length to copy, could be more than 2x PAGE_SIZE
1110+
*
1111+
* Not safe against concurrent execution; useful for JITs to dump
1112+
* new code blocks into unused regions of RX memory. Can be used in
1113+
* conjunction with synchronize_rcu_tasks() to wait for existing
1114+
* execution to quiesce after having made sure no existing functions
1115+
* pointers are live.
1116+
*/
1117+
void *text_poke_copy(void *addr, const void *opcode, size_t len)
1118+
{
1119+
unsigned long start = (unsigned long)addr;
1120+
size_t patched = 0;
1121+
1122+
if (WARN_ON_ONCE(core_kernel_text(start)))
1123+
return NULL;
1124+
1125+
mutex_lock(&text_mutex);
1126+
while (patched < len) {
1127+
unsigned long ptr = start + patched;
1128+
size_t s;
1129+
1130+
s = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(ptr), len - patched);
1131+
1132+
__text_poke((void *)ptr, opcode + patched, s);
1133+
patched += s;
1134+
}
1135+
mutex_unlock(&text_mutex);
1136+
return addr;
1137+
}
1138+
11051139
static void do_sync_core(void *info)
11061140
{
11071141
sync_core();

0 commit comments

Comments
 (0)