From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=205.220.168.131 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793206580; b=rvnYJLW3tZ7zooImtVO12pKGrmaiISMNAAi+47v2rsK3PFzJleLezIAw216AehG/OWU1 z+QUGWDUVtA2RMhHiPH/3RLs9x220OMCVG84dDah1y6tqGuLCBT3IpXbTMfUrCcWfPNO6 obcGMN3HbbzoyYDj46AfXqo9kFUZeAB99M7JEpnnkVjm7oUny0Oik6hGAU3v9uLas8b/V MgAgiccr1rwfewZl1+P0x1djhx+Hj6zu/ydkNGfxtGNO2oKdndeDLicGJIsrntPpSdmsy vfK4AJRywf9x1TK/sUeMcu1KZgkUgsrYfH5Z+WrvYMeD7GAdrv0PctyFqbkmdRFtuMw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793206580; h=DMARC-Filter:Received:DKIM-Signature:Received:Received:Received: Received:From:To:Cc:Subject:Date:Message-ID:X-Mailer:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding: X-Proofpoint-Reinject:X-QCInternal:X-QCInternal: X-Proofpoint-ORIG-GUID:X-Proofpoint-Spam-Details-Enc: X-Proofpoint-GUID:X-Proofpoint-Spam-Info:X-Authority-Analysis: X-Proofpoint-Virus-Version:X-Proofpoint-Spam-Details; bh=7WmdMPjJ2NrxzGe7d5uluyZgYPehQw5MUFdjLbKyP8Q=; b=0fRwLUs/ou2axZ8mcknxUeFJzCEA8sNYqQFUxy0k14qpbJrj0LSmHytSOe7DttTjpfVG GP+OPNHnNCN08I7TPtnXFoH2aReWQkIVLkQQEvDDWzX1/FuwpZCX2OgDK7D5J0LeDlp4l He2/v77ljkwoGrFOybFhNl2+yC1l1dSKbYPZZT/XdTr9o0P90CxYVSRJz0biIxe1Gg319 dLZ1ds76KPIgABlW3otd65/T2+uEK79trNt82rXFE0YyjhEoxZH4RJMFRZvj42ERZdHjj yO2wZOOYBI+UlRxtIix3UZQCPJFpsfDi8EWs69Y22A3lPtmQmk6/BJKuGxJhLQrkY9g== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=qualcomm.com; dkim=pass header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=duo7yyJf; arc=none smtp.remote-ip=205.220.168.131 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57984606A31C; Wed, 28 Oct 2026 16:56:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 57984606A31C Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=qualcomm.com header.i=@qualcomm.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=duo7yyJf Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 69SF9xOZ2542978; Wed, 28 Oct 2026 16:55:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=qcppdkim1; bh=7WmdMPjJ2Nr xzGe7d5uluyZgYPehQw5MUFdjLbKyP8Q=; b=duo7yyJfD/fQH6Wr9/R1cUfQ8EG xZVrwJK5u21sZZ6Q5b0AV5uM4H6/IOlAke8uTWNKxbV7/6v+sG5G7cyBkF5HPcap TiLBuh9Yy1Jn+oyCdlDFryZ0Fps93PA9z9EYBypekEglSrsj/mIzNZ0HKcpc74L9 MaJ/fTcZJAIgQ+R1AO2wAJN7uZ/35a9/jIECjs5nRDBkYIgaWBZeXuP9Upo6cN4H ZeKgvGtiqH6DlB9IXOzqSHYuVrSy0BTXHG3R07wuO5MABXGKDS7Ry84zbsKf3r0Z wj6WrEMahYqI7CliJubVneCdVu1/TMXKqXs3lEKVWDtPLnugmizHtOwE9Mg== Received: from apblrppmta01.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4hkkehrgev-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 28 Oct 2026 16:55:38 +0000 (GMT) Received: from pps.filterd (apblrppmta01.qualcomm.com [127.0.0.1]) by APBLRPPMTA01.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 69SGtYEX1881526; Wed, 28 Oct 2026 16:55:35 GMT Received: from hu-devc-blr-u24-a.qualcomm.com (hu-anuppate-blr.qualcomm.com [10.131.36.165]) by APBLRPPMTA01.qualcomm.com (PPS) with ESMTPS id 69SGtZMD1881554 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 28 Oct 2026 16:55:35 +0000 (GMT) Received: by hu-devc-blr-u24-a.qualcomm.com (Postfix, from userid 486687) id 3BD0624B5A; Wed, 28 Oct 2026 22:25:33 +0530 (+0530) From: Anup Patel To: Palmer Dabbelt , Paul Walmsley , Alexandre Ghiti , Himanshu Chauhan , Conor Dooley , Atish Patra , Anup Patel Cc: Zhanpeng Zhang , Yunhui Cui , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark , Will Deacon , Thomas Gleixner , Jonathan Corbet , Randy Dunlap , Shuah Khan , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, Susheng Yang Subject: [PATCH v11 6/9] perf: RISC-V: support callchains with SSE delivery Date: Wed, 28 Oct 2026 22:25:28 +0530 Message-ID: <20261028165531.940336-7-anup.patel@oss.qualcomm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20261028165531.940336-1-anup.patel@oss.qualcomm.com> References: <20261028165531.940336-1-anup.patel@oss.qualcomm.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-ORIG-GUID: 6xShqfkFfh8v9YvfQrlOIUVUh-Q0zUGQ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYxMDI4MDA2NyBTYWx0ZWRfX0pmetC6uT463 7DnnQ85MyHaoT3/LavgdSdYNQsxN5OmEwJdp5VG5p0sXodOR+0MacgOJs3R5j3ufaJ9XtkX6vKd jA3vgx9VPudYVJ1OxmSbufQnT5zZElvVf2hJh+uj37cqpzrQRw6CRhXB/qUZ1wsCWhZHX1u6qNL AArv1YjMs0ybhnIEoBjBs6o12Orn/THJPnRkU/wa0ns0x+GHZ/EtscpS70c4Dg2pu0Esg5qie22 tlAB+tS2uTZ5odfV+r0vmvX7sKX/wAe/50omSQWzMuA6KNURSoiXGmy9IFDcyTot+3fLzGrv/9B jDdwNRbwfJGWCf/KqoFUZgiuwSlUpoUMDSIL26FziR2qdqNulEXYMTZFW0DqNV4dsvBzZPqJqJF cJG1Xb7oLO50atlfT1GBWXImtl0g3yQUvG1uLuvjjEmf0jyUWkyCFzuctC5pKmW3by5Axoe2Jdk tHV/YeHNcg9X7iglFCw== X-Proofpoint-GUID: 6xShqfkFfh8v9YvfQrlOIUVUh-Q0zUGQ X-Proofpoint-Spam-Info: AW1haW4tMjYxMDI4MDA2NyBTYWx0ZWRfX0v7nfO9VCYhg /iHSEjY2rJw1v4dFc4/pKs+5uhvDmmHhiaoNfZ6LuWo7dK/avyZvtywW6Sxz7CoH/2y/vSdd5ct 97p/MCDhRNqUj2S5HGrb61bIxpq06gY= X-Authority-Analysis: v=2.4 cv=bYv+w+PB c=1 sm=1 tr=0 ts=6ae2290a cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=660iZSQnnn4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=eoimf2acIAo5FJnRuUoq:22 a=968KyxNXAAAA:8 a=1RTuLK3dAAAA:8 a=oUB1ajNOr_kzCuKrLyYA:9 a=kRpfLKi8w9umh8uBmg1i:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.138,FMLib:17.12.100.49 definitions=2026-10-28_05,2026-10-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 malwarescore=0 bulkscore=0 spamscore=0 phishscore=0 lowpriorityscore=0 clxscore=1011 adultscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2610190000 definitions=main-2610280067 From: Zhanpeng Zhang PMU overflow delivery through SSE enters Linux with a synthetic supervisor context on a dedicated event stack. The perf unwinder must use the context interrupted by the overflow rather than treating the SSE handler frame as the sampled frame. Use the interrupted pt_regs published by the RISC-V SSE entry path. Walk a kernel callchain only when the interrupted PC, SP, and frame pointer are consistent with the current task stack. For sensitive entry windows and IRQ stacks whose bounds cannot be proven, retain the interrupted PC without following an unsafe frame chain. User callchains continue through the existing nofault RISC-V user unwinder. If hstatus.SPV says the interrupted context was a guest, do not interpret the guest stack through the host address space. DWARF callchains additionally copy a raw user stack. The generic arch_perf_out_copy_user() implementation can take an exception-table handled fault when a source page is not resident. Repeated nested faults from the SSE handler can corrupt the interrupted kernel context under load. Provide an SSE-specific RISC-V copy path. Verify that the active page table belongs to current, use fast-only GUP to acquire each resident source page without falling back to a faulting slow path, and copy through the kernel mapping while holding the page reference. Stop at the first unavailable page and preserve perf's existing truncated-user-stack semantics. Keep the generic in-atomic user copy unchanged outside an SSE handler. Susheng Yang reported this failure with perf callchain workloads. Reported-by: Susheng Yang Signed-off-by: Zhanpeng Zhang --- arch/riscv/include/asm/perf_event.h | 10 ++ arch/riscv/kernel/perf_callchain.c | 142 ++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/arch/riscv/include/asm/perf_event.h b/arch/riscv/include/asm/perf_event.h index bcc928fd3785..ddc404794751 100644 --- a/arch/riscv/include/asm/perf_event.h +++ b/arch/riscv/include/asm/perf_event.h @@ -18,6 +18,16 @@ (regs)->sp = current_stack_pointer; \ (regs)->status = SR_PP; \ } + +#ifdef CONFIG_RISCV_SBI_SSE +/* + * Raw user-stack sampling can run in the NMI-like SSE context. Route it + * through an implementation that does not fault on a non-resident page. + */ +unsigned long riscv_perf_out_copy_user(void *dst, const void *src, + unsigned long n); +#define arch_perf_out_copy_user riscv_perf_out_copy_user +#endif #endif #endif /* _ASM_RISCV_PERF_EVENT_H */ diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c index b465bc9eb870..ec75689c7aec 100644 --- a/arch/riscv/kernel/perf_callchain.c +++ b/arch/riscv/kernel/perf_callchain.c @@ -1,9 +1,15 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ +#include +#include #include +#include +#include #include +#include +#include #include static bool fill_callchain(void *entry, unsigned long pc) @@ -11,6 +17,128 @@ static bool fill_callchain(void *entry, unsigned long pc) return perf_callchain_store(entry, pc) == 0; } +#ifdef CONFIG_RISCV_SBI_SSE +static bool sse_addr_on_task_stack(unsigned long addr, unsigned long size) +{ + unsigned long end = addr + size; + unsigned long stack; + + if (end < addr) + return false; + + stack = (unsigned long)task_stack_page(current); + if (addr >= stack && end <= stack + THREAD_SIZE) + return true; + + return false; +} + +static bool sse_kernel_regs_safe(struct pt_regs *regs) +{ + unsigned long fp = frame_pointer(regs); + unsigned long pc = instruction_pointer(regs); + unsigned long sp = user_stack_pointer(regs); + + if (!__kernel_text_address(pc)) + return false; + if (!sse_addr_on_task_stack(sp, sizeof(unsigned long))) + return false; + if (fp < sizeof(struct stackframe)) + return false; + + return sse_addr_on_task_stack(fp - sizeof(struct stackframe), + sizeof(struct stackframe)); +} + +static bool sse_callchain_is_guest(const struct riscv_sse_interrupted_context *context) +{ + return context && (context->hstatus & HSTATUS_SPV); +} + +static bool sse_callchain_kernel(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) +{ + const struct riscv_sse_interrupted_context *context; + unsigned long pc; + + context = riscv_sse_get_interrupted_context(); + if (!context || context->regs != regs) + return false; + + /* A guest stack cannot be walked using the host kernel address space. */ + if (sse_callchain_is_guest(context)) + return true; + + if (user_mode(regs)) + return true; + + if (sse_kernel_regs_safe(regs)) { + walk_stackframe(NULL, regs, fill_callchain, entry); + return true; + } + + /* + * Keep the sample useful for sensitive entry paths and IRQ stacks. The + * generic walker does not take explicit IRQ stack bounds, and its + * THREAD_SIZE alignment assumption fails for non-vmapped IRQ stacks. + * Conservatively avoid walking IRQ stacks in every configuration. + */ + pc = instruction_pointer(regs); + if (__kernel_text_address(pc)) + perf_callchain_store(entry, pc); + + return true; +} + +unsigned long riscv_perf_out_copy_user(void *dst, const void *src, + unsigned long n) +{ + unsigned long addr = (unsigned long)src; + unsigned long copied = 0; + + /* Keep the generic fast path unchanged outside an SSE handler. */ + if (!riscv_sse_get_interrupted_context()) { + unsigned long ret; + + pagefault_disable(); + ret = __copy_from_user_inatomic(dst, src, n); + pagefault_enable(); + return ret; + } + + if (!access_ok(src, n)) + return n; + + /* Do not sample user memory through an unrelated active page table. */ + if (!current->mm || + (csr_read(CSR_SATP) & SATP_PPN) != virt_to_pfn(current->mm->pgd)) + return n; + + while (copied < n) { + unsigned long offset = offset_in_page(addr); + unsigned long chunk = min(n - copied, PAGE_SIZE - offset); + struct page *page; + + /* + * Fast-only GUP cannot fault. This follows perf_virt_to_phys(): + * local interrupts remain disabled throughout SSE processing, so a + * concurrent unmap cannot complete its TLB teardown before this + * temporary reference is put. + */ + if (!get_user_page_fast_only(addr, 0, &page)) + break; + + memcpy((char *)dst + copied, + (char *)page_address(page) + offset, chunk); + put_page(page); + addr += chunk; + copied += chunk; + } + + return n - copied; +} +#endif + /* * This will be called when the target is in user mode * This function will only be called when we use @@ -28,6 +156,15 @@ static bool fill_callchain(void *entry, unsigned long pc) void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { +#ifdef CONFIG_RISCV_SBI_SSE + const struct riscv_sse_interrupted_context *context; + + context = riscv_sse_get_interrupted_context(); + /* A guest stack cannot be walked using the host address space. */ + if (sse_callchain_is_guest(context)) + return; +#endif + if (perf_guest_state()) { /* TODO: We don't support guest os callchain now */ return; @@ -39,6 +176,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { +#ifdef CONFIG_RISCV_SBI_SSE + if (sse_callchain_kernel(entry, regs)) + return; +#endif + if (perf_guest_state()) { /* TODO: We don't support guest os callchain now */ return; -- 2.43.0