From patchwork Sat Aug 24 11:14:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Donglin Peng X-Patchwork-Id: 13776406 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D1AFEC52D6F for ; Sat, 24 Aug 2024 11:16:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=vtgbP1Eu0xbx3WuHiPWCXRNvM9xiFDKBn97sk+bYRDE=; b=TSi9PjzzF7pOiuADlOC2HTpZCw hLUsQ9k2t8cR7zzoOoeLujnXsbFS9DZODOD8sGZ1UQEh2K6lBtkYJIp54tzYgJUfQicGWMxBpXuZV PmXxX+VZS2ZDbqNY7rLzOjUQs/blbXJWIHwIvW+BVzi4gIj2PERhbeARwtE6sKPytAj9onYitLcTQ pBdnRjCrR4TiZh75X29Ybj7UIeLf97F1B/fh730W/7R57o1Pz0yzWI/nmejAUihyGyET16upl2Oxo THhf7mAuVaxchhZ6LTMWo/Uz2CXX6wD30lTUcSLL1Yo52BGgiosv13LpucVluxKA7/yZvdNHevMcz jpyM9znw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1shokN-000000026Lz-2GDY; Sat, 24 Aug 2024 11:15:55 +0000 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1shojb-000000026HV-3ThU for linux-arm-kernel@lists.infradead.org; Sat, 24 Aug 2024 11:15:09 +0000 Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-20227ba378eso25959605ad.0 for ; Sat, 24 Aug 2024 04:15:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1724498105; x=1725102905; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=vtgbP1Eu0xbx3WuHiPWCXRNvM9xiFDKBn97sk+bYRDE=; b=R01j2cqR+QPe2CzPd1hJ68hryD2aicwhJizOoajRdu5f+faKKU0L0v+0VB0rxlprj1 UYcX08LQw0Sv2S83XaXJbnOuljGFPgbwC3eLUOg9ROllg+wOLvWd9s0NuBTSZ6VB389j +wB4fIkci46eSlnxSE7ooGK8dbpznveyYvIak7d5kYgxVhjx4CLIvAyRpJNuKYqsi16B v8zCLY73HRravc0rS3/TZFryet7Czu6j5Zw+e2bgwXgJXpaMsEeUadn43Py8rHzxUBps Uf8jtnqEBj6lYxfD3xCwjEm6Nv9qy0nOAasbhXIdzGzgixylAvEOFXZlzGmPherkM4L1 6uTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724498105; x=1725102905; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vtgbP1Eu0xbx3WuHiPWCXRNvM9xiFDKBn97sk+bYRDE=; b=UY4g34jAYqPkhwVkJVUvTV+/t4Uv404d4/7Wvtel6QSC5L9yA4LbFSXJ8RWQvDA1Qq Lo2V9vZNPKutaHNu4GU7MwI1HIsKvW1YZQnJTXf3ha0PBlE9t8U2/I7fCtcc1ozYYVwX trTAvmCpxpU98f+ToI3eSGEbgRV7MXEYR8QbieWyIad5jLCCBtINCfrE64ArTz3wViKn RJejpNiUCyesxfDtts+rAIsxUivenNC3JT3AbrX0Rquj1Sdpqz+yXOCBGo7DGJbQTB01 U4exAuBSpT+t5QwAbaXG79CYV7D+GtpFceA1E0d06z0EMZV3en5SfK6F75zifis0vjTq PH4A== X-Forwarded-Encrypted: i=1; AJvYcCXXnd5Z6Dh3oAvFvCBt8rD+1+PE3ibB+lx3EeZbsQOt6A2xdZ6zKrHI0fIkbCvKSg5aKL8tHYhKTZh+Hq0PsnOH@lists.infradead.org X-Gm-Message-State: AOJu0YzsM2Z7fikW8iYS4Sgi4QfKHrHa2yaR1/9ZOEBX6ZTFQo5suDv8 /GfxrdgAwhKYx+OZEoh1+Qp/VojLigObTVqrNrCOSR213+dQeAnb X-Google-Smtp-Source: AGHT+IHThhIjh7iP7Nff7xqy1wHlA8i7h4Sk41vDwZjjd4OoLQ5/BoylpoE4cDLARhVadl2f125EXw== X-Received: by 2002:a17:903:22c5:b0:203:a11a:30c8 with SMTP id d9443c01a7336-203a11a30e9mr50657965ad.43.1724498105106; Sat, 24 Aug 2024 04:15:05 -0700 (PDT) Received: from ubuntu.localdomain ([106.39.150.171]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20385bdc663sm40786255ad.273.2024.08.24.04.15.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Aug 2024 04:15:04 -0700 (PDT) From: Donglin Peng To: catalin.marinas@arm.com Cc: mark.rutland@arm.com, will@kernel.org, wangkefeng.wang@huawei.com, ryan.roberts@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Donglin Peng Subject: [PATCH] arm64: Trace the memory abort exception Date: Sat, 24 Aug 2024 04:14:56 -0700 Message-Id: <20240824111456.289367-1-dolinux.peng@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240824_041507_899141_0F6FD13C X-CRM114-Status: GOOD ( 19.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Introduce an event to trace the occurrence of memory abort exceptions. The event can be useful if you only want to trace the page fault exception when accessing a specific virtual address range, and it can also help in locating the userspace code that triggers the fault. I have referred to the trace_page_fault_user/trace_page_fault_kernel on the x86 platform. For example: $ sudo perf record -e exceptions:mem_abort_user \ --filter 'address >= 0xffff8fe00010 && address <= 0xffff90e00010' \ -g -p 596 -- sleep 10 $ sudo perf script fault 596 [000] 1218.765001: exceptions:mem_abort_user: address=0xffff9010e010 ip=0xaaaad8c90a6c error_code=0x9200000b ffff800080028e78 do_mem_abort+0xd0 ([kernel.kallsyms]) ffff800080028e78 do_mem_abort+0xd0 ([kernel.kallsyms]) ffff800080c89a38 el0_da+0x38 ([kernel.kallsyms]) ffff800080c8ac54 el0t_64_sync_handler+0x8c ([kernel.kallsyms]) ffff80008001148c el0t_64_sync+0x14c ([kernel.kallsyms]) aaaad8c90a6c func_three+0xf0 (/home/pengdl/demo/pagefault/fault) aaaad8c90ae4 func_two+0x20 (/home/pengdl/demo/pagefault/fault) aaaad8c90b0c func_one+0x20 (/home/pengdl/demo/pagefault/fault) aaaad8c90c54 main+0x140 (/home/pengdl/demo/pagefault/fault) ffff90fece10 __libc_start_main+0xe8 (/usr/lib/aarch64-linux-gnu/libc-2.31.so) aaaad8c908a4 _start+0x34 (/home/pengdl/demo/pagefault/fault) Signed-off-by: Donglin Peng --- arch/arm64/include/asm/trace/common.h | 18 +++++++ arch/arm64/include/asm/trace/exceptions.h | 59 +++++++++++++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/tracepoint.c | 23 +++++++++ arch/arm64/mm/fault.c | 18 +++++++ 5 files changed, 119 insertions(+) create mode 100644 arch/arm64/include/asm/trace/common.h create mode 100644 arch/arm64/include/asm/trace/exceptions.h create mode 100644 arch/arm64/kernel/tracepoint.c diff --git a/arch/arm64/include/asm/trace/common.h b/arch/arm64/include/asm/trace/common.h new file mode 100644 index 000000000000..a3efa45e2f20 --- /dev/null +++ b/arch/arm64/include/asm/trace/common.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Based on arch/x86/include/asm/trace/common.h + * + */ + +#ifndef _ASM_TRACE_COMMON_H +#define _ASM_TRACE_COMMON_H + +#ifdef CONFIG_TRACING +DECLARE_STATIC_KEY_FALSE(trace_memabort_key); +#define trace_memabort_enabled() \ + static_branch_unlikely(&trace_memabort_key) +#else +static inline bool trace_memabort_enabled(void) { return false; } +#endif + +#endif diff --git a/arch/arm64/include/asm/trace/exceptions.h b/arch/arm64/include/asm/trace/exceptions.h new file mode 100644 index 000000000000..919400c7682d --- /dev/null +++ b/arch/arm64/include/asm/trace/exceptions.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Based on arch/x86/include/asm/trace/exceptions.h + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM exceptions + +#if !defined(_TRACE_MEM_ABORT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MEM_ABORT_H + +#include +#include + +extern int trace_memabort_reg(void); +extern void trace_memabort_unreg(void); + +DECLARE_EVENT_CLASS(arm64_exceptions, + + TP_PROTO(unsigned long address, struct pt_regs *regs, + unsigned long error_code), + + TP_ARGS(address, regs, error_code), + + TP_STRUCT__entry( + __field( unsigned long, address ) + __field( unsigned long, ip ) + __field( unsigned long, error_code ) + ), + + TP_fast_assign( + __entry->address = address; + __entry->ip = regs->pc; + __entry->error_code = error_code; + ), + + TP_printk("address=%ps ip=%ps error_code=0x%lx", + (void *)__entry->address, (void *)__entry->ip, + __entry->error_code) ); + +#define DEFINE_MEM_ABORT_EVENT(name) \ +DEFINE_EVENT_FN(arm64_exceptions, name, \ + TP_PROTO(unsigned long address, struct pt_regs *regs, \ + unsigned long error_code), \ + TP_ARGS(address, regs, error_code), \ + trace_memabort_reg, trace_memabort_unreg); + +DEFINE_MEM_ABORT_EVENT(mem_abort_user); +DEFINE_MEM_ABORT_EVENT(mem_abort_kernel); + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH asm/trace +#define TRACE_INCLUDE_FILE exceptions +#endif /* _TRACE_MEM_ABORT_H */ + +/* This part must be outside protection */ +#include diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 2b112f3b7510..f78aa49b8587 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_KUSER_HELPERS) += kuser32.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o obj-$(CONFIG_MODULES) += module.o module-plts.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o +obj-$(CONFIG_TRACING) += tracepoint.o obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o obj-$(CONFIG_CPU_PM) += sleep.o suspend.o diff --git a/arch/arm64/kernel/tracepoint.c b/arch/arm64/kernel/tracepoint.c new file mode 100644 index 000000000000..c322e3644f75 --- /dev/null +++ b/arch/arm64/kernel/tracepoint.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Based on arch/x86/kernel/tracepoint.c + * + */ + +#include +#include + +#include + +DEFINE_STATIC_KEY_FALSE(trace_memabort_key); + +int trace_memabort_reg(void) +{ + static_branch_inc(&trace_memabort_key); + return 0; +} + +void trace_memabort_unreg(void) +{ + static_branch_dec(&trace_memabort_key); +} diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 451ba7cbd5ad..aaccccb831a6 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -43,6 +43,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + struct fault_info { int (*fn)(unsigned long far, unsigned long esr, struct pt_regs *regs); @@ -818,11 +821,26 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 63" }, }; +static __always_inline void +trace_mem_abort_entries(struct pt_regs *regs, unsigned long error_code, + unsigned long address) +{ + if (!trace_memabort_enabled()) + return; + + if (user_mode(regs)) + trace_mem_abort_user(address, regs, error_code); + else + trace_mem_abort_kernel(address, regs, error_code); +} + void do_mem_abort(unsigned long far, unsigned long esr, struct pt_regs *regs) { const struct fault_info *inf = esr_to_fault_info(esr); unsigned long addr = untagged_addr(far); + trace_mem_abort_entries(regs, esr, addr); + if (!inf->fn(far, esr, regs)) return;