• Pratyush Anand's avatar
    arm64: kprobe: Always clear pstate.D in breakpoint exception handler · 7419333f
    Pratyush Anand authored
    Whenever we are hitting a kprobe from a none-kprobe debug exception handler,
    we hit an infinite occurrences of "Unexpected kernel single-step exception
    at EL1"
    
    PSTATE.D is debug exception mask bit. It is set whenever we enter into an
    exception mode. When it is set then Watchpoint, Breakpoint, and Software
    Step exceptions are masked. However, software Breakpoint Instruction
    exceptions can never be masked. Therefore, if we ever execute a BRK
    instruction, irrespective of D-bit setting, we will be receiving a
    corresponding breakpoint exception.
    
    For example:
    
    - We are executing kprobe pre/post handler, and kprobe has been inserted in
      one of the instruction of a function called by handler. So, it executes
      BRK instruction and we land into the case of KPROBE_REENTER. (This case is
      already handled by current code)
    
    - We are executing uprobe handler or any other BRK handler such as in
      WARN_ON (BRK BUG_BRK_IMM), and we trace that path using kprobe.So, we
      enter into kprobe breakpoint handler,from another BRK handler.(This case
      is not being handled currently)
    
    In all such cases kprobe breakpoint exception will be raised when we were
    already in debug exception mode. SPSR's D bit (bit 9) shows the value of
    PSTATE.D immediately before the exception was taken. So, in above example
    cases we would find it set in kprobe breakpoint handler.  Single step
    exception will always be followed by a kprobe breakpoint exception.However,
    it will only be raised gracefully if we clear D bit while returning from
    breakpoint exception.  If D bit is set then, it results into undefined
    exception and when it's handler enables dbg then single step exception is
    generated, however it will never be handled(because address does not match
    and therefore treated as unexpected).
    
    This patch clears D-flag unconditionally in setup_singlestep, so that we can
    always get single step exception correctly after returning from breakpoint
    exception. Additionally, it also removes D-flag set statement for
    KPROBE_REENTER return path, because debug exception for KPROBE_REENTER will
    always take place in a debug exception state. So, D-flag will already be set
    in this case.
    Acked-by: default avatarSandeepa Prabhu <sandeepa.s.prabhu@gmail.com>
    Acked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
    Signed-off-by: default avatarPratyush Anand <panand@redhat.com>
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    7419333f
kprobes.c 17.4 KB