From mboxrd@z Thu Jan 1 00:00:00 1970 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 5EA40284B5C; Thu, 24 Apr 2025 16:24:36 +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=1745511876; cv=none; b=JTR7slSrrD9t9dTNRTNy1y9t9Ui5GjESKs2x1Mv+shdsE9Yj5h8ReMbIRkAwj817NKz5Z5FTWJaONzdIn09h9bLuBysS5WQRKpHFfaobyiLQg41u/dsBqkdf3AmxR4aOOnjnKoliNtiUtJO0SO5t16FiEOxBBTliEB9RdZaDv5A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745511876; c=relaxed/simple; bh=igARkNZC/TIED4+oym5/hyDA5+Veavsbq4flZdcAzZ8=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=TX3io01Eo9tBMS2jFOIu0q/MGw7B0kToEVGrryUovjtVqrjvTn588LcdzlQiCVQLxmNrH8/C8o+RTu1y+Pf4/fl76UuopdGP7zC224QCdMfqa0k5RKLAdoI8mCWCz94VGcF7U/7INOcRFKi2UmHl8uIWk0s0L5MrCO8plpVJABI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11BD7C4CEF8; Thu, 24 Apr 2025 16:24:36 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1u7zPD-0000000GyXC-4AQT; Thu, 24 Apr 2025 12:26:31 -0400 Message-ID: <20250424162631.842333564@goodmis.org> User-Agent: quilt/0.68 Date: Thu, 24 Apr 2025 12:25:33 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Josh Poimboeuf , x86@kernel.org, Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Indu Bhagat , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , linux-perf-users@vger.kernel.org, Mark Brown , linux-toolchains@vger.kernel.org, Jordan Rome , Sam James , Andrii Nakryiko , Jens Remus , Florian Weimer , Andy Lutomirski , Weinan Liu , Blake Jones , Beau Belgrave , "Jose E. Marchesi" Subject: [PATCH v5 04/17] perf/x86: Rename and move get_segment_base() and make it global References: <20250424162529.686762589@goodmis.org> Precedence: bulk X-Mailing-List: linux-toolchains@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 From: Josh Poimboeuf get_segment_base() will be used by the unwind_user code, so make it global and rename it so it doesn't conflict with a KVM function of the same name. As the function is no longer specific to perf, move it to ptrace.c as that seems to be a better location for a generic function like this. Signed-off-by: Josh Poimboeuf Signed-off-by: Steven Rostedt (Google) --- Changes since v4: https://lore.kernel.org/all/e54e48ab228aa386fb4c5f64ee02ef5291f2d3da.1737511963.git.jpoimboe@kernel.org/ - Moved function out of perf and to ptrace.c (Peter Zijlstra) - Added lockdep_assert_irqs_disabled() as it needs interrupts disabled (Steven Rostedt) arch/x86/events/core.c | 44 ++++------------------------------- arch/x86/include/asm/ptrace.h | 2 ++ arch/x86/kernel/ptrace.c | 38 ++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index d390472f6c10..1d11e1b04071 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "perf_event.h" @@ -2807,41 +2808,6 @@ valid_user_frame(const void __user *fp, unsigned long size) return __access_ok(fp, size); } -static unsigned long get_segment_base(unsigned int segment) -{ - struct desc_struct *desc; - unsigned int idx = segment >> 3; - - if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) { -#ifdef CONFIG_MODIFY_LDT_SYSCALL - struct ldt_struct *ldt; - - /* - * If we're not in a valid context with a real (not just lazy) - * user mm, then don't even try. - */ - if (!nmi_uaccess_okay()) - return 0; - - /* IRQs are off, so this synchronizes with smp_store_release */ - ldt = smp_load_acquire(¤t->mm->context.ldt); - if (!ldt || idx >= ldt->nr_entries) - return 0; - - desc = &ldt->entries[idx]; -#else - return 0; -#endif - } else { - if (idx >= GDT_ENTRIES) - return 0; - - desc = raw_cpu_ptr(gdt_page.gdt) + idx; - } - - return get_desc_base(desc); -} - #ifdef CONFIG_UPROBES /* * Heuristic-based check if uprobe is installed at the function entry. @@ -2898,8 +2864,8 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent if (user_64bit_mode(regs)) return 0; - cs_base = get_segment_base(regs->cs); - ss_base = get_segment_base(regs->ss); + cs_base = segment_base_address(regs->cs); + ss_base = segment_base_address(regs->ss); fp = compat_ptr(ss_base + regs->bp); pagefault_disable(); @@ -3018,11 +2984,11 @@ static unsigned long code_segment_base(struct pt_regs *regs) return 0x10 * regs->cs; if (user_mode(regs) && regs->cs != __USER_CS) - return get_segment_base(regs->cs); + return segment_base_address(regs->cs); #else if (user_mode(regs) && !user_64bit_mode(regs) && regs->cs != __USER32_CS) - return get_segment_base(regs->cs); + return segment_base_address(regs->cs); #endif return 0; } diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 50f75467f73d..59357ec98e52 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -314,6 +314,8 @@ static __always_inline bool regs_irqs_disabled(struct pt_regs *regs) return !(regs->flags & X86_EFLAGS_IF); } +unsigned long segment_base_address(unsigned int segment); + /* Query offset/name of register from its name/offset */ extern int regs_query_register_offset(const char *name); extern const char *regs_query_register_name(unsigned int offset); diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 095f04bdabdc..81353a09701b 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "tls.h" @@ -339,6 +340,43 @@ static int set_segment_reg(struct task_struct *task, #endif /* CONFIG_X86_32 */ +unsigned long segment_base_address(unsigned int segment) +{ + struct desc_struct *desc; + unsigned int idx = segment >> 3; + + lockdep_assert_irqs_disabled(); + + if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) { +#ifdef CONFIG_MODIFY_LDT_SYSCALL + struct ldt_struct *ldt; + + /* + * If we're not in a valid context with a real (not just lazy) + * user mm, then don't even try. + */ + if (!nmi_uaccess_okay()) + return 0; + + /* IRQs are off, so this synchronizes with smp_store_release */ + ldt = smp_load_acquire(¤t->mm->context.ldt); + if (!ldt || idx >= ldt->nr_entries) + return 0; + + desc = &ldt->entries[idx]; +#else + return 0; +#endif + } else { + if (idx >= GDT_ENTRIES) + return 0; + + desc = raw_cpu_ptr(gdt_page.gdt) + idx; + } + + return get_desc_base(desc); +} + static unsigned long get_flags(struct task_struct *task) { unsigned long retval = task_pt_regs(task)->flags; -- 2.47.2