lkml.org 
[lkml]   [2023]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6/8] arm64: patching: Add aarch64_insn_write_literal_u64()
    Date
    In subsequent patches we'll need to atomically write to a
    naturally-aligned 64-bit literal embedded within the kernel text.

    Add a helper for this. For consistency with other text patching code we
    use copy_to_kernel_nofault(), which is atomic for naturally-aligned
    accesses up to 64-bits.

    Signed-off-by: Mark Rutland <mark.rutland@arm.com>
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Florent Revest <revest@chromium.org>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Will Deacon <will@kernel.org>
    ---
    arch/arm64/include/asm/patching.h | 2 ++
    arch/arm64/kernel/patching.c | 17 +++++++++++++++++
    2 files changed, 19 insertions(+)

    diff --git a/arch/arm64/include/asm/patching.h b/arch/arm64/include/asm/patching.h
    index 6bf5adc562950..68908b82b168f 100644
    --- a/arch/arm64/include/asm/patching.h
    +++ b/arch/arm64/include/asm/patching.h
    @@ -7,6 +7,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);
    +
    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 33e0fabc0b79b..b4835f6d594bc 100644
    --- a/arch/arm64/kernel/patching.c
    +++ b/arch/arm64/kernel/patching.c
    @@ -88,6 +88,23 @@ int __kprobes aarch64_insn_write(void *addr, u32 insn)
    return __aarch64_insn_write(addr, cpu_to_le32(insn));
    }

    +noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val)
    +{
    + u64 *waddr;
    + unsigned long flags;
    + int ret;
    +
    + raw_spin_lock_irqsave(&patch_lock, flags);
    + waddr = patch_map(addr, FIX_TEXT_POKE0);
    +
    + ret = copy_to_kernel_nofault(waddr, &val, sizeof(val));
    +
    + patch_unmap(FIX_TEXT_POKE0);
    + raw_spin_unlock_irqrestore(&patch_lock, flags);
    +
    + return ret;
    +}
    +
    int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
    {
    u32 *tp = addr;
    --
    2.30.2
    \
     
     \ /
      Last update: 2023-03-26 23:33    [W:2.222 / U:0.244 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site