Xu Kuohai <xukuohai@xxxxxxxxxxxxxxx> writes: > On 1/25/2024 9:31 PM, Puranjay Mohan wrote: >> The text_poke API is used to implement functions like memcpy() and >> memset() for instruction memory (RO+X). The implementation is similar to >> the x86 version. >> >> This will be used by the BPF JIT to write and modify BPF programs. There >> could be more users of this in the future. >> >> Signed-off-by: Puranjay Mohan <puranjay12@xxxxxxxxx> >> --- >> arch/arm64/include/asm/patching.h | 2 + >> arch/arm64/kernel/patching.c | 80 +++++++++++++++++++++++++++++++ >> 2 files changed, 82 insertions(+) >> >> diff --git a/arch/arm64/include/asm/patching.h b/arch/arm64/include/asm/patching.h >> index 68908b82b168..587bdb91ab7a 100644 >> --- a/arch/arm64/include/asm/patching.h >> +++ b/arch/arm64/include/asm/patching.h >> @@ -8,6 +8,8 @@ int aarch64_insn_read(void *addr, u32 *insnp); >> int aarch64_insn_write(void *addr, u32 insn); >> >> int aarch64_insn_write_literal_u64(void *addr, u64 val); >> +void *aarch64_insn_set(void *dst, u32 insn, size_t len); >> +void *aarch64_insn_copy(void *dst, void *src, size_t len); >> >> int aarch64_insn_patch_text_nosync(void *addr, u32 insn); >> int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt); >> diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c >> index b4835f6d594b..5c2d34d890cf 100644 >> --- a/arch/arm64/kernel/patching.c >> +++ b/arch/arm64/kernel/patching.c >> @@ -105,6 +105,86 @@ noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val) >> return ret; >> } >> >> +typedef void text_poke_f(void *dst, void *src, size_t patched, size_t len); >> + > > How about removing the argument 'patched' and passing 'src + patched' as the > second argument? > The memcpy() function needs 'src + patched' but the memset() needs only the 'src' and will ignore the 'patched'. To make these implementations generic, I pass both src and patched separately and allow the implementation of text_poke_f() to use them. If you think there is a better way to implement this then I would love to use that. >> +static void *__text_poke(text_poke_f func, void *addr, void *src, size_t len) >> +{ >> + unsigned long flags; >> + size_t patched = 0; >> + size_t size; >> + void *waddr; >> + void *ptr; >> + int ret; >> + >> + raw_spin_lock_irqsave(&patch_lock, flags); >> + >> + while (patched < len) { >> + ptr = addr + patched; >> + size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr), >> + len - patched); >> + >> + waddr = patch_map(ptr, FIX_TEXT_POKE0); >> + func(waddr, src, patched, size); >> + patch_unmap(FIX_TEXT_POKE0); >> + >> + if (ret < 0) { > > Where is 'ret' assigned? > Will remove the error check in next version as func() is of type void and this error check was left from the previous version. Thanks, Puranjay