[PATCH 0/2] sparc64: fix relbranch_fixup() for BPr, FBfcc and FBPfcc

From: Danish Khateeb

Date: Wed Sep 23 2026 - 12:30:07 EST


kprobes and uprobes on sparc64 single-step a copy of the probed
instruction, and each has a relbranch_fixup() that moves a taken
branch's target from the copy back to the probed code. Both only
recognize call, BPcc and Bicc. A taken BPr, FBfcc or FBPfcc therefore
continues next to the copy, which crashes the kernel for a kprobe and
kills the task with SIGILL for a uprobe. BPr is a common first
instruction (a brz,pn on an argument), so a probe on a function's entry
is enough to hit it.

Patch 1 fixes kprobes, where the check dates back to the start of git
history. Patch 2 fixes the uprobes copy of it. They are independent of
each other, and of my pending uprobes kmap_local_page() patch.

Testing, in QEMU sun4u with sparc64_defconfig plus PREEMPT,
DEBUG_PREEMPT, PROVE_LOCKING and DEBUG_ATOMIC_SLEEP. A static init puts
uprobes on seven branches in its own code: brz,pn at a function's entry,
brgz,pt, fbe,pt %fcc0 (FBPfcc) and fbe (FBfcc), plus be (Bicc),
be,pt %xcc (BPcc) and call as controls. Each function runs 200 times in
a child, alternating taken and not taken, and the delay slot's effect
and the path taken are both checked. It then puts a kprobe on
__se_sys_getcpu(), which starts with "brz,pn %o0", and calls getcpu()
200 times, half of them with a NULL cpu pointer.

- fe2ec83746e5 (v7.3-rc4+): the four new uprobe cases die with SIGILL
on their first taken branch, the controls pass, and the first taken
getcpu() under the kprobe crashes the kernel.
- Patch 1 only: the kprobe case passes with 200 hits; uprobes as before.
- Both patches: everything passes, with no new kernel warnings. Boot
has three DEBUG_PREEMPT "__this_cpu_read() in preemptible" reports
from iommu_tbl_range_alloc(), with or without these patches.

W=1 and sparse are clean for both files.

Danish Khateeb (2):
sparc64: kprobes: fix relbranch_fixup() for BPr, FBfcc and FBPfcc
sparc64: uprobes: fix relbranch_fixup() for BPr, FBfcc and FBPfcc

arch/sparc/kernel/kprobes.c | 13 ++++++++-----
arch/sparc/kernel/uprobes.c | 13 ++++++++-----
2 files changed, 16 insertions(+), 10 deletions(-)


base-commit: fe2ec83746e501645709761605c2464a44fd2929
--
2.55.0