lkml.org 
[lkml]   [2022]   [Jan]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v5 bpf-next 5/7] x86/alternative: introduce text_poke_copy
    Date
    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 <song@kernel.org>
    ---
    arch/x86/include/asm/text-patching.h | 1 +
    arch/x86/kernel/alternative.c | 32 ++++++++++++++++++++++++++++
    2 files changed, 33 insertions(+)

    diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h
    index b7421780e4e9..4cc18ba1b75e 100644
    --- a/arch/x86/include/asm/text-patching.h
    +++ b/arch/x86/include/asm/text-patching.h
    @@ -44,6 +44,7 @@ extern void text_poke_early(void *addr, const void *opcode, size_t len);
    extern void *text_poke(void *addr, const void *opcode, size_t len);
    extern void text_poke_sync(void);
    extern void *text_poke_kgdb(void *addr, const void *opcode, size_t len);
    +extern void *text_poke_copy(void *addr, const void *opcode, size_t len);
    extern int poke_int3_handler(struct pt_regs *regs);
    extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void *emulate);

    diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
    index 23fb4d51a5da..903a415c19fa 100644
    --- a/arch/x86/kernel/alternative.c
    +++ b/arch/x86/kernel/alternative.c
    @@ -1102,6 +1102,38 @@ void *text_poke_kgdb(void *addr, const void *opcode, size_t len)
    return __text_poke(addr, opcode, len);
    }

    +/**
    + * text_poke_copy - Copy instructions into (an unused part of) RX memory
    + * @addr: address to modify
    + * @opcode: source of the copy
    + * @len: length to copy, could be more than 2x PAGE_SIZE
    + *
    + * Not safe against concurrent execution; useful for JITs to dump
    + * new code blocks into unused regions of RX memory. Can be used in
    + * conjunction with synchronize_rcu_tasks() to wait for existing
    + * execution to quiesce after having made sure no existing functions
    + * pointers are live.
    + */
    +void *text_poke_copy(void *addr, const void *opcode, size_t len)
    +{
    + unsigned long start = (unsigned long)addr;
    + size_t patched = 0;
    +
    + if (WARN_ON_ONCE(core_kernel_text(start)))
    + return NULL;
    +
    + while (patched < len) {
    + unsigned long ptr = start + patched;
    + size_t s;
    +
    + s = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(ptr), len - patched);
    +
    + __text_poke((void *)ptr, opcode + patched, s);
    + patched += s;
    + }
    + return addr;
    +}
    +
    static void do_sync_core(void *info)
    {
    sync_core();
    --
    2.30.2
    \
     
     \ /
      Last update: 2022-01-20 20:15    [W:2.918 / U:0.476 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site