lkml.org 
[lkml]   [2019]   [Nov]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH RFC 1/6] perf/x86: Add perf text poke event
On Fri, Nov 01, 2019 at 11:04:40AM +0100, Peter Zijlstra wrote:

> I'm thinking something along the lines of:
>
> static uintptr_t nosync_addr;
> static u32 nosync_insn;
>
> int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
> {
> const u32 break = // some_breakpoint_insn;
> uintptr_t tp = (uintptr_t)addr;
> int ret;
>
> lockdep_assert_held(&text_mutex);
>
> /* A64 instructions must be word aligned */
> if (tp & 0x3)
> return -EINVAL;
>
> if (perf_text_poke_update_enabled()) {
>
> nosync_insn = insn;
> smp_store_release(&nosync_addr, tp);
>
> ret = aarch64_insn_write(addr, break);
> if (ret == 0)
> __flush_icache_range(tp, tp + AARCH64_INSN_SIZE);
>
> perf_event_text_poke(....);
> }
>
> ret = aarch64_insn_write(addr, insn);
> if (ret == 0)
> __flush_icache_range(tp, tp + AARCH64_INSN_SIZE);

// barrier that guarantees iflush completion ? dsb(osh) ?

WRITE_ONCE(nosync_addr, NULL);

> return ret;
> }
>
> And have the 'break' handler do:
>
> aarch64_insn_break_handler(struct pt_regs *regs)
> {
> unsigned long addr = smp_load_acquire(&nosync_addr);
> u32 insn = nosync_insn;
>
> if (regs->ip != addr)
> return;
>
> // emulate @insn
> }
>
> I understood from Will the whole nosync scheme only works for a limited
> set of instructions, but you only have to implement emulation for the
> actual instructions used of course.
>
> (which is what we do on x86)
>
> Does this sound workable?

\
 
 \ /
  Last update: 2019-11-01 11:09    [W:0.124 / U:0.208 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site