From nobody Tue Dec 2 03:00:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AAE0632E140; Mon, 17 Nov 2025 12:41:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763383282; cv=none; b=WrAfUW8EM6AmiXJJgMf867NIgcq+lBOVjtjsN/hYQnTU41iNNibnmid4v6ZO4Sa+qNqMV+lj+zjwLLfbAxmxSdnuqaFpT4LPnqV7Jr3+ttD/8oK1cioSeOLSf+wOT8bBaBGgTsSowxrufOOuIFId59Tk/HcelTOeLQ2TD8RDuhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763383282; c=relaxed/simple; bh=yjQSutv+PRPuxVWoLTWx0ZnuJMKaycwr6No20fC2bV4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y83XHT4GQ0Hth3ksRsn6JhiXechEISvz0C3IDKlqrssn4cJxRA8j/9EuFJMGSX1nD1ebPUX+asahgaNkLkUH3jjO+gZ3i6xrNDxcZ9FS1lz1Z3DyDMiomOiF3C6xdSdQgmjwcLOsNTHF9jpaJ8ulTHmyqaLgtqHxcTc58pq+Q0A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Jdw0gcJE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Jdw0gcJE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA027C4CEF1; Mon, 17 Nov 2025 12:41:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1763383282; bh=yjQSutv+PRPuxVWoLTWx0ZnuJMKaycwr6No20fC2bV4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Jdw0gcJEN6R2llFhQRFnVmahQKHonD/DJHHathwL/BlrSQ1uI/RlVmapHpcqO2Cyo az8zzUI1MZz5tuF/3ooUwKM+1bTfsVg9quavN+wiICkk1OxSn4PDkXkq4WXGq+P6Pz ie0XcArxvgOr8viIisaqTmIGkfNNIsZNOJ6LFwe7ncmKoyTPlRh/VwO+rXFL5dnS2C 611B4VjgaSKaBahGGoYyok6FWEawppuGd7cU9Nv6QSFFTvdSAZ14iMIu76IpA9qYUR wZwy/k5SgrwirhcX9e3AbUhlcTV6toDird6zSvBqInITZgS6Ik/erfZYHYMq/+SRE6 axOTHhfth2INA== From: Jiri Olsa To: Oleg Nesterov , Masami Hiramatsu , Peter Zijlstra , Andrii Nakryiko Cc: bpf@vger.kernel.org, linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, x86@kernel.org, Song Liu , Yonghong Song , John Fastabend , Steven Rostedt , Ingo Molnar , David Laight Subject: [RFC PATCH 1/8] uprobe/x86: Introduce struct arch_uprobe_xol object Date: Mon, 17 Nov 2025 13:40:50 +0100 Message-ID: <20251117124057.687384-2-jolsa@kernel.org> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20251117124057.687384-1-jolsa@kernel.org> References: <20251117124057.687384-1-jolsa@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Mov xol data into separate arch_uprobe_xol object so we can hold more of them in following changes. Signed-off-by: Jiri Olsa --- arch/x86/include/asm/uprobes.h | 16 ++++--- arch/x86/kernel/uprobes.c | 78 +++++++++++++++++----------------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 1ee2e5115955..819e35aa61c4 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h @@ -27,12 +27,7 @@ enum { =20 struct uprobe_xol_ops; =20 -struct arch_uprobe { - union { - u8 insn[MAX_UINSN_BYTES]; - u8 ixol[MAX_UINSN_BYTES]; - }; - +struct arch_uprobe_xol { const struct uprobe_xol_ops *ops; =20 union { @@ -50,6 +45,15 @@ struct arch_uprobe { u8 ilen; } push; }; +}; + +struct arch_uprobe { + union { + u8 insn[MAX_UINSN_BYTES]; + u8 ixol[MAX_UINSN_BYTES]; + }; + + struct arch_uprobe_xol xol; =20 unsigned long flags; }; diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 845aeaf36b8d..fb9457b29dbc 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -560,14 +560,14 @@ static void riprel_analyze(struct arch_uprobe *auprob= e, struct insn *insn) */ if (reg !=3D 6 && reg2 !=3D 6) { reg2 =3D 6; - auprobe->defparam.fixups |=3D UPROBE_FIX_RIP_SI; + auprobe->xol.defparam.fixups |=3D UPROBE_FIX_RIP_SI; } else if (reg !=3D 7 && reg2 !=3D 7) { reg2 =3D 7; - auprobe->defparam.fixups |=3D UPROBE_FIX_RIP_DI; + auprobe->xol.defparam.fixups |=3D UPROBE_FIX_RIP_DI; /* TODO (paranoia): force maskmovq to not use di */ } else { reg2 =3D 3; - auprobe->defparam.fixups |=3D UPROBE_FIX_RIP_BX; + auprobe->xol.defparam.fixups |=3D UPROBE_FIX_RIP_BX; } /* * Point cursor at the modrm byte. The next 4 bytes are the @@ -586,9 +586,9 @@ static void riprel_analyze(struct arch_uprobe *auprobe,= struct insn *insn) static inline unsigned long * scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs) { - if (auprobe->defparam.fixups & UPROBE_FIX_RIP_SI) + if (auprobe->xol.defparam.fixups & UPROBE_FIX_RIP_SI) return ®s->si; - if (auprobe->defparam.fixups & UPROBE_FIX_RIP_DI) + if (auprobe->xol.defparam.fixups & UPROBE_FIX_RIP_DI) return ®s->di; return ®s->bx; } @@ -599,18 +599,18 @@ scratch_reg(struct arch_uprobe *auprobe, struct pt_re= gs *regs) */ static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *re= gs) { - if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { + if (auprobe->xol.defparam.fixups & UPROBE_FIX_RIP_MASK) { struct uprobe_task *utask =3D current->utask; unsigned long *sr =3D scratch_reg(auprobe, regs); =20 utask->autask.saved_scratch_register =3D *sr; - *sr =3D utask->vaddr + auprobe->defparam.ilen; + *sr =3D utask->vaddr + auprobe->xol.defparam.ilen; } } =20 static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *r= egs) { - if (auprobe->defparam.fixups & UPROBE_FIX_RIP_MASK) { + if (auprobe->xol.defparam.fixups & UPROBE_FIX_RIP_MASK) { struct uprobe_task *utask =3D current->utask; unsigned long *sr =3D scratch_reg(auprobe, regs); =20 @@ -1265,16 +1265,16 @@ static int default_post_xol_op(struct arch_uprobe *= auprobe, struct pt_regs *regs struct uprobe_task *utask =3D current->utask; =20 riprel_post_xol(auprobe, regs); - if (auprobe->defparam.fixups & UPROBE_FIX_IP) { + if (auprobe->xol.defparam.fixups & UPROBE_FIX_IP) { long correction =3D utask->vaddr - utask->xol_vaddr; regs->ip +=3D correction; - } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) { + } else if (auprobe->xol.defparam.fixups & UPROBE_FIX_CALL) { regs->sp +=3D sizeof_long(regs); /* Pop incorrect return address */ - if (emulate_push_stack(regs, utask->vaddr + auprobe->defparam.ilen)) + if (emulate_push_stack(regs, utask->vaddr + auprobe->xol.defparam.ilen)) return -ERESTART; } /* popf; tell the caller to not touch TF */ - if (auprobe->defparam.fixups & UPROBE_FIX_SETF) + if (auprobe->xol.defparam.fixups & UPROBE_FIX_SETF) utask->autask.saved_tf =3D true; =20 return 0; @@ -1293,7 +1293,7 @@ static const struct uprobe_xol_ops default_xol_ops = =3D { =20 static bool branch_is_call(struct arch_uprobe *auprobe) { - return auprobe->branch.opc1 =3D=3D 0xe8; + return auprobe->xol.branch.opc1 =3D=3D 0xe8; } =20 #define CASE_COND \ @@ -1329,7 +1329,7 @@ static bool check_jmp_cond(struct arch_uprobe *auprob= e, struct pt_regs *regs) { unsigned long flags =3D regs->flags; =20 - switch (auprobe->branch.opc1) { + switch (auprobe->xol.branch.opc1) { #define DO(expr) \ return expr; CASE_COND @@ -1346,8 +1346,8 @@ static bool check_jmp_cond(struct arch_uprobe *auprob= e, struct pt_regs *regs) =20 static bool branch_emulate_op(struct arch_uprobe *auprobe, struct pt_regs = *regs) { - unsigned long new_ip =3D regs->ip +=3D auprobe->branch.ilen; - unsigned long offs =3D (long)auprobe->branch.offs; + unsigned long new_ip =3D regs->ip +=3D auprobe->xol.branch.ilen; + unsigned long offs =3D (long)auprobe->xol.branch.offs; =20 if (branch_is_call(auprobe)) { /* @@ -1371,11 +1371,11 @@ static bool branch_emulate_op(struct arch_uprobe *a= uprobe, struct pt_regs *regs) =20 static bool push_emulate_op(struct arch_uprobe *auprobe, struct pt_regs *r= egs) { - unsigned long *src_ptr =3D (void *)regs + auprobe->push.reg_offset; + unsigned long *src_ptr =3D (void *)regs + auprobe->xol.push.reg_offset; =20 if (emulate_push_stack(regs, *src_ptr)) return false; - regs->ip +=3D auprobe->push.ilen; + regs->ip +=3D auprobe->xol.push.ilen; return true; } =20 @@ -1469,16 +1469,16 @@ static int branch_setup_xol_ops(struct arch_uprobe = *auprobe, struct insn *insn) } =20 setup: - auprobe->branch.opc1 =3D opc1; - auprobe->branch.ilen =3D insn->length; - auprobe->branch.offs =3D insn->immediate.value; + auprobe->xol.branch.opc1 =3D opc1; + auprobe->xol.branch.ilen =3D insn->length; + auprobe->xol.branch.offs =3D insn->immediate.value; =20 - auprobe->ops =3D &branch_xol_ops; + auprobe->xol.ops =3D &branch_xol_ops; return 0; } =20 /* Returns -ENOSYS if push_xol_ops doesn't handle this insn */ -static int push_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *in= sn) +static int push_setup_xol_ops(struct arch_uprobe_xol *xol, struct insn *in= sn) { u8 opc1 =3D OPCODE1(insn), reg_offset =3D 0; =20 @@ -1552,9 +1552,9 @@ static int push_setup_xol_ops(struct arch_uprobe *aup= robe, struct insn *insn) } } =20 - auprobe->push.reg_offset =3D reg_offset; - auprobe->push.ilen =3D insn->length; - auprobe->ops =3D &push_xol_ops; + xol->push.reg_offset =3D reg_offset; + xol->push.ilen =3D insn->length; + xol->ops =3D &push_xol_ops; return 0; } =20 @@ -1582,7 +1582,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *aupr= obe, struct mm_struct *mm, if (ret !=3D -ENOSYS) return ret; =20 - ret =3D push_setup_xol_ops(auprobe, &insn); + ret =3D push_setup_xol_ops(&auprobe->xol, &insn); if (ret !=3D -ENOSYS) return ret; =20 @@ -1592,7 +1592,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *aupr= obe, struct mm_struct *mm, */ switch (OPCODE1(&insn)) { case 0x9d: /* popf */ - auprobe->defparam.fixups |=3D UPROBE_FIX_SETF; + auprobe->xol.defparam.fixups |=3D UPROBE_FIX_SETF; break; case 0xc3: /* ret or lret -- ip is correct */ case 0xcb: @@ -1618,10 +1618,10 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *au= probe, struct mm_struct *mm, riprel_analyze(auprobe, &insn); } =20 - auprobe->defparam.ilen =3D insn.length; - auprobe->defparam.fixups |=3D fix_ip_or_call; + auprobe->xol.defparam.ilen =3D insn.length; + auprobe->xol.defparam.fixups |=3D fix_ip_or_call; =20 - auprobe->ops =3D &default_xol_ops; + auprobe->xol.ops =3D &default_xol_ops; return 0; } =20 @@ -1634,8 +1634,8 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, = struct pt_regs *regs) { struct uprobe_task *utask =3D current->utask; =20 - if (auprobe->ops->pre_xol) { - int err =3D auprobe->ops->pre_xol(auprobe, regs); + if (auprobe->xol.ops->pre_xol) { + int err =3D auprobe->xol.ops->pre_xol(auprobe, regs); if (err) return err; } @@ -1686,8 +1686,8 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe,= struct pt_regs *regs) WARN_ON_ONCE(current->thread.trap_nr !=3D UPROBE_TRAP_NR); current->thread.trap_nr =3D utask->autask.saved_trap_nr; =20 - if (auprobe->ops->post_xol) { - err =3D auprobe->ops->post_xol(auprobe, regs); + if (auprobe->xol.ops->post_xol) { + err =3D auprobe->xol.ops->post_xol(auprobe, regs); if (err) { /* * Restore ->ip for restart or post mortem analysis. @@ -1754,8 +1754,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprob= e, struct pt_regs *regs) { struct uprobe_task *utask =3D current->utask; =20 - if (auprobe->ops->abort) - auprobe->ops->abort(auprobe, regs); + if (auprobe->xol.ops->abort) + auprobe->xol.ops->abort(auprobe, regs); =20 current->thread.trap_nr =3D utask->autask.saved_trap_nr; regs->ip =3D utask->vaddr; @@ -1766,8 +1766,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprob= e, struct pt_regs *regs) =20 static bool __skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) { - if (auprobe->ops->emulate) - return auprobe->ops->emulate(auprobe, regs); + if (auprobe->xol.ops->emulate) + return auprobe->xol.ops->emulate(auprobe, regs); return false; } =20 --=20 2.51.1