From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 539593AE6FA for ; Fri, 6 Mar 2026 14:35:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807755; cv=none; b=KY5Pd2ArfZDG9WWg81Uo6DA8/008RbD9gydde/L8jdKmzYnc+HJjb2xS3cUI6af/F5E5LK3TnrmUV5190eLmXnA+P+aZKYvo/kxWyUs9L8UztngfWOHhazg2uhBZM+Z/lknS+QmOiwWLUzBsIkJgASHxsbQdJ385H4HPMBdo9j0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807755; c=relaxed/simple; bh=Hz/rHu9p9uFE73JluB0dAIuM1LGGVJBibGRScbVoAfE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qGIkTNnVhrD5cI6ZQHjpTz+Q5yjWARF+wx+EPIlItL+mUI4YVeUqqycjslhTaypKM6qby4FFTg9sK2xTByqkSMSO3AlDOnLdaY9R/KGmi9uZUO6mCDdHy8IesJoiGpvl1NbSLYp5VlxjaA+hAv+LObD+9Te+WSP/6XDUWPlGxTI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KMDqRpwW; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KMDqRpwW" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4839fc4cef6so93268085e9.0 for ; Fri, 06 Mar 2026 06:35:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807753; x=1773412553; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/Q6YHflryAt4GuwVgZW5CjVF0OSLajguucPNlc9fXbU=; b=KMDqRpwWmuOWz1wjbwaBXWH1WxI/ZqLp0MMSQlKTkVuPgspCH01ad/d5mxuV8ILoyc II751UmB/xLgBjFv+nloagl4T26Covr2lXpFwVyKlnBa69UWYQxTW1pnK3pS7g3BvXoC dbaPq9pN7yr+MAotb8N+/BadF/QgLZecETBGNymUk92YUE9+Pa5GrV7laWbg0PqvreAf WqlgzXA0N+fzxPwTu5+HhyVXyROIu7IRvzHw7UhBAQOuQaM1i5Wzcpr+OLqvLG8Gmuh+ h42RmCz3qcA7kEkK+YTKbMtwnAh74cNdFlGJCA056hcG5A5am5UrH0oYObYl6zOyl1Db AseA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807753; x=1773412553; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/Q6YHflryAt4GuwVgZW5CjVF0OSLajguucPNlc9fXbU=; b=MlQBbqXNvt5ERcQTFWkfuQ6XGLM2WU+4QlbRjV1xljQhAhw4efzWBuUStfxi80xg62 /1sZkNhS3AY1U2k8SwT82LVbDv+vSJVMRiZgcubMTTSxYLO6B+3e8n6HcrWdr+TGezRW C/YhdEQ9c2Nh6h/VeYaWqFxATkEJSm1a1exwcD+nAtCJER12hafLPWvhy8s1FaXR5TDR 0aKo3Sncuruj2cwP6EpIE9X7AqWXIvQwzBgdPcnNLsUZtzVyKQ8Sz3isQgTBFGztu9Ga cyajFGiUI8EMp2/S3DCisKNpHHc4tbGBuaMG0w/WfWUtMcnOcuyNC5vcLzMnehYqwk6+ PNIQ== X-Forwarded-Encrypted: i=1; AJvYcCV4TM0dJmm9jARzHwNb93tCsPm/3fYxnBqshg8UeA2qaTScU0D5UxMIsvkUu4gaZ6xyJuSzHUgZySfwRlc=@vger.kernel.org X-Gm-Message-State: AOJu0Yx0tZfFfHRJKQKHT1r9P+7F8QFqS6uvIBjygJ9N1hgwNB1KyiOI mhlNtcLQtfmcyH77H6AStymBEiXvhMlSCZn145/CVzL9ikcZw4Vt6WJ5RE0OyHqZb8bW6ALzTTS 6t40v6fJTV5Tor05VnPD0Uw== X-Received: from wmpg39.prod.google.com ([2002:a05:600c:4ca7:b0:483:8ade:6472]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:64c7:b0:47e:e59c:67c5 with SMTP id 5b1f17b1804b1-4852671d9c3mr34583765e9.8.1772807752682; Fri, 06 Mar 2026 06:35:52 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:05 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-2-vdonnefort@google.com> Subject: [PATCH v13 01/32] ring-buffer: Add page statistics to the meta-page From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add two fields pages_touched and pages_lost to the ring-buffer meta-page. Those fields are useful to get the number of used pages in the ring-buffer. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/uapi/linux/trace_mmap.h b/include/uapi/linux/trace_mma= p.h index c102ef35d11e..e8185889a1c8 100644 --- a/include/uapi/linux/trace_mmap.h +++ b/include/uapi/linux/trace_mmap.h @@ -17,8 +17,8 @@ * @entries: Number of entries in the ring-buffer. * @overrun: Number of entries lost in the ring-buffer. * @read: Number of entries that have been read. - * @Reserved1: Internal use only. - * @Reserved2: Internal use only. + * @pages_lost: Number of pages overwritten by the writer. + * @pages_touched: Number of pages written by the writer. */ struct trace_buffer_meta { __u32 meta_page_size; @@ -39,8 +39,8 @@ struct trace_buffer_meta { __u64 overrun; __u64 read; =20 - __u64 Reserved1; - __u64 Reserved2; + __u64 pages_lost; + __u64 pages_touched; }; =20 #define TRACE_MMAP_IOCTL_GET_READER _IO('R', 0x20) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index f16f053ef77d..1b8be41faa78 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -6154,6 +6154,8 @@ static void rb_update_meta_page(struct ring_buffer_pe= r_cpu *cpu_buffer) meta->entries =3D local_read(&cpu_buffer->entries); meta->overrun =3D local_read(&cpu_buffer->overrun); meta->read =3D cpu_buffer->read; + meta->pages_lost =3D local_read(&cpu_buffer->pages_lost); + meta->pages_touched =3D local_read(&cpu_buffer->pages_touched); =20 /* Some archs do not have data cache coherency between kernel and user-sp= ace */ flush_kernel_vmap_range(cpu_buffer->meta_page, PAGE_SIZE); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B1E303AE709 for ; Fri, 6 Mar 2026 14:35:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807757; cv=none; b=Sv9kdqcFB86NdDfWpWtlZyt0L+Feg8n0pAeYpwNCPw5ECbp+6nIiV6Tpyek4/PeH7KhEPirw1vxc1O+BDoC76CV4zwHAUijeAfKk4Q8xFuAc6FM0+sqzQQjL/yIIbifOvY09PODFIxbRpYY6dazHrmgh/HKhxUwgGRQwsuBmFJ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807757; c=relaxed/simple; bh=boc/4d3DKHVDTv6LY/mfgI2uhQ4fDoqeAnOqtQ703cY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ab/47NxEtJUFkd8vUbOmVLfM7cDOlLbxYrRrjUaEQcb0g8DwI7B12wjzLZFgV/LQHtsEboTm7xV5CDEGnAHO6UbB9ZZQOiNGCpIx14qUksEvC8gQ3/YGXSIg8oP9d9fF3L5IqFLKYNYiK6+jlhGCzthLz24pyHdha7T3sC5/EVg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=QsRPWM71; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="QsRPWM71" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-439da07c5bfso759417f8f.1 for ; Fri, 06 Mar 2026 06:35:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807754; x=1773412554; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3Jbx9+EVK6y4U1OT7nCohIUASMhFn/GxeOgFoW/iLRw=; b=QsRPWM710yAJ8jnvtv3QfveiUmtO9znO1M91J3KtlnSV2bJqtlPJqVkSzzjhSFxiNa OCa48h9q3k+4eoyYOpkNfMERzqYlwlWP786bCBf6BbX6xfMbJyHkX2wTVj4JaAop7T+x QY968X1rIoOXfhhtwQov30JBsGXk1DhSw2RcfAMYd30Yr6U5iaEN4xqKh+c9op/re+LI aEzhdAUg79MhqmF9VzFl/hu5lgXJt5Jr5AxrKXGNZgxovjPxDx4qVnBaH7WMHIussV1t KYPZr2D0/stGdLK9gj3wRfFhFVesVup4AHLobqRW+wUElHaCgnqxjAZ0s2xY/lCQFZiq jZ9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807754; x=1773412554; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3Jbx9+EVK6y4U1OT7nCohIUASMhFn/GxeOgFoW/iLRw=; b=KCe+Y45axI3OGDzYtyrAlOB7zHRhATcWjw4wqG5LyXO1tepkRKk/xFgEGsGcpxLSSv 6V9rwvpIozdl+JOh8saB4h2PbN8UWGhUuCnKdBAi5OetvaPUrAmXJwo+pK4yuVpfwp5D OxlO+DAtKtqOWZXj05B6KNJKaYd3H6pFL9UPBVu7YIOz3EIScnQnnuX3zVbdpqs/cJte GK4J/PLBvlbxTm/fwzD5JPc53+jIuwUF07EAC/l4fUfQlSHS6O0NmBLyBFqTOIlwhlFE dHur978mBbLG2HMconcnqgiySHVxf/rKcR2lHgK/8lg5oh2UFAmPx30+q5MoYybGL739 Yecw== X-Forwarded-Encrypted: i=1; AJvYcCW2Lvnu3ocXlZmt/g9vV+9JBlmuQUozqKbevedbDSkCRoF39xC2Slh1yqQIoxw61WX8kkGYUd9eidhPZM0=@vger.kernel.org X-Gm-Message-State: AOJu0YybTUb7TqFDOG3m2YjPeqjvO/VRbxkja8mC/mEgP3CFch9UywDI P9tc8aPVCpPJ/atRS1cgQe+EtT1atEjzW05jVBbrsLsEn7A461Mqvw8Ee4gmzvvrUdale3jIDiM RLJg0KueDLmP4MwOzimUXyA== X-Received: from wmbjt23.prod.google.com ([2002:a05:600c:5697:b0:483:2c43:9664]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3488:b0:47a:81b7:9a20 with SMTP id 5b1f17b1804b1-48526923bc7mr37026555e9.9.1772807753846; Fri, 06 Mar 2026 06:35:53 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:06 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-3-vdonnefort@google.com> Subject: [PATCH v13 02/32] ring-buffer: Store bpage pointers into subbuf_ids From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The subbuf_ids field allows to point to a specific page from the ring-buffer based on its ID. As a preparation or the upcoming ring-buffer remote support, point this array to the buffer_page instead of the buffer_data_page. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 1b8be41faa78..45ec49d6c81d 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -555,7 +555,7 @@ struct ring_buffer_per_cpu { unsigned int mapped; unsigned int user_mapped; /* user space mapping */ struct mutex mapping_lock; - unsigned long *subbuf_ids; /* ID to subbuf VA */ + struct buffer_page **subbuf_ids; /* ID to subbuf VA */ struct trace_buffer_meta *meta_page; struct ring_buffer_cpu_meta *ring_meta; =20 @@ -7036,7 +7036,7 @@ static void rb_free_meta_page(struct ring_buffer_per_= cpu *cpu_buffer) } =20 static void rb_setup_ids_meta_page(struct ring_buffer_per_cpu *cpu_buffer, - unsigned long *subbuf_ids) + struct buffer_page **subbuf_ids) { struct trace_buffer_meta *meta =3D cpu_buffer->meta_page; unsigned int nr_subbufs =3D cpu_buffer->nr_pages + 1; @@ -7045,7 +7045,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, int id =3D 0; =20 id =3D rb_page_id(cpu_buffer, cpu_buffer->reader_page, id); - subbuf_ids[id++] =3D (unsigned long)cpu_buffer->reader_page->page; + subbuf_ids[id++] =3D cpu_buffer->reader_page; cnt++; =20 first_subbuf =3D subbuf =3D rb_set_head_page(cpu_buffer); @@ -7055,7 +7055,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, if (WARN_ON(id >=3D nr_subbufs)) break; =20 - subbuf_ids[id] =3D (unsigned long)subbuf->page; + subbuf_ids[id] =3D subbuf; =20 rb_inc_page(&subbuf); id++; @@ -7064,7 +7064,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, =20 WARN_ON(cnt !=3D nr_subbufs); =20 - /* install subbuf ID to kern VA translation */ + /* install subbuf ID to bpage translation */ cpu_buffer->subbuf_ids =3D subbuf_ids; =20 meta->meta_struct_len =3D sizeof(*meta); @@ -7220,13 +7220,15 @@ static int __rb_map_vma(struct ring_buffer_per_cpu = *cpu_buffer, } =20 while (p < nr_pages) { + struct buffer_page *subbuf; struct page *page; int off =3D 0; =20 if (WARN_ON_ONCE(s >=3D nr_subbufs)) return -EINVAL; =20 - page =3D virt_to_page((void *)cpu_buffer->subbuf_ids[s]); + subbuf =3D cpu_buffer->subbuf_ids[s]; + page =3D virt_to_page((void *)subbuf->page); =20 for (; off < (1 << (subbuf_order)); off++, page++) { if (p >=3D nr_pages) @@ -7253,7 +7255,8 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, struct vm_area_struct *vma) { struct ring_buffer_per_cpu *cpu_buffer; - unsigned long flags, *subbuf_ids; + struct buffer_page **subbuf_ids; + unsigned long flags; int err; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) @@ -7277,7 +7280,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, if (err) return err; =20 - /* subbuf_ids include the reader while nr_pages does not */ + /* subbuf_ids includes the reader while nr_pages does not */ subbuf_ids =3D kcalloc(cpu_buffer->nr_pages + 1, sizeof(*subbuf_ids), GFP= _KERNEL); if (!subbuf_ids) { rb_free_meta_page(cpu_buffer); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1136F3B3BF5 for ; Fri, 6 Mar 2026 14:35:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807760; cv=none; b=IL04e65H8C85xJKWOO8O43XNrmUK78QQmUAA+HiX69URoSCWcL6F8vF/rkNNpVxlkLgoKi3lSJnATO9ATitm9EWGBlGrJ7y5XOkZ6pP/k+bS8LSabYuUuuF71oUgr/n2/XKNXof5iZwpoUgo/VihU1cpvjA6nAOVW10ADpJFb08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807760; c=relaxed/simple; bh=bnvoSeyxY+OXq8f/eSgSweGk60QbXyvXNRWO31ZiN5o=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=m9vqJcpmNgUDxlZqXP63A6XY4vVGBN2ilncAeUXY/crKgcCVEdLIN/8zlqqp1wvK7ZdwL83TGhts+nZcQdpoOi/lmEesXN0gvOW38Tj+sLQxCvAwjJCiMnVLrckZuSG3WzQ7MFlWQSp23QDtIUFge03WqFxEuFbTQildnP6sGbU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=yJox+NrQ; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="yJox+NrQ" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-439d74ebf89so1273911f8f.1 for ; Fri, 06 Mar 2026 06:35:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807755; x=1773412555; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=zlJAD5NNQRl2Mf7RSQLnzzKiQqc5ePERxgasohUjyi4=; b=yJox+NrQJNiyLMleO7cCX0dhqgf5r6CCnhVhKm5qq8nTKFynUUoDu5Mob2bzRoq8PF FZaF22oLpQs/zQ8cHHcC9MnzBNN0Kqcou4iQjPXgtrtzmGUxqrEAc+CTjDLnVluJkSV8 Vk0aLjvWYWucJLUGW9BaiZe4Lgu5FdNkcP8BfejqHUll8uElXf6JIN8ZGp8IlG4fLzu9 YMppX41ue0pmOMrH2WWZZLAbr+rzZKTjVqePWTwS81pMbOjFNm/pa2ASt1iHRBcu7D1w GaKfAmeUzbMq2mC0KUrT4tMAi3lH+VpIzFvhQ8NANWGfJPj9lQJ5Jkn1uM0y66XLz1m7 UfUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807755; x=1773412555; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zlJAD5NNQRl2Mf7RSQLnzzKiQqc5ePERxgasohUjyi4=; b=dSth1Vzww5Cr+7Gvgn3EQH41uC+V8cQtZSldamziTug/1TiRiKEZhFjUfQSfuWdlX1 bfvKx26hSBlymMBPb997Gy79CEkNWq81VBNWfBQLO2owop5VL0x4LPFKtNn55kndmP+f FT+nASaNmaRORGUvWrTTnnfdV2P32dLci9kCCgJnb43AHUd48oFY4uzPfsKZudABFLGe 6TeiJKo74yQkpaEzjLAL72Z9krv6xTMkPtdi8xxYj9KNFLNDp/r+8ViS2sq3DhudBCvj f7ytgym//iONEHxzY6RMwwDvwW1EnEPstj5flGWqFVtPGFqysEg70QweekwilzRE6M5e wQTA== X-Forwarded-Encrypted: i=1; AJvYcCWlTEvQnRUxFZJmz4o9UdofLTZa0cxQPzSNUCpt7are5OqUrOKhd97XRIGOiNBvUjVlVrCoEgSk9S0s2l4=@vger.kernel.org X-Gm-Message-State: AOJu0YwNHjhIHc3xgZKzWAGqNbav//3Ml/+jLWPWtdIr2oBb4JfQzxfw bc39isA3PWG4srYuu00Ur1SiXMIbmV/Zr9U0K7OpTe/16PEb7hUlXvH/uorldlY9yALNuRtgKaE fk6+b+23nRU1tIx0dWYTaIg== X-Received: from wrbcc13.prod.google.com ([2002:a5d:5c0d:0:b0:439:d755:aa7b]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2313:b0:439:cbb6:39cb with SMTP id ffacd0b85a97d-439da35ca26mr4535196f8f.24.1772807755204; Fri, 06 Mar 2026 06:35:55 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:07 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-4-vdonnefort@google.com> Subject: [PATCH v13 03/32] ring-buffer: Introduce ring-buffer remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A ring-buffer remote is an entity outside of the kernel (most likely a firmware or a hypervisor) capable of writing events in a ring-buffer following the same format as the tracefs ring-buffer. To setup the ring-buffer on the kernel side, a description of the pages forming the ring-buffer (struct trace_buffer_desc) must be given. Callbacks (swap_reader_page and reset) must also be provided. It is expected from the remote to keep the meta-page updated. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 876358cfe1b1..41193c5b0d28 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -250,4 +250,62 @@ int ring_buffer_map(struct trace_buffer *buffer, int c= pu, struct vm_area_struct *vma); int ring_buffer_unmap(struct trace_buffer *buffer, int cpu); int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu); + +struct ring_buffer_desc { + int cpu; + unsigned int nr_page_va; /* excludes the meta page */ + unsigned long meta_va; + unsigned long page_va[] __counted_by(nr_page_va); +}; + +struct trace_buffer_desc { + int nr_cpus; + size_t struct_len; + char __data[]; /* list of ring_buffer_desc */ +}; + +static inline struct ring_buffer_desc *__next_ring_buffer_desc(struct ring= _buffer_desc *desc) +{ + size_t len =3D struct_size(desc, page_va, desc->nr_page_va); + + return (struct ring_buffer_desc *)((void *)desc + len); +} + +static inline struct ring_buffer_desc *__first_ring_buffer_desc(struct tra= ce_buffer_desc *desc) +{ + return (struct ring_buffer_desc *)(&desc->__data[0]); +} + +static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned i= nt nr_cpus) +{ + unsigned int nr_pages =3D max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) = + 1; + struct ring_buffer_desc *rbdesc; + + return size_add(offsetof(struct trace_buffer_desc, __data), + size_mul(nr_cpus, struct_size(rbdesc, page_va, nr_pages))); +} + +#define for_each_ring_buffer_desc(__pdesc, __cpu, __trace_pdesc) \ + for (__pdesc =3D __first_ring_buffer_desc(__trace_pdesc), __cpu =3D 0; \ + (__cpu) < (__trace_pdesc)->nr_cpus; \ + (__cpu)++, __pdesc =3D __next_ring_buffer_desc(__pdesc)) + +struct ring_buffer_remote { + struct trace_buffer_desc *desc; + int (*swap_reader_page)(unsigned int cpu, void *priv); + int (*reset)(unsigned int cpu, void *priv); + void *priv; +}; + +int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu); + +struct trace_buffer * +__ring_buffer_alloc_remote(struct ring_buffer_remote *remote, + struct lock_class_key *key); + +#define ring_buffer_alloc_remote(remote) \ +({ \ + static struct lock_class_key __key; \ + __ring_buffer_alloc_remote(remote, &__key); \ +}) #endif /* _LINUX_RING_BUFFER_H */ diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 45ec49d6c81d..da0cd8e82105 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -559,6 +559,8 @@ struct ring_buffer_per_cpu { struct trace_buffer_meta *meta_page; struct ring_buffer_cpu_meta *ring_meta; =20 + struct ring_buffer_remote *remote; + /* ring buffer pages to update, > 0 to add, < 0 to remove */ long nr_pages_to_update; struct list_head new_pages; /* new pages to add */ @@ -581,6 +583,8 @@ struct trace_buffer { =20 struct ring_buffer_per_cpu **buffers; =20 + struct ring_buffer_remote *remote; + struct hlist_node node; u64 (*clock)(void); =20 @@ -2238,6 +2242,40 @@ static void rb_meta_buffer_update(struct ring_buffer= _per_cpu *cpu_buffer, } } =20 +static struct ring_buffer_desc *ring_buffer_desc(struct trace_buffer_desc = *trace_desc, int cpu) +{ + struct ring_buffer_desc *desc, *end; + size_t len; + int i; + + if (!trace_desc) + return NULL; + + if (cpu >=3D trace_desc->nr_cpus) + return NULL; + + end =3D (struct ring_buffer_desc *)((void *)trace_desc + trace_desc->stru= ct_len); + desc =3D __first_ring_buffer_desc(trace_desc); + len =3D struct_size(desc, page_va, desc->nr_page_va); + desc =3D (struct ring_buffer_desc *)((void *)desc + (len * cpu)); + + if (desc < end && desc->cpu =3D=3D cpu) + return desc; + + /* Missing CPUs, need to linear search */ + for_each_ring_buffer_desc(desc, i, trace_desc) { + if (desc->cpu =3D=3D cpu) + return desc; + } + + return NULL; +} + +static void *ring_buffer_desc_page(struct ring_buffer_desc *desc, int page= _id) +{ + return page_id > desc->nr_page_va ? NULL : (void *)desc->page_va[page_id]; +} + static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, long nr_pages, struct list_head *pages) { @@ -2245,6 +2283,7 @@ static int __rb_allocate_pages(struct ring_buffer_per= _cpu *cpu_buffer, struct ring_buffer_cpu_meta *meta =3D NULL; struct buffer_page *bpage, *tmp; bool user_thread =3D current->mm !=3D NULL; + struct ring_buffer_desc *desc =3D NULL; long i; =20 /* @@ -2273,6 +2312,12 @@ static int __rb_allocate_pages(struct ring_buffer_pe= r_cpu *cpu_buffer, if (buffer->range_addr_start) meta =3D rb_range_meta(buffer, nr_pages, cpu_buffer->cpu); =20 + if (buffer->remote) { + desc =3D ring_buffer_desc(buffer->remote->desc, cpu_buffer->cpu); + if (!desc || WARN_ON(desc->nr_page_va !=3D (nr_pages + 1))) + return -EINVAL; + } + for (i =3D 0; i < nr_pages; i++) { =20 bpage =3D alloc_cpu_page(cpu_buffer->cpu); @@ -2297,6 +2342,16 @@ static int __rb_allocate_pages(struct ring_buffer_pe= r_cpu *cpu_buffer, rb_meta_buffer_update(cpu_buffer, bpage); bpage->range =3D 1; bpage->id =3D i + 1; + } else if (desc) { + void *p =3D ring_buffer_desc_page(desc, i + 1); + + if (WARN_ON(!p)) + goto free_pages; + + bpage->page =3D p; + bpage->range =3D 1; /* bpage->page can't be freed */ + bpage->id =3D i + 1; + cpu_buffer->subbuf_ids[i + 1] =3D bpage; } else { int order =3D cpu_buffer->buffer->subbuf_order; bpage->page =3D alloc_cpu_data(cpu_buffer->cpu, order); @@ -2394,6 +2449,30 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, = long nr_pages, int cpu) if (cpu_buffer->ring_meta->head_buffer) rb_meta_buffer_update(cpu_buffer, bpage); bpage->range =3D 1; + } else if (buffer->remote) { + struct ring_buffer_desc *desc =3D ring_buffer_desc(buffer->remote->desc,= cpu); + + if (!desc) + goto fail_free_reader; + + cpu_buffer->remote =3D buffer->remote; + cpu_buffer->meta_page =3D (struct trace_buffer_meta *)(void *)desc->meta= _va; + cpu_buffer->nr_pages =3D nr_pages; + cpu_buffer->subbuf_ids =3D kcalloc(cpu_buffer->nr_pages + 1, + sizeof(*cpu_buffer->subbuf_ids), GFP_KERNEL); + if (!cpu_buffer->subbuf_ids) + goto fail_free_reader; + + /* Remote buffers are read-only and immutable */ + atomic_inc(&cpu_buffer->record_disabled); + atomic_inc(&cpu_buffer->resize_disabled); + + bpage->page =3D ring_buffer_desc_page(desc, cpu_buffer->meta_page->reade= r.id); + if (!bpage->page) + goto fail_free_reader; + + bpage->range =3D 1; + cpu_buffer->subbuf_ids[0] =3D bpage; } else { int order =3D cpu_buffer->buffer->subbuf_order; bpage->page =3D alloc_cpu_data(cpu, order); @@ -2453,6 +2532,9 @@ static void rb_free_cpu_buffer(struct ring_buffer_per= _cpu *cpu_buffer) =20 irq_work_sync(&cpu_buffer->irq_work.work); =20 + if (cpu_buffer->remote) + kfree(cpu_buffer->subbuf_ids); + free_buffer_page(cpu_buffer->reader_page); =20 if (head) { @@ -2475,7 +2557,8 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, int order, unsigned long start, unsigned long end, unsigned long scratch_size, - struct lock_class_key *key) + struct lock_class_key *key, + struct ring_buffer_remote *remote) { struct trace_buffer *buffer __free(kfree) =3D NULL; long nr_pages; @@ -2515,6 +2598,8 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, if (!buffer->buffers) goto fail_free_cpumask; =20 + cpu =3D raw_smp_processor_id(); + /* If start/end are specified, then that overrides size */ if (start && end) { unsigned long buffers_start; @@ -2570,6 +2655,15 @@ static struct trace_buffer *alloc_buffer(unsigned lo= ng size, unsigned flags, buffer->range_addr_end =3D end; =20 rb_range_meta_init(buffer, nr_pages, scratch_size); + } else if (remote) { + struct ring_buffer_desc *desc =3D ring_buffer_desc(remote->desc, cpu); + + buffer->remote =3D remote; + /* The writer is remote. This ring-buffer is read-only */ + atomic_inc(&buffer->record_disabled); + nr_pages =3D desc->nr_page_va - 1; + if (nr_pages < 2) + goto fail_free_buffers; } else { =20 /* need at least two pages */ @@ -2578,7 +2672,6 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, nr_pages =3D 2; } =20 - cpu =3D raw_smp_processor_id(); cpumask_set_cpu(cpu, buffer->cpumask); buffer->buffers[cpu] =3D rb_allocate_cpu_buffer(buffer, nr_pages, cpu); if (!buffer->buffers[cpu]) @@ -2620,7 +2713,7 @@ struct trace_buffer *__ring_buffer_alloc(unsigned lon= g size, unsigned flags, struct lock_class_key *key) { /* Default buffer page size - one system page */ - return alloc_buffer(size, flags, 0, 0, 0, 0, key); + return alloc_buffer(size, flags, 0, 0, 0, 0, key, NULL); =20 } EXPORT_SYMBOL_GPL(__ring_buffer_alloc); @@ -2647,7 +2740,18 @@ struct trace_buffer *__ring_buffer_alloc_range(unsig= ned long size, unsigned flag struct lock_class_key *key) { return alloc_buffer(size, flags, order, start, start + range_size, - scratch_size, key); + scratch_size, key, NULL); +} + +/** + * __ring_buffer_alloc_remote - allocate a new ring_buffer from a remote + * @remote: Contains a description of the ring-buffer pages and remote cal= lbacks. + * @key: ring buffer reader_lock_key. + */ +struct trace_buffer *__ring_buffer_alloc_remote(struct ring_buffer_remote = *remote, + struct lock_class_key *key) +{ + return alloc_buffer(0, 0, 0, 0, 0, 0, key, remote); } =20 void *ring_buffer_meta_scratch(struct trace_buffer *buffer, unsigned int *= size) @@ -5274,6 +5378,16 @@ unsigned long ring_buffer_overruns(struct trace_buff= er *buffer) } EXPORT_SYMBOL_GPL(ring_buffer_overruns); =20 +static bool rb_read_remote_meta_page(struct ring_buffer_per_cpu *cpu_buffe= r) +{ + local_set(&cpu_buffer->entries, READ_ONCE(cpu_buffer->meta_page->entries)= ); + local_set(&cpu_buffer->overrun, READ_ONCE(cpu_buffer->meta_page->overrun)= ); + local_set(&cpu_buffer->pages_touched, READ_ONCE(cpu_buffer->meta_page->pa= ges_touched)); + local_set(&cpu_buffer->pages_lost, READ_ONCE(cpu_buffer->meta_page->pages= _lost)); + + return rb_num_of_entries(cpu_buffer); +} + static void rb_iter_reset(struct ring_buffer_iter *iter) { struct ring_buffer_per_cpu *cpu_buffer =3D iter->cpu_buffer; @@ -5428,7 +5542,43 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *i= ter, } =20 static struct buffer_page * -rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +__rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer) +{ + struct buffer_page *new_reader, *prev_reader; + + if (!rb_read_remote_meta_page(cpu_buffer)) + return NULL; + + /* More to read on the reader page */ + if (cpu_buffer->reader_page->read < rb_page_size(cpu_buffer->reader_page)= ) { + if (!cpu_buffer->reader_page->read) + cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + return cpu_buffer->reader_page; + } + + prev_reader =3D cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id]; + + WARN_ON_ONCE(cpu_buffer->remote->swap_reader_page(cpu_buffer->cpu, + cpu_buffer->remote->priv)); + /* nr_pages doesn't include the reader page */ + if (WARN_ON_ONCE(cpu_buffer->meta_page->reader.id > cpu_buffer->nr_pages)) + return NULL; + + new_reader =3D cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id]; + + WARN_ON_ONCE(prev_reader =3D=3D new_reader); + + cpu_buffer->reader_page->page =3D new_reader->page; + cpu_buffer->reader_page->id =3D new_reader->id; + cpu_buffer->reader_page->read =3D 0; + cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + cpu_buffer->lost_events =3D cpu_buffer->meta_page->reader.lost_events; + + return rb_page_size(cpu_buffer->reader_page) ? cpu_buffer->reader_page : = NULL; +} + +static struct buffer_page * +__rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) { struct buffer_page *reader =3D NULL; unsigned long bsize =3D READ_ONCE(cpu_buffer->buffer->subbuf_size); @@ -5598,6 +5748,13 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_b= uffer) return reader; } =20 +static struct buffer_page * +rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +{ + return cpu_buffer->remote ? __rb_get_reader_page_from_remote(cpu_buffer) : + __rb_get_reader_page(cpu_buffer); +} + static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) { struct ring_buffer_event *event; @@ -5998,7 +6155,7 @@ ring_buffer_read_start(struct trace_buffer *buffer, i= nt cpu, gfp_t flags) struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_iter *iter; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask)) + if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) return NULL; =20 iter =3D kzalloc_obj(*iter, flags); @@ -6166,6 +6323,23 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) { struct buffer_page *page; =20 + if (cpu_buffer->remote) { + if (!cpu_buffer->remote->reset) + return; + + cpu_buffer->remote->reset(cpu_buffer->cpu, cpu_buffer->remote->priv); + rb_read_remote_meta_page(cpu_buffer); + + /* Read related values, not covered by the meta-page */ + local_set(&cpu_buffer->pages_read, 0); + cpu_buffer->read =3D 0; + cpu_buffer->read_bytes =3D 0; + cpu_buffer->last_overrun =3D 0; + cpu_buffer->reader_page->read =3D 0; + + return; + } + rb_head_page_deactivate(cpu_buffer); =20 cpu_buffer->head_page @@ -6396,6 +6570,48 @@ bool ring_buffer_empty_cpu(struct trace_buffer *buff= er, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu); =20 +int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return -EINVAL; + + cpu_buffer =3D buffer->buffers[cpu]; + + guard(raw_spinlock)(&cpu_buffer->reader_lock); + if (rb_read_remote_meta_page(cpu_buffer)) + rb_wakeups(buffer, cpu_buffer); + + return 0; + } + + cpus_read_lock(); + + /* + * Make sure all the ring buffers are up to date before we start reading + * them. + */ + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer =3D buffer->buffers[cpu]; + + guard(raw_spinlock)(&cpu_buffer->reader_lock); + rb_read_remote_meta_page(cpu_buffer); + } + + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer =3D buffer->buffers[cpu]; + + if (rb_num_of_entries(cpu_buffer)) + rb_wakeups(buffer, cpu_buffer); + } + + cpus_read_unlock(); + + return 0; +} + #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP /** * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers @@ -6634,6 +6850,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, unsigned int commit; unsigned int read; u64 save_timestamp; + bool force_memcpy; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) return -1; @@ -6671,6 +6888,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer, /* Check if any events were dropped */ missed_events =3D cpu_buffer->lost_events; =20 + force_memcpy =3D cpu_buffer->mapped || cpu_buffer->remote; + /* * If this page has been partially read or * if len is not big enough to read the rest of the page or @@ -6680,7 +6899,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, */ if (read || (len < (commit - read)) || cpu_buffer->reader_page =3D=3D cpu_buffer->commit_page || - cpu_buffer->mapped) { + force_memcpy) { struct buffer_data_page *rpage =3D cpu_buffer->reader_page->page; unsigned int rpos =3D read; unsigned int pos =3D 0; @@ -7259,7 +7478,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, unsigned long flags; int err; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask)) + if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) return -EINVAL; =20 cpu_buffer =3D buffer->buffers[cpu]; --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E52153B4E91 for ; Fri, 6 Mar 2026 14:35:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807759; cv=none; b=HjhGUoQugDJZay4yw4Tk+ZKrCcV/JsMLiVs/lCwViODpQsS0UmOrDiHNfpljbCok4KFdPo6gh7k6MDsrCawkgSmdA6hRlIzp8FK5B5vdsEkfEP8SN7bJcLG45+b+mfevMOsNNYoNX7TOXMtq1dVW3sr57nHSNDVepQn/LjRJ3tQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807759; c=relaxed/simple; bh=D4gaKwLVIIsxcpxTwTQ6S3QUNIVaidgJpeYUAPhqmYU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=MtTzValgT6wMM0y3qbNfr+bnD4YVP22eS4PQe269Ac9JLl8icUwtYRYm1wGszzclkmmeGd4iqbwlBnQLA5OUqTJQqbaMXO4A80BFf1A6O8+rx5YR5U9l9fw9J99p42yk1ILPfni9nM1R6Afg8dC3HcI3gUgEz0V2L8BsuY6sKXQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ch2LI+Y+; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ch2LI+Y+" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4836cc0b38eso96125015e9.2 for ; Fri, 06 Mar 2026 06:35:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807756; x=1773412556; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ScN1NtxqIf/BVWk6GfS8Edcv4lujSSl4suwU/Na612k=; b=Ch2LI+Y+HnP3z88K6jlBj9CLljZwbW0A9De3o0S0mWinLq3HaPyDd5HGVh1EqkKKVv 22BJy0TQCLcIUiyNrpHmuU4TAG+t5aqwcYmCfRP35wNA3ZuSjNxKp5MWJdCG+jGJ+YN7 HOIflqy2oCUzFUMB5vSwSIEo8SQrB0UMNpY6/1E+EO95relzR/wGNjGDfZZ7pOf55Uq3 zDCHQiUWZUUsLBA802pOKemyxWM5C3UJNTQD3d/T5aGoAMV7yjS5ZLd3oEHQzEfBqwvK TBzgEud2NDeKptmr/EKYfsmXc2ghvQ6M7a35BBDopW/o1uSMxPBwqzmPE6oUDbgh9KGu A5UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807756; x=1773412556; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ScN1NtxqIf/BVWk6GfS8Edcv4lujSSl4suwU/Na612k=; b=oN27f+J6fqd0x4gE3WkV2ZjgynHPtASL3N5FXDiqfcArWqFxuPsDTDA3hNzy8w1n72 tXqNLTGS4WYm5NE0MDH+XP6MmTZmSR9I7P0BASvgwiSZEZp0ZfIpM6hiO0cxqjj0uWY1 fr8ixS55m2EHeW1Gv+YSgsCvLvWuMvRFENv9XP4SuN0jqePti9lLkLAGCvxk7RG/XXb7 pJh9SAfsT60KCdmprDBWr4zt+2eUoXI+oa80emUNhX8iGB43TlxVRHIeYJGcz32zSHJf n2Xw+ODE2osya3aehFIzJbGlgU2Yz0nOCPFuc5yqn4oRwQIVLLH5T079WsGdL2OCykzB SiHw== X-Forwarded-Encrypted: i=1; AJvYcCWJ3IwJ0OHGyX0chQz6JkYyRDd+wg+1AUvBSQr97mtNZ5cTSwJLzkOD0R4fCE6OFXoY8Pdr8lsuYBkR4ko=@vger.kernel.org X-Gm-Message-State: AOJu0YxiAdqRA4oIj4jv/AtAsIQbhNeGlIdF8iju3WYFbx1k3ZpM2LkW vMC7p6InTwy0WUl+Xsv3/WUDkqoZvDN0U79J43Nhfw7U5xKy6+P6HQITWgZK19UB0YJFgmFKuIX 1PMG+Yxfx7o5GYvDB7syMjg== X-Received: from wmcu23.prod.google.com ([2002:a7b:c057:0:b0:483:2758:404d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b5b:b0:46e:4e6d:79f4 with SMTP id 5b1f17b1804b1-48526927a4dmr39013355e9.15.1772807756248; Fri, 06 Mar 2026 06:35:56 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:08 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-5-vdonnefort@google.com> Subject: [PATCH v13 04/32] ring-buffer: Add non-consuming read for ring-buffer remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hopefully, the remote will only swap pages on the kernel instruction (via the swap_reader_page() callback). This means we know at what point the ring-buffer geometry has changed. It is therefore possible to rearrange the kernel view of that ring-buffer to allow non-consuming read. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index da0cd8e82105..115435f2e8b9 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5388,10 +5388,51 @@ static bool rb_read_remote_meta_page(struct ring_bu= ffer_per_cpu *cpu_buffer) return rb_num_of_entries(cpu_buffer); } =20 +static void rb_update_remote_head(struct ring_buffer_per_cpu *cpu_buffer) +{ + struct buffer_page *next, *orig; + int retry =3D 3; + + orig =3D next =3D cpu_buffer->head_page; + rb_inc_page(&next); + + /* Run after the writer */ + while (cpu_buffer->head_page->page->time_stamp > next->page->time_stamp) { + rb_inc_page(&next); + + rb_list_head_clear(cpu_buffer->head_page->list.prev); + rb_inc_page(&cpu_buffer->head_page); + rb_set_list_to_head(cpu_buffer->head_page->list.prev); + + if (cpu_buffer->head_page =3D=3D orig) { + if (WARN_ON_ONCE(!(--retry))) + return; + } + } + + orig =3D cpu_buffer->commit_page =3D cpu_buffer->head_page; + retry =3D 3; + + while (cpu_buffer->commit_page->page->time_stamp < next->page->time_stamp= ) { + rb_inc_page(&next); + rb_inc_page(&cpu_buffer->commit_page); + + if (cpu_buffer->commit_page =3D=3D orig) { + if (WARN_ON_ONCE(!(--retry))) + return; + } + } +} + static void rb_iter_reset(struct ring_buffer_iter *iter) { struct ring_buffer_per_cpu *cpu_buffer =3D iter->cpu_buffer; =20 + if (cpu_buffer->remote) { + rb_read_remote_meta_page(cpu_buffer); + rb_update_remote_head(cpu_buffer); + } + /* Iterator usage is expected to have record disabled */ iter->head_page =3D cpu_buffer->reader_page; iter->head =3D cpu_buffer->reader_page->read; @@ -5544,7 +5585,7 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *it= er, static struct buffer_page * __rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer) { - struct buffer_page *new_reader, *prev_reader; + struct buffer_page *new_reader, *prev_reader, *prev_head, *new_head, *las= t; =20 if (!rb_read_remote_meta_page(cpu_buffer)) return NULL; @@ -5568,10 +5609,32 @@ __rb_get_reader_page_from_remote(struct ring_buffer= _per_cpu *cpu_buffer) =20 WARN_ON_ONCE(prev_reader =3D=3D new_reader); =20 - cpu_buffer->reader_page->page =3D new_reader->page; - cpu_buffer->reader_page->id =3D new_reader->id; - cpu_buffer->reader_page->read =3D 0; - cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + prev_head =3D new_reader; /* New reader was also the previous head */ + new_head =3D prev_head; + rb_inc_page(&new_head); + last =3D prev_head; + rb_dec_page(&last); + + /* Clear the old HEAD flag */ + rb_list_head_clear(cpu_buffer->head_page->list.prev); + + prev_reader->list.next =3D prev_head->list.next; + prev_reader->list.prev =3D prev_head->list.prev; + + /* Swap prev_reader with new_reader */ + last->list.next =3D &prev_reader->list; + new_head->list.prev =3D &prev_reader->list; + + new_reader->list.prev =3D &new_reader->list; + new_reader->list.next =3D &new_head->list; + + /* Reactivate the HEAD flag */ + rb_set_list_to_head(&last->list); + + cpu_buffer->head_page =3D new_head; + cpu_buffer->reader_page =3D new_reader; + cpu_buffer->pages =3D &new_head->list; + cpu_buffer->read_stamp =3D new_reader->page->time_stamp; cpu_buffer->lost_events =3D cpu_buffer->meta_page->reader.lost_events; =20 return rb_page_size(cpu_buffer->reader_page) ? cpu_buffer->reader_page : = NULL; @@ -6155,7 +6218,7 @@ ring_buffer_read_start(struct trace_buffer *buffer, i= nt cpu, gfp_t flags) struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_iter *iter; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) + if (!cpumask_test_cpu(cpu, buffer->cpumask)) return NULL; =20 iter =3D kzalloc_obj(*iter, flags); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-ed1-f74.google.com (mail-ed1-f74.google.com [209.85.208.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 337063B3BE2 for ; Fri, 6 Mar 2026 14:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807761; cv=none; b=sniM3hsX6aYbUnUXM1Za/ycVJ0kuvQk5DqLVG/4pV/+jqtqXtzT/XvuOh53Q880cSKXhaKFoc12LC6SnT6+ERySQMrFCy2SCTS8lpZDJqhzDsAgm+p2w4ePA5h/J9pEHu4gKrSgj3mCZrgUrgDNrR2CV2qXj/J6UtHR1IiSCLn0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807761; c=relaxed/simple; bh=ICoaYrorym2fgGYduOG9nA5svB1QGl/q7oSh3z5Zo8Y=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VH2VFZz5Hofr5HW0+TxfYv6VsAoAf10kTkCx5Xee3XHwW94J+NNZBK7VSlJGlLpt206ywXByEmJcezj0HDZhd/7RtkAQbXs99kLheE7Mt4/cJjbQZHLyAYLRVUUg09Eyjoo1xVENvpg2MkwXYTa+N7tLeTlfQv6jSpGzw0A9NXU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=d9GnIbbU; arc=none smtp.client-ip=209.85.208.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="d9GnIbbU" Received: by mail-ed1-f74.google.com with SMTP id 4fb4d7f45d1cf-6613f3c484aso2051440a12.3 for ; Fri, 06 Mar 2026 06:35:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807757; x=1773412557; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+y9NRc54RUDILj7SaXrGmAwbDsY+dgljpFmx2V6fIQs=; b=d9GnIbbUVu20d0uT3IW+hdGBsN4jZS86xoGRtIhkKFfbCWGwt8tORNmEYw0tN0a3+K OPUEmU2+PGT4bEgPYaR/TCqMM1AupuULOlt/6jdQiFnfBZ+XKhvTiWDaaae4xUI+/I/q uR2ONfcgXQ+ExqRBffb/HyJzolEWLw3W1fehbM9g6NQ/i6ld/WLl8duJXk22XrqE84Xt Fl8JP2Qc4qUpvgD8cu0q8ennMZ/3MTOySgxG4Y0v7NHpRAb/kVhUsY7LnUGTPSIS6rd6 mDhWx4dNqbrvdLuNq/RPv6auDUmc2/HOjkWD7vueTw97KkylblPK3I9Hhr9eM0uG9eDV Ep4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807757; x=1773412557; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+y9NRc54RUDILj7SaXrGmAwbDsY+dgljpFmx2V6fIQs=; b=msa1UhLX2aUpRsyqXEZncUs3qPVrU2qvYe5h/9Mqb05L825Dj3SZEsEK9jWzmgF33H q5lARc31nVwYNX5lDa3bbA5+Vdh5sS7nqO/pRUPhtpQob8LoqWeFBc2ERGOp1tGghPcS WXsjb5EXyZ4XdQOBzVfyilKTCtckt4R1FAtZ0xKaALAfiR3ch3O+tzvlwxY0ghReqrET scgj3gWA5IugHPSMU+uiELprVkXE1Ir9phPqXHOMbO9D10418LdDtHgmYyd1EpeEqUlG cY069H8+NAt2QZ3SXW2AUrSBNbEnB0kusRudOcYQ3HDPRCUJ1Wk5XBZ4tdOmHuwBr9dY jctQ== X-Forwarded-Encrypted: i=1; AJvYcCXwHoPfzOv9mX/iSvPNlY9YzhauaqgrELON4I04VJMX05H6MfxOa2wbboE57BNLRBYAxDQyONZLT8DsSGg=@vger.kernel.org X-Gm-Message-State: AOJu0Yzj9miSr1/jMbbOuGBQO33fsXXJiNHigxlEW13eWkvFxLKXTc2t P5wtIKzj2T2j4Fc3RFiEhEF6u2cfmxp4njP5VFVPz5zO+lIDum6+Mjvnxk8Ac+UYEkehoTLkObk P40U0XADcitNU1UmeXx2txQ== X-Received: from edgi5-n2.prod.google.com ([2002:a05:6402:a585:20b0:660:e0ce:15a3]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:27d3:b0:64b:5562:c8f4 with SMTP id 4fb4d7f45d1cf-6619d49a0e9mr1236909a12.7.1772807757410; Fri, 06 Mar 2026 06:35:57 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:09 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-6-vdonnefort@google.com> Subject: [PATCH v13 05/32] tracing: Introduce trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A trace remote relies on ring-buffer remotes to read and control compatible tracing buffers, written by entity such as firmware or hypervisor. Add a Tracefs directory remotes/ that contains all instances of trace remotes. Each instance follows the same hierarchy as any other to ease the support by existing user-space tools. This currently does not provide any event support, which will come later. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h new file mode 100644 index 000000000000..65b7e7b8267c --- /dev/null +++ b/include/linux/trace_remote.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_TRACE_REMOTE_H +#define _LINUX_TRACE_REMOTE_H + +#include + +/** + * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote + * @load_trace_buffer: Called before Tracefs accesses the trace buffer fo= r the first + * time. Must return a &trace_buffer_desc + * (most likely filled with trace_remote_alloc_buffer()) + * @unload_trace_buffer: + * Called once Tracefs has no use for the trace buffer + * (most likely call trace_remote_free_buffer()) + * @enable_tracing: Called on Tracefs tracing_on. It is expected from the + * remote to allow writing. + * @swap_reader_page: Called when Tracefs consumes a new page from a + * ring-buffer. It is expected from the remote to isolate a + * new reader-page from the @cpu ring-buffer. + */ +struct trace_remote_callbacks { + struct trace_buffer_desc *(*load_trace_buffer)(unsigned long size, void *= priv); + void (*unload_trace_buffer)(struct trace_buffer_desc *desc, void *priv); + int (*enable_tracing)(bool enable, void *priv); + int (*swap_reader_page)(unsigned int cpu, void *priv); +}; + +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv); + +int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_= size, size_t buffer_size, + const struct cpumask *cpumask); + +void trace_remote_free_buffer(struct trace_buffer_desc *desc); + +#endif diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 49de13cae428..384dd36c8e29 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1281,4 +1281,7 @@ config HIST_TRIGGERS_DEBUG =20 source "kernel/trace/rv/Kconfig" =20 +config TRACE_REMOTE + bool + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 04096c21d06b..318923ce39f5 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -128,4 +128,5 @@ obj-$(CONFIG_FPROBE_EVENTS) +=3D trace_fprobe.o obj-$(CONFIG_TRACEPOINT_BENCHMARK) +=3D trace_benchmark.o obj-$(CONFIG_RV) +=3D rv/ =20 +obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o libftrace-y :=3D ftrace.o diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 23de3719f495..bef491af8bce 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8576,7 +8576,7 @@ static struct dentry *tracing_dentry_percpu(struct tr= ace_array *tr, int cpu) return tr->percpu_dir; } =20 -static struct dentry * +struct dentry * trace_create_cpu_file(const char *name, umode_t mode, struct dentry *paren= t, void *data, long cpu, const struct file_operations *fops) { diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b8f3804586a0..d6af4405b341 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -689,6 +689,12 @@ struct dentry *trace_create_file(const char *name, struct dentry *parent, void *data, const struct file_operations *fops); +struct dentry *trace_create_cpu_file(const char *name, + umode_t mode, + struct dentry *parent, + void *data, + long cpu, + const struct file_operations *fops); =20 =20 /** diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c new file mode 100644 index 000000000000..8b06f730376e --- /dev/null +++ b/kernel/trace/trace_remote.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +#define TRACEFS_DIR "remotes" +#define TRACEFS_MODE_WRITE 0640 +#define TRACEFS_MODE_READ 0440 + +struct trace_remote_iterator { + struct trace_remote *remote; + struct trace_seq seq; + struct delayed_work poll_work; + unsigned long lost_events; + u64 ts; + int cpu; + int evt_cpu; +}; + +struct trace_remote { + struct trace_remote_callbacks *cbs; + void *priv; + struct trace_buffer *trace_buffer; + struct trace_buffer_desc *trace_buffer_desc; + unsigned long trace_buffer_size; + struct ring_buffer_remote rb_remote; + struct mutex lock; + unsigned int nr_readers; + unsigned int poll_ms; + bool tracing_on; +}; + +static bool trace_remote_loaded(struct trace_remote *remote) +{ + return !!remote->trace_buffer; +} + +static int trace_remote_load(struct trace_remote *remote) +{ + struct ring_buffer_remote *rb_remote =3D &remote->rb_remote; + struct trace_buffer_desc *desc; + + lockdep_assert_held(&remote->lock); + + if (trace_remote_loaded(remote)) + return 0; + + desc =3D remote->cbs->load_trace_buffer(remote->trace_buffer_size, remote= ->priv); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + rb_remote->desc =3D desc; + rb_remote->swap_reader_page =3D remote->cbs->swap_reader_page; + rb_remote->priv =3D remote->priv; + remote->trace_buffer =3D ring_buffer_alloc_remote(rb_remote); + if (!remote->trace_buffer) { + remote->cbs->unload_trace_buffer(desc, remote->priv); + return -ENOMEM; + } + + remote->trace_buffer_desc =3D desc; + + return 0; +} + +static void trace_remote_try_unload(struct trace_remote *remote) +{ + lockdep_assert_held(&remote->lock); + + if (!trace_remote_loaded(remote)) + return; + + /* The buffer is being read or writable */ + if (remote->nr_readers || remote->tracing_on) + return; + + /* The buffer has readable data */ + if (!ring_buffer_empty(remote->trace_buffer)) + return; + + ring_buffer_free(remote->trace_buffer); + remote->trace_buffer =3D NULL; + remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv); +} + +static int trace_remote_enable_tracing(struct trace_remote *remote) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (remote->tracing_on) + return 0; + + ret =3D trace_remote_load(remote); + if (ret) + return ret; + + ret =3D remote->cbs->enable_tracing(true, remote->priv); + if (ret) { + trace_remote_try_unload(remote); + return ret; + } + + remote->tracing_on =3D true; + + return 0; +} + +static int trace_remote_disable_tracing(struct trace_remote *remote) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (!remote->tracing_on) + return 0; + + ret =3D remote->cbs->enable_tracing(false, remote->priv); + if (ret) + return ret; + + ring_buffer_poll_remote(remote->trace_buffer, RING_BUFFER_ALL_CPUS); + remote->tracing_on =3D false; + trace_remote_try_unload(remote); + + return 0; +} + +static ssize_t +tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) +{ + struct trace_remote *remote =3D filp->private_data; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + ret =3D val ? trace_remote_enable_tracing(remote) : trace_remote_disable_= tracing(remote); + if (ret) + return ret; + + return cnt; +} +static int tracing_on_show(struct seq_file *s, void *unused) +{ + struct trace_remote *remote =3D s->private; + + seq_printf(s, "%d\n", remote->tracing_on); + + return 0; +} +DEFINE_SHOW_STORE_ATTRIBUTE(tracing_on); + +static ssize_t buffer_size_kb_write(struct file *filp, const char __user *= ubuf, size_t cnt, + loff_t *ppos) +{ + struct trace_remote *remote =3D filp->private_data; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + /* KiB to Bytes */ + if (!val || check_shl_overflow(val, 10, &val)) + return -EINVAL; + + guard(mutex)(&remote->lock); + + if (trace_remote_loaded(remote)) + return -EBUSY; + + remote->trace_buffer_size =3D val; + + return cnt; +} + +static int buffer_size_kb_show(struct seq_file *s, void *unused) +{ + struct trace_remote *remote =3D s->private; + + seq_printf(s, "%lu (%s)\n", remote->trace_buffer_size >> 10, + trace_remote_loaded(remote) ? "loaded" : "unloaded"); + + return 0; +} +DEFINE_SHOW_STORE_ATTRIBUTE(buffer_size_kb); + +static int trace_remote_get(struct trace_remote *remote, int cpu) +{ + int ret; + + if (remote->nr_readers =3D=3D UINT_MAX) + return -EBUSY; + + ret =3D trace_remote_load(remote); + if (ret) + return ret; + + remote->nr_readers++; + + return 0; +} + +static void trace_remote_put(struct trace_remote *remote) +{ + if (WARN_ON(!remote->nr_readers)) + return; + + remote->nr_readers--; + if (remote->nr_readers) + return; + + trace_remote_try_unload(remote); +} + +static void __poll_remote(struct work_struct *work) +{ + struct delayed_work *dwork =3D to_delayed_work(work); + struct trace_remote_iterator *iter; + + iter =3D container_of(dwork, struct trace_remote_iterator, poll_work); + ring_buffer_poll_remote(iter->remote->trace_buffer, iter->cpu); + schedule_delayed_work((struct delayed_work *)work, + msecs_to_jiffies(iter->remote->poll_ms)); +} + +static struct trace_remote_iterator *trace_remote_iter(struct trace_remote= *remote, int cpu) +{ + struct trace_remote_iterator *iter =3D NULL; + int ret; + + lockdep_assert_held(&remote->lock); + + + ret =3D trace_remote_get(remote, cpu); + if (ret) + return ERR_PTR(ret); + + /* Test the CPU */ + ret =3D ring_buffer_poll_remote(remote->trace_buffer, cpu); + if (ret) + goto err; + + iter =3D kzalloc_obj(*iter); + if (iter) { + iter->remote =3D remote; + iter->cpu =3D cpu; + trace_seq_init(&iter->seq); + INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); + schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_ms= )); + + return iter; + } + ret =3D -ENOMEM; + +err: + kfree(iter); + trace_remote_put(remote); + + return ERR_PTR(ret); +} + +static void trace_remote_iter_free(struct trace_remote_iterator *iter) +{ + struct trace_remote *remote; + + if (!iter) + return; + + remote =3D iter->remote; + + lockdep_assert_held(&remote->lock); + + kfree(iter); + trace_remote_put(remote); +} + +static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) +{ + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + int cpu =3D iter->cpu; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + if (ring_buffer_empty_cpu(trace_buffer, cpu)) + return false; + + if (!ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_events)) + return false; + + iter->evt_cpu =3D cpu; + return true; + } + + iter->ts =3D U64_MAX; + for_each_possible_cpu(cpu) { + unsigned long lost_events; + u64 ts; + + if (ring_buffer_empty_cpu(trace_buffer, cpu)) + continue; + + if (!ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events)) + continue; + + if (ts >=3D iter->ts) + continue; + + iter->ts =3D ts; + iter->evt_cpu =3D cpu; + iter->lost_events =3D lost_events; + } + + return iter->ts !=3D U64_MAX; +} + +static int trace_remote_iter_print_event(struct trace_remote_iterator *ite= r) +{ + unsigned long usecs_rem; + u64 ts =3D iter->ts; + + if (iter->lost_events) + trace_seq_printf(&iter->seq, "CPU:%d [LOST %lu EVENTS]\n", + iter->evt_cpu, iter->lost_events); + + do_div(ts, 1000); + usecs_rem =3D do_div(ts, USEC_PER_SEC); + + trace_seq_printf(&iter->seq, "[%03d]\t%5llu.%06lu: ", iter->evt_cpu, + ts, usecs_rem); + + return trace_seq_has_overflowed(&iter->seq) ? -EOVERFLOW : 0; +} + +static int trace_pipe_open(struct inode *inode, struct file *filp) +{ + struct trace_remote *remote =3D inode->i_private; + struct trace_remote_iterator *iter; + int cpu =3D RING_BUFFER_ALL_CPUS; + + if (inode->i_cdev) + cpu =3D (long)inode->i_cdev - 1; + + guard(mutex)(&remote->lock); + iter =3D trace_remote_iter(remote, cpu); + filp->private_data =3D iter; + + return IS_ERR(iter) ? PTR_ERR(iter) : 0; +} + +static int trace_pipe_release(struct inode *inode, struct file *filp) +{ + struct trace_remote_iterator *iter =3D filp->private_data; + struct trace_remote *remote =3D iter->remote; + + guard(mutex)(&remote->lock); + + trace_remote_iter_free(iter); + + return 0; +} + +static ssize_t trace_pipe_read(struct file *filp, char __user *ubuf, size_= t cnt, loff_t *ppos) +{ + struct trace_remote_iterator *iter =3D filp->private_data; + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + int ret; + +copy_to_user: + ret =3D trace_seq_to_user(&iter->seq, ubuf, cnt); + if (ret !=3D -EBUSY) + return ret; + + trace_seq_init(&iter->seq); + + ret =3D ring_buffer_wait(trace_buffer, iter->cpu, 0, NULL, NULL); + if (ret < 0) + return ret; + + while (trace_remote_iter_read_event(iter)) { + int prev_len =3D iter->seq.seq.len; + + if (trace_remote_iter_print_event(iter)) { + iter->seq.seq.len =3D prev_len; + break; + } + + ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + } + + goto copy_to_user; +} + +static const struct file_operations trace_pipe_fops =3D { + .open =3D trace_pipe_open, + .read =3D trace_pipe_read, + .release =3D trace_pipe_release, +}; + +static int trace_remote_init_tracefs(const char *name, struct trace_remote= *remote) +{ + struct dentry *remote_d, *percpu_d, *d; + static struct dentry *root; + static DEFINE_MUTEX(lock); + bool root_inited =3D false; + int cpu; + + guard(mutex)(&lock); + + if (!root) { + root =3D tracefs_create_dir(TRACEFS_DIR, NULL); + if (!root) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"\n"); + return -ENOMEM; + } + root_inited =3D true; + } + + remote_d =3D tracefs_create_dir(name, root); + if (!remote_d) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"%s/\n", name); + goto err; + } + + d =3D trace_create_file("tracing_on", TRACEFS_MODE_WRITE, remote_d, remot= e, &tracing_on_fops); + if (!d) + goto err; + + d =3D trace_create_file("buffer_size_kb", TRACEFS_MODE_WRITE, remote_d, r= emote, + &buffer_size_kb_fops); + if (!d) + goto err; + + d =3D trace_create_file("trace_pipe", TRACEFS_MODE_READ, remote_d, remote= , &trace_pipe_fops); + if (!d) + goto err; + + percpu_d =3D tracefs_create_dir("per_cpu", remote_d); + if (!percpu_d) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"%s/per_cpu/\n", name); + goto err; + } + + for_each_possible_cpu(cpu) { + struct dentry *cpu_d; + char cpu_name[16]; + + snprintf(cpu_name, sizeof(cpu_name), "cpu%d", cpu); + cpu_d =3D tracefs_create_dir(cpu_name, percpu_d); + if (!cpu_d) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"%s/percpu/cpu%d\n", + name, cpu); + goto err; + } + + d =3D trace_create_cpu_file("trace_pipe", TRACEFS_MODE_READ, cpu_d, remo= te, cpu, + &trace_pipe_fops); + if (!d) + goto err; + } + + return 0; + +err: + if (root_inited) { + tracefs_remove(root); + root =3D NULL; + } else { + tracefs_remove(remote_d); + } + + return -ENOMEM; +} + +/** + * trace_remote_register() - Register a Tracefs remote + * @name: Name of the remote, used for the Tracefs remotes/ directory. + * @cbs: Set of callbacks used to control the remote. + * @priv: Private data, passed to each callback from @cbs. + * @events: Array of events. &remote_event.name and &remote_event.id must = be + * filled by the caller. + * @nr_events: Number of events in the @events array. + * + * A trace remote is an entity, outside of the kernel (most likely firmwar= e or + * hypervisor) capable of writing events into a Tracefs compatible ring-bu= ffer. + * The kernel would then act as a reader. + * + * The registered remote will be found under the Tracefs directory + * remotes/. + * + * Return: 0 on success, negative error code on failure. + */ +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv) +{ + struct trace_remote *remote; + + remote =3D kzalloc_obj(*remote); + if (!remote) + return -ENOMEM; + + remote->cbs =3D cbs; + remote->priv =3D priv; + remote->trace_buffer_size =3D 7 << 10; + remote->poll_ms =3D 100; + mutex_init(&remote->lock); + + if (trace_remote_init_tracefs(name, remote)) { + kfree(remote); + return -ENOMEM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(trace_remote_register); + +/** + * trace_remote_free_buffer() - Free trace buffer allocated with trace_rem= ote_alloc_buffer() + * @desc: Descriptor of the per-CPU ring-buffers, originally filled by + * trace_remote_alloc_buffer() + * + * Most likely called from &trace_remote_callbacks.unload_trace_buffer. + */ +void trace_remote_free_buffer(struct trace_buffer_desc *desc) +{ + struct ring_buffer_desc *rb_desc; + int cpu; + + for_each_ring_buffer_desc(rb_desc, cpu, desc) { + unsigned int id; + + free_page(rb_desc->meta_va); + + for (id =3D 0; id < rb_desc->nr_page_va; id++) + free_page(rb_desc->page_va[id]); + } +} +EXPORT_SYMBOL_GPL(trace_remote_free_buffer); + +/** + * trace_remote_alloc_buffer() - Dynamically allocate a trace buffer + * @desc: Uninitialized trace_buffer_desc + * @desc_size: Size of the trace_buffer_desc. Must be at least equal to + * trace_buffer_desc_size() + * @buffer_size: Size in bytes of each per-CPU ring-buffer + * @cpumask: CPUs to allocate a ring-buffer for + * + * Helper to dynamically allocate a set of pages (enough to cover @buffer_= size) + * for each CPU from @cpumask and fill @desc. Most likely called from + * &trace_remote_callbacks.load_trace_buffer. + * + * Return: 0 on success, negative error code on failure. + */ +int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_= size, size_t buffer_size, + const struct cpumask *cpumask) +{ + unsigned int nr_pages =3D max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) = + 1; + void *desc_end =3D desc + desc_size; + struct ring_buffer_desc *rb_desc; + int cpu, ret =3D -ENOMEM; + + if (desc_size < struct_size(desc, __data, 0)) + return -EINVAL; + + desc->nr_cpus =3D 0; + desc->struct_len =3D struct_size(desc, __data, 0); + + rb_desc =3D (struct ring_buffer_desc *)&desc->__data[0]; + + for_each_cpu(cpu, cpumask) { + unsigned int id; + + if ((void *)rb_desc + struct_size(rb_desc, page_va, nr_pages) > desc_end= ) { + ret =3D -EINVAL; + goto err; + } + + rb_desc->cpu =3D cpu; + rb_desc->nr_page_va =3D 0; + rb_desc->meta_va =3D (unsigned long)__get_free_page(GFP_KERNEL); + if (!rb_desc->meta_va) + goto err; + + for (id =3D 0; id < nr_pages; id++) { + rb_desc->page_va[id] =3D (unsigned long)__get_free_page(GFP_KERNEL); + if (!rb_desc->page_va[id]) + goto err; + + rb_desc->nr_page_va++; + } + desc->nr_cpus++; + desc->struct_len +=3D offsetof(struct ring_buffer_desc, page_va); + desc->struct_len +=3D struct_size(rb_desc, page_va, rb_desc->nr_page_va); + rb_desc =3D __next_ring_buffer_desc(rb_desc); + } + + return 0; + +err: + trace_remote_free_buffer(desc); + return ret; +} +EXPORT_SYMBOL_GPL(trace_remote_alloc_buffer); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA2E53B5843 for ; Fri, 6 Mar 2026 14:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807761; cv=none; b=biezuUwPaiyvgs69KrLahLiyNWndu577N9HSE+t4LGRJYQwS03hTnZt/xjkbnjcfn2H5BRdlKPfcM+T280PjFKXsx345PuaO/8seSFmhtxqE3E1broI1mokJ0gi/Yq7Uj8XH//vzfUgwhZmxuOsWvhw2omvdVatBgMXwkPYQTZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807761; c=relaxed/simple; bh=CQB4OHKC6a/USHlkPZV7C6bsVAu6PnT5zM7PXiaR5YY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pTQ1G+5rXSeYSEW/nyEfdY/99hunFMyIuSe1D3GVYYV5pnnTYhxX76rtDyRIRzHyMzy90os9a6swXQZP41+iu4/ORODxrpkPqf2IqXKVzg5jjOr31AsErZDjhukAK2fm/yrX86UDAxc4ZjOUJjiYF7iiuLV8OR/S9eqhA4WfchQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=2klLqfyp; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="2klLqfyp" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-439b484ee04so3874913f8f.1 for ; Fri, 06 Mar 2026 06:35:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807758; x=1773412558; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=IFq1QzHqVSYqV3EhHbsp/w5T0l1q5txSHzBQrIlCqvk=; b=2klLqfypXA3qMN7IUVd1+oqlazX/Q3iJd1WG4vQyGbP6X6cqRZwFVh9ZRmHw/3zwMv gTCC6D1WLOZdNuqQUQZeTLkSN/cw/KSxyZmKp8pHuzDGRyUCajHfj+CN3+6zKtVkknhn jU3Op6+ovpC4EV5VTnE2MwX1rMcSxE81Cve7uEAN74XJf8yNUuNghQ6JZeW0yV+ta2Ud 3Emg7+0q+5JnWDhLG7ZCZ4N802bGxtbFJAAL7Lpz1IDelbFdl9vCULY79flcI3AGPuxS F+4GuF4ynKwdnIpGSJxPyYyTOd2IspyAhlByHwHdAeHVEM7KLD31FbQiJuEeYVhaowwx Y8aA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807758; x=1773412558; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IFq1QzHqVSYqV3EhHbsp/w5T0l1q5txSHzBQrIlCqvk=; b=hSce43cbC2IE/4Rblnlx+dcwuU6QXScbtdPycm+oAOlmguVRqI8xHZ+g1JU+bPAqYV gXCvZOZ8iAw0VGHjZ/g4D6Fn4PWXUQz0l2lFy13VVc5pzlAMFUj826LImY5lu75XqXZo LjnAqNIB2y2fSZt19hHfd3DaLaw5w0eXOjFIWpxZQJiO6hJdiAs2wKVtzASD2LJPAvZk y+wiv6nAnLvJG2vQvAp0rGgozdDbYb8LwUjVaGhgmo8d5LUolVG6cTvEvfBKUkFkql61 mgmiTF7GOhFWqNHcoF8Ajbx0/Vf1dq78eoLSTm0mUky00VD2Hlqg7X7Q0bb+JwkIbMmv 6c8A== X-Forwarded-Encrypted: i=1; AJvYcCWVkYdShv2M/7zoUnQM5ogn2PWd87pQte//+U35Y1I1t45T99I+gLEwPRyacK+omizaX2nXggG/JEhWi+A=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2b52HfnOVYV33X96N5OwGZsb/LYUKW8UpPoE41VZuMgJVMGxA 4u2cSkom2AGeX48e3FGAYZLew5iQJcBgm6VFccqZSdyYS8OZq3RT5Bc8Oro/I4+vGR77zCepXF9 M8UIuTTUrBlHiHcScB/0Ceg== X-Received: from wmbf16.prod.google.com ([2002:a05:600c:5950:b0:47b:d5ad:dd7f]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b2b:b0:477:9890:9ab8 with SMTP id 5b1f17b1804b1-48526715213mr34206555e9.3.1772807758338; Fri, 06 Mar 2026 06:35:58 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:10 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-7-vdonnefort@google.com> Subject: [PATCH v13 06/32] tracing: Add reset to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow to reset the trace remote buffer by writing to the Tracefs "trace" file. This is similar to the regular Tracefs interface. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 65b7e7b8267c..10ca03dc192b 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -17,6 +17,8 @@ * remote to allow writing. * @swap_reader_page: Called when Tracefs consumes a new page from a * ring-buffer. It is expected from the remote to isolate a + * @reset: Called on `echo 0 > trace`. It is expected from the + * remote to reset all ring-buffer pages. * new reader-page from the @cpu ring-buffer. */ struct trace_remote_callbacks { @@ -24,6 +26,7 @@ struct trace_remote_callbacks { void (*unload_trace_buffer)(struct trace_buffer_desc *desc, void *priv); int (*enable_tracing)(bool enable, void *priv); int (*swap_reader_page)(unsigned int cpu, void *priv); + int (*reset)(unsigned int cpu, void *priv); }; =20 int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv); diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 8b06f730376e..a7b94736dd38 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -63,6 +63,7 @@ static int trace_remote_load(struct trace_remote *remote) rb_remote->desc =3D desc; rb_remote->swap_reader_page =3D remote->cbs->swap_reader_page; rb_remote->priv =3D remote->priv; + rb_remote->reset =3D remote->cbs->reset; remote->trace_buffer =3D ring_buffer_alloc_remote(rb_remote); if (!remote->trace_buffer) { remote->cbs->unload_trace_buffer(desc, remote->priv); @@ -138,6 +139,21 @@ static int trace_remote_disable_tracing(struct trace_r= emote *remote) return 0; } =20 +static void trace_remote_reset(struct trace_remote *remote, int cpu) +{ + lockdep_assert_held(&remote->lock); + + if (!trace_remote_loaded(remote)) + return; + + if (cpu =3D=3D RING_BUFFER_ALL_CPUS) + ring_buffer_reset(remote->trace_buffer); + else + ring_buffer_reset_cpu(remote->trace_buffer, cpu); + + trace_remote_try_unload(remote); +} + static ssize_t tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) { @@ -414,6 +430,26 @@ static const struct file_operations trace_pipe_fops = =3D { .release =3D trace_pipe_release, }; =20 +static ssize_t trace_write(struct file *filp, const char __user *ubuf, siz= e_t cnt, loff_t *ppos) +{ + struct inode *inode =3D file_inode(filp); + struct trace_remote *remote =3D inode->i_private; + int cpu =3D RING_BUFFER_ALL_CPUS; + + if (inode->i_cdev) + cpu =3D (long)inode->i_cdev - 1; + + guard(mutex)(&remote->lock); + + trace_remote_reset(remote, cpu); + + return cnt; +} + +static const struct file_operations trace_fops =3D { + .write =3D trace_write, +}; + static int trace_remote_init_tracefs(const char *name, struct trace_remote= *remote) { struct dentry *remote_d, *percpu_d, *d; @@ -452,6 +488,10 @@ static int trace_remote_init_tracefs(const char *name,= struct trace_remote *remo if (!d) goto err; =20 + d =3D trace_create_file("trace", TRACEFS_MODE_WRITE, remote_d, remote, &t= race_fops); + if (!d) + goto err; + percpu_d =3D tracefs_create_dir("per_cpu", remote_d); if (!percpu_d) { pr_err("Failed to create tracefs dir "TRACEFS_DIR"%s/per_cpu/\n", name); @@ -474,6 +514,11 @@ static int trace_remote_init_tracefs(const char *name,= struct trace_remote *remo &trace_pipe_fops); if (!d) goto err; + + d =3D trace_create_cpu_file("trace", TRACEFS_MODE_WRITE, cpu_d, remote, = cpu, + &trace_fops); + if (!d) + goto err; } =20 return 0; --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF0313B5852 for ; Fri, 6 Mar 2026 14:36:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807763; cv=none; b=QV7PbZCnzVdUIg4ugBp5PboLuCaKSQPIE2q3oI9O8As3VkV95mc+Y0FFHV1xbojJhZdvYXfRt/ia2+X+TasWToaHNBnonnvNzY3hN9QNZZL/iQkM1TSwz+EVpUM/1BGQ34n2PFZVe1VFXHlE6YMMPDIlsce7/Jen4aNp5ZOJF1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807763; c=relaxed/simple; bh=PAQcVF01kK9wFwuSLOaC5m9jNYjnlzu/n72SIkQy6Ik=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KIR9tJl7C4K+779NQpjHQbF7XtzFO5WzFzBqZA6haf4bpIaVMYPOYEf6UxgEahms0DvudskVu2PDhtztIhhlAu+FHDiXzWvOCHGa/DOdC7ayT+RBI4R9HwyCIrCnKU1ZIst8YSJtvWa/XoSkZNECZaJgd6UIw5VPw8oCfskJXVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0xSSONUm; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0xSSONUm" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4837b6f6b93so72038345e9.3 for ; Fri, 06 Mar 2026 06:36:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807759; x=1773412559; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ohzslEpnT6pZ6rsUGgoH32ellL4Qkj/ES5tdzdxl8bQ=; b=0xSSONUmwW6nQaKCNGrmGNzhpbNighGZ1iTZqonhvt5qYyiBlmvuATxi81xOKdZV4b pYPK/YEYeKrjcg2qEAcOow2qdN03koHHdt95KnAsj9HR///5qp0rI9S1nAH3g5OP8Ts2 L+e3eOqkAKI5BgjpLOxDyo+nilJYveoJLvZpE9NCUcnOji8j0nupjRg5QYRpKBfFs4SV 3rtCC0EvYnCyaZOiB1pQfqy9lsbQKNZXexjdObGKagFEg6eVGzc/wnTlUwyxSiM380TZ 5FMPXaU6q8Aza3/heLf2RU1o5HXHJ3sWhpaNfNn6HJOSUAUJIktOGUQ9nPThAETZCtNX Js0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807759; x=1773412559; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ohzslEpnT6pZ6rsUGgoH32ellL4Qkj/ES5tdzdxl8bQ=; b=pAZGOHQ/S6J9VEE+VPf1N6K0iXSu+7FIzgUMLedbd7tCfW9qpYBJ6i/NaVz370/ly/ qyr6aev/eOO4gG79UaqbW5Y5coHvhQbsJUkyeKO/1nmMTLqLliGFRCR4mz5oKBBOf1Jq JCVUUC0YyYV8GhIyrVorDXDODu9Yx98DXpY2MXxPZ7RrmR/DQVxGMYEOfOR1/aeb1w6z l53FkLQDqLauREX7M35dcVKNVEay6/9dIV5yNjOnOG60WohgHtTiQwqPjO5HThfT8Ut6 LPGECoatC8mR+knckTh/ll1DUdUntkTQRQiJ/UtLwJ4TfsAU3m5uUeBAWns9WR8QBGOm b79g== X-Forwarded-Encrypted: i=1; AJvYcCWHYM30bpwRSD/Odvd8wJg4PvMkOL0lTAuaCGWdm2e8GHlCdt5XuL5BEK3Qp22AwOirhybthN8MfWRufOg=@vger.kernel.org X-Gm-Message-State: AOJu0YzqO0G+oBg6yX3k4ItxoEOrxVSwW5J67abKYQkXU63uhm3FPM1w oBlyPx3d6idR0gLXgLGAZZvhahe5JK5oNXeTF6d2WwMeZagewkE6JKQsCWHnSS+gFCF+44ImKop hvl8UD3TrJKYHgz+IiJdI2A== X-Received: from wmi8.prod.google.com ([2002:a05:600c:208:b0:47d:5bef:a379]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4e03:b0:483:702f:4641 with SMTP id 5b1f17b1804b1-48526918685mr38530565e9.3.1772807759107; Fri, 06 Mar 2026 06:35:59 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:11 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-8-vdonnefort@google.com> Subject: [PATCH v13 07/32] tracing: Add non-consuming read to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow reading the trace file for trace remotes. This performs a non-consuming read of the trace buffer. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bef491af8bce..dba941bf2b74 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -3856,7 +3856,7 @@ static int s_show(struct seq_file *m, void *v) * Should be used after trace_array_get(), trace_types_lock * ensures that i_cdev was already initialized. */ -static inline int tracing_get_cpu(struct inode *inode) +int tracing_get_cpu(struct inode *inode) { if (inode->i_cdev) /* See trace_create_cpu_file() */ return (long)inode->i_cdev - 1; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d6af4405b341..fbbd0b2ee76f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -695,6 +695,7 @@ struct dentry *trace_create_cpu_file(const char *name, void *data, long cpu, const struct file_operations *fops); +int tracing_get_cpu(struct inode *inode); =20 =20 /** diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index a7b94736dd38..039ba71c3b3e 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -18,14 +18,23 @@ #define TRACEFS_MODE_WRITE 0640 #define TRACEFS_MODE_READ 0440 =20 +enum tri_type { + TRI_CONSUMING, + TRI_NONCONSUMING, +}; + struct trace_remote_iterator { struct trace_remote *remote; struct trace_seq seq; struct delayed_work poll_work; unsigned long lost_events; u64 ts; + struct ring_buffer_iter *rb_iter; + struct ring_buffer_iter **rb_iters; int cpu; int evt_cpu; + loff_t pos; + enum tri_type type; }; =20 struct trace_remote { @@ -36,6 +45,8 @@ struct trace_remote { unsigned long trace_buffer_size; struct ring_buffer_remote rb_remote; struct mutex lock; + struct rw_semaphore reader_lock; + struct rw_semaphore *pcpu_reader_locks; unsigned int nr_readers; unsigned int poll_ms; bool tracing_on; @@ -230,6 +241,20 @@ static int trace_remote_get(struct trace_remote *remot= e, int cpu) if (ret) return ret; =20 + if (cpu !=3D RING_BUFFER_ALL_CPUS && !remote->pcpu_reader_locks) { + int lock_cpu; + + remote->pcpu_reader_locks =3D kcalloc(nr_cpu_ids, sizeof(*remote->pcpu_r= eader_locks), + GFP_KERNEL); + if (!remote->pcpu_reader_locks) { + trace_remote_try_unload(remote); + return -ENOMEM; + } + + for_each_possible_cpu(lock_cpu) + init_rwsem(&remote->pcpu_reader_locks[lock_cpu]); + } + remote->nr_readers++; =20 return 0; @@ -244,6 +269,9 @@ static void trace_remote_put(struct trace_remote *remot= e) if (remote->nr_readers) return; =20 + kfree(remote->pcpu_reader_locks); + remote->pcpu_reader_locks =3D NULL; + trace_remote_try_unload(remote); } =20 @@ -258,13 +286,55 @@ static void __poll_remote(struct work_struct *work) msecs_to_jiffies(iter->remote->poll_ms)); } =20 -static struct trace_remote_iterator *trace_remote_iter(struct trace_remote= *remote, int cpu) +static void __free_ring_buffer_iter(struct trace_remote_iterator *iter, in= t cpu) +{ + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + ring_buffer_read_finish(iter->rb_iter); + return; + } + + for_each_possible_cpu(cpu) { + if (iter->rb_iters[cpu]) + ring_buffer_read_finish(iter->rb_iters[cpu]); + } + + kfree(iter->rb_iters); +} + +static int __alloc_ring_buffer_iter(struct trace_remote_iterator *iter, in= t cpu) +{ + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + iter->rb_iter =3D ring_buffer_read_start(iter->remote->trace_buffer, cpu= , GFP_KERNEL); + + return iter->rb_iter ? 0 : -ENOMEM; + } + + iter->rb_iters =3D kcalloc(nr_cpu_ids, sizeof(*iter->rb_iters), GFP_KERNE= L); + if (!iter->rb_iters) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + iter->rb_iters[cpu] =3D ring_buffer_read_start(iter->remote->trace_buffe= r, cpu, + GFP_KERNEL); + if (!iter->rb_iters[cpu]) { + __free_ring_buffer_iter(iter, RING_BUFFER_ALL_CPUS); + return -ENOMEM; + } + } + + return 0; +} + +static struct trace_remote_iterator +*trace_remote_iter(struct trace_remote *remote, int cpu, enum tri_type typ= e) { struct trace_remote_iterator *iter =3D NULL; int ret; =20 lockdep_assert_held(&remote->lock); =20 + if (type =3D=3D TRI_NONCONSUMING && !trace_remote_loaded(remote)) + return NULL; =20 ret =3D trace_remote_get(remote, cpu); if (ret) @@ -279,9 +349,21 @@ static struct trace_remote_iterator *trace_remote_iter= (struct trace_remote *remo if (iter) { iter->remote =3D remote; iter->cpu =3D cpu; + iter->type =3D type; trace_seq_init(&iter->seq); - INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); - schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_ms= )); + + switch (type) { + case TRI_CONSUMING: + INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); + schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_m= s)); + break; + case TRI_NONCONSUMING: + ret =3D __alloc_ring_buffer_iter(iter, cpu); + break; + } + + if (ret) + goto err; =20 return iter; } @@ -305,10 +387,100 @@ static void trace_remote_iter_free(struct trace_remo= te_iterator *iter) =20 lockdep_assert_held(&remote->lock); =20 + switch (iter->type) { + case TRI_CONSUMING: + cancel_delayed_work_sync(&iter->poll_work); + break; + case TRI_NONCONSUMING: + __free_ring_buffer_iter(iter, iter->cpu); + break; + } + kfree(iter); trace_remote_put(remote); } =20 +static void trace_remote_iter_read_start(struct trace_remote_iterator *ite= r) +{ + struct trace_remote *remote =3D iter->remote; + int cpu =3D iter->cpu; + + /* Acquire global reader lock */ + if (cpu =3D=3D RING_BUFFER_ALL_CPUS && iter->type =3D=3D TRI_CONSUMING) + down_write(&remote->reader_lock); + else + down_read(&remote->reader_lock); + + if (cpu =3D=3D RING_BUFFER_ALL_CPUS) + return; + + /* + * No need for the remote lock here, iter holds a reference on + * remote->nr_readers + */ + + /* Get the per-CPU one */ + if (WARN_ON_ONCE(!remote->pcpu_reader_locks)) + return; + + if (iter->type =3D=3D TRI_CONSUMING) + down_write(&remote->pcpu_reader_locks[cpu]); + else + down_read(&remote->pcpu_reader_locks[cpu]); +} + +static void trace_remote_iter_read_finished(struct trace_remote_iterator *= iter) +{ + struct trace_remote *remote =3D iter->remote; + int cpu =3D iter->cpu; + + /* Release per-CPU reader lock */ + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + /* + * No need for the remote lock here, iter holds a reference on + * remote->nr_readers + */ + if (iter->type =3D=3D TRI_CONSUMING) + up_write(&remote->pcpu_reader_locks[cpu]); + else + up_read(&remote->pcpu_reader_locks[cpu]); + } + + /* Release global reader lock */ + if (cpu =3D=3D RING_BUFFER_ALL_CPUS && iter->type =3D=3D TRI_CONSUMING) + up_write(&remote->reader_lock); + else + up_read(&remote->reader_lock); +} + +static struct ring_buffer_iter *__get_rb_iter(struct trace_remote_iterator= *iter, int cpu) +{ + return iter->cpu !=3D RING_BUFFER_ALL_CPUS ? iter->rb_iter : iter->rb_ite= rs[cpu]; +} + +static struct ring_buffer_event * +__peek_event(struct trace_remote_iterator *iter, int cpu, u64 *ts, unsigne= d long *lost_events) +{ + struct ring_buffer_event *rb_evt; + struct ring_buffer_iter *rb_iter; + + switch (iter->type) { + case TRI_CONSUMING: + return ring_buffer_peek(iter->remote->trace_buffer, cpu, ts, lost_events= ); + case TRI_NONCONSUMING: + rb_iter =3D __get_rb_iter(iter, cpu); + rb_evt =3D ring_buffer_iter_peek(rb_iter, ts); + if (!rb_evt) + return NULL; + + *lost_events =3D ring_buffer_iter_dropped(rb_iter); + + return rb_evt; + } + + return NULL; +} + static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) { struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; @@ -318,7 +490,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) return false; =20 - if (!ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_events)) + if (!__peek_event(iter, cpu, &iter->ts, &iter->lost_events)) return false; =20 iter->evt_cpu =3D cpu; @@ -333,7 +505,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) continue; =20 - if (!ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events)) + if (!__peek_event(iter, cpu, &ts, &lost_events)) continue; =20 if (ts >=3D iter->ts) @@ -347,6 +519,20 @@ static bool trace_remote_iter_read_event(struct trace_= remote_iterator *iter) return iter->ts !=3D U64_MAX; } =20 +static void trace_remote_iter_move(struct trace_remote_iterator *iter) +{ + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + + switch (iter->type) { + case TRI_CONSUMING: + ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + break; + case TRI_NONCONSUMING: + ring_buffer_iter_advance(__get_rb_iter(iter, iter->evt_cpu)); + break; + } +} + static int trace_remote_iter_print_event(struct trace_remote_iterator *ite= r) { unsigned long usecs_rem; @@ -369,13 +555,14 @@ static int trace_pipe_open(struct inode *inode, struc= t file *filp) { struct trace_remote *remote =3D inode->i_private; struct trace_remote_iterator *iter; - int cpu =3D RING_BUFFER_ALL_CPUS; - - if (inode->i_cdev) - cpu =3D (long)inode->i_cdev - 1; + int cpu =3D tracing_get_cpu(inode); =20 guard(mutex)(&remote->lock); - iter =3D trace_remote_iter(remote, cpu); + + iter =3D trace_remote_iter(remote, cpu, TRI_CONSUMING); + if (IS_ERR(iter)) + return PTR_ERR(iter); + filp->private_data =3D iter; =20 return IS_ERR(iter) ? PTR_ERR(iter) : 0; @@ -410,6 +597,8 @@ static ssize_t trace_pipe_read(struct file *filp, char = __user *ubuf, size_t cnt, if (ret < 0) return ret; =20 + trace_remote_iter_read_start(iter); + while (trace_remote_iter_read_event(iter)) { int prev_len =3D iter->seq.seq.len; =20 @@ -418,9 +607,11 @@ static ssize_t trace_pipe_read(struct file *filp, char= __user *ubuf, size_t cnt, break; } =20 - ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + trace_remote_iter_move(iter); } =20 + trace_remote_iter_read_finished(iter); + goto copy_to_user; } =20 @@ -430,14 +621,127 @@ static const struct file_operations trace_pipe_fops = =3D { .release =3D trace_pipe_release, }; =20 +static void *trace_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct trace_remote_iterator *iter =3D m->private; + + ++*pos; + + if (!iter || !trace_remote_iter_read_event(iter)) + return NULL; + + trace_remote_iter_move(iter); + iter->pos++; + + return iter; +} + +static void *trace_start(struct seq_file *m, loff_t *pos) +{ + struct trace_remote_iterator *iter =3D m->private; + loff_t i; + + if (!iter) + return NULL; + + trace_remote_iter_read_start(iter); + + if (!*pos) { + iter->pos =3D -1; + return trace_next(m, NULL, &i); + } + + i =3D iter->pos; + while (i < *pos) { + iter =3D trace_next(m, NULL, &i); + if (!iter) + return NULL; + } + + return iter; +} + +static int trace_show(struct seq_file *m, void *v) +{ + struct trace_remote_iterator *iter =3D v; + + trace_seq_init(&iter->seq); + + if (trace_remote_iter_print_event(iter)) { + seq_printf(m, "[EVENT %d PRINT TOO BIG]\n", iter->evt->id); + return 0; + } + + return trace_print_seq(m, &iter->seq); +} + +static void trace_stop(struct seq_file *m, void *v) +{ + struct trace_remote_iterator *iter =3D m->private; + + if (iter) + trace_remote_iter_read_finished(iter); +} + +static const struct seq_operations trace_sops =3D { + .start =3D trace_start, + .next =3D trace_next, + .show =3D trace_show, + .stop =3D trace_stop, +}; + +static int trace_open(struct inode *inode, struct file *filp) +{ + struct trace_remote *remote =3D inode->i_private; + struct trace_remote_iterator *iter =3D NULL; + int cpu =3D tracing_get_cpu(inode); + int ret; + + if (!(filp->f_mode & FMODE_READ)) + return 0; + + guard(mutex)(&remote->lock); + + iter =3D trace_remote_iter(remote, cpu, TRI_NONCONSUMING); + if (IS_ERR(iter)) + return PTR_ERR(iter); + + ret =3D seq_open(filp, &trace_sops); + if (ret) { + trace_remote_iter_free(iter); + return ret; + } + + ((struct seq_file *)filp->private_data)->private =3D (void *)iter; + + return 0; +} + +static int trace_release(struct inode *inode, struct file *filp) +{ + struct trace_remote_iterator *iter; + + if (!(filp->f_mode & FMODE_READ)) + return 0; + + iter =3D ((struct seq_file *)filp->private_data)->private; + seq_release(inode, filp); + + if (!iter) + return 0; + + guard(mutex)(&iter->remote->lock); + + trace_remote_iter_free(iter); + + return 0; +} + static ssize_t trace_write(struct file *filp, const char __user *ubuf, siz= e_t cnt, loff_t *ppos) { struct inode *inode =3D file_inode(filp); struct trace_remote *remote =3D inode->i_private; - int cpu =3D RING_BUFFER_ALL_CPUS; - - if (inode->i_cdev) - cpu =3D (long)inode->i_cdev - 1; + int cpu =3D tracing_get_cpu(inode); =20 guard(mutex)(&remote->lock); =20 @@ -447,7 +751,11 @@ static ssize_t trace_write(struct file *filp, const ch= ar __user *ubuf, size_t cn } =20 static const struct file_operations trace_fops =3D { + .open =3D trace_open, .write =3D trace_write, + .read =3D seq_read, + .read_iter =3D seq_read_iter, + .release =3D trace_release, }; =20 static int trace_remote_init_tracefs(const char *name, struct trace_remote= *remote) @@ -565,6 +873,7 @@ int trace_remote_register(const char *name, struct trac= e_remote_callbacks *cbs, remote->trace_buffer_size =3D 7 << 10; remote->poll_ms =3D 100; mutex_init(&remote->lock); + init_rwsem(&remote->reader_lock); =20 if (trace_remote_init_tracefs(name, remote)) { kfree(remote); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B51063B7B6B for ; Fri, 6 Mar 2026 14:36:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807763; cv=none; b=aqNbrJXoAF9f+z+E7+qqxpFY8aV4NiTkapt3gPQzaDVlPTX/HsB3/Gak4+Ady3nrFbuFGQW8CCl5z+GjK+mM3SCh7VN9waNTHmUTfMBZp+R41edSZrARXgZvdoeOLZgQbc805F+9qufb0+PeP/HWqzs2IZZQcIRvIACHTMeQcqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807763; c=relaxed/simple; bh=nCoqfYLkFALSGqFmK5+OUBL2T+SjXlSRskeq0sqM6lo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=CijCnzu8cVdAA5Xd7XhAOz+5JAf2oltPswLXNkml0Yoz7/frwDD8jXxQFSoKIIx96+qu+5KRGgO/W/OOQc52r9v4dbS0JUvti1Bt558Fgsp/36mEnuNCJq0dB/xjbJjyZ1hz/wkZBn8jk+TsgvSaKbZiNT1AwkVVD+SrTYsK8JQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ff7HgNG8; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ff7HgNG8" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-439c794edd9so2865936f8f.3 for ; Fri, 06 Mar 2026 06:36:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807760; x=1773412560; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=/el005jPydhTNUS1hr5dgVCq32s5flSC0Li9+BCYSpc=; b=Ff7HgNG8qkz/SWjxwzh2AAjN07lK7vhPSr+wcruMKyD76jRTj1gURwDMcuAG6JXxd7 KmKFWmRPQnMckV/CJRQ+E6NEIX/ynL7Dql1KpNtoPtoPL6PJP/fwUnE+pUzCLmh3LVJM roaWijkoA6lLPQZ+0z8N8EI95osWCUif3OiC87eCQq5+sYsdAVsm1hIM8GE8C65Zujo7 tWmmvurZzM5ZGZ5rSyNyfmlYQpDBKSFBupYqndOefcZlvBpK6FW2przKtGdRd9sbt8RP VuW+txHt4eAln1a6l8nK5LUDTscRPgGQLZHUFM+lBINjioj1byraMpX9cGjQofL2+Ibu pAdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807760; x=1773412560; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/el005jPydhTNUS1hr5dgVCq32s5flSC0Li9+BCYSpc=; b=OO8yrIxFM1hefBMQS9t1EAW9xduWF5fBmpb6tnaDT01U/ZADUk4ZAZfgAVprUaguB0 NRbS2CljWPCSUP4XpswIOJ2rCO52v7zFRCrQtpbU+IcZwDDRw6SIIq3N193ej+P/bMRW VTqw73ESw3/vJTcRY09GR9vsuzxrRxiu8G9bT8Iqk68k+zfZIKWLE3Wc08oGpMDRcglA 0ADxXNG9hxIFHq0mgN1FalPUYopJwmdV30nNsLUbpJnoCcaJK/8BoXTCIzTO1y33AJ0I eO3mDbnhQYSNN1WsOisvZgOUm/70wh2p5y3OFUIyHetoqvlDtD2QJL1kpXHGf/UpIPMh qozQ== X-Forwarded-Encrypted: i=1; AJvYcCWB3bXrRo3pBBQiStOx7+VSi9JQ+cs2F4Q2IHahtoOzq698gTrCjKSp3ATy+LI0VZvS7UrX2YHGfeS1grU=@vger.kernel.org X-Gm-Message-State: AOJu0YyQtF9DIMKRfbj1e4enDwQoYJnyyM2IFjLwkXwB35oykcPU0Bvl g1YSvW4eCWiRPP1A3Q8knCgyEPh5BJMuYtbMLXZdSFjQNDWRCqkYLllSVMdl4Dd6NzZk5kJpmcw 0iK6URjQLsEX+DwqX8plkHg== X-Received: from wrph18.prod.google.com ([2002:adf:f4d2:0:b0:439:cb0d:43ff]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:40dc:b0:439:c9d0:5fc2 with SMTP id ffacd0b85a97d-439da891b2cmr4112557f8f.39.1772807759879; Fri, 06 Mar 2026 06:35:59 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:12 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-9-vdonnefort@google.com> Subject: [PATCH v13 08/32] tracing: Add init callback to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a .init call back so the trace remote callers can add entries to the tracefs directory. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 10ca03dc192b..090c58b7d92b 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -3,10 +3,13 @@ #ifndef _LINUX_TRACE_REMOTE_H #define _LINUX_TRACE_REMOTE_H =20 +#include #include =20 /** * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote + * @init: Called once the remote has been registered. Allows the + * caller to extend the Tracefs remote directory * @load_trace_buffer: Called before Tracefs accesses the trace buffer fo= r the first * time. Must return a &trace_buffer_desc * (most likely filled with trace_remote_alloc_buffer()) @@ -22,6 +25,7 @@ * new reader-page from the @cpu ring-buffer. */ struct trace_remote_callbacks { + int (*init)(struct dentry *d, void *priv); struct trace_buffer_desc *(*load_trace_buffer)(unsigned long size, void *= priv); void (*unload_trace_buffer)(struct trace_buffer_desc *desc, void *priv); int (*enable_tracing)(bool enable, void *priv); diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 039ba71c3b3e..294d051dcef1 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -863,6 +863,7 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv) { struct trace_remote *remote; + int ret; =20 remote =3D kzalloc_obj(*remote); if (!remote) @@ -880,7 +881,11 @@ int trace_remote_register(const char *name, struct tra= ce_remote_callbacks *cbs, return -ENOMEM; } =20 - return 0; + ret =3D cbs->init ? cbs->init(remote->dentry, priv) : 0; + if (ret) + pr_err("Init failed for trace remote '%s' (%d)\n", name, ret); + + return ret; } EXPORT_SYMBOL_GPL(trace_remote_register); =20 --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D308A3B8924 for ; Fri, 6 Mar 2026 14:36:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807765; cv=none; b=OS6YGNDDjj6fUjVWa0M9cGiNKzSMiLXlkOcf1oQtcj0QgYpuoRSHRmj6q2OlvF1NuHTn8GFwwTrMAPhL9qcYOhAoudYNuYNFGovU/qCIlkWWjMTFr/a9YwgYDUv6bgolkAxRMZZMXXJB75zVeCMYQLua/AH5ZD/y2JnkD1Cl/CY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807765; c=relaxed/simple; bh=Jha7KCAf/aGigSIpEYFnWOlx0m+vBfjCGIq0BsRP280=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jRPGdtvTXwHp8Kr57J0dt7NPlPHK/8KerqZlkfKbesPeR967b+VRZJ4naxhxwhTUoxfgfT5nv1Ttly29jLL3myoSkivRFZbk9yI0ym4zg8hG45OyyauuJ8SfKZJoYlrEUW4mRIZ1vDt68OObFBMyzKynhcJDzBDzKpOoaLNPFuo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=NoXHGClE; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="NoXHGClE" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-48378df3469so66698405e9.1 for ; Fri, 06 Mar 2026 06:36:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807761; x=1773412561; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=SzA+Osz3kQ/kOGZ2u4m1uxtf+GL8avujMCpzy98IWzg=; b=NoXHGClEjnndKneF0Ouy97u6QKS3dOvBDU5C82nPb3I3+qfbjSbfBRoAIqmrkw3FoR 4PcD0O5QQ8qX6vz+Gg2oYwlsMuN0ujmlEPxwQxuDHem9yYZNPN7D5JZcfgI9vQnTgMQF yg2+9h/wKPEb8IGlVC7Ass1wkoSncfqrAW9pw1NEVgpfvpQG4izIAA9oEGBhdibTMRAy kUXHZoqz7XyhO0l5/PU8UZG+ABrtpUsHpbFA3PCi0noFDzdzv3usL1sFBcUKpoyKEs4d jlAJPqv448YVXkDgPF9iAMRGj+x6ZVKrQISSRdvb5I3pE8leDlDvb1J2K5GbX5HhHj8l RKTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807761; x=1773412561; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=SzA+Osz3kQ/kOGZ2u4m1uxtf+GL8avujMCpzy98IWzg=; b=Xnl/OeqJSubvWb0nrdmmU37SeLIj+cI/eVA8v973cDgoTYOV5qQKu04eOynaednljh wyaSfCNOeWfxF+miLqr1gUq7yMJfRhM/iH+oUsGhGgZDaLBP9ORI9j4dbAE6W9pfGWVd 4wysy4dgn+A3QpTnOWQRMaG0bLeQ+EteCOnADM4BctQpA/I132UFXUwc01ZKzqnpdoBd 7x7nkuo6jSz9J5n2BE+2LdUnYlIeugN2Kf7TXagKZETJOZ7UJw1bgL/b0xql5Iy/X0qn r+g229zhe6LheWPcHbCpi1PWykKyPjoZexx1h0ERIVZ1U7H44p7yfoUpHRW6EVclvmVq kdTA== X-Forwarded-Encrypted: i=1; AJvYcCUeSGg3KAw02pn/G0t1CzvDgm1vIaG8JQymqvLqwfeyrdEuBfMv52oRuPeUennAgQLeFkKisvabMFMK8Jg=@vger.kernel.org X-Gm-Message-State: AOJu0YyNi7fJIqKY3EMpKJYaZNUBBo/gss9CmTg21tJNZ6CErsNTlq74 lWsHgM5/FB5zHuUZaR1w/8aIREyw7Ix3o1sQQZFyRFQotyFMkwMksK/21vWWYnVxqDFqlrK2bDg c3fEtrpNDo4z4565yJfKShA== X-Received: from wmqh16.prod.google.com ([2002:a05:600c:3510:b0:483:8b61:16bd]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:64c7:b0:47e:e59c:67c5 with SMTP id 5b1f17b1804b1-4852671d9c3mr34593065e9.8.1772807761187; Fri, 06 Mar 2026 06:36:01 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:13 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-10-vdonnefort@google.com> Subject: [PATCH v13 09/32] tracing: Add events to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An event is predefined point in the writer code that allows to log data. Following the same scheme as kernel events, add remote events, described to user-space within the events/ tracefs directory found in the corresponding trace remote. Remote events are expected to be described during the trace remote registration. Add also a .enable_event callback for trace_remote to toggle the event logging, if supported. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 090c58b7d92b..fcd1d46ea466 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -5,6 +5,7 @@ =20 #include #include +#include =20 /** * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote @@ -23,6 +24,8 @@ * @reset: Called on `echo 0 > trace`. It is expected from the * remote to reset all ring-buffer pages. * new reader-page from the @cpu ring-buffer. + * @enable_event: Called on events/event_name/enable. It is expected from + * the remote to allow the writing event @id. */ struct trace_remote_callbacks { int (*init)(struct dentry *d, void *priv); @@ -31,9 +34,11 @@ struct trace_remote_callbacks { int (*enable_tracing)(bool enable, void *priv); int (*swap_reader_page)(unsigned int cpu, void *priv); int (*reset)(unsigned int cpu, void *priv); + int (*enable_event)(unsigned short id, bool enable, void *priv); }; =20 -int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv); +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv, + struct remote_event *events, size_t nr_events); =20 int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_= size, size_t buffer_size, const struct cpumask *cpumask); diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remot= e_event.h new file mode 100644 index 000000000000..a4449008a075 --- /dev/null +++ b/include/linux/trace_remote_event.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_TRACE_REMOTE_EVENTS_H +#define _LINUX_TRACE_REMOTE_EVENTS_H + +struct trace_remote; +struct trace_event_fields; + +struct remote_event_hdr { + unsigned short id; +}; + +#define REMOTE_EVENT_NAME_MAX 30 +struct remote_event { + char name[REMOTE_EVENT_NAME_MAX]; + unsigned short id; + bool enabled; + struct trace_remote *remote; + struct trace_event_fields *fields; + char *print_fmt; + void (*print)(void *evt, struct trace_seq *seq); +}; +#endif diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 294d051dcef1..0d0af53c0ce9 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -31,6 +31,7 @@ struct trace_remote_iterator { u64 ts; struct ring_buffer_iter *rb_iter; struct ring_buffer_iter **rb_iters; + struct remote_event_hdr *evt; int cpu; int evt_cpu; loff_t pos; @@ -42,6 +43,10 @@ struct trace_remote { void *priv; struct trace_buffer *trace_buffer; struct trace_buffer_desc *trace_buffer_desc; + struct dentry *dentry; + struct eventfs_inode *eventfs; + struct remote_event *events; + unsigned long nr_events; unsigned long trace_buffer_size; struct ring_buffer_remote rb_remote; struct mutex lock; @@ -168,7 +173,8 @@ static void trace_remote_reset(struct trace_remote *rem= ote, int cpu) static ssize_t tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) { - struct trace_remote *remote =3D filp->private_data; + struct seq_file *seq =3D filp->private_data; + struct trace_remote *remote =3D seq->private; unsigned long val; int ret; =20 @@ -197,7 +203,8 @@ DEFINE_SHOW_STORE_ATTRIBUTE(tracing_on); static ssize_t buffer_size_kb_write(struct file *filp, const char __user *= ubuf, size_t cnt, loff_t *ppos) { - struct trace_remote *remote =3D filp->private_data; + struct seq_file *seq =3D filp->private_data; + struct trace_remote *remote =3D seq->private; unsigned long val; int ret; =20 @@ -484,16 +491,19 @@ __peek_event(struct trace_remote_iterator *iter, int = cpu, u64 *ts, unsigned long static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) { struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + struct ring_buffer_event *rb_evt; int cpu =3D iter->cpu; =20 if (cpu !=3D RING_BUFFER_ALL_CPUS) { if (ring_buffer_empty_cpu(trace_buffer, cpu)) return false; =20 - if (!__peek_event(iter, cpu, &iter->ts, &iter->lost_events)) + rb_evt =3D __peek_event(iter, cpu, &iter->ts, &iter->lost_events); + if (!rb_evt) return false; =20 iter->evt_cpu =3D cpu; + iter->evt =3D ring_buffer_event_data(rb_evt); return true; } =20 @@ -505,7 +515,8 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) continue; =20 - if (!__peek_event(iter, cpu, &ts, &lost_events)) + rb_evt =3D __peek_event(iter, cpu, &ts, &lost_events); + if (!rb_evt) continue; =20 if (ts >=3D iter->ts) @@ -513,6 +524,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) =20 iter->ts =3D ts; iter->evt_cpu =3D cpu; + iter->evt =3D ring_buffer_event_data(rb_evt); iter->lost_events =3D lost_events; } =20 @@ -533,8 +545,11 @@ static void trace_remote_iter_move(struct trace_remote= _iterator *iter) } } =20 +static struct remote_event *trace_remote_find_event(struct trace_remote *r= emote, unsigned short id); + static int trace_remote_iter_print_event(struct trace_remote_iterator *ite= r) { + struct remote_event *evt; unsigned long usecs_rem; u64 ts =3D iter->ts; =20 @@ -548,6 +563,12 @@ static int trace_remote_iter_print_event(struct trace_= remote_iterator *iter) trace_seq_printf(&iter->seq, "[%03d]\t%5llu.%06lu: ", iter->evt_cpu, ts, usecs_rem); =20 + evt =3D trace_remote_find_event(iter->remote, iter->evt->id); + if (!evt) + trace_seq_printf(&iter->seq, "UNKNOWN id=3D%d\n", iter->evt->id); + else + evt->print(iter->evt, &iter->seq); + return trace_seq_has_overflowed(&iter->seq) ? -EOVERFLOW : 0; } =20 @@ -829,6 +850,8 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo goto err; } =20 + remote->dentry =3D remote_d; + return 0; =20 err: @@ -842,6 +865,9 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo return -ENOMEM; } =20 +static int trace_remote_register_events(const char *remote_name, struct tr= ace_remote *remote, + struct remote_event *events, size_t nr_events); + /** * trace_remote_register() - Register a Tracefs remote * @name: Name of the remote, used for the Tracefs remotes/ directory. @@ -860,7 +886,8 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo * * Return: 0 on success, negative error code on failure. */ -int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv) +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv, + struct remote_event *events, size_t nr_events) { struct trace_remote *remote; int ret; @@ -881,6 +908,13 @@ int trace_remote_register(const char *name, struct tra= ce_remote_callbacks *cbs, return -ENOMEM; } =20 + ret =3D trace_remote_register_events(name, remote, events, nr_events); + if (ret) { + pr_err("Failed to register events for trace remote '%s' (%d)\n", + name, ret); + return ret; + } + ret =3D cbs->init ? cbs->init(remote->dentry, priv) : 0; if (ret) pr_err("Init failed for trace remote '%s' (%d)\n", name, ret); @@ -976,3 +1010,223 @@ int trace_remote_alloc_buffer(struct trace_buffer_de= sc *desc, size_t desc_size, return ret; } EXPORT_SYMBOL_GPL(trace_remote_alloc_buffer); + +static int +trace_remote_enable_event(struct trace_remote *remote, struct remote_event= *evt, bool enable) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (evt->enabled =3D=3D enable) + return 0; + + ret =3D remote->cbs->enable_event(evt->id, enable, remote->priv); + if (ret) + return ret; + + evt->enabled =3D enable; + + return 0; +} + +static int remote_event_enable_show(struct seq_file *s, void *unused) +{ + struct remote_event *evt =3D s->private; + + seq_printf(s, "%d\n", evt->enabled); + + return 0; +} + +static ssize_t remote_event_enable_write(struct file *filp, const char __u= ser *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *seq =3D filp->private_data; + struct remote_event *evt =3D seq->private; + struct trace_remote *remote =3D evt->remote; + u8 enable; + int ret; + + ret =3D kstrtou8_from_user(ubuf, count, 10, &enable); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + ret =3D trace_remote_enable_event(remote, evt, enable); + if (ret) + return ret; + + return count; +} +DEFINE_SHOW_STORE_ATTRIBUTE(remote_event_enable); + +static int remote_event_id_show(struct seq_file *s, void *unused) +{ + struct remote_event *evt =3D s->private; + + seq_printf(s, "%d\n", evt->id); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(remote_event_id); + +static int remote_event_format_show(struct seq_file *s, void *unused) +{ + size_t offset =3D sizeof(struct remote_event_hdr); + struct remote_event *evt =3D s->private; + struct trace_event_fields *field; + + seq_printf(s, "name: %s\n", evt->name); + seq_printf(s, "ID: %d\n", evt->id); + seq_puts(s, + "format:\n\tfield:unsigned short common_type;\toffset:0;\tsize:2;\tsign= ed:0;\n\n"); + + field =3D &evt->fields[0]; + while (field->name) { + seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%u;\tsigned:%d;\n", + field->type, field->name, offset, field->size, + field->is_signed); + offset +=3D field->size; + field++; + } + + if (field !=3D &evt->fields[0]) + seq_puts(s, "\n"); + + seq_printf(s, "print fmt: %s\n", evt->print_fmt); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(remote_event_format); + +static int remote_event_callback(const char *name, umode_t *mode, void **d= ata, + const struct file_operations **fops) +{ + if (!strcmp(name, "enable")) { + *mode =3D TRACEFS_MODE_WRITE; + *fops =3D &remote_event_enable_fops; + return 1; + } + + if (!strcmp(name, "id")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_event_id_fops; + return 1; + } + + if (!strcmp(name, "format")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_event_format_fops; + return 1; + } + + return 0; +} + +static int trace_remote_init_eventfs(const char *remote_name, struct trace= _remote *remote, + struct remote_event *evt) +{ + struct eventfs_inode *eventfs =3D remote->eventfs; + static struct eventfs_entry entries[] =3D { + { + .name =3D "enable", + .callback =3D remote_event_callback, + }, { + .name =3D "id", + .callback =3D remote_event_callback, + }, { + .name =3D "format", + .callback =3D remote_event_callback, + } + }; + bool eventfs_create =3D false; + + if (!eventfs) { + eventfs =3D eventfs_create_events_dir("events", remote->dentry, NULL, 0,= NULL); + if (IS_ERR(eventfs)) + return PTR_ERR(eventfs); + + /* + * Create similar hierarchy as local events even if a single system is s= upported at + * the moment + */ + eventfs =3D eventfs_create_dir(remote_name, eventfs, NULL, 0, NULL); + if (IS_ERR(eventfs)) + return PTR_ERR(eventfs); + + remote->eventfs =3D eventfs; + eventfs_create =3D true; + } + + eventfs =3D eventfs_create_dir(evt->name, eventfs, entries, ARRAY_SIZE(en= tries), evt); + if (IS_ERR(eventfs)) { + if (eventfs_create) { + eventfs_remove_events_dir(remote->eventfs); + remote->eventfs =3D NULL; + } + return PTR_ERR(eventfs); + } + + return 0; +} + +static int trace_remote_attach_events(struct trace_remote *remote, struct = remote_event *events, + size_t nr_events) +{ + int i; + + for (i =3D 0; i < nr_events; i++) { + struct remote_event *evt =3D &events[i]; + + if (evt->remote) + return -EEXIST; + + evt->remote =3D remote; + + /* We need events to be sorted for efficient lookup */ + if (i && evt->id <=3D events[i - 1].id) + return -EINVAL; + } + + remote->events =3D events; + remote->nr_events =3D nr_events; + + return 0; +} + +static int trace_remote_register_events(const char *remote_name, struct tr= ace_remote *remote, + struct remote_event *events, size_t nr_events) +{ + int i, ret; + + ret =3D trace_remote_attach_events(remote, events, nr_events); + if (ret) + return ret; + + for (i =3D 0; i < nr_events; i++) { + struct remote_event *evt =3D &events[i]; + + ret =3D trace_remote_init_eventfs(remote_name, remote, evt); + if (ret) + pr_warn("Failed to init eventfs for event '%s' (%d)", + evt->name, ret); + } + + return 0; +} + +static int __cmp_events(const void *key, const void *data) +{ + const struct remote_event *evt =3D data; + int id =3D (int)((long)key); + + return id - (int)evt->id; +} + +static struct remote_event *trace_remote_find_event(struct trace_remote *r= emote, unsigned short id) +{ + return bsearch((const void *)(unsigned long)id, remote->events, remote->n= r_events, + sizeof(*remote->events), __cmp_events); +} --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31FB73B8BA1 for ; Fri, 6 Mar 2026 14:36:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807766; cv=none; b=DQYZGGJWSGrV2tsIFvCo056+qtGwxbcgGdKh89hoCNvZgOc/tlCs6rr45/QDR4aHzKBxsSoU9kC3Kmtoa/Wchhe9ZmXIukAwy89RAvjxUx++vFGFz++juoQNgZJrPe4eVrfVjN6ARb7TI3V6gGBaCxio+tO764WgEhy7Q1EmOgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807766; c=relaxed/simple; bh=oVeFrLwB7bHbLEm+WgXqG+lLycY4roQA1dY8WYMr0I4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pRfj8KeKqkmQNZEBz2u8tIxAVGzo2ll1S1zK73xMhvIrKX6q9ECFyrPE3G1YCaNcLmgwJljool98rVhM7uIWDfWZEhDuClIuwBPn34Fa+1um1qv8PJgq0Ciaei7sri1mNcmmGz9cwV5RIXuHBnRw4hCvckTB1V0KM6EdEjfRoT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fLlFYh1o; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fLlFYh1o" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-b9071b7cc09so688387766b.1 for ; Fri, 06 Mar 2026 06:36:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807762; x=1773412562; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=TDGVgx5O+tN6SEgYjU5DtzNVpKkiMVojTG14bXRGtGk=; b=fLlFYh1o7jTPIDDcUQNgbk2ZRgrvyNiH6WKocIo66zZNMuFH4DkpRWVKk1c9TWlodu BjcWwofzPqtwPShA5eleQ/SRIpY9Xjz2X+T8HnUyTrWC8DGCFD6lWB0ArganaZEoH9ok 3Gg98LZe646WXMk5oKyL6D7v3Mpe7hJYvP+AwQvQmi3QbnOaqxxFwyjeB9pxw/cPPyUI qpBGmGXdH3aVV9ZB1JjNZnnRlF1JlgBeOfVd1BH7FkHfMi8aHbmzQ6YcfX4xPiZloGiU pGtI443BnkmZ8iiDpKz8f4Fu7q4n2oWV936dxvPw5C104AXvLudcC8MzNxsevtWjjGdG 0gSw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807762; x=1773412562; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=TDGVgx5O+tN6SEgYjU5DtzNVpKkiMVojTG14bXRGtGk=; b=RNLQxTxmApFnJe6lE6bnwiTE+05Je57u2nslsTvpQrHJgiHREF/VsydSkhQQ//yjXH YFMYEvUy+j+k2N8Co8+z9ee0ezc1CzUqJd9CQjKy1/ged8MXmrWfYmw0U4nuz8hJLcoO xXpI4hbssBQuotu82NoVNhacD3imfYfz/IyTj2o6Y9d4vyzR1Epd9H3kAzFBbojwLSJl G9wWrQsH6Va0+SFRPqDTYa81K4HTXwo8Yuzr3gc2l8Rzd5e73eBYBHxAUZI6sZVT8K96 eKR7z6A9qnsRGQi6y3snixsdr6odCqLml/6FzCCmoyO1G/E/UZx2Kh1NhOJvmfp8JO9W 7TQg== X-Forwarded-Encrypted: i=1; AJvYcCX47SMajuEOp5fvBQv9yox6Ha7S0/kE9bYfMB3HVe9hSObKfSoovNilrG7DMdssyhTSdcezJSqVr3Ar5J4=@vger.kernel.org X-Gm-Message-State: AOJu0YyOTaEbcubdK9kfyK+mzWQ2ssbxBfZZF3TFwhg6fLo982o2TA/i fyhe/eLyomnU9Cdu3dgj4k+rmzDoDHhapyKkrKFfR7dDMAxfKFBWQG83wcVt3ccmwFCba5PFGYC /ydRhX36lpc7CdrSRDXiE0A== X-Received: from ejeb12.prod.google.com ([2002:a17:906:194c:b0:b93:695d:528c]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:3e0d:b0:b8f:ae35:cbd3 with SMTP id a640c23a62f3a-b942e05d792mr145125366b.60.1772807762262; Fri, 06 Mar 2026 06:36:02 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:14 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-11-vdonnefort@google.com> Subject: [PATCH v13 10/32] tracing: Add events/ root files to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Just like for the kernel events directory, add 'enable', 'header_page' and 'header_event' at the root of the trace remote events/ directory. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 115435f2e8b9..60492e66a679 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -640,7 +640,8 @@ int ring_buffer_print_page_header(struct trace_buffer *= buffer, struct trace_seq trace_seq_printf(s, "\tfield: char data;\t" "offset:%u;\tsize:%u;\tsigned:%u;\n", (unsigned int)offsetof(typeof(field), data), - (unsigned int)buffer->subbuf_size, + (unsigned int)(buffer ? buffer->subbuf_size : + PAGE_SIZE - BUF_PAGE_HDR_SIZE), (unsigned int)is_signed_type(char)); =20 return !trace_seq_has_overflowed(s); diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 0d0af53c0ce9..0d78e5f5fe98 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -1125,10 +1125,145 @@ static int remote_event_callback(const char *name,= umode_t *mode, void **data, return 0; } =20 +static ssize_t remote_events_dir_enable_write(struct file *filp, const cha= r __user *ubuf, + size_t count, loff_t *ppos) +{ + struct trace_remote *remote =3D file_inode(filp)->i_private; + int i, ret; + u8 enable; + + ret =3D kstrtou8_from_user(ubuf, count, 10, &enable); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + for (i =3D 0; i < remote->nr_events; i++) { + struct remote_event *evt =3D &remote->events[i]; + + trace_remote_enable_event(remote, evt, enable); + } + + return count; +} + +static ssize_t remote_events_dir_enable_read(struct file *filp, char __use= r *ubuf, size_t cnt, + loff_t *ppos) +{ + struct trace_remote *remote =3D file_inode(filp)->i_private; + const char enabled_char[] =3D {'0', '1', 'X'}; + char enabled_str[] =3D " \n"; + int i, enabled =3D -1; + + guard(mutex)(&remote->lock); + + for (i =3D 0; i < remote->nr_events; i++) { + struct remote_event *evt =3D &remote->events[i]; + + if (enabled =3D=3D -1) { + enabled =3D evt->enabled; + } else if (enabled !=3D evt->enabled) { + enabled =3D 2; + break; + } + } + + enabled_str[0] =3D enabled_char[enabled =3D=3D -1 ? 0 : enabled]; + + return simple_read_from_buffer(ubuf, cnt, ppos, enabled_str, 2); +} + +static const struct file_operations remote_events_dir_enable_fops =3D { + .write =3D remote_events_dir_enable_write, + .read =3D remote_events_dir_enable_read, +}; + +static ssize_t +remote_events_dir_header_page_read(struct file *filp, char __user *ubuf, s= ize_t cnt, loff_t *ppos) +{ + struct trace_seq *s; + int ret; + + s =3D kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + trace_seq_init(s); + + ring_buffer_print_page_header(NULL, s); + ret =3D simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_use= d(s)); + kfree(s); + + return ret; +} + +static const struct file_operations remote_events_dir_header_page_fops =3D= { + .read =3D remote_events_dir_header_page_read, +}; + +static ssize_t +remote_events_dir_header_event_read(struct file *filp, char __user *ubuf, = size_t cnt, loff_t *ppos) +{ + struct trace_seq *s; + int ret; + + s =3D kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + trace_seq_init(s); + + ring_buffer_print_entry_header(s); + ret =3D simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_use= d(s)); + kfree(s); + + return ret; +} + +static const struct file_operations remote_events_dir_header_event_fops = =3D { + .read =3D remote_events_dir_header_event_read, +}; + +static int remote_events_dir_callback(const char *name, umode_t *mode, voi= d **data, + const struct file_operations **fops) +{ + if (!strcmp(name, "enable")) { + *mode =3D TRACEFS_MODE_WRITE; + *fops =3D &remote_events_dir_enable_fops; + return 1; + } + + if (!strcmp(name, "header_page")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_events_dir_header_page_fops; + return 1; + } + + if (!strcmp(name, "header_event")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_events_dir_header_event_fops; + return 1; + } + + return 0; +} + static int trace_remote_init_eventfs(const char *remote_name, struct trace= _remote *remote, struct remote_event *evt) { struct eventfs_inode *eventfs =3D remote->eventfs; + static struct eventfs_entry dir_entries[] =3D { + { + .name =3D "enable", + .callback =3D remote_events_dir_callback, + }, { + .name =3D "header_page", + .callback =3D remote_events_dir_callback, + }, { + .name =3D "header_event", + .callback =3D remote_events_dir_callback, + } + }; static struct eventfs_entry entries[] =3D { { .name =3D "enable", @@ -1144,7 +1279,8 @@ static int trace_remote_init_eventfs(const char *remo= te_name, struct trace_remot bool eventfs_create =3D false; =20 if (!eventfs) { - eventfs =3D eventfs_create_events_dir("events", remote->dentry, NULL, 0,= NULL); + eventfs =3D eventfs_create_events_dir("events", remote->dentry, dir_entr= ies, + ARRAY_SIZE(dir_entries), remote); if (IS_ERR(eventfs)) return PTR_ERR(eventfs); =20 --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5E4D3B8BB4 for ; Fri, 6 Mar 2026 14:36:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807766; cv=none; b=EAbAsAzuoKzO3hvWPBEtI16hbcKuZDC55xVAcZhCALH1uziAasHIF/2VbIFIlWEIFskRGBwt4Jn1ugTdbKlW0DF0HOfTay/Bdg0oA28wXdpQrMgqVvsDouWSNodYNC2vMal2iGr//OR6hV60pZpa1yqOtTlQtRxIl5C9YWhUJcg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807766; c=relaxed/simple; bh=JwsRGkcOcaoB6c3jYX0g+dDTHBJdqjZ8mV0DWOQIH+Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=nqShsF7I8/eUml2mpdW6P+niy5l7YS9t4lT3qNLtqbaC72weftEYEH5BIIlJ+3xPZ44C75S1tQO0yIu+filit7Yuv5ZHOWyOWtDH4hXhxMJ02So72XzyQri7VW4aq94jowlEJq9hxKoaqCRqoVSubsP8R/kTCLw5HcI0+GYE3Xs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=qKZpR/Ll; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="qKZpR/Ll" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4837b9913c9so73313815e9.0 for ; Fri, 06 Mar 2026 06:36:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807763; x=1773412563; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ik5Gwulkcj6xpLazaW4U87LROZJemTRhzFJsU5ExpD4=; b=qKZpR/LlZt3p/Hn5yfbApZLkxvKtyg0JmAB/fXTAO2t+DMTivA92z/REDceLJxr4RL 8dCvczad1c6w+d1f/5C9fptTA+vTiohd9tlronp6MGYck1o1z/DtCpoM9/NK/bQsLpqW ybtl858VNtDLtQYzP/5ayz6GO/3XNqwVOyTbvwSMza8Nb3tlD+571k/HdD5TG6iLeC2X 6dUXKHydsZov15BMpG0XfiTB0Icgop7jeVWPoqDOUDo6fxpoUI91PSjTHYIFK7XfifxU U0XOut68vbDnOcIZys5Z2sQ63hqKkpecGwK27jCzG37ZJU7SHSO7q51PWCjDVGKSTtrJ T5oA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807763; x=1773412563; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ik5Gwulkcj6xpLazaW4U87LROZJemTRhzFJsU5ExpD4=; b=m1AE1nX5+VJdKcVWCg9XdT5v4mRBF/ziAwECuZHVLSq9uiaSOcIYagkdVcqsHoPXZm YnTnu0sYMlTdPHQqvtt6AslfUTtHAiQLksG9cA999NitQxgzS42JloTa2EYoUfUcGJ4e 5jf8hp6xUHH27qGgcSafKucJtxEVeLCt2ryg3wPLSRae4D4H/qNPpiJVSxp4un9+HLzK kgF5mOau1Elq+UwWvKUg36IlJyx1E57+EvCl8AT77cvhvtI4Cf36J186tCc/PRMhmnEw JvZlMtSDe0hCjgeyHZ4Df+ap6mlRXp+G85JXKCGjd1bOMoCRG/0p7P4Hzz8B7ArSORzu +WqA== X-Forwarded-Encrypted: i=1; AJvYcCWmxnYDkzKFJS6kTESGGh30yYO4HXcQzfQPasI3RRmgadpg8sU9qgoFkkMYietK1JPsOgel3X8RkxbUSNU=@vger.kernel.org X-Gm-Message-State: AOJu0YzwNPX2nwcosNkdiqZe3RoI/JhBKUYpyPiQ5kHY2pw0xch4zzIh qqBWMwVqAEqlYnJ6byWhpymuwFPjgIy6s7g7jht4K5PIa+YgOZJcpuulBJBg0NZ4bOk4ggJuTcR gmJXkNnvTjse3WHS5zixsKg== X-Received: from wmlu24.prod.google.com ([2002:a05:600c:2118:b0:47e:ddf0:fd00]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b0c:b0:480:3ad0:93bf with SMTP id 5b1f17b1804b1-48526979668mr36579565e9.24.1772807763338; Fri, 06 Mar 2026 06:36:03 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:15 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-12-vdonnefort@google.com> Subject: [PATCH v13 11/32] tracing: Add helpers to create trace remote events From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Declaring remote events can be cumbersome let's add a set of macros to simplify developers life. The declaration of a remote event is very similar to kernel's events: REMOTE_EVENT(name, id, RE_STRUCT( re_field(u64 foo) ), RE_PRINTK("foo=3D%llu", __entry->foo) ) Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remot= e_event.h index a4449008a075..c8ae1e1f5e72 100644 --- a/include/linux/trace_remote_event.h +++ b/include/linux/trace_remote_event.h @@ -5,6 +5,7 @@ =20 struct trace_remote; struct trace_event_fields; +struct trace_seq; =20 struct remote_event_hdr { unsigned short id; @@ -20,4 +21,13 @@ struct remote_event { char *print_fmt; void (*print)(void *evt, struct trace_seq *seq); }; + +#define RE_STRUCT(__args...) __args +#define re_field(__type, __field) __type __field; + +#define REMOTE_EVENT_FORMAT(__name, __struct) \ + struct remote_event_format_##__name { \ + struct remote_event_hdr hdr; \ + __struct \ + } #endif diff --git a/include/trace/define_remote_events.h b/include/trace/define_re= mote_events.h new file mode 100644 index 000000000000..676e803dc144 --- /dev/null +++ b/include/trace/define_remote_events.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include +#include + +#define REMOTE_EVENT_INCLUDE(__file) __stringify(../../__file) + +#ifdef REMOTE_EVENT_SECTION +# define __REMOTE_EVENT_SECTION(__name) __used __section(REMOTE_EVENT_SECT= ION"."#__name) +#else +# define __REMOTE_EVENT_SECTION(__name) +#endif + +#define REMOTE_PRINTK_COUNT_ARGS(__args...) \ + __COUNT_ARGS(, ##__args, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0) + +#define __remote_printk0() \ + trace_seq_putc(seq, '\n') + +#define __remote_printk1(__fmt) \ + trace_seq_puts(seq, " " __fmt "\n") \ + +#define __remote_printk2(__fmt, __args...) \ +do { \ + trace_seq_putc(seq, ' '); \ + trace_seq_printf(seq, __fmt, __args); \ + trace_seq_putc(seq, '\n'); \ +} while (0) + +/* Apply the appropriate trace_seq sequence according to the number of arg= uments */ +#define remote_printk(__args...) \ + CONCATENATE(__remote_printk, REMOTE_PRINTK_COUNT_ARGS(__args))(__args) + +#define RE_PRINTK(__args...) __args + +#define REMOTE_EVENT(__name, __id, __struct, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + static void remote_event_print_##__name(void *evt, struct trace_seq *seq)= \ + { \ + struct remote_event_format_##__name __maybe_unused *__entry =3D evt; \ + trace_seq_puts(seq, #__name); \ + remote_printk(__printk); \ + } +#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) + +#undef REMOTE_EVENT +#undef RE_PRINTK +#undef re_field +#define re_field(__type, __field) \ + { \ + .type =3D #__type, .name =3D #__field, \ + .size =3D sizeof(__type), .align =3D __alignof__(__type), \ + .is_signed =3D is_signed_type(__type), \ + }, +#define __entry REC +#define RE_PRINTK(__fmt, __args...) "\"" __fmt "\", " __stringify(__args) +#define REMOTE_EVENT(__name, __id, __struct, __printk) \ + static struct trace_event_fields remote_event_fields_##__name[] =3D { \ + __struct \ + {} \ + }; \ + static char remote_event_print_fmt_##__name[] =3D __printk; \ + static struct remote_event __REMOTE_EVENT_SECTION(__name) \ + remote_event_##__name =3D { \ + .name =3D #__name, \ + .id =3D __id, \ + .fields =3D remote_event_fields_##__name, \ + .print_fmt =3D remote_event_print_fmt_##__name, \ + .print =3D remote_event_print_##__name, \ + } +#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24B783B8D46 for ; Fri, 6 Mar 2026 14:36:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807768; cv=none; b=uF7k6lRcoC67/6/CBv48GjUQZ2FvD9/iEuLU3E+2jvKwmygkV65BmXMc7/TcUn96cCUyBR9WAduEjxNZnPc8BqTse2CB6R2zt6QQnzb4+S72NgOnnBpKPAr3s+in6aMJwIgtA4IlN3/2tji86POXtyjJBXuZBRR8gTp/C+GyXbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807768; c=relaxed/simple; bh=bRMPRQ6NDGKO/79oRcKvy6u1F4kH2tLwljEjHcAin/A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r0MOSHK//gAwlvKTP+tsjRcwMMQDbh9Vp4Z1L0H7InYVCm9OaE2qrxAi30UjhN5I7Qu+mn/WEz6XEHm9ke8f/CQUOsHV9t388hVjtx/RwvvRpFyPJuxpFaNzpTp8NcFlB884mngTmTs30o13QRQdiUpSfoAI8wodd2kUbdXCYUo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=CyTDd9Ix; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="CyTDd9Ix" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4836b7c302fso93470295e9.1 for ; Fri, 06 Mar 2026 06:36:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807764; x=1773412564; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=A0wMQ/1n9X5j3XgVqCp+O5b7W1hHbkcpIUXjLxrGdB0=; b=CyTDd9Ix5XsPZNRDxCHWFt22iFa4oDgT1ifRqa/qOUTq2ASLkSnbpd9TD8OsPN6hMU UkqUXSriIPDiLzFHlwolyUMJSz8G31ZVg1fL7EynVVM2Bk+nJrh0BzI80VKR/yVpRxRi M8dC+O9u6PAUhkyA+0X21WyXzHghSCu18KP6NbsVY1NDqhjiEd3Y5+vXI619rHWX8DS3 5M7xefK+vyjCsKVX4Mr7Vrhxt4jWdpL+gXrDhuO/N90dwPFmRLxiC5IzSUDbbycamoKz V++lyITp295P7DQ/UgOPR0F1e3yaywz8BLfNfYyO7XvoWqJFUlqFpj7ToWZQuDL9ExnG qCUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807764; x=1773412564; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=A0wMQ/1n9X5j3XgVqCp+O5b7W1hHbkcpIUXjLxrGdB0=; b=QLJ8v4pEC/COQ5IoO1SS2GvD/BdTeW0givf16mkg3cNuoCvxVKtqfx/1DRswnczA8g A7K8u2dkqzi2dZUjnokeJqQr0dycldoppk5R3C94+pMMzpKCYkXF+FE7iFPigqUZzkI6 vSbiZEdsAaPMVFZIKHHaTLWxTo6v1scEjAWlDZI3kb1d2vr2kQXjXM2BHnc22OTVlKwq b7mAgqoAjjWJlG+1IbjsrhjQkh+zGTmnCmwft9KDA7z9HkzJ4e86NLm31g6+Wqy3Vg9C DYIX6AmzDQ5ys1ebIyxBGwaJN1z/lAfgpS93xbK+kLZMfDQqcwXXRVHyw3NDzvL8jQXM k7EA== X-Forwarded-Encrypted: i=1; AJvYcCVlMAWRq1wa35S+odA8aaC8b8QJPMkvkGvnbcxvdY0cf+zVnW+plKf8gSogAiVO5shD8neUZW0pDEgRE9o=@vger.kernel.org X-Gm-Message-State: AOJu0YwwyNasvhfqaB8MEzzM1kvT3teatDMJCsyHbaK7jVSzM123S4Tf wPfreVdJw2PGjqrRq0tzkW3qzYYJqB9m6YW7osfvCzBsLZPEAFbTqzzs1dqptxQ/BM7H834TY9T G/f8w4o35aegKItyImSU1cA== X-Received: from wmbjw5.prod.google.com ([2002:a05:600c:5745:b0:483:6c98:3d2f]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1991:b0:479:35e7:a0e3 with SMTP id 5b1f17b1804b1-48526977699mr37901595e9.30.1772807764177; Fri, 06 Mar 2026 06:36:04 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:16 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-13-vdonnefort@google.com> Subject: [PATCH v13 12/32] ring-buffer: Export buffer_data_page and macros From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for allowing the writing of ring-buffer compliant pages outside of ring_buffer.c, move buffer_data_page and timestamps encoding macros into the publicly available ring_buffer_types.h. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer_types.h b/include/linux/ring_buffer_= types.h new file mode 100644 index 000000000000..54577021a49d --- /dev/null +++ b/include/linux/ring_buffer_types.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_RING_BUFFER_TYPES_H +#define _LINUX_RING_BUFFER_TYPES_H + +#include + +#define TS_SHIFT 27 +#define TS_MASK ((1ULL << TS_SHIFT) - 1) +#define TS_DELTA_TEST (~TS_MASK) + +/* + * We need to fit the time_stamp delta into 27 bits. + */ +static inline bool test_time_stamp(u64 delta) +{ + return !!(delta & TS_DELTA_TEST); +} + +#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) + +#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) +#define RB_ALIGNMENT 4U +#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) +#define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ + +#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS +# define RB_FORCE_8BYTE_ALIGNMENT 0 +# define RB_ARCH_ALIGNMENT RB_ALIGNMENT +#else +# define RB_FORCE_8BYTE_ALIGNMENT 1 +# define RB_ARCH_ALIGNMENT 8U +#endif + +#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) + +struct buffer_data_page { + u64 time_stamp; /* page time stamp */ + local_t commit; /* write committed index */ + unsigned char data[] RB_ALIGN_DATA; /* data of buffer page */ +}; +#endif diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 60492e66a679..d92b615e9246 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4,6 +4,7 @@ * * Copyright (C) 2008 Steven Rostedt */ +#include #include #include #include @@ -157,23 +158,6 @@ int ring_buffer_print_entry_header(struct trace_seq *s) /* Used for individual buffers (after the counter) */ #define RB_BUFFER_OFF (1 << 20) =20 -#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) - -#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) -#define RB_ALIGNMENT 4U -#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) -#define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ - -#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS -# define RB_FORCE_8BYTE_ALIGNMENT 0 -# define RB_ARCH_ALIGNMENT RB_ALIGNMENT -#else -# define RB_FORCE_8BYTE_ALIGNMENT 1 -# define RB_ARCH_ALIGNMENT 8U -#endif - -#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) - /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX =20 @@ -316,10 +300,6 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data); #define for_each_online_buffer_cpu(buffer, cpu) \ for_each_cpu_and(cpu, buffer->cpumask, cpu_online_mask) =20 -#define TS_SHIFT 27 -#define TS_MASK ((1ULL << TS_SHIFT) - 1) -#define TS_DELTA_TEST (~TS_MASK) - static u64 rb_event_time_stamp(struct ring_buffer_event *event) { u64 ts; @@ -338,12 +318,6 @@ static u64 rb_event_time_stamp(struct ring_buffer_even= t *event) =20 #define RB_MISSED_MASK (3 << 30) =20 -struct buffer_data_page { - u64 time_stamp; /* page time stamp */ - local_t commit; /* write committed index */ - unsigned char data[] RB_ALIGN_DATA; /* data of buffer page */ -}; - struct buffer_data_read_page { unsigned order; /* order of the page */ struct buffer_data_page *data; /* actual data, stored in this page */ @@ -437,14 +411,6 @@ static struct buffer_data_page *alloc_cpu_data(int cpu= , int order) return dpage; } =20 -/* - * We need to fit the time_stamp delta into 27 bits. - */ -static inline bool test_time_stamp(u64 delta) -{ - return !!(delta & TS_DELTA_TEST); -} - struct rb_irq_work { struct irq_work work; wait_queue_head_t waiters; --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36F7D3B95FC for ; Fri, 6 Mar 2026 14:36:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807769; cv=none; b=Xodk7K9ankf/yijYrYO5Gc6AVq6nIZpcu+5udc48mz6MrQy/WU1QVQUGNfIxkGuNRCWAPt0WPA+p7f1YkHJU3nJWda1CuLHnXnSFzGolFAUOgunOO+zeTN4jnZiKNqoKLfwcU+6hrwq08Q9WEhhyAXgLGEcz49OK3/tYAeRg6zM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807769; c=relaxed/simple; bh=SOtPV2kJuegkUz5un0jOBurnkb2AK0pc4kYvTYA4brA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aDsjeUp/sDtkw1Qf7ZGUIKUzTl24ULq2xst62jMSov1NQWlxT+2SHfyYKphn95aDpoeU8e70wlpAaWT1Blpy4oawcBlfrk6MGPIeV0TvCezUYKZnjCwofxOQCyBn7ZeYXaypBIFPNAPJekOkst1AQBaGUpP/MVqj/OfR72hmaAk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Jh6D3KIm; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Jh6D3KIm" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4837b6f6b93so72040855e9.3 for ; Fri, 06 Mar 2026 06:36:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807765; x=1773412565; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ZNOTRs4iIipAmbGcStURHU2dLg0jPZDKU5s35fK2kQc=; b=Jh6D3KImsTmLQmGHmTmyMy1icyl5DCytxV093GqJUM2BcSsMDhAkVGg34rn6TEetZ7 aPaA2SiDY+b/b2BqfqTE+qyBYw6er3t3Z8K1JdLPi3H797MMHHQNP/Ytyy3aOJ2NZVan UZpcImreA/I8kbQmwQ9cJKuGiheJtwCey3lnA6l54aaYLRhLPRvIkXY24QaLfi9Gucsg K2MW/E0Kmt7VjeNX3u1oivFl5vZehzOdFkSjZEJnzYntFqkfBx/COuhhAazueday3QUv QgtfyrMQtMUFs5CY+l9JX07Bkk8rZSS3ZoX4LucmwjQQ3sjChoAPEgxh1iBabOyXp0XP v9rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807765; x=1773412565; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ZNOTRs4iIipAmbGcStURHU2dLg0jPZDKU5s35fK2kQc=; b=HDaJaFt0CQiX+D+vwy96Pm2qRdVcJofbBWEyOSW926E1Frm1pf9a90vtM044aCNwR0 L5nXDuJ/QDKtx551o+hVsFL/SP+kS8RXXw3TkxmicBl50FW1QZIwGxIGVT9+ylWQepmJ 8/A/NNh/m2vdcemXd8NVmgZ5HuajlsBVCvUtTa2ZPvTg9vcz3rCzFmSXATk+1I9EKOOe fZra7S5UYJeWdFwU8/vxyd5OMRv2Um/siF8V6f/t5f3NpGUhcCO5SBtEvBkmjwQ89Pde z7PmDc6tZ0UqZqwAKX0NM1JdLJi6Vppl4cxDZ7tIA1VIqougdksbdHYmA4zVYx+vGO/Z Kpag== X-Forwarded-Encrypted: i=1; AJvYcCWKOzuKzeXOhhSosH4OXAGapny1Qqu/4ZWMPaj4Ckgvx0kTbl/hJNwCtUWq2dJV8lYA0bxbDcG03u9LM1g=@vger.kernel.org X-Gm-Message-State: AOJu0Yz3oargEeOLTLLkk/w829NoSsUTGZQEY5PFo+tW1avIZ1chaXpZ FGod+hQC7RXz5RR2yweg5L2DozUEFUCcypKesEncYZpLt/Xb8NQCpSivQPf7lUNTuZcO7VdWC6V psRyVQ95wA9iiePOqfU0Hkw== X-Received: from wmpz11.prod.google.com ([2002:a05:600c:a0b:b0:483:7a98:f072]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:470d:b0:483:7f4e:fef6 with SMTP id 5b1f17b1804b1-48526966afamr37942495e9.26.1772807765432; Fri, 06 Mar 2026 06:36:05 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:17 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-14-vdonnefort@google.com> Subject: [PATCH v13 13/32] tracing: Introduce simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a simple implementation of the kernel ring-buffer. This intends to be used later by ring-buffer remotes such as the pKVM hypervisor, hence the need for a cut down version (write only) without any dependency. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/simple_ring_buffer.h b/include/linux/simple_ring= _buffer.h new file mode 100644 index 000000000000..2c4c0ae336bc --- /dev/null +++ b/include/linux/simple_ring_buffer.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_SIMPLE_RING_BUFFER_H +#define _LINUX_SIMPLE_RING_BUFFER_H + +#include +#include +#include +#include + +/* + * Ideally those struct would stay private but the caller needs to know + * the allocation size for simple_ring_buffer_init(). + */ +struct simple_buffer_page { + struct list_head link; + struct buffer_data_page *page; + u64 entries; + u32 write; + u32 id; +}; + +struct simple_rb_per_cpu { + struct simple_buffer_page *tail_page; + struct simple_buffer_page *reader_page; + struct simple_buffer_page *head_page; + struct simple_buffer_page *bpages; + struct trace_buffer_meta *meta; + u32 nr_pages; + +#define SIMPLE_RB_UNAVAILABLE 0 +#define SIMPLE_RB_READY 1 +#define SIMPLE_RB_WRITING 2 + u32 status; + + u64 last_overrun; + u64 write_stamp; + + struct simple_rb_cbs *cbs; +}; + +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc); + +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer); + +void *simple_ring_buffer_reserve(struct simple_rb_per_cpu *cpu_buffer, uns= igned long length, + u64 timestamp); + +void simple_ring_buffer_commit(struct simple_rb_per_cpu *cpu_buffer); + +int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable); + +int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer); + +int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); + +#endif diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 384dd36c8e29..edbdd7b38f61 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1284,4 +1284,7 @@ source "kernel/trace/rv/Kconfig" config TRACE_REMOTE bool =20 +config SIMPLE_RING_BUFFER + bool + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 318923ce39f5..2e39b09398b3 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -129,4 +129,5 @@ obj-$(CONFIG_TRACEPOINT_BENCHMARK) +=3D trace_benchmark= .o obj-$(CONFIG_RV) +=3D rv/ =20 obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o +obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o libftrace-y :=3D ftrace.o diff --git a/kernel/trace/simple_ring_buffer.c b/kernel/trace/simple_ring_b= uffer.c new file mode 100644 index 000000000000..15df9781411b --- /dev/null +++ b/kernel/trace/simple_ring_buffer.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include +#include + +enum simple_rb_link_type { + SIMPLE_RB_LINK_NORMAL =3D 0, + SIMPLE_RB_LINK_HEAD =3D 1, + SIMPLE_RB_LINK_HEAD_MOVING +}; + +#define SIMPLE_RB_LINK_MASK ~(SIMPLE_RB_LINK_HEAD | SIMPLE_RB_LINK_HEAD_MO= VING) + +static void simple_bpage_set_head_link(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)bpage->link.next; + + link &=3D SIMPLE_RB_LINK_MASK; + link |=3D SIMPLE_RB_LINK_HEAD; + + /* + * Paired with simple_rb_find_head() to order access between the head + * link and overrun. It ensures we always report an up-to-date value + * after swapping the reader page. + */ + smp_store_release(&bpage->link.next, (struct list_head *)link); +} + +static bool simple_bpage_unset_head_link(struct simple_buffer_page *bpage, + struct simple_buffer_page *dst, + enum simple_rb_link_type new_type) +{ + unsigned long *link =3D (unsigned long *)(&bpage->link.next); + unsigned long old =3D (*link & SIMPLE_RB_LINK_MASK) | SIMPLE_RB_LINK_HEAD; + unsigned long new =3D (unsigned long)(&dst->link) | new_type; + + return try_cmpxchg(link, &old, new); +} + +static void simple_bpage_set_normal_link(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)bpage->link.next; + + WRITE_ONCE(bpage->link.next, (struct list_head *)(link & SIMPLE_RB_LINK_M= ASK)); +} + +static struct simple_buffer_page *simple_bpage_from_link(struct list_head = *link) +{ + unsigned long ptr =3D (unsigned long)link & SIMPLE_RB_LINK_MASK; + + return container_of((struct list_head *)ptr, struct simple_buffer_page, l= ink); +} + +static struct simple_buffer_page *simple_bpage_next_page(struct simple_buf= fer_page *bpage) +{ + return simple_bpage_from_link(bpage->link.next); +} + +static void simple_bpage_reset(struct simple_buffer_page *bpage) +{ + bpage->write =3D 0; + bpage->entries =3D 0; + + local_set(&bpage->page->commit, 0); +} + +static void simple_bpage_init(struct simple_buffer_page *bpage, unsigned l= ong page) +{ + INIT_LIST_HEAD(&bpage->link); + bpage->page =3D (struct buffer_data_page *)page; + + simple_bpage_reset(bpage); +} + +#define simple_rb_meta_inc(__meta, __inc) \ + WRITE_ONCE((__meta), (__meta + __inc)) + +static bool simple_rb_loaded(struct simple_rb_per_cpu *cpu_buffer) +{ + return !!cpu_buffer->bpages; +} + +static int simple_rb_find_head(struct simple_rb_per_cpu *cpu_buffer) +{ + int retry =3D cpu_buffer->nr_pages * 2; + struct simple_buffer_page *head; + + head =3D cpu_buffer->head_page; + + while (retry--) { + unsigned long link; + +spin: + /* See smp_store_release in simple_bpage_set_head_link() */ + link =3D (unsigned long)smp_load_acquire(&head->link.prev->next); + + switch (link & ~SIMPLE_RB_LINK_MASK) { + /* Found the head */ + case SIMPLE_RB_LINK_HEAD: + cpu_buffer->head_page =3D head; + return 0; + /* The writer caught the head, we can spin, that won't be long */ + case SIMPLE_RB_LINK_HEAD_MOVING: + goto spin; + } + + head =3D simple_bpage_next_page(head); + } + + return -EBUSY; +} + +/** + * simple_ring_buffer_swap_reader_page - Swap ring-buffer head with the re= ader + * @cpu_buffer: A simple_rb_per_cpu + * + * This function enables consuming reading. It ensures the current head pa= ge will not be overwritten + * and can be safely read. + * + * Returns 0 on success, -ENODEV if @cpu_buffer was unloaded or -EBUSY if = we failed to catch the + * head page. + */ +int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er) +{ + struct simple_buffer_page *last, *head, *reader; + unsigned long overrun; + int retry =3D 8; + int ret; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + reader =3D cpu_buffer->reader_page; + + do { + /* Run after the writer to find the head */ + ret =3D simple_rb_find_head(cpu_buffer); + if (ret) + return ret; + + head =3D cpu_buffer->head_page; + + /* Connect the reader page around the header page */ + reader->link.next =3D head->link.next; + reader->link.prev =3D head->link.prev; + + /* The last page before the head */ + last =3D simple_bpage_from_link(head->link.prev); + + /* The reader page points to the new header page */ + simple_bpage_set_head_link(reader); + + overrun =3D cpu_buffer->meta->overrun; + } while (!simple_bpage_unset_head_link(last, reader, SIMPLE_RB_LINK_NORMA= L) && retry--); + + if (!retry) + return -EINVAL; + + cpu_buffer->head_page =3D simple_bpage_from_link(reader->link.next); + cpu_buffer->head_page->link.prev =3D &reader->link; + cpu_buffer->reader_page =3D head; + cpu_buffer->meta->reader.lost_events =3D overrun - cpu_buffer->last_overr= un; + cpu_buffer->meta->reader.id =3D cpu_buffer->reader_page->id; + cpu_buffer->last_overrun =3D overrun; + + return 0; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_swap_reader_page); + +static struct simple_buffer_page *simple_rb_move_tail(struct simple_rb_per= _cpu *cpu_buffer) +{ + struct simple_buffer_page *tail, *new_tail; + + tail =3D cpu_buffer->tail_page; + new_tail =3D simple_bpage_next_page(tail); + + if (simple_bpage_unset_head_link(tail, new_tail, SIMPLE_RB_LINK_HEAD_MOVI= NG)) { + /* + * Oh no! we've caught the head. There is none anymore and + * swap_reader will spin until we set the new one. Overrun must + * be written first, to make sure we report the correct number + * of lost events. + */ + simple_rb_meta_inc(cpu_buffer->meta->overrun, new_tail->entries); + simple_rb_meta_inc(cpu_buffer->meta->pages_lost, 1); + + simple_bpage_set_head_link(new_tail); + simple_bpage_set_normal_link(tail); + } + + simple_bpage_reset(new_tail); + cpu_buffer->tail_page =3D new_tail; + + simple_rb_meta_inc(cpu_buffer->meta->pages_touched, 1); + + return new_tail; +} + +static unsigned long rb_event_size(unsigned long length) +{ + struct ring_buffer_event *event; + + return length + RB_EVNT_HDR_SIZE + sizeof(event->array[0]); +} + +static struct ring_buffer_event * +rb_event_add_ts_extend(struct ring_buffer_event *event, u64 delta) +{ + event->type_len =3D RINGBUF_TYPE_TIME_EXTEND; + event->time_delta =3D delta & TS_MASK; + event->array[0] =3D delta >> TS_SHIFT; + + return (struct ring_buffer_event *)((unsigned long)event + 8); +} + +static struct ring_buffer_event * +simple_rb_reserve_next(struct simple_rb_per_cpu *cpu_buffer, unsigned long= length, u64 timestamp) +{ + unsigned long ts_ext_size =3D 0, event_size =3D rb_event_size(length); + struct simple_buffer_page *tail =3D cpu_buffer->tail_page; + struct ring_buffer_event *event; + u32 write, prev_write; + u64 time_delta; + + time_delta =3D timestamp - cpu_buffer->write_stamp; + + if (test_time_stamp(time_delta)) + ts_ext_size =3D 8; + + prev_write =3D tail->write; + write =3D prev_write + event_size + ts_ext_size; + + if (unlikely(write > (PAGE_SIZE - BUF_PAGE_HDR_SIZE))) + tail =3D simple_rb_move_tail(cpu_buffer); + + if (!tail->entries) { + tail->page->time_stamp =3D timestamp; + time_delta =3D 0; + ts_ext_size =3D 0; + write =3D event_size; + prev_write =3D 0; + } + + tail->write =3D write; + tail->entries++; + + cpu_buffer->write_stamp =3D timestamp; + + event =3D (struct ring_buffer_event *)(tail->page->data + prev_write); + if (ts_ext_size) { + event =3D rb_event_add_ts_extend(event, time_delta); + time_delta =3D 0; + } + + event->type_len =3D 0; + event->time_delta =3D time_delta; + event->array[0] =3D event_size - RB_EVNT_HDR_SIZE; + + return event; +} + +/** + * simple_ring_buffer_reserve - Reserve an entry in @cpu_buffer + * @cpu_buffer: A simple_rb_per_cpu + * @length: Size of the entry in bytes + * @timestamp: Timestamp of the entry + * + * Returns the address of the entry where to write data or NULL + */ +void *simple_ring_buffer_reserve(struct simple_rb_per_cpu *cpu_buffer, uns= igned long length, + u64 timestamp) +{ + struct ring_buffer_event *rb_event; + + if (cmpxchg(&cpu_buffer->status, SIMPLE_RB_READY, SIMPLE_RB_WRITING) !=3D= SIMPLE_RB_READY) + return NULL; + + rb_event =3D simple_rb_reserve_next(cpu_buffer, length, timestamp); + + return &rb_event->array[1]; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_reserve); + +/** + * simple_ring_buffer_commit - Commit the entry reserved with simple_ring_= buffer_reserve() + * @cpu_buffer: The simple_rb_per_cpu where the entry has been reserved + */ +void simple_ring_buffer_commit(struct simple_rb_per_cpu *cpu_buffer) +{ + local_set(&cpu_buffer->tail_page->page->commit, + cpu_buffer->tail_page->write); + simple_rb_meta_inc(cpu_buffer->meta->entries, 1); + + /* + * Paired with simple_rb_enable_tracing() to ensure data is + * written to the ring-buffer before teardown. + */ + smp_store_release(&cpu_buffer->status, SIMPLE_RB_READY); +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_commit); + +static u32 simple_rb_enable_tracing(struct simple_rb_per_cpu *cpu_buffer, = bool enable) +{ + u32 prev_status; + + if (enable) + return cmpxchg(&cpu_buffer->status, SIMPLE_RB_UNAVAILABLE, SIMPLE_RB_REA= DY); + + /* Wait for the buffer to be released */ + do { + prev_status =3D cmpxchg_acquire(&cpu_buffer->status, + SIMPLE_RB_READY, + SIMPLE_RB_UNAVAILABLE); + } while (prev_status =3D=3D SIMPLE_RB_WRITING); + + return prev_status; +} + +/** + * simple_ring_buffer_reset - Reset @cpu_buffer + * @cpu_buffer: A simple_rb_per_cpu + * + * This will not clear the content of the data, only reset counters and po= inters + * + * Returns 0 on success or -ENODEV if @cpu_buffer was unloaded. + */ +int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer) +{ + struct simple_buffer_page *bpage; + u32 prev_status; + int ret; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + prev_status =3D simple_rb_enable_tracing(cpu_buffer, false); + + ret =3D simple_rb_find_head(cpu_buffer); + if (ret) + return ret; + + bpage =3D cpu_buffer->tail_page =3D cpu_buffer->head_page; + do { + simple_bpage_reset(bpage); + bpage =3D simple_bpage_next_page(bpage); + } while (bpage !=3D cpu_buffer->head_page); + + simple_bpage_reset(cpu_buffer->reader_page); + + cpu_buffer->last_overrun =3D 0; + cpu_buffer->write_stamp =3D 0; + + cpu_buffer->meta->reader.read =3D 0; + cpu_buffer->meta->reader.lost_events =3D 0; + cpu_buffer->meta->entries =3D 0; + cpu_buffer->meta->overrun =3D 0; + cpu_buffer->meta->read =3D 0; + cpu_buffer->meta->pages_lost =3D 0; + cpu_buffer->meta->pages_touched =3D 0; + + if (prev_status =3D=3D SIMPLE_RB_READY) + simple_rb_enable_tracing(cpu_buffer, true); + + return 0; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_reset); + +/** + * simple_ring_buffer_init - Init @cpu_buffer based on @desc + * @cpu_buffer: A simple_rb_per_cpu buffer to init, allocated by the calle= r. + * @bpages: Array of simple_buffer_pages, with as many elements as @desc->= nr_page_va + * @desc: A ring_buffer_desc + * + * Returns 0 on success or -EINVAL if the content of @desc is invalid + */ +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc) +{ + struct simple_buffer_page *bpage =3D bpages; + int i; + + /* At least 1 reader page and two pages in the ring-buffer */ + if (desc->nr_page_va < 3) + return -EINVAL; + + memset(cpu_buffer, 0, sizeof(*cpu_buffer)); + + cpu_buffer->bpages =3D bpages; + + cpu_buffer->meta =3D (void *)desc->meta_va; + memset(cpu_buffer->meta, 0, sizeof(*cpu_buffer->meta)); + cpu_buffer->meta->meta_page_size =3D PAGE_SIZE; + cpu_buffer->meta->nr_subbufs =3D cpu_buffer->nr_pages; + + /* The reader page is not part of the ring initially */ + simple_bpage_init(bpage, desc->page_va[0]); + bpage->id =3D 0; + + cpu_buffer->nr_pages =3D 1; + + cpu_buffer->reader_page =3D bpage; + cpu_buffer->tail_page =3D bpage + 1; + cpu_buffer->head_page =3D bpage + 1; + + for (i =3D 1; i < desc->nr_page_va; i++) { + simple_bpage_init(++bpage, desc->page_va[i]); + + bpage->link.next =3D &(bpage + 1)->link; + bpage->link.prev =3D &(bpage - 1)->link; + bpage->id =3D i; + + cpu_buffer->nr_pages =3D i + 1; + } + + /* Close the ring */ + bpage->link.next =3D &cpu_buffer->tail_page->link; + cpu_buffer->tail_page->link.prev =3D &bpage->link; + + /* The last init'ed page points to the head page */ + simple_bpage_set_head_link(bpage); + + return 0; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_init); + +/** + * simple_ring_buffer_unload - Prepare @cpu_buffer for deletion + * @cpu_buffer: A simple_rb_per_cpu that will be deleted. + */ +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +{ + if (!simple_rb_loaded(cpu_buffer)) + return; + + simple_rb_enable_tracing(cpu_buffer, false); + + cpu_buffer->bpages =3D NULL; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_unload); + +/** + * simple_ring_buffer_enable_tracing - Enable or disable writing to @cpu_b= uffer + * @cpu_buffer: A simple_rb_per_cpu + * @enable: True to enable tracing, False to disable it + * + * Returns 0 on success or -ENODEV if @cpu_buffer was unloaded + */ +int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable) +{ + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + simple_rb_enable_tracing(cpu_buffer, enable); + + return 0; +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_enable_tracing); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-ed1-f74.google.com (mail-ed1-f74.google.com [209.85.208.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 713CF3BA230 for ; Fri, 6 Mar 2026 14:36:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807770; cv=none; b=FP9I98Hu2xt7cbjtCZOsBbGvUUmit9TL24FeCaYjSXiL9U+UjZz7MxTj8628c+UKFjNCjnhV6pVo8t8pTvfIgBWw8v1UONfoeySp5p2cBRRywYbvYhMwkmdvWdMgKEmfs+OBMB7PdJMfQZnRJgveNbh7udz4aQMwxAfdObSfC5s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807770; c=relaxed/simple; bh=La5H0+eSc2f/3ad9bpFJQWMSyen05nzmJ9+5BKnfkKg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=X4u3IjBWOSnoyq/X9kj34PasZRtnRUVnY0QuwnC+ix0Hs029x5cCzV+p7Prnbh4B/0dbKe3G6BrGzLSmOTxlfsbIGqMVCaNJI0Vy7fKV+7RqAsesXoSWtZ658qXMTtNdhME9S2lN024Fh9By6tb2dJXX15Wc8TL4/59lHyWIuuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=VTS/Jeu+; arc=none smtp.client-ip=209.85.208.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VTS/Jeu+" Received: by mail-ed1-f74.google.com with SMTP id 4fb4d7f45d1cf-660fa747a8aso2864492a12.2 for ; Fri, 06 Mar 2026 06:36:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807767; x=1773412567; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xgroQyy8qgZmYVsuEFGo6Q2+HkCJ1V8/DHMPUdpqy9U=; b=VTS/Jeu+BFbweA4NtsrLzzMgbmKfxS3OGS9lLwKme9IteX4FFaw2uKjQ1QjFsEuCpu MjGyFxHhLz5pWQFWMngiVttel/8eEB3B3//alF951ZFH9s4M3ubKoW9DV8CgQInC92GO 5yis7hkEUoBspBXHh/k/Dd7gffK7swRlUHIstaL2B5VE68ExMqNl8NEpswTi6xHMFRa5 t2s1MQacAb0oVLRceADzrWsC4xHc3S25mQ3PqskSgWycl+hyYCkVTbvP93EDwvOjUnBw pTES05dEPbdJq94DHVatRAvHg6uhK3SmtwAR7eCM3arE0rHg9thVpNFX58oRMkKUiKXc ud9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807767; x=1773412567; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xgroQyy8qgZmYVsuEFGo6Q2+HkCJ1V8/DHMPUdpqy9U=; b=lH234DdYOM6nt7AvzMwSbP0zKjPpyv30ImDiMKDSFv/K1d5DdUvqjMna7KPP/ThUJ1 P0VFP800Bfq5Foy5Zih+//5RZkFZyXFIMiLeHPXwpDNkJCbMJJ6+HLKK/8p7j5KJuacL m/V0i/0JI0V6ixNDiSwkJBNQPiBB34OQYgDpxM3pt+Yge+cn7HAko1g+pxwSQpZG5+om 2s18s5UNBicPxiPm6zlSdgz9rNXTFOd8wZL/0YHMEJgkg6PDXSqRLuAYfKsHrITbyc6x PKMdJ+wkre3bPpL5eHd+gnv0r8rGNL9eF0guOgQf/ts69etXkJRtfWK9uA1BnAVmfMGE 4VLQ== X-Forwarded-Encrypted: i=1; AJvYcCWTW46Yzzg115d2YoQ4WudgpDPn3ogqoN1wK/98zoXDwwi3hOAlP/qvBoTpzBt4TDe4fFyxqj/Au9/pr3s=@vger.kernel.org X-Gm-Message-State: AOJu0Yxc2GktX/x4ue2zOEoQLXieQ99LlAAneDl4ZZx11BHxzdji3mZ+ CSRuvYIwZjdvJvBKN1kuNC+twQuiNQ4JiQxRBfArb+KX0SoQPvW9b/idjQv7CTyYnZVYDcDXcX6 cfyN230WtOtSuoQQqS9fkug== X-Received: from edew6-n1.prod.google.com ([2002:a05:6402:a206:10b0:660:e0df:9755]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:210b:b0:661:169b:fce6 with SMTP id 4fb4d7f45d1cf-6619d47f1e9mr1318369a12.12.1772807766681; Fri, 06 Mar 2026 06:36:06 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:18 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-15-vdonnefort@google.com> Subject: [PATCH v13 14/32] tracing: Add a trace remote module for testing From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a module to help testing the tracefs support for trace remotes. This module: * Use simple_ring_buffer to write into a ring-buffer. * Declare a single "selftest" event that can be triggered from user-space. * Register a "test" trace remote. This is intended to be used by trace remote selftests. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 51c00c8fa175..edfdf139cb02 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -664,6 +664,7 @@ struct dentry *tracefs_create_file(const char *name, um= ode_t mode, fsnotify_create(d_inode(dentry->d_parent), dentry); return tracefs_end_creating(dentry); } +EXPORT_SYMBOL_GPL(tracefs_create_file); =20 static struct dentry *__create_dir(const char *name, struct dentry *parent, const struct inode_operations *ops) diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index edbdd7b38f61..e130da35808f 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1287,4 +1287,12 @@ config TRACE_REMOTE config SIMPLE_RING_BUFFER bool =20 +config TRACE_REMOTE_TEST + tristate "Test module for remote tracing" + select TRACE_REMOTE + select SIMPLE_RING_BUFFER + help + This trace remote includes a ring-buffer writer implementation using + "simple_ring_buffer". This is solely intending for testing. + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 2e39b09398b3..d106beca8d7f 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -130,4 +130,6 @@ obj-$(CONFIG_RV) +=3D rv/ =20 obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o +obj-$(CONFIG_TRACE_REMOTE_TEST) +=3D remote_test.o + libftrace-y :=3D ftrace.o diff --git a/kernel/trace/remote_test.c b/kernel/trace/remote_test.c new file mode 100644 index 000000000000..e5023b9d2611 --- /dev/null +++ b/kernel/trace/remote_test.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include +#include + +#define REMOTE_EVENT_INCLUDE_FILE kernel/trace/remote_test_events.h +#include + +static DEFINE_PER_CPU(struct simple_rb_per_cpu *, simple_rbs); +static struct trace_buffer_desc *remote_test_buffer_desc; + +/* + * The trace_remote lock already serializes accesses from the trace_remote= _callbacks. + * However write_event can still race with load/unload. + */ +static DEFINE_MUTEX(simple_rbs_lock); + +static int remote_test_load_simple_rb(int cpu, struct ring_buffer_desc *rb= _desc) +{ + struct simple_rb_per_cpu *cpu_buffer; + struct simple_buffer_page *bpages; + int ret =3D -ENOMEM; + + cpu_buffer =3D kmalloc(sizeof(*cpu_buffer), GFP_KERNEL); + if (!cpu_buffer) + return ret; + + bpages =3D kmalloc_array(rb_desc->nr_page_va, sizeof(*bpages), GFP_KERNEL= ); + if (!bpages) + goto err_free_cpu_buffer; + + ret =3D simple_ring_buffer_init(cpu_buffer, bpages, rb_desc); + if (ret) + goto err_free_bpages; + + scoped_guard(mutex, &simple_rbs_lock) { + WARN_ON(*per_cpu_ptr(&simple_rbs, cpu)); + *per_cpu_ptr(&simple_rbs, cpu) =3D cpu_buffer; + } + + return 0; + +err_free_bpages: + kfree(bpages); + +err_free_cpu_buffer: + kfree(cpu_buffer); + + return ret; +} + +static void remote_test_unload_simple_rb(int cpu) +{ + struct simple_rb_per_cpu *cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + struct simple_buffer_page *bpages; + + if (!cpu_buffer) + return; + + guard(mutex)(&simple_rbs_lock); + + bpages =3D cpu_buffer->bpages; + simple_ring_buffer_unload(cpu_buffer); + kfree(bpages); + kfree(cpu_buffer); + *per_cpu_ptr(&simple_rbs, cpu) =3D NULL; +} + +static struct trace_buffer_desc *remote_test_load(unsigned long size, void= *unused) +{ + struct ring_buffer_desc *rb_desc; + struct trace_buffer_desc *desc; + size_t desc_size; + int cpu, ret; + + if (WARN_ON(remote_test_buffer_desc)) + return ERR_PTR(-EINVAL); + + desc_size =3D trace_buffer_desc_size(size, num_possible_cpus()); + if (desc_size =3D=3D SIZE_MAX) { + ret =3D -E2BIG; + goto err; + } + + desc =3D kmalloc(desc_size, GFP_KERNEL); + if (!desc) { + ret =3D -ENOMEM; + goto err; + } + + ret =3D trace_remote_alloc_buffer(desc, desc_size, size, cpu_possible_mas= k); + if (ret) + goto err_free_desc; + + for_each_ring_buffer_desc(rb_desc, cpu, desc) { + ret =3D remote_test_load_simple_rb(rb_desc->cpu, rb_desc); + if (ret) + goto err_unload; + } + + remote_test_buffer_desc =3D desc; + + return remote_test_buffer_desc; + +err_unload: + for_each_ring_buffer_desc(rb_desc, cpu, remote_test_buffer_desc) + remote_test_unload_simple_rb(rb_desc->cpu); + trace_remote_free_buffer(remote_test_buffer_desc); + +err_free_desc: + kfree(desc); + +err: + return ERR_PTR(ret); +} + +static void remote_test_unload(struct trace_buffer_desc *desc, void *unuse= d) +{ + struct ring_buffer_desc *rb_desc; + int cpu; + + if (WARN_ON(desc !=3D remote_test_buffer_desc)) + return; + + for_each_ring_buffer_desc(rb_desc, cpu, desc) + remote_test_unload_simple_rb(rb_desc->cpu); + + remote_test_buffer_desc =3D NULL; + trace_remote_free_buffer(desc); + kfree(desc); +} + +static int remote_test_enable_tracing(bool enable, void *unused) +{ + struct ring_buffer_desc *rb_desc; + int cpu; + + if (!remote_test_buffer_desc) + return -ENODEV; + + for_each_ring_buffer_desc(rb_desc, cpu, remote_test_buffer_desc) + WARN_ON(simple_ring_buffer_enable_tracing(*per_cpu_ptr(&simple_rbs, rb_d= esc->cpu), + enable)); + return 0; +} + +static int remote_test_swap_reader_page(unsigned int cpu, void *unused) +{ + struct simple_rb_per_cpu *cpu_buffer; + + if (cpu >=3D NR_CPUS) + return -EINVAL; + + cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + if (!cpu_buffer) + return -EINVAL; + + return simple_ring_buffer_swap_reader_page(cpu_buffer); +} + +static int remote_test_reset(unsigned int cpu, void *unused) +{ + struct simple_rb_per_cpu *cpu_buffer; + + if (cpu >=3D NR_CPUS) + return -EINVAL; + + cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + if (!cpu_buffer) + return -EINVAL; + + return simple_ring_buffer_reset(cpu_buffer); +} + +static int remote_test_enable_event(unsigned short id, bool enable, void *= unused) +{ + if (id !=3D REMOTE_TEST_EVENT_ID) + return -EINVAL; + + /* + * Let's just use the struct remote_event enabled field that is turned on= and off by + * trace_remote. This is a bit racy but good enough for a simple test mod= ule. + */ + return 0; +} + +static ssize_t +write_event_write(struct file *filp, const char __user *ubuf, size_t cnt, = loff_t *pos) +{ + struct remote_event_format_selftest *evt_test; + struct simple_rb_per_cpu *cpu_buffer; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + guard(mutex)(&simple_rbs_lock); + + if (!remote_event_selftest.enabled) + return -ENODEV; + + guard(preempt)(); + + cpu_buffer =3D *this_cpu_ptr(&simple_rbs); + if (!cpu_buffer) + return -ENODEV; + + evt_test =3D simple_ring_buffer_reserve(cpu_buffer, + sizeof(struct remote_event_format_selftest), + trace_clock_global()); + if (!evt_test) + return -ENODEV; + + evt_test->hdr.id =3D REMOTE_TEST_EVENT_ID; + evt_test->id =3D val; + + simple_ring_buffer_commit(cpu_buffer); + + return cnt; +} + +static const struct file_operations write_event_fops =3D { + .write =3D write_event_write, +}; + +static int remote_test_init_tracefs(struct dentry *d, void *unused) +{ + return tracefs_create_file("write_event", 0200, d, NULL, &write_event_fop= s) ? + 0 : -ENOMEM; +} + +static struct trace_remote_callbacks trace_remote_callbacks =3D { + .init =3D remote_test_init_tracefs, + .load_trace_buffer =3D remote_test_load, + .unload_trace_buffer =3D remote_test_unload, + .enable_tracing =3D remote_test_enable_tracing, + .swap_reader_page =3D remote_test_swap_reader_page, + .reset =3D remote_test_reset, + .enable_event =3D remote_test_enable_event, +}; + +static int __init remote_test_init(void) +{ + return trace_remote_register("test", &trace_remote_callbacks, NULL, + &remote_event_selftest, 1); +} + +module_init(remote_test_init); + +MODULE_DESCRIPTION("Test module for the trace remote interface"); +MODULE_AUTHOR("Vincent Donnefort"); +MODULE_LICENSE("GPL"); diff --git a/kernel/trace/remote_test_events.h b/kernel/trace/remote_test_e= vents.h new file mode 100644 index 000000000000..26b93b3406fc --- /dev/null +++ b/kernel/trace/remote_test_events.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#define REMOTE_TEST_EVENT_ID 1 + +REMOTE_EVENT(selftest, REMOTE_TEST_EVENT_ID, + RE_STRUCT( + re_field(u64, id) + ), + RE_PRINTK("id=3D%llu", __entry->id) +); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:26 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 583693BA257 for ; Fri, 6 Mar 2026 14:36:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807771; cv=none; b=DnVzAggyqJ9AjalutGPaW6TG5HCSOO29q1i+mABex04DS7sPeVAyQh80xordc5rQ0nAF9kR6IrnXSD8g3rDRRDnHtFU08UFt7CQgKPTQwcFsicK/7ZRkLSDuZH270mRU6prPIuXHJSQKY5fCernMmk3LzZ+sS3aBeZhUokkkDJg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807771; c=relaxed/simple; bh=QgrpnA9vqWR0LvqBZTQt9eWvlVYE0nDC3NQs7drGfDs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=b2SN5pXfk8Oo0ZVFYlJBkS9tTkkXkUMucyQ5ChnuE3OaqX0/+KDWsrHGF9yQ1USCXotyYhGyBxH/A3868LJ6i0GoJyyUrYZVqIvKstzJrbHeun1rfG1lB1iwbNkIYISQjicn5DvjQ29F2xvd6lhmzl5YFk6NicEL8tKEYGOtckY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=qzowjEd9; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="qzowjEd9" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-483bcfdaf7dso92741905e9.0 for ; Fri, 06 Mar 2026 06:36:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807768; x=1773412568; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=7EWtEU3hLDTOygEgGBU2HCNdGhHgmpQrxlmxxTt9Vi8=; b=qzowjEd9pD4cyAlbUXPUcoGDx3DUvenLjITrPIelpbqVy+zhp/cmE4JrVvsEH7ckCM HnXUeScVTrqXaPfq3fvj8l7FzV4MSYgNcFPpEEvPHG4lDOQXWi5jGhe9HwROxb4ULUCy PbUwo6yUk6F9169wD3yGVbQOS5vRUxLoGyeU9Dad4nZOuS+zRGY/vKyx7ZbblNBh5LPu 6IAB56okLl6BjSHpI9v03fT/xhPteldg7V7iuZHK3qpsEHBty8y2V4O3R9ahvffT19RI SWeuaAUZTtXD+JpoMNTFMJdBqJad82gpbsEpN8LLKimwslP8mXccCjIvoHBBAVN0F1Qv hOvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807768; x=1773412568; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=7EWtEU3hLDTOygEgGBU2HCNdGhHgmpQrxlmxxTt9Vi8=; b=adhEVhv+6BHP7XZkZ+R4bSIiHUC0M/OPH28uCcIUKMf8cb/7/tt9zAt+zaSjUgcwXa QtHqUP8wfcHZqjNOxJXJoy5pEkunpqZUJUuuPP46GN3MX8bpNrHaAh0d60i7v0C9sO30 Fl3AWOpTyCU49/h12RSJAtFbn0/j6gZ/rAfcOm8HMZiNYgHMfURw2ZSIv2wgmz/EMJz5 lIwf+eQ3j0WsYYgiOMTj7f704OL2ooln4bX0hCZhGa4WagE+tg4X6XEZs5R8vJM40ggE ulNE3LjcVIcxjT4A+TVK703a1dJmNzN4/1uRkpqYdieGZmCYKc1tTgKpT0WsSKv0TaZk 03fw== X-Forwarded-Encrypted: i=1; AJvYcCXx7N9qEaqUnvneFHTDCHv1BdLhARLsVNqsry2yCHqaIwawlwd7NMS7YCf2BvA4WJMN1JIQLq919+QQt/g=@vger.kernel.org X-Gm-Message-State: AOJu0Yx0lXjfROqBf2yd0hw76Zhca675+cNhqlg1oGfNkyrSG21HmsKY edWNqUeHK2ST04hD8nTpVB/Q6AT6/b+QQdMEcHAJIH2ipQ2tVE7dW1r5Jvy7UL0FCpOIL+a+Wq7 wCVnwM1w7lenP0PkkN1PzTQ== X-Received: from wmgb17.prod.google.com ([2002:a05:600c:1511:b0:480:6b05:6b98]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:64c7:b0:47a:935f:61a0 with SMTP id 5b1f17b1804b1-485268bd694mr39238285e9.0.1772807767833; Fri, 06 Mar 2026 06:36:07 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:19 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-16-vdonnefort@google.com> Subject: [PATCH v13 15/32] tracing: selftests: Add trace remote tests From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Shuah Khan , linux-kselftest@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Exercise the tracefs interface for trace remote with a set of tests to check: * loading/unloading (unloading.tc) * reset (reset.tc) * size changes (buffer_size.tc) * consuming read (trace_pipe.tc) * non-consuming read (trace.tc) Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc b= /tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc new file mode 100644 index 000000000000..1a43280ffa97 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote buffer size +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_buffer_size() +{ + echo 0 > tracing_on + assert_unloaded + + echo 4096 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + echo 0 > tracing_on + echo 7 > buffer_size_kb +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + setup_remote_test + test_buffer_size +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/functions b/tool= s/testing/selftests/ftrace/test.d/remotes/functions new file mode 100644 index 000000000000..97a09d564a34 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/functions @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: GPL-2.0 + +setup_remote() +{ + local name=3D$1 + + [ -e $TRACING_DIR/remotes/$name/write_event ] || exit_unresolved + + cd remotes/$name/ + echo 0 > tracing_on + clear_trace + echo 7 > buffer_size_kb + echo 0 > events/enable + echo 1 > events/$name/selftest/enable + echo 1 > tracing_on +} + +setup_remote_test() +{ + [ -d $TRACING_DIR/remotes/test/ ] || modprobe remote_test || exit_unresol= ved + + setup_remote "test" +} + +assert_loaded() +{ + grep -q "(loaded)" buffer_size_kb +} + +assert_unloaded() +{ + grep -q "(unloaded)" buffer_size_kb +} + +dump_trace_pipe() +{ + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + cat trace_pipe > $output & + pid=3D$! + sleep 1 + kill -1 $pid + + echo $output +} + +check_trace() +{ + start_id=3D"$1" + end_id=3D"$2" + file=3D"$3" + + # Ensure the file is not empty + test -n "$(head $file)" + + prev_ts=3D0 + id=3D0 + + # Only keep + tmp=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + sed -e 's/\[[0-9]*\]\s*\([0-9]*.[0-9]*\): [a-z]* id=3D\([0-9]*\)/\1 \2/' = $file > $tmp + + while IFS=3D read -r line; do + ts=3D$(echo $line | cut -d ' ' -f 1) + id=3D$(echo $line | cut -d ' ' -f 2) + + test $(echo "$ts>$prev_ts" | bc) -eq 1 + test $id -eq $start_id + + prev_ts=3D$ts + start_id=3D$((start_id + 1)) + done < $tmp + + test $id -eq $end_id + rm $tmp +} + +get_cpu_ids() +{ + sed -n 's/^processor\s*:\s*\([0-9]\+\).*/\1/p' /proc/cpuinfo +} + +get_page_size() { + sed -ne 's/^.*data.*size:\([0-9][0-9]*\).*/\1/p' events/header_page +} + +get_selftest_event_size() { + sed -ne 's/^.*field:.*;.*size:\([0-9][0-9]*\);.*/\1/p' events/*/selfte= st/format | awk '{s+=3D$1} END {print s}' +} diff --git a/tools/testing/selftests/ftrace/test.d/remotes/reset.tc b/tools= /testing/selftests/ftrace/test.d/remotes/reset.tc new file mode 100644 index 000000000000..4d176349b2bc --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/reset.tc @@ -0,0 +1,90 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote reset +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +check_reset() +{ + write_event_path=3D"write_event" + taskset=3D"" + + clear_trace + + # Is the buffer empty? + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 0 + + if $(echo $(pwd) | grep -q "per_cpu/cpu"); then + write_event_path=3D"../../write_event" + cpu_id=3D$(echo $(pwd) | sed -e 's/.*per_cpu\/cpu//') + taskset=3D"taskset -c $cpu_id" + fi + rm $output + + # Can we properly write a new event? + $taskset echo 7890 > $write_event_path + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 1 + grep -q "id=3D7890" $output + rm $output +} + +test_global_interface() +{ + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + + # Confidence check + echo 123456 > write_event + output=3D$(dump_trace_pipe) + grep -q "id=3D123456" $output + rm $output + + # Reset single event + echo 1 > write_event + check_reset + + # Reset lost events + for i in $(seq 1 10000); do + echo 1 > write_event + done + check_reset +} + +test_percpu_interface() +{ + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + for cpu in $(get_cpu_ids); do + taskset -c $cpu echo 1 > write_event + done + + check_non_empty=3D0 + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + + if [ $check_non_empty -eq 0 ]; then + check_reset + check_non_empty=3D1 + else + # Check we have only reset 1 CPU + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 1 + rm $output + fi + cd - + done +} + +test_reset() +{ + test_global_interface + test_percpu_interface +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + setup_remote_test + test_reset +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace.tc b/tools= /testing/selftests/ftrace/test.d/remotes/trace.tc new file mode 100644 index 000000000000..170f7648732a --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace.tc @@ -0,0 +1,127 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote non-consuming read +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_trace() +{ + echo 0 > tracing_on + assert_unloaded + + echo 7 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + # Simple test: Emit few events and try to read them + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + # + # Test interaction with consuming read + # + + cat trace_pipe > /dev/null & + pid=3D$! + + sleep 1 + kill $pid + + test $(wc -l < trace) -eq 0 + + for i in $(seq 16 32); do + echo $i > write_event + done + + check_trace 16 32 trace + + # + # Test interaction with reset + # + + echo 0 > trace + + test $(wc -l < trace) -eq 0 + + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + # + # Test interaction with lost events + # + + # Ensure the writer is not on the reader page by reloading the buffer + echo 0 > tracing_on + echo 0 > trace + assert_unloaded + echo 1 > tracing_on + assert_loaded + + # Ensure ring-buffer overflow by emitting events from the same CPU + for cpu in $(get_cpu_ids); do + break + done + + events_per_page=3D$(($(get_page_size) / $(get_selftest_event_size))) #= Approx: does not take TS into account + nr_events=3D$(($events_per_page * 2)) + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + id=3D$(sed -n -e '1s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=3D\([0-9]*\= )/\1/p' trace) + test $id -ne 1 + + check_trace $id $nr_events trace + + # + # Test per-CPU interface + # + echo 0 > trace + + for cpu in $(get_cpu_ids) ; do + taskset -c $cpu echo $cpu > write_event + done + + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + + check_trace $cpu $cpu trace + + cd - > /dev/null + done + + # + # Test with hotplug + # + + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + echo 0 > trace + + for cpu in $(get_cpu_ids); do + echo 0 > /sys/devices/system/cpu/cpu$cpu/online || return 0 + break + done + + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + echo 1 > /sys/devices/system/cpu/cpu$cpu/online +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_trace +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc b/= tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc new file mode 100644 index 000000000000..669a7288ed7c --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc @@ -0,0 +1,127 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote consuming read +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_trace_pipe() +{ + echo 0 > tracing_on + assert_unloaded + + # Emit events from the same CPU + for cpu in $(get_cpu_ids); do + break + done + + # + # Simple test: Emit enough events to fill few pages + # + + echo 1024 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + events_per_page=3D$(($(get_page_size) / $(get_selftest_event_size))) + nr_events=3D$(($events_per_page * 4)) + + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + + cat trace_pipe > $output & + pid=3D$! + + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + echo 0 > tracing_on + sleep 1 + kill $pid + + check_trace 1 $nr_events $output + + rm $output + + # + # Test interaction with lost events + # + + assert_unloaded + echo 7 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + nr_events=3D$((events_per_page * 2)) + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + output=3D$(dump_trace_pipe) + + lost_events=3D$(sed -n -e '1s/CPU:.*\[LOST \([0-9]*\) EVENTS\]/\1/p' $= output) + test -n "$lost_events" + + id=3D$(sed -n -e '2s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=3D\([0-9]*\= )/\1/p' $output) + test "$id" -eq $(($lost_events + 1)) + + # Drop [LOST EVENTS] line + sed -i '1d' $output + + check_trace $id $nr_events $output + + rm $output + + # + # Test per-CPU interface + # + + echo 0 > trace + echo 1 > tracing_on + + for cpu in $(get_cpu_ids); do + taskset -c $cpu echo $cpu > write_event + done + + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + output=3D$(dump_trace_pipe) + + check_trace $cpu $cpu $output + + rm $output + cd - > /dev/null + done + + # + # Test interaction with hotplug + # + + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + echo 0 > trace + + for cpu in $(get_cpu_ids); do + echo 0 > /sys/devices/system/cpu/cpu$cpu/online || return 0 + break + done + + for i in $(seq 1 8); do + echo $i > write_event + done + + output=3D$(dump_trace_pipe) + + check_trace 1 8 $output + + rm $output + + echo 1 > /sys/devices/system/cpu/cpu$cpu/online +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_trace_pipe +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc b/t= ools/testing/selftests/ftrace/test.d/remotes/unloading.tc new file mode 100644 index 000000000000..cac2190183f6 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc @@ -0,0 +1,41 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote unloading +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_unloading() +{ + # No reader, writing + assert_loaded + + # No reader, no writing + echo 0 > tracing_on + assert_unloaded + + # 1 reader, no writing + cat trace_pipe & + pid=3D$! + sleep 1 + assert_loaded + kill $pid + assert_unloaded + + # No reader, no writing, events + echo 1 > tracing_on + echo 1 > write_event + echo 0 > tracing_on + assert_loaded + + # Test reset + clear_trace + assert_unloaded +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_unloading +fi --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7CA4E3BD646 for ; Fri, 6 Mar 2026 14:36:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807772; cv=none; b=HBXYOKPfqRGsXdzKFq+m25iJLQH87L04J+FoQB23ygRKXXsS9zQHWxvlIhrHlal3ANpkFnmSBHL3CwdG/KBkcn1oMqtP+Wcd34FNbrKj+tNYTPuwUVXjoDMdGo6ln2C537fualQ3HE8nQeEIpTGoJAUmnRDnG48f3vEPfKLn8U0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807772; c=relaxed/simple; bh=7bMiRK0ShivdAJEqAqq8p+bSixyyMffBJzLzrorCG00=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=T/Zj8TzI4j0jwUbrpYDgOWF4X168vDuHXca02XSbK8NR6d4gCixLdDaRWXJ/h3ewi3bYYCghbgsx5LOfwK6LTfWSSmWeM5OVa93KDH/dpkDr7KwMmxP4SextBsQLtH6LPvbMOjSvmViydh6fsJdfEzZuRtJj0kPZm7lmdjvbo6o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=hTHWL3n5; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="hTHWL3n5" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso114699485e9.1 for ; Fri, 06 Mar 2026 06:36:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807769; x=1773412569; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=B6OW0CQFlfUo8gIs8zWJuy/R7hSbmdzTUEKNvWrAy54=; b=hTHWL3n5dqWaLK6E4Y0RAg2V2tS1MgAaNLnhGzERTe76vsBQGn8yx+6ZkMDi7e5so0 aKtZSw7tK3zJ5uHYEFePTKZ5pdlB/yODX7otGJItggYU71+Ej6UCE8ROuYhGYAm1Uaqd 34zwLwAVrLAoFIFIu7WmnRWIhOs9NCy5I/KZ3vQq13ZaPFQMoW28SsGBV0QTzyCQertN NEHuee4sUGJCPGAwz4grGKVr1AXfmsMpTytHXuAPnnBKopF/PLmwmFNaafIIDPYgAJKp kZxecYgiO0wGOvc2Wpih18EDsGnXAYCkByQTE3JDFcR6f1JYRSdYA/gzCpqBAfNWArCW KeMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807769; x=1773412569; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=B6OW0CQFlfUo8gIs8zWJuy/R7hSbmdzTUEKNvWrAy54=; b=O9HWJfvQ2FvxjbmmXfi08DphwgRLQs9NyV6jrN0cJXbqKRoYEOhUPko0cEgoB3mh8O fCTWfxgVA0d/NXBcw1aKTqqpQDjcqgzhjv6ubrE24/PtRrhcMMcJ6x6ULtM8VHlxoqTv 7e8DO5tQxIbjgDCidPIFpMaYbPXsZc22BIPsR/hBBmYhLCIIrg5ffgdLAs4eo32sV3+D ZK4kTV8wvE/fU9UOK82IC08taM9CEpHgoZ0IGM11dgl66rccCSXR3g7Iahb60hRQa4HE RRgwTAXLEUHe9gTMM6q8nszoZxCNSBZ7kY29N04clwF2Zf9uxXObYzcDS4qYap0WcEE0 nAuA== X-Forwarded-Encrypted: i=1; AJvYcCUp2Rt/7R0C2G+fuNV4aGMv4w62Wu0Cvn9pjCbCbAIKe8tbJKnh+ps9fHNkg64DcmnmmR2icgh6SVUiMCw=@vger.kernel.org X-Gm-Message-State: AOJu0YykO4LEoONafglfVkYLSIuGQaHVFLMwguuIAztEbe+NTXuxB0u3 Y4qQ4QmM8ul491+nGa2Ouk0JLwBmJ8gspX6PgIOh9vsTdLzBaDIyoEREXHFg0uIDU2v9bXEGCxe 7I3kON9oPzj1+otVS4jJF+g== X-Received: from wmlu14.prod.google.com ([2002:a05:600c:210e:b0:480:6c6f:8c06]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4451:b0:483:bcff:7948 with SMTP id 5b1f17b1804b1-4852692427cmr37315825e9.10.1772807768794; Fri, 06 Mar 2026 06:36:08 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:20 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-17-vdonnefort@google.com> Subject: [PATCH v13 16/32] Documentation: tracing: Add tracing remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation about the newly introduced tracing remotes framework. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst index 338bc4d7cfab..036db96864d2 100644 --- a/Documentation/trace/index.rst +++ b/Documentation/trace/index.rst @@ -91,6 +91,17 @@ interactions. user_events uprobetracer =20 +Remote Tracing +-------------- + +This section covers the framework to read compatible ring-buffers, written= by +entities outside of the kernel (most likely firmware or hypervisor) + +.. toctree:: + :maxdepth: 1 + + remotes + Additional Resources -------------------- =20 diff --git a/Documentation/trace/remotes.rst b/Documentation/trace/remotes.= rst new file mode 100644 index 000000000000..1f9d764f69aa --- /dev/null +++ b/Documentation/trace/remotes.rst @@ -0,0 +1,66 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Tracing Remotes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +:Author: Vincent Donnefort + +Overview +=3D=3D=3D=3D=3D=3D=3D=3D +Firmware and hypervisors are black boxes to the kernel. Having a way to se= e what +they are doing can be useful to debug both. This is where remote tracing b= uffers +come in. A remote tracing buffer is a ring buffer executed by the firmware= or +hypervisor into memory that is memory mapped to the host kernel. This is s= imilar +to how user space memory maps the kernel ring buffer but in this case the = kernel +is acting like user space and the firmware or hypervisor is the "kernel" s= ide. +With a trace remote ring buffer, the firmware and hypervisor can record ev= ents +for which the host kernel can see and expose to user space. + +Register a remote +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +A remote must provide a set of callbacks `struct trace_remote_callbacks` w= hom +description can be found below. Those callbacks allows Tracefs to enable a= nd +disable tracing and events, to load and unload a tracing buffer (a set of +ring-buffers) and to swap a reader page with the head page, which enables +consuming reading. + +.. kernel-doc:: include/linux/trace_remote.h + +Once registered, an instance will appear for this remote in the Tracefs +directory **remotes/**. Buffers can then be read using the usual Tracefs f= iles +**trace_pipe** and **trace**. + +Declare a remote event +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Macros are provided to ease the declaration of remote events, in a similar +fashion to in-kernel events. A declaration must provide an ID, a descripti= on of +the event arguments and how to print the event: + +.. code-block:: c + + REMOTE_EVENT(foo, EVENT_FOO_ID, + RE_STRUCT( + re_field(u64, bar) + ), + RE_PRINTK("bar=3D%lld", __entry->bar) + ); + +Then those events must be declared in a C file with the following: + +.. code-block:: c + + #define REMOTE_EVENT_INCLUDE_FILE foo_events.h + #include + +This will provide a `struct remote_event remote_event_foo` that can be giv= en to +`trace_remote_register`. + +Registered events appear in the remote directory under **events/**. + +Simple ring-buffer +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +A simple implementation for a ring-buffer writer can be found in +kernel/trace/simple_ring_buffer.c. + +.. kernel-doc:: include/linux/simple_ring_buffer.h --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16C183A9601 for ; Fri, 6 Mar 2026 14:36:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807773; cv=none; b=Rxegz48HfrZTOlk9BNuzVltyeZWkqwR040CI7b5ZF94iLUwEPpIIzIWFr9jcb2wvYzetufGT0FxeTQG1R0FVLlBselJLT768p6dXAhwPlmYLLF2V2JDyob2PEFKi7kpMSH/ADt2xCy/AnOogEiRNnUD3mvvhbshgogsfoVFCcJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807773; c=relaxed/simple; bh=Jp/JRHhovKqXYlmtWvfEyNpyPkJYjfLK/98vY6yVHro=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=dfQlqGdodVUDkue70XcIO52ubreCX0soYP1ygOmMXbkFJwvMyzXSM96JfHWHQ9wJePKrbIX1OoVaUQW7xcOqaM/fI/K0AsRV0JYWJiMokAj8c15ZYOuVIXd9RYMmvINAp/KGA3S5KVukj255Gvie3tlvcPWHHoaxiJfl4hiCRQU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=rGS/B7JT; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="rGS/B7JT" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4836c819456so71431925e9.3 for ; Fri, 06 Mar 2026 06:36:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807769; x=1773412569; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=aYLWsoQ02WLCqnUt0cBCdmffcm851eUUlDHUboLm26o=; b=rGS/B7JTg0aSbaJ4ANQnKXqTIRhTg8WJINkdAVlV+7TWxN6i7oYGuXbJ1kdXK2FF6r YIlB3uMjeYug18jzh15TMsv3JRqWAsYTPkpmibCCN/+LjoZQfFMpvDyErxdX0nuBGXBx qIlJctdRrPAsItUjOZjfsUDONxBp99FndwcZApo/34Nv8pUHh0QPbE/xghNHLmgeliBq Z1R7b0vqnzGmjGH9wP9XuinmQOqu/WSkUFdz2snyqBjYLLXKvtaBh/UdUAPyT4/2W67A 6fiX33siEZzaKJFQOwS9i097S3Oh3/PMhADPRpOOHT2dMW7gJTtYMw78akx1rd4rCpU0 iPVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807769; x=1773412569; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=aYLWsoQ02WLCqnUt0cBCdmffcm851eUUlDHUboLm26o=; b=MhEvv4RaKQwLYzOjDONaZuhU2Lb1ZJrq1zjejPm2pivy+vQ9NJcDaoM+aeFLJtH2YM WbxTYnRkCTKothdKp40op2Fvk5JhHKyzOTOHTmNHb2xr/qPNHm1bJc6x5FPH92n4Ggfd sRidD1w3ddmCqtsZaPq032tfDtXXjcwpIT3mwGeJkBoiF60y8pdfxwunFmsyMztlDX0s temFYfNtsYHiwtjE2ZsJAGps2E6FzXd4pfvZpyuI/1ieTvLSWBJDejmOYoNzwUatIgMl IwOPI/11cUsfxFosw7YQSiZ55ckOZ7UK2+XO4Bbg25I+XVkhbkY7YsGkgMoRnL7cgEIr DGKw== X-Forwarded-Encrypted: i=1; AJvYcCUl4tlnP/AYZLBagOBx7MywaeT/Nt69nDT93lDfSjDsO2QTqosLQU7qXifUkwrFNF+GOd9iOxfb0G3zPzI=@vger.kernel.org X-Gm-Message-State: AOJu0YxYUOMlQfGMlLBW9by6biau7xEjZ2i3Eqb3UId/Nt7RR5WGnA1K Tu8+iqmUzvOwJio7b7pZra1gusIfcp2MaGCdApI3BkJ4V1dZ2GJUC2exizRcu1UY6KwdLihoZuf Jw3DisL0vrf0ywOMYrrxy0A== X-Received: from wmbdv11.prod.google.com ([2002:a05:600c:620b:b0:483:7c8d:ed1d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b27:b0:483:abeb:7a5c with SMTP id 5b1f17b1804b1-48526923bfdmr36464775e9.12.1772807769565; Fri, 06 Mar 2026 06:36:09 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:21 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-18-vdonnefort@google.com> Subject: [PATCH v13 17/32] tracing: load/unload page callbacks for simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add load/unload callback used for each admitted page in the ring-buffer. This will be later useful for the pKVM hypervisor which uses a different VA space and need to dynamically map/unmap the ring-buffer pages. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/include/linux/simple_ring_buffer.h b/include/linux/simple_ring= _buffer.h index 2c4c0ae336bc..21aec556293e 100644 --- a/include/linux/simple_ring_buffer.h +++ b/include/linux/simple_ring_buffer.h @@ -54,4 +54,12 @@ int simple_ring_buffer_reset(struct simple_rb_per_cpu *c= pu_buffer); =20 int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); =20 +int simple_ring_buffer_init_mm(struct simple_rb_per_cpu *cpu_buffer, + struct simple_buffer_page *bpages, + const struct ring_buffer_desc *desc, + void *(*load_page)(unsigned long va), + void (*unload_page)(void *va)); + +void simple_ring_buffer_unload_mm(struct simple_rb_per_cpu *cpu_buffer, + void (*unload_page)(void *)); #endif diff --git a/kernel/trace/simple_ring_buffer.c b/kernel/trace/simple_ring_b= uffer.c index 15df9781411b..02af2297ae5a 100644 --- a/kernel/trace/simple_ring_buffer.c +++ b/kernel/trace/simple_ring_buffer.c @@ -71,7 +71,7 @@ static void simple_bpage_reset(struct simple_buffer_page = *bpage) local_set(&bpage->page->commit, 0); } =20 -static void simple_bpage_init(struct simple_buffer_page *bpage, unsigned l= ong page) +static void simple_bpage_init(struct simple_buffer_page *bpage, void *page) { INIT_LIST_HEAD(&bpage->link); bpage->page =3D (struct buffer_data_page *)page; @@ -372,18 +372,15 @@ int simple_ring_buffer_reset(struct simple_rb_per_cpu= *cpu_buffer) } EXPORT_SYMBOL_GPL(simple_ring_buffer_reset); =20 -/** - * simple_ring_buffer_init - Init @cpu_buffer based on @desc - * @cpu_buffer: A simple_rb_per_cpu buffer to init, allocated by the calle= r. - * @bpages: Array of simple_buffer_pages, with as many elements as @desc->= nr_page_va - * @desc: A ring_buffer_desc - * - * Returns 0 on success or -EINVAL if the content of @desc is invalid - */ -int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, - const struct ring_buffer_desc *desc) +int simple_ring_buffer_init_mm(struct simple_rb_per_cpu *cpu_buffer, + struct simple_buffer_page *bpages, + const struct ring_buffer_desc *desc, + void *(*load_page)(unsigned long va), + void (*unload_page)(void *va)) { struct simple_buffer_page *bpage =3D bpages; + int ret =3D 0; + void *page; int i; =20 /* At least 1 reader page and two pages in the ring-buffer */ @@ -392,15 +389,22 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu = *cpu_buffer, struct simple_ =20 memset(cpu_buffer, 0, sizeof(*cpu_buffer)); =20 - cpu_buffer->bpages =3D bpages; + cpu_buffer->meta =3D load_page(desc->meta_va); + if (!cpu_buffer->meta) + return -EINVAL; =20 - cpu_buffer->meta =3D (void *)desc->meta_va; memset(cpu_buffer->meta, 0, sizeof(*cpu_buffer->meta)); cpu_buffer->meta->meta_page_size =3D PAGE_SIZE; cpu_buffer->meta->nr_subbufs =3D cpu_buffer->nr_pages; =20 /* The reader page is not part of the ring initially */ - simple_bpage_init(bpage, desc->page_va[0]); + page =3D load_page(desc->page_va[0]); + if (!page) { + unload_page(cpu_buffer->meta); + return -EINVAL; + } + + simple_bpage_init(bpage, page); bpage->id =3D 0; =20 cpu_buffer->nr_pages =3D 1; @@ -410,7 +414,13 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu *= cpu_buffer, struct simple_ cpu_buffer->head_page =3D bpage + 1; =20 for (i =3D 1; i < desc->nr_page_va; i++) { - simple_bpage_init(++bpage, desc->page_va[i]); + page =3D load_page(desc->page_va[i]); + if (!page) { + ret =3D -EINVAL; + break; + } + + simple_bpage_init(++bpage, page); =20 bpage->link.next =3D &(bpage + 1)->link; bpage->link.prev =3D &(bpage - 1)->link; @@ -419,6 +429,14 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu *= cpu_buffer, struct simple_ cpu_buffer->nr_pages =3D i + 1; } =20 + if (ret) { + for (i--; i >=3D 0; i--) + unload_page((void *)desc->page_va[i]); + unload_page(cpu_buffer->meta); + + return ret; + } + /* Close the ring */ bpage->link.next =3D &cpu_buffer->tail_page->link; cpu_buffer->tail_page->link.prev =3D &bpage->link; @@ -426,23 +444,58 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu = *cpu_buffer, struct simple_ /* The last init'ed page points to the head page */ simple_bpage_set_head_link(bpage); =20 + cpu_buffer->bpages =3D bpages; + return 0; } -EXPORT_SYMBOL_GPL(simple_ring_buffer_init); + +static void *__load_page(unsigned long page) +{ + return (void *)page; +} + +static void __unload_page(void *page) { } =20 /** - * simple_ring_buffer_unload - Prepare @cpu_buffer for deletion - * @cpu_buffer: A simple_rb_per_cpu that will be deleted. + * simple_ring_buffer_init - Init @cpu_buffer based on @desc + * @cpu_buffer: A simple_rb_per_cpu buffer to init, allocated by the calle= r. + * @bpages: Array of simple_buffer_pages, with as many elements as @desc->= nr_page_va + * @desc: A ring_buffer_desc + * + * Returns 0 on success or -EINVAL if the content of @desc is invalid */ -void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc) +{ + return simple_ring_buffer_init_mm(cpu_buffer, bpages, desc, __load_page, = __unload_page); +} +EXPORT_SYMBOL_GPL(simple_ring_buffer_init); + +void simple_ring_buffer_unload_mm(struct simple_rb_per_cpu *cpu_buffer, + void (*unload_page)(void *)) { + int p; + if (!simple_rb_loaded(cpu_buffer)) return; =20 simple_rb_enable_tracing(cpu_buffer, false); =20 + unload_page(cpu_buffer->meta); + for (p =3D 0; p < cpu_buffer->nr_pages; p++) + unload_page(cpu_buffer->bpages[p].page); + cpu_buffer->bpages =3D NULL; } + +/** + * simple_ring_buffer_unload - Prepare @cpu_buffer for deletion + * @cpu_buffer: A simple_rb_per_cpu that will be deleted. + */ +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +{ + return simple_ring_buffer_unload_mm(cpu_buffer, __unload_page); +} EXPORT_SYMBOL_GPL(simple_ring_buffer_unload); =20 /** --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E4C13BE148 for ; Fri, 6 Mar 2026 14:36:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807774; cv=none; b=pxsHes3cz0g653Jf81R/RYHrEMORVGMOuPcpSgOJk57JLFK571TDA/AdSDSFKLn9aStOAUs+qtshllX+floq5LYrFnf0rxQ7znQ/im+dmKuj+0gU6cOBQzCDyLbTZgH6VyMr7lznRt3bL1WyM+EdW6I7DmYk6OXaGdCCcaZSPeA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807774; c=relaxed/simple; bh=nvJVMgivk0n7tnxwYIskJ85licES15A0ESfOQLBBACk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Ovrnf/OgVuunsMZoSpwqvA+/ohwDkE/5FQaP0Tws+eoOAuLv2Ysgt0ZTQ69VIWKVjYNaJK4Orup4Pu95HQAipCgTZxCW5XLxOtzq9bkc17hkoZ9szDlZYFDA9tMX5pbAOWPS9vHSk1taHKx7gXYyjhscPsGSofOZqMp1A4tKTrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=2LhAlu1/; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="2LhAlu1/" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-48069a43217so97677515e9.1 for ; Fri, 06 Mar 2026 06:36:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807771; x=1773412571; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ISTtnZxQZml/VUbaQMgN/rAKYfhBuJPSGaUgT7FyeoU=; b=2LhAlu1/5hgEy78QDmfqwTRIoP+cRlXaips4nkNgzEqaEF6B/9Ymj35VV8CN21JeAJ 0zV955lcz1O/gI7h0Kio30v2iwoxb9XIUtMyZute+kc6nmcNNGqmlaSWGyGnIGu2uhQJ 2A4FjQqNsgIW5soPxOzDBuUnQYMXUjANztEn6bdCZOD0AGLPGDEH0I9ximzlxBqwOtR+ 2efgCZyjI3hndl+78Hkw6esH4K4WUweCC1AwzPAbK2Jss+BTURoCfPg0TREHAwmL/iij l4YeNrxgV/JYvz9KfI2r2Qt/a8v9XGn/qdocdoNmEXhbA/Uw3QNMt7qZtoNxWQveLZNI 3OVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807771; x=1773412571; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ISTtnZxQZml/VUbaQMgN/rAKYfhBuJPSGaUgT7FyeoU=; b=lCuWjZf+E+swcw1562uVYETCzuL2jy315dKvh7WZbM+tMpbzsWor7j1daG4E4kHYQ5 EJ9qgz1f3nktAd84wohr2cstz57u38wS7mqAFcMuEYfaSCesqF3rXDkXDsRnXDBkTlYJ sWRfMi1KkgmNeCOcR4YsPWsxahBepxLInqZuWcNafsa9ew7XRymgfIkPI6C/gowXWV2V VQk7/QWyWz5u56KmvxUgMunXas+BNUTXENmWa19gn62PF4i0uVTeOPpKblPDdMRnhX4T /d1+k/XhGZS9zdE41IVBVbU/8K6RRfDtd/LIK6sImIAC1FuRWDYaU9HrvlVoMxy2ULmD LLoA== X-Forwarded-Encrypted: i=1; AJvYcCXp57K2yU5Ex6BFXs6H0iKVI9amqlBVprt0Fng4WEvwJEnl3QN6Qlb24csB1kGyiFoqrvv/LZaY2hHqoFA=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5j+fkHotFUXK9ahg09nOQOt0VYdBAl47Vago9oy7aE0mBtBWy yJoakiLBezHce9owMH+GPpVkV3tGcWSS55Cd5F7KCAXJyKnamudHfP9IP2cgO+ZiHBXsmraW2ph eDG05XxbF/Z2wVx6WBvbt+A== X-Received: from wmbfl21.prod.google.com ([2002:a05:600c:b95:b0:483:6ff0:11a0]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1e88:b0:483:1403:c47f with SMTP id 5b1f17b1804b1-485269182b5mr44060185e9.6.1772807770415; Fri, 06 Mar 2026 06:36:10 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:22 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-19-vdonnefort@google.com> Subject: [PATCH v13 18/32] tracing: Check for undefined symbols in simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The simple_ring_buffer implementation must remain simple enough to be used by the pKVM hypervisor. Prevent the object build if unresolved symbols are found. Reviewed-by: Steven Rostedt (Google) Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index d106beca8d7f..3182e1bc1cf7 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -132,4 +132,20 @@ obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o obj-$(CONFIG_TRACE_REMOTE_TEST) +=3D remote_test.o =20 +# +# simple_ring_buffer is used by the pKVM hypervisor which does not have ac= cess +# to all kernel symbols. Fail the build if forbidden symbols are found. +# +UNDEFINED_ALLOWLIST :=3D memset alt_cb_patch_nops __x86 __ubsan __asan __k= asan __gcov __aeabi_unwind +UNDEFINED_ALLOWLIST +=3D __stack_chk_fail stackleak_track_stack __ref_stac= k __sanitizer +UNDEFINED_ALLOWLIST :=3D $(addprefix -e , $(UNDEFINED_ALLOWLIST)) + +quiet_cmd_check_undefined =3D NM $< + cmd_check_undefined =3D test -z "`$(NM) -u $< | grep -v $(UNDEFINED_= ALLOWLIST)`" + +$(obj)/%.o.checked: $(obj)/%.o FORCE + $(call if_changed,check_undefined) + +always-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o.checked + libftrace-y :=3D ftrace.o --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E8833BD622 for ; Fri, 6 Mar 2026 14:36:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807775; cv=none; b=sbKh2vRvPgEWG2vdifi9RY9SalZcChy22K40Jcd/ErngG/d5T0+4qirNyk7BcG+CR24CqJzC4NRNGv6oAcaMoKUFObXsjUwj5ByMcqqDujNIUOtpHE9uMxGh5DffouZVt3eRnmil1iwCJo9bEkMJqX2DXhmHUdkFS0Lt4rcpDd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807775; c=relaxed/simple; bh=wFFwKKRSoeQ+hvE9YtKcm+s8Wq0rCUCB3HKs84iPvt0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=g68VA2k6p197DxFhw4eVMszJ2pssaeKQ1AEciXzrwtAuwESCTyEeGqdolx7+U6PspvZ6A8c6NCEhZcg3L8vrmlCL952zZABzDK5w9Cda/OBlS+1qkLESvGLrb+byvdnlovRWCfGst/7BZNokmu+LQ6S313MctfA+QGvzsn5gMJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=gcJz4L/L; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gcJz4L/L" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-48372facfedso83408805e9.0 for ; Fri, 06 Mar 2026 06:36:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807772; x=1773412572; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=d8Z7WAdfX72ZQ1vrHpbOchqHWcE4sgC6MSulzPzgnyE=; b=gcJz4L/L8lmO3cIZ7xP0qxAYg40aapgwHayJsqZyqOd7VesHuWBfd7gJLTh/swLZte HT0LxLlWvwOlfAvlPacdl6VDvx7nUGv3cR5BoX8rDjw/FDs/exrUUDwp8yYyBzm1Gpmz K8BNdHtYaIX7t/J7xaMzSlEr8h1FX+zlhodXe+9QCzuPcUDX5f8LFhWzDFSJlsRSQ+d0 3UX7R7vbh30ztsA47C9uq7/0tpvzi37SZU4oWL3SYOZ3ksoGyU7jKClSJ3K3iJbKiBNi 4QFCsGR9tSVjezKKTs8QzJk1VuiO5h3WJSzOuHXum5kPJwSUiIqMuS34TFRpzx9VqESY lgrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807772; x=1773412572; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=d8Z7WAdfX72ZQ1vrHpbOchqHWcE4sgC6MSulzPzgnyE=; b=ZMZadgVSnw3U5eDVYGrwk9WH6eb+Pn7s2MPpGJVbTeEYaiUCxQ//m/1gGm/rVI9Vit HSl+/42rzM2jVt6ZL+SGJVcittQst0fsq1PhZFa8OHkNfABmns5jL24qw7VeenYps7e6 R4Zy7Li18TNfXJ4YtTKTpafOfumV4tQGLn0yIFnYSVRRULWFsmDDO9oxJjB2aa1LPyKh gefp5ICSsHYcHVeXL0oDHtrT5hT3os5k3mG1QeEQ4NW7ydZoRAKwzTexKLg3vMRBzd1F nGJFTujLdsoeVGesm72yDwCCLMeUgUKOskLEvM4PGimdkh0qFXefOwQsRJ56SyM2zSso RSEQ== X-Forwarded-Encrypted: i=1; AJvYcCX73ujl8M/6QJquQtC79EzlBBLbIjnz8FAS78F2ezbOm6l/X7tZvwAK+0VxnBF/BkRgIEzdCU7JG20PTJM=@vger.kernel.org X-Gm-Message-State: AOJu0YzxtVBgUbz7LXJy5ezuJinRz7dusEtTJRNFGaWzFS9Z1Ttbc3dl CpAFUCSlvTAMnW1q+FoEOVVsM3II49XTbpv9QnAwmc25J8jR2G52MWuRyX43ncxmObA6K2v/Eea qEM7OkxvFVhsxLjg5/lH7Iw== X-Received: from wrbby19.prod.google.com ([2002:a05:6000:993:b0:439:c3d1:a394]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a7b:c7cd:0:b0:483:78e7:ce15 with SMTP id 5b1f17b1804b1-4851eea0e51mr82902955e9.13.1772807771399; Fri, 06 Mar 2026 06:36:11 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:23 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-20-vdonnefort@google.com> Subject: [PATCH v13 19/32] KVM: arm64: Add PKVM_DISABLE_STAGE2_ON_PANIC From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Kalesh Singh Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On NVHE_EL2_DEBUG, when using pKVM, the host stage-2 is relaxed to grant the kernel access to the stacktrace, hypervisor bug table and text to symbolize addresses. This is unsafe for production. In preparation for adding more debug options to NVHE_EL2_DEBUG, decouple the stage-2 relaxation into a separate option. While at it, rename PROTECTED_NVHE_STACKTRACE into PKVM_STACKTRACE, following the same naming scheme as PKVM_DISABLE_STAGE2_ON_PANIC. Reviewed-by: Kalesh Singh Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 7d1f22fd490b..14b2d0b0b831 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -42,9 +42,27 @@ menuconfig KVM =20 If unsure, say N. =20 +if KVM + +config PTDUMP_STAGE2_DEBUGFS + bool "Present the stage-2 pagetables to debugfs" + depends on DEBUG_KERNEL + depends on DEBUG_FS + depends on ARCH_HAS_PTDUMP + select PTDUMP + default n + help + Say Y here if you want to show the stage-2 kernel pagetables + layout in a debugfs file. This information is only useful for kernel de= velopers + who are working in architecture specific areas of the kernel. + It is probably not a good idea to enable this feature in a production + kernel. + + If in doubt, say N. + config NVHE_EL2_DEBUG bool "Debug mode for non-VHE EL2 object" - depends on KVM + default n help Say Y here to enable the debug mode for the non-VHE KVM EL2 object. Failure reports will BUG() in the hypervisor. This is intended for @@ -52,10 +70,23 @@ config NVHE_EL2_DEBUG =20 If unsure, say N. =20 -config PROTECTED_NVHE_STACKTRACE - bool "Protected KVM hypervisor stacktraces" - depends on NVHE_EL2_DEBUG +if NVHE_EL2_DEBUG + +config PKVM_DISABLE_STAGE2_ON_PANIC + bool "Disable the host stage-2 on panic" default n + help + Relax the host stage-2 on hypervisor panic to allow the kernel to + unwind and symbolize the hypervisor stacktrace. This however tampers + the system security. This is intended for local EL2 hypervisor + development. + + If unsure, say N. + +config PKVM_STACKTRACE + bool "Protected KVM hypervisor stacktraces" + depends on PKVM_DISABLE_STAGE2_ON_PANIC + default y help Say Y here to enable pKVM hypervisor stacktraces on hyp_panic() =20 @@ -65,21 +96,6 @@ config PROTECTED_NVHE_STACKTRACE =20 If unsure, or not using protected nVHE (pKVM), say N. =20 -config PTDUMP_STAGE2_DEBUGFS - bool "Present the stage-2 pagetables to debugfs" - depends on KVM - depends on DEBUG_KERNEL - depends on DEBUG_FS - depends on ARCH_HAS_PTDUMP - select PTDUMP - default n - help - Say Y here if you want to show the stage-2 kernel pagetables - layout in a debugfs file. This information is only useful for kernel de= velopers - who are working in architecture specific areas of the kernel. - It is probably not a good idea to enable this feature in a production - kernel. - - If in doubt, say N. - +endif # NVHE_EL2_DEBUG +endif # KVM endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index cc7d5d1709cb..54aedf93c78b 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -539,7 +539,7 @@ void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, = u64 spsr, =20 /* All hyp bugs, including warnings, are treated as fatal. */ if (!is_protected_kvm_enabled() || - IS_ENABLED(CONFIG_NVHE_EL2_DEBUG)) { + IS_ENABLED(CONFIG_PKVM_DISABLE_STAGE2_ON_PANIC)) { struct bug_entry *bug =3D find_bug(elr_in_kimg); =20 if (bug) diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S index eef15b374abb..3092befcd97c 100644 --- a/arch/arm64/kvm/hyp/nvhe/host.S +++ b/arch/arm64/kvm/hyp/nvhe/host.S @@ -120,7 +120,7 @@ SYM_FUNC_START(__hyp_do_panic) =20 mov x29, x0 =20 -#ifdef CONFIG_NVHE_EL2_DEBUG +#ifdef PKVM_DISABLE_STAGE2_ON_PANIC /* Ensure host stage-2 is disabled */ mrs x0, hcr_el2 bic x0, x0, #HCR_VM diff --git a/arch/arm64/kvm/hyp/nvhe/stacktrace.c b/arch/arm64/kvm/hyp/nvhe= /stacktrace.c index 5b6eeab1a774..7c832d60d22b 100644 --- a/arch/arm64/kvm/hyp/nvhe/stacktrace.c +++ b/arch/arm64/kvm/hyp/nvhe/stacktrace.c @@ -34,7 +34,7 @@ static void hyp_prepare_backtrace(unsigned long fp, unsig= ned long pc) stacktrace_info->pc =3D pc; } =20 -#ifdef CONFIG_PROTECTED_NVHE_STACKTRACE +#ifdef CONFIG_PKVM_STACKTRACE #include =20 DEFINE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], pkvm_sta= cktrace); @@ -134,11 +134,11 @@ static void pkvm_save_backtrace(unsigned long fp, uns= igned long pc) =20 unwind(&state, pkvm_save_backtrace_entry, &idx); } -#else /* !CONFIG_PROTECTED_NVHE_STACKTRACE */ +#else /* !CONFIG_PKVM_STACKTRACE */ static void pkvm_save_backtrace(unsigned long fp, unsigned long pc) { } -#endif /* CONFIG_PROTECTED_NVHE_STACKTRACE */ +#endif /* CONFIG_PKVM_STACKTRACE */ =20 /* * kvm_nvhe_prepare_backtrace - prepare to dump the nVHE backtrace diff --git a/arch/arm64/kvm/stacktrace.c b/arch/arm64/kvm/stacktrace.c index af5eec681127..9724c320126b 100644 --- a/arch/arm64/kvm/stacktrace.c +++ b/arch/arm64/kvm/stacktrace.c @@ -197,7 +197,7 @@ static void hyp_dump_backtrace(unsigned long hyp_offset) kvm_nvhe_dump_backtrace_end(); } =20 -#ifdef CONFIG_PROTECTED_NVHE_STACKTRACE +#ifdef CONFIG_PKVM_STACKTRACE DECLARE_KVM_NVHE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], pkvm_stacktrace); =20 @@ -225,12 +225,12 @@ static void pkvm_dump_backtrace(unsigned long hyp_off= set) kvm_nvhe_dump_backtrace_entry((void *)hyp_offset, stacktrace[i]); kvm_nvhe_dump_backtrace_end(); } -#else /* !CONFIG_PROTECTED_NVHE_STACKTRACE */ +#else /* !CONFIG_PKVM_STACKTRACE */ static void pkvm_dump_backtrace(unsigned long hyp_offset) { - kvm_err("Cannot dump pKVM nVHE stacktrace: !CONFIG_PROTECTED_NVHE_STACKTR= ACE\n"); + kvm_err("Cannot dump pKVM nVHE stacktrace: !CONFIG_PKVM_STACKTRACE\n"); } -#endif /* CONFIG_PROTECTED_NVHE_STACKTRACE */ +#endif /* CONFIG_PKVM_STACKTRACE */ =20 /* * kvm_nvhe_dump_backtrace - Dump KVM nVHE hypervisor backtrace. --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ed1-f74.google.com (mail-ed1-f74.google.com [209.85.208.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 566853BED4B for ; Fri, 6 Mar 2026 14:36:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807777; cv=none; b=Ntp6kici7dMKpF4mSSXwSsfTNXWhpGDET4h/Bx6ahDokSxznsuhAEkvL9bDeSNIgl/xhER1f4UoVBXQF9O2+Et/HOTrXXGmeUdL3mqROOpT7doI+0RfaNTZRH0G5yw7MZQ+v15X51dZE3BZS505aSGLUVG4oD0nzlzgSi/oTTXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807777; c=relaxed/simple; bh=h2rVCYiv2RErJ8J/DPs4R6liat0vq1OWoPSAfx6DS2s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=eYKscLGSsq2pa6qtdPRzutmX6ACE9pOzb+w4CmIcyYSNZZD9+c+ucVddyitfvCq/+Xh4ov4z5cmxdDyZ5upZby7PvRPDqj3h531uQpsx+TT8UBMqHtzGmNlELLKEI1psNZnHsfnP3j8qYDVYowhtBz/KQq4Zc7SFFlNvq8VJMlg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3TpykPHX; arc=none smtp.client-ip=209.85.208.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3TpykPHX" Received: by mail-ed1-f74.google.com with SMTP id 4fb4d7f45d1cf-661aff85c3eso1313694a12.2 for ; Fri, 06 Mar 2026 06:36:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807774; x=1773412574; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xnACahr8ULD6CcAQo9gjmAw66hUMbPmLgQ2wO/RqDz0=; b=3TpykPHXQU3ww5fDK/M2qWCg34NpDgpsq3NnEADVs76ZiNFBtq9w+2KV0QJn1Df2nw T03htRbS8hOH2iAxLhlHHhZZTdgEVVFVVzmtil9bZq9FTljpJjjTn7XcdPR8gYCDE5K7 YO/Q86yVAGwDWM4tGxWfS+1D8nqLEH4R3jx9JEtlauKoOlpAQGW2/pERMTZhBVs7RWF7 NdWLcP9wB8PqdwWWGtWg0D8HAkETmSdYEzJxE7+TrdKWI3lRdhNgA8zfRWFf8+PI8HEv 1qgsTnXcSednLdq/VIMGyz7gKUDYYwL8d0qmKUsKlqXkvDXnDlZBqIWyCRZCt10N8+Oy YmtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807774; x=1773412574; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xnACahr8ULD6CcAQo9gjmAw66hUMbPmLgQ2wO/RqDz0=; b=hT/NWOK8hfbh4YAjEAlRj2U6StKwEfjmv1Cw2DdhqpClyQc3uHP5xO0wj8Q86b96V1 7aaLBcpAOYvCUp6CLewk+ix9wfEJseecIQ2FuGunmELi71T0r9abYDGUoM13I4rht/Qb aNgk5b8s5FelywaLxj6ps9icedhQhpyPIvlD/qiMHDYWGZLRteGptqlWM53lS861bM3F p2Xv7gIBTFntfZzfQHHhoEPEfhAACs50QyaIIqIHyU1fO/K0kwiOqrW8na7XKN7Q9eQC MTUsQseye3jo2W31yyD3zUTbqtQ1EfHp/V0SRJMnXxUoXqf1+j5C3QksvPz/8yxXw/qR lERQ== X-Forwarded-Encrypted: i=1; AJvYcCW36LxxXZYmlaCqcnnekazG1HsqH03h+G97Hmn8Cjc+tqiYhtIbCiwfKjmA78hz8RDuv1KFd6FWXOOn0bs=@vger.kernel.org X-Gm-Message-State: AOJu0YzpSAGFyH5p9EwR/leFuLoO1finn1laYVAwTe5Dhub66cuTllSj wxtnCBF4UGxcDu4GAiaQhOhiM6kpVWnRoh6xLDb4xWFVrIJLr3D30/VtROEqVhDliXkpXNvvziv azCF88SRjw0lsBUeYhyk9Kg== X-Received: from edrs15.prod.google.com ([2002:aa7:c54f:0:b0:660:a4e3:2ed2]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:430c:b0:65a:2ec5:99c0 with SMTP id 4fb4d7f45d1cf-6619d4565b4mr1408474a12.3.1772807772463; Fri, 06 Mar 2026 06:36:12 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:24 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-21-vdonnefort@google.com> Subject: [PATCH v13 20/32] KVM: arm64: Add clock support to nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for supporting tracing from the nVHE hyp, add support to generate timestamps with a clock fed by the CNTCVT counter. The clock can be kept in sync with the kernel's by updating the slope values. This will be done later. As current we do only create a trace clock, make the whole support dependent on the upcoming CONFIG_NVHE_EL2_TRACING. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/include/nvhe/clock.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/clock.h new file mode 100644 index 000000000000..9f429f5c0664 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/clock.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ARM64_KVM_HYP_NVHE_CLOCK_H +#define __ARM64_KVM_HYP_NVHE_CLOCK_H +#include + +#include + +#ifdef CONFIG_NVHE_EL2_TRACING +void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc); +u64 trace_clock(void); +#else +static inline void +trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc) { } +static inline u64 trace_clock(void) { return 0; } +#endif +#endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index a244ec25f8c5..8dc95257c291 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -17,7 +17,7 @@ ccflags-y +=3D -fno-stack-protector \ hostprogs :=3D gen-hyprel HOST_EXTRACFLAGS +=3D -I$(objtree)/include =20 -lib-objs :=3D clear_page.o copy_page.o memcpy.o memset.o +lib-objs :=3D clear_page.o copy_page.o memcpy.o memset.o tishift.o lib-objs :=3D $(addprefix ../../../lib/, $(lib-objs)) =20 CFLAGS_switch.nvhe.o +=3D -Wno-override-init @@ -29,6 +29,7 @@ hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cp= uif-proxy.o ../entry.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-y +=3D ../../../kernel/smccc-call.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o +hyp-obj-$(CONFIG_NVHE_EL2_TRACING) +=3D clock.o hyp-obj-y +=3D $(lib-objs) =20 ## diff --git a/arch/arm64/kvm/hyp/nvhe/clock.c b/arch/arm64/kvm/hyp/nvhe/cloc= k.c new file mode 100644 index 000000000000..32fc4313fe43 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/clock.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include + +#include +#include + +static struct clock_data { + struct { + u32 mult; + u32 shift; + u64 epoch_ns; + u64 epoch_cyc; + u64 cyc_overflow64; + } data[2]; + u64 cur; +} trace_clock_data; + +static u64 __clock_mult_uint128(u64 cyc, u32 mult, u32 shift) +{ + __uint128_t ns =3D (__uint128_t)cyc * mult; + + ns >>=3D shift; + + return (u64)ns; +} + +/* Does not guarantee no reader on the modified bank. */ +void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc) +{ + struct clock_data *clock =3D &trace_clock_data; + u64 bank =3D clock->cur ^ 1; + + clock->data[bank].mult =3D mult; + clock->data[bank].shift =3D shift; + clock->data[bank].epoch_ns =3D epoch_ns; + clock->data[bank].epoch_cyc =3D epoch_cyc; + clock->data[bank].cyc_overflow64 =3D ULONG_MAX / mult; + + smp_store_release(&clock->cur, bank); +} + +/* Use untrusted host data */ +u64 trace_clock(void) +{ + struct clock_data *clock =3D &trace_clock_data; + u64 bank =3D smp_load_acquire(&clock->cur); + u64 cyc, ns; + + cyc =3D __arch_counter_get_cntvct() - clock->data[bank].epoch_cyc; + + if (likely(cyc < clock->data[bank].cyc_overflow64)) { + ns =3D cyc * clock->data[bank].mult; + ns >>=3D clock->data[bank].shift; + } else { + ns =3D __clock_mult_uint128(cyc, clock->data[bank].mult, + clock->data[bank].shift); + } + + return (u64)ns + clock->data[bank].epoch_ns; +} --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E9283BED45 for ; Fri, 6 Mar 2026 14:36:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807777; cv=none; b=qW/SlXrsKBDPIMHYC4ozySV2y+oCwEXwPrFDwE0yK9ZvPiMBgOP1JxznKsscb7YBzOm1BTx1PDc7IyNc6HWv1fsObXOpWL3We9fKIGpdAZoV92D+4mVElJ/1dF2hSpAmoArC152RTaW4SGMMfydEzJw9Prj8pGMQuqVHdpnLrLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807777; c=relaxed/simple; bh=Qjw69/BBWT9BSPH1lQiEuT1/lOOedls+e1TJNd0iMvs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Gz+gDXtjNcAnZIzY8Gtf6S+/4HHST3h/hPEHzCF5/IB5lTRsA6qlbsWo3fcsrzVy3ExtDGXuXnSAfmcUyj39sHkuioSYbq783YeQzbdgr5CpLN4PCftC0xSBSH7iG/msiejdn0hA1MxNGE6qgBccunKBxC01n51dFB2sydDX5C4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=k03yidtD; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="k03yidtD" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-6610d8f357cso3207652a12.0 for ; Fri, 06 Mar 2026 06:36:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807774; x=1773412574; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2KM8z/si7HcTp05zjHIB0T7h5Dhh3bTdr1CGW99HQcs=; b=k03yidtDbT1pOLeG/SaQvIuJi8nTxqYEaGlRTLEKHfV1MafdPYWrCVLU6n/L8KqhVQ YsXQwbfvwhb0Yyag85vrJ2XoUsxYzKE1zy6yZ5anRgWE0NvtaPepx0AIINgMhCyQAHx7 p/KAfMAvWid6sPfDECzVDaMgXMYGM4ZuKVdVuncGo69C3s+OJKnQNnBrxQjk0ai3n9XD yTfp8JVlYbjtvqp+UJnrswOFmJrkp34daSHbOF+og/mVtdD8MqvhYQakwpwrp0xSP5cY b/uRpVBtXxzqcAUSWnkbdzfosE/i/9aH9WFhMG98zQIRbpLTNtMj+curI46uWbihFH7z ajGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807774; x=1773412574; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2KM8z/si7HcTp05zjHIB0T7h5Dhh3bTdr1CGW99HQcs=; b=DzFqtUi8cqvYV+Y9kb4NMdnXw1pWXR1d0WrKU3WRhI/aIlFdWdAHj8zOHfczrOfnKe EHC2RZP+ywfVaBkWp0BHobqgZJT13kTbEq9LkqOY5CIyUQzo0awQWpkYoDs2Rflzi6SJ /1xesGat5hwfdBKDkUczKsmMQi2ulqVoUt5ogFhISfK1lANoWa44N/Uey2b0hQZ/11OF XmVsBGbMNIE2GRiVt0Ju76CNF0KzFQ8Mb0tNirKb7DCf3Frs155pIZlm4rCGPi6RsDaq laWXNjW+5vNUs86sDMwRef5KqNJcsL70gaN+j297dNUIUg7gpZ4vsmoWrHpWnnhjfuGY wtvw== X-Forwarded-Encrypted: i=1; AJvYcCWJyVFeJpMkruE87exD8OepfxjJc44HXXknToojHVaIkHir2Lvx2wnEImeYi+C6PwVsVCe3sdyiBLRxWc0=@vger.kernel.org X-Gm-Message-State: AOJu0YyDc8qpkzYG3oYh6GvotzcvYlzm4rBcNkQLflPS4APXm8xhVlrJ uRkOh8iMObcxCNg4DHCj4pQdt7q01i7zjmFYIzNcN0vw2crJrnsYXLPLQ7N0o6LToD/3CMAwB/W /wT0ZQqVnqz1yf1DoptQJww== X-Received: from edbio12-n2.prod.google.com ([2002:a05:6402:218c:20b0:661:1191:6d3a]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:51ce:b0:660:ce49:f6b3 with SMTP id 4fb4d7f45d1cf-6619d52e969mr1236686a12.30.1772807773593; Fri, 06 Mar 2026 06:36:13 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:25 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-22-vdonnefort@google.com> Subject: [PATCH v13 21/32] KVM: arm64: Initialise hyp_nr_cpus for nVHE hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Knowing the number of CPUs is necessary for determining the boundaries of per-cpu variables, which will be used for upcoming hypervisor tracing. hyp_nr_cpus which stores this value, is only initialised for the pKVM hypervisor. Make it accessible for the nVHE hypervisor as well. With the kernel now responsible for initialising hyp_nr_cpus, the nr_cpus parameter is no longer needed in __pkvm_init. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_= hyp.h index 76ce2b94bd97..4bf63025061e 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -129,8 +129,7 @@ void __noreturn __hyp_do_panic(struct kvm_cpu_context *= host_ctxt, u64 spsr, #ifdef __KVM_NVHE_HYPERVISOR__ void __pkvm_init_switch_pgd(phys_addr_t pgd, unsigned long sp, void (*fn)(void)); -int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpu= s, - unsigned long *per_cpu_base, u32 hyp_va_bits); +int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long *per_c= pu_base, u32 hyp_va_bits); void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt); #endif =20 @@ -147,5 +146,6 @@ extern u64 kvm_nvhe_sym(id_aa64smfr0_el1_sys_val); extern unsigned long kvm_nvhe_sym(__icache_flags); extern unsigned int kvm_nvhe_sym(kvm_arm_vmid_bits); extern unsigned int kvm_nvhe_sym(kvm_host_sve_max_vl); +extern unsigned long kvm_nvhe_sym(hyp_nr_cpus); =20 #endif /* __ARM64_KVM_HYP_H__ */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 410ffd41fd73..1371f9b3ecea 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -2465,7 +2466,7 @@ static int __init do_pkvm_init(u32 hyp_va_bits) preempt_disable(); cpu_hyp_init_context(); ret =3D kvm_call_hyp_nvhe(__pkvm_init, hyp_mem_base, hyp_mem_size, - num_possible_cpus(), kern_hyp_va(per_cpu_base), + kern_hyp_va(per_cpu_base), hyp_va_bits); cpu_hyp_init_features(); =20 @@ -2674,6 +2675,8 @@ static int __init init_hyp_mode(void) kvm_nvhe_sym(kvm_arm_hyp_percpu_base)[cpu] =3D (unsigned long)page_addr; } =20 + kvm_nvhe_sym(hyp_nr_cpus) =3D num_possible_cpus(); + /* * Map the Hyp-code called directly from the host */ diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm= /hyp/include/nvhe/mem_protect.h index 5f9d56754e39..f8a7b8c04c49 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -30,8 +30,6 @@ enum pkvm_component_id { PKVM_ID_FFA, }; =20 -extern unsigned long hyp_nr_cpus; - int __pkvm_prot_finalize(void); int __pkvm_host_share_hyp(u64 pfn); int __pkvm_host_unshare_hyp(u64 pfn); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index e7790097db93..8ae3c348ed81 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -486,17 +486,15 @@ static void handle___pkvm_init(struct kvm_cpu_context= *host_ctxt) { DECLARE_REG(phys_addr_t, phys, host_ctxt, 1); DECLARE_REG(unsigned long, size, host_ctxt, 2); - DECLARE_REG(unsigned long, nr_cpus, host_ctxt, 3); - DECLARE_REG(unsigned long *, per_cpu_base, host_ctxt, 4); - DECLARE_REG(u32, hyp_va_bits, host_ctxt, 5); + DECLARE_REG(unsigned long *, per_cpu_base, host_ctxt, 3); + DECLARE_REG(u32, hyp_va_bits, host_ctxt, 4); =20 /* * __pkvm_init() will return only if an error occurred, otherwise it * will tail-call in __pkvm_init_finalise() which will have to deal * with the host context directly. */ - cpu_reg(host_ctxt, 1) =3D __pkvm_init(phys, size, nr_cpus, per_cpu_base, - hyp_va_bits); + cpu_reg(host_ctxt, 1) =3D __pkvm_init(phys, size, per_cpu_base, hyp_va_bi= ts); } =20 static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setu= p.c index 90bd014e952f..d8e5b563fd3d 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -341,8 +341,7 @@ void __noreturn __pkvm_init_finalise(void) __host_enter(host_ctxt); } =20 -int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpu= s, - unsigned long *per_cpu_base, u32 hyp_va_bits) +int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long *per_c= pu_base, u32 hyp_va_bits) { struct kvm_nvhe_init_params *params; void *virt =3D hyp_phys_to_virt(phys); @@ -355,7 +354,6 @@ int __pkvm_init(phys_addr_t phys, unsigned long size, u= nsigned long nr_cpus, return -EINVAL; =20 hyp_spin_lock_init(&pkvm_pgd_lock); - hyp_nr_cpus =3D nr_cpus; =20 ret =3D divide_memory_pool(virt, size); if (ret) --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DFB83BFE34 for ; Fri, 6 Mar 2026 14:36:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807778; cv=none; b=rq8FzZ0ph4imeaXwMR1xTWBOpe5lBDWYTg22utzEJ3ShG4AwMPT/W7gN1A2Di2ePTijxiBFeqeE75H9uxf/Loghwy9tERNDJRHrd5OV2yTdKbRsvHNTUPbM7d9+LdlVzyRwfPXIw9CXksrWjHEf55lHSYItrHXtA4x6ki59TlqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807778; c=relaxed/simple; bh=cWmCVGc8Z9dVFyLjcgMh+d+QoVHI1pxbCmuYrrytJC8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EpqjRz061soWQO8Oswaw1/QlID+EKeQn9d7MM/hX4DpBPtVPint111gjgXXW86kU4dK8Fn4kqj86QBlYOOxcaUMBn7+nni7mGE/kj4V5twiNZSziATy0AGDlR5u9mgGx5dwxMW5N6z1BYcGuRck2vzmcqdrBI+vgh2k1/P+36NA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=OicWoWRe; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="OicWoWRe" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4836cf00787so96817095e9.1 for ; Fri, 06 Mar 2026 06:36:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807775; x=1773412575; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+KUjQbuHQJ21p2RQALWJdLghrvcyrBZVXJ9cfGciG9M=; b=OicWoWRedZyV0n8lR/4qhRNHL9aDsjFdrTnHO0v+9u9epvAoaeVf1G1vypX7LuU41p 4sbXZywU28/20qF9DaYPtqHZzs1D8qcCTW4MW3iNZotpv2MSOf9AK5vFP9g96QSjS8iK tTpM4EE5Vrue+mIt40BAg8biP9WNFmfSv0qUKejnm6zOW834SVkPFPLGKxnBv/lZXhhd QlBBFDQhgI4tmpyh7OQds3Gh9h8B4QEB69BLA+zp/SxJ00EoA2PeLqPQu/jWPtOphoyd OjFHRRHtnMX78nqvLBuPSYxHxCVjfrTr1f/2Vbi55afU6qQxD7u3eIIOW78d2tj/9VXC Lifg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807775; x=1773412575; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+KUjQbuHQJ21p2RQALWJdLghrvcyrBZVXJ9cfGciG9M=; b=XelLMU1uzDq7PY/yrxYgB6qDvCo4Ba91b4IOxPFyFOVqyj9zVVi3hsqpCM0pgWapi5 NahAvXZCKiTcD13seFptdR8EHqbE38jWEwzYhDWXzxZPlMBq0Py9gee9dSaDmBlSqDAk w1ylcnZt6C6z3ZxqIidUjRrtAhV8mjI3loU57mIn3QD7byGk+bDGoQpSd+fbSZPeYeGW 8qjpOcoYO+kKLhw80hNFwUtJd1dUPOWLNdiwyPvczdDIAkuZkNhVqLGLIpGxtKTaBJoQ +Re20E5yYsFB0hdvKMDZLKM4BK91OGQ5+Jy8AdQm35ngRfGGCW3M1oUf8X1hMGFjggoA i3jQ== X-Forwarded-Encrypted: i=1; AJvYcCU/DWWjXLB5h8HxbZAxzh8gwDjCtpFPmAmlOBNww4GLCUKoaduUu9Y/UtOpBUrIQlaUXaCeSZK7lsYZ3eg=@vger.kernel.org X-Gm-Message-State: AOJu0YwMz1ztW4Jesd6kBc6G+jtRmQKCw/Pv0UDp6/xxm5H8e7HgOfsV v0R2qMBp4SLqaZSkzWbEyw0HNSYI4o6296fXhk52RYpmCM77Jvn5z3QM3gJW/5TEgrLbWlO4+v7 +QIWZn+LoiATekrlGgV7B3Q== X-Received: from wmcn3-n1.prod.google.com ([2002:a05:600c:c0c3:10b0:479:2d82:5535]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4446:b0:483:29f4:26b3 with SMTP id 5b1f17b1804b1-48526715248mr36686515e9.1.1772807774527; Fri, 06 Mar 2026 06:36:14 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:26 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-23-vdonnefort@google.com> Subject: [PATCH v13 22/32] KVM: arm64: Support unaligned fixmap in the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Return the fixmap VA with the page offset, instead of the page base address. This allows to use hyp_fixmap_map() seamlessly regardless of the address alignment. While at it, do the same for hyp_fixblock_map(). Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index 218976287d3f..c98cec0c150f 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -244,7 +244,7 @@ static void *fixmap_map_slot(struct hyp_fixmap_slot *sl= ot, phys_addr_t phys) =20 void *hyp_fixmap_map(phys_addr_t phys) { - return fixmap_map_slot(this_cpu_ptr(&fixmap_slots), phys); + return fixmap_map_slot(this_cpu_ptr(&fixmap_slots), phys) + offset_in_pag= e(phys); } =20 static void fixmap_clear_slot(struct hyp_fixmap_slot *slot) @@ -366,7 +366,7 @@ void *hyp_fixblock_map(phys_addr_t phys, size_t *size) #ifdef HAS_FIXBLOCK *size =3D PMD_SIZE; hyp_spin_lock(&hyp_fixblock_lock); - return fixmap_map_slot(&hyp_fixblock_slot, phys); + return fixmap_map_slot(&hyp_fixblock_slot, phys) + offset_in_page(phys); #else *size =3D PAGE_SIZE; return hyp_fixmap_map(phys); --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40D413BFE5D for ; Fri, 6 Mar 2026 14:36:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807779; cv=none; b=fwjrGVlFehZRJXZxif8EW/R2yfE94QpCmR1vBZKFsSmkoQK6G+lRyFSBd+e4PaOjsWvhAJDutET/TdSi5OJ0WBy1X8J6odttSzvZDEj6nzij0j3ot0XcRZcFtGOulLnHi6vkPo5LD34/I8iDC1d0KtC2DOD/lmSzXADCeUzBUm8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807779; c=relaxed/simple; bh=CRt95CGaWijgNj0CX4vEgeqs4J3WLR5sXJJoHfm5ouE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=BeKwf/+1k9SJaRBOHbmpFUdMQ9EmczREx0VENxnLEvtyxw4e4z/3GMaly7JQD29A6HblP+o2sw+8fXDJu8bGyGC/wp+5kQ1hTSv/ckFPcAAv2tlgP7PaAkC92FJcbFHxuid6841X/ouKP0cVkb5c0vuzF54lXlUu489nYKcgqdw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0FqV3Gs2; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0FqV3Gs2" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-b8ff07df5e4so807797466b.3 for ; Fri, 06 Mar 2026 06:36:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807776; x=1773412576; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=eJmDPKvMyOS51BKv2G6prQvsGdyE4gzwJ4Z5A59URQg=; b=0FqV3Gs23Z2IcC/k/JcLdh6x1VWjVl48UvixgfnqfCvPoBdrnwRJysCsh9ZCUwEAKj 9+X6skaqc6N8jNUNkDzSIkmpTw8a9DllptaV8k0/5l3NEC8RsMB5SsrmB6F6bf21Xgu1 ZQsiYxmBZT9UQHvsFL6ziO+4QTMmdSfmuzIZNUZT2460kFPKIBRFVmf2AHW6GXWUAxuX aLvYpxj3TzTBVXMYI0fPa5YkdFsCXiPWr9E3n/Y2ER6C2umLjAAihXvlFGpL+jyPo0Jn PWo+HlNrq3q7sULa5inuS5vedqI+A+tzubzf2YzWFsX6tkUHRqVTDssUpQ9ol4RKyYyY yYFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807776; x=1773412576; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=eJmDPKvMyOS51BKv2G6prQvsGdyE4gzwJ4Z5A59URQg=; b=ViDtSlxXbzQPuB+A8iTLhLmnOugcBeILOwVNF1vjknAFgTVXpwUsHv8Em/x7Vw0eRT PDLxUJ3BbpCdisv/YyvAHMASKzcErb/Zn3wKO92Tg9+VL45NNjPcUjcr7qld21JMty5s d69lSXCAj0//jczMj+DNu69akVyUV4Rls7+WqG7EjqQXRJyk/5/dn9m+nUC8hJ6uXtAi d6iF0fjr/4qC8gsWChFlKnKXv0e57lx1slPsmsV3ZW143AsmQHGqCNUB5R7IlVtwuI2F s4SzrAjYni+nTYM8cwwGAfvL8iwxB3pSBUJtmuPqJ6cT6gqRA8J/rmmEpZfQR1o441rT fACw== X-Forwarded-Encrypted: i=1; AJvYcCUXNQqE+7ubNeIS7Ki5nNv0oe66IqL1yTDA+uXin+8zsYnBKdC9E7NWDLdwTxADWX9Hj6es9xEu3+enDpU=@vger.kernel.org X-Gm-Message-State: AOJu0Yy4yjS9FqiUKDV4SfsuereFPduokNEP8G32v9TQzPZ9z/0gQ8IL JfcuRQMtlGURlTqfG4LcUHda6YjZ5cbKcMGvpEr29gjYDct6TwCAKKAxkcZ3F3elIQLvYlyjDPH yPJADkq+IF7GRAx5e2GgQZw== X-Received: from ejcaz22.prod.google.com ([2002:a17:907:9056:b0:b94:31f:e313]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:60d2:b0:b8f:7014:48fb with SMTP id a640c23a62f3a-b942dbdc666mr126492766b.16.1772807775523; Fri, 06 Mar 2026 06:36:15 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:27 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-24-vdonnefort@google.com> Subject: [PATCH v13 23/32] KVM: arm64: Add tracing capability for the nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" There is currently no way to inspect or log what's happening at EL2 when the nVHE or pKVM hypervisor is used. With the growing set of features for pKVM, the need for tooling is more pressing. And tracefs, by its reliability, versatility and support for user-space is fit for purpose. Add support to write into a tracefs compatible ring-buffer. There's no way the hypervisor could log events directly into the host tracefs ring-buffers. So instead let's use our own, where the hypervisor is the writer and the host the reader. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index a1ad12c72ebf..d46d9196d661 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -89,6 +89,10 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load, __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put, __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid, + __KVM_HOST_SMCCC_FUNC___tracing_load, + __KVM_HOST_SMCCC_FUNC___tracing_unload, + __KVM_HOST_SMCCC_FUNC___tracing_enable, + __KVM_HOST_SMCCC_FUNC___tracing_swap_reader, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm= /kvm_hyptrace.h new file mode 100644 index 000000000000..9c30a479bc36 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hyptrace.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_HYPTRACE_H_ +#define __ARM64_KVM_HYPTRACE_H_ + +#include + +struct hyp_trace_desc { + unsigned long bpages_backing_start; + size_t bpages_backing_size; + struct trace_buffer_desc trace_buffer_desc; + +}; +#endif diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 14b2d0b0b831..d215348370fa 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -72,6 +72,11 @@ config NVHE_EL2_DEBUG =20 if NVHE_EL2_DEBUG =20 +config NVHE_EL2_TRACING + bool + depends on TRACING + default y + config PKVM_DISABLE_STAGE2_ON_PANIC bool "Disable the host stage-2 on panic" default n diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h new file mode 100644 index 000000000000..7da8788ce527 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_HYP_NVHE_TRACE_H +#define __ARM64_KVM_HYP_NVHE_TRACE_H +#include + +#ifdef CONFIG_NVHE_EL2_TRACING +void *tracing_reserve_entry(unsigned long length); +void tracing_commit_entry(void); + +int __tracing_load(unsigned long desc_va, size_t desc_size); +void __tracing_unload(void); +int __tracing_enable(bool enable); +int __tracing_swap_reader(unsigned int cpu); +#else +static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } +static inline void tracing_commit_entry(void) { } + +static inline int __tracing_load(unsigned long desc_va, size_t desc_size) = { return -ENODEV; } +static inline void __tracing_unload(void) { } +static inline int __tracing_enable(bool enable) { return -ENODEV; } +static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } +#endif +#endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index 8dc95257c291..f1840628d2d6 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -29,9 +29,12 @@ hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-c= puif-proxy.o ../entry.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-y +=3D ../../../kernel/smccc-call.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_NVHE_EL2_TRACING) +=3D clock.o +hyp-obj-$(CONFIG_NVHE_EL2_TRACING) +=3D clock.o trace.o hyp-obj-y +=3D $(lib-objs) =20 +# Path to simple_ring_buffer.c +CFLAGS_trace.nvhe.o +=3D -I$(objtree)/kernel/trace/ + ## ## Build rules for compiling nVHE hyp code ## Output of this folder is `kvm_nvhe.o`, a partially linked object diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 8ae3c348ed81..ae04204ea81f 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include =20 DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); @@ -587,6 +588,33 @@ static void handle___pkvm_teardown_vm(struct kvm_cpu_c= ontext *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_teardown_vm(handle); } =20 +static void handle___tracing_load(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); + DECLARE_REG(size_t, desc_size, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) =3D __tracing_load(desc_hva, desc_size); +} + +static void handle___tracing_unload(struct kvm_cpu_context *host_ctxt) +{ + __tracing_unload(); +} + +static void handle___tracing_enable(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(bool, enable, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __tracing_enable(enable); +} + +static void handle___tracing_swap_reader(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __tracing_swap_reader(cpu); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -628,6 +656,10 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_vcpu_load), HANDLE_FUNC(__pkvm_vcpu_put), HANDLE_FUNC(__pkvm_tlb_flush_vmid), + HANDLE_FUNC(__tracing_load), + HANDLE_FUNC(__tracing_unload), + HANDLE_FUNC(__tracing_enable), + HANDLE_FUNC(__tracing_swap_reader), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c new file mode 100644 index 000000000000..282cba70ce9b --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "simple_ring_buffer.c" + +static DEFINE_PER_CPU(struct simple_rb_per_cpu, __simple_rbs); + +static struct hyp_trace_buffer { + struct simple_rb_per_cpu __percpu *simple_rbs; + void *bpages_backing_start; + size_t bpages_backing_size; + hyp_spinlock_t lock; +} trace_buffer =3D { + .simple_rbs =3D &__simple_rbs, + .lock =3D __HYP_SPIN_LOCK_UNLOCKED, +}; + +static bool hyp_trace_buffer_loaded(struct hyp_trace_buffer *trace_buffer) +{ + return trace_buffer->bpages_backing_size > 0; +} + +void *tracing_reserve_entry(unsigned long length) +{ + return simple_ring_buffer_reserve(this_cpu_ptr(trace_buffer.simple_rbs), = length, + trace_clock()); +} + +void tracing_commit_entry(void) +{ + simple_ring_buffer_commit(this_cpu_ptr(trace_buffer.simple_rbs)); +} + +static int __admit_host_mem(void *start, u64 size) +{ + if (!PAGE_ALIGNED(start) || !PAGE_ALIGNED(size) || !size) + return -EINVAL; + + if (!is_protected_kvm_enabled()) + return 0; + + return __pkvm_host_donate_hyp(hyp_virt_to_pfn(start), size >> PAGE_SHIFT); +} + +static void __release_host_mem(void *start, u64 size) +{ + if (!is_protected_kvm_enabled()) + return; + + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(start), size >> PAGE_SHIFT= )); +} + +static int hyp_trace_buffer_load_bpage_backing(struct hyp_trace_buffer *tr= ace_buffer, + struct hyp_trace_desc *desc) +{ + void *start =3D (void *)kern_hyp_va(desc->bpages_backing_start); + size_t size =3D desc->bpages_backing_size; + int ret; + + ret =3D __admit_host_mem(start, size); + if (ret) + return ret; + + memset(start, 0, size); + + trace_buffer->bpages_backing_start =3D start; + trace_buffer->bpages_backing_size =3D size; + + return 0; +} + +static void hyp_trace_buffer_unload_bpage_backing(struct hyp_trace_buffer = *trace_buffer) +{ + void *start =3D trace_buffer->bpages_backing_start; + size_t size =3D trace_buffer->bpages_backing_size; + + if (!size) + return; + + memset(start, 0, size); + + __release_host_mem(start, size); + + trace_buffer->bpages_backing_start =3D 0; + trace_buffer->bpages_backing_size =3D 0; +} + +static void *__pin_shared_page(unsigned long kern_va) +{ + void *va =3D kern_hyp_va((void *)kern_va); + + if (!is_protected_kvm_enabled()) + return va; + + return hyp_pin_shared_mem(va, va + PAGE_SIZE) ? NULL : va; +} + +static void __unpin_shared_page(void *va) +{ + if (!is_protected_kvm_enabled()) + return; + + hyp_unpin_shared_mem(va, va + PAGE_SIZE); +} + +static void hyp_trace_buffer_unload(struct hyp_trace_buffer *trace_buffer) +{ + int cpu; + + hyp_assert_lock_held(&trace_buffer->lock); + + if (!hyp_trace_buffer_loaded(trace_buffer)) + return; + + for (cpu =3D 0; cpu < hyp_nr_cpus; cpu++) + simple_ring_buffer_unload_mm(per_cpu_ptr(trace_buffer->simple_rbs, cpu), + __unpin_shared_page); + + hyp_trace_buffer_unload_bpage_backing(trace_buffer); +} + +static int hyp_trace_buffer_load(struct hyp_trace_buffer *trace_buffer, + struct hyp_trace_desc *desc) +{ + struct simple_buffer_page *bpages; + struct ring_buffer_desc *rb_desc; + int ret, cpu; + + hyp_assert_lock_held(&trace_buffer->lock); + + if (hyp_trace_buffer_loaded(trace_buffer)) + return -EINVAL; + + ret =3D hyp_trace_buffer_load_bpage_backing(trace_buffer, desc); + if (ret) + return ret; + + bpages =3D trace_buffer->bpages_backing_start; + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) { + ret =3D simple_ring_buffer_init_mm(per_cpu_ptr(trace_buffer->simple_rbs,= cpu), + bpages, rb_desc, __pin_shared_page, + __unpin_shared_page); + if (ret) + break; + + bpages +=3D rb_desc->nr_page_va; + } + + if (ret) + hyp_trace_buffer_unload(trace_buffer); + + return ret; +} + +static bool hyp_trace_desc_validate(struct hyp_trace_desc *desc, size_t de= sc_size) +{ + struct ring_buffer_desc *rb_desc; + unsigned int cpu; + size_t nr_bpages; + void *desc_end; + + /* + * Both desc_size and bpages_backing_size are untrusted host-provided + * values. We rely on __pkvm_host_donate_hyp() to enforce their validity. + */ + desc_end =3D (void *)desc + desc_size; + nr_bpages =3D desc->bpages_backing_size / sizeof(struct simple_buffer_pag= e); + + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) { + /* Can we read nr_page_va? */ + if ((void *)rb_desc + struct_size(rb_desc, page_va, 0) > desc_end) + return false; + + /* Overflow desc? */ + if ((void *)rb_desc + struct_size(rb_desc, page_va, rb_desc->nr_page_va)= > desc_end) + return false; + + /* Overflow bpages backing memory? */ + if (nr_bpages < rb_desc->nr_page_va) + return false; + + if (cpu >=3D hyp_nr_cpus) + return false; + + if (cpu !=3D rb_desc->cpu) + return false; + + nr_bpages -=3D rb_desc->nr_page_va; + } + + return true; +} + +int __tracing_load(unsigned long desc_hva, size_t desc_size) +{ + struct hyp_trace_desc *desc =3D (struct hyp_trace_desc *)kern_hyp_va(desc= _hva); + int ret; + + ret =3D __admit_host_mem(desc, desc_size); + if (ret) + return ret; + + if (!hyp_trace_desc_validate(desc, desc_size)) + goto err_release_desc; + + hyp_spin_lock(&trace_buffer.lock); + + ret =3D hyp_trace_buffer_load(&trace_buffer, desc); + + hyp_spin_unlock(&trace_buffer.lock); + +err_release_desc: + __release_host_mem(desc, desc_size); + return ret; +} + +void __tracing_unload(void) +{ + hyp_spin_lock(&trace_buffer.lock); + hyp_trace_buffer_unload(&trace_buffer); + hyp_spin_unlock(&trace_buffer.lock); +} + +int __tracing_enable(bool enable) +{ + int cpu, ret =3D enable ? -EINVAL : 0; + + hyp_spin_lock(&trace_buffer.lock); + + if (!hyp_trace_buffer_loaded(&trace_buffer)) + goto unlock; + + for (cpu =3D 0; cpu < hyp_nr_cpus; cpu++) + simple_ring_buffer_enable_tracing(per_cpu_ptr(trace_buffer.simple_rbs, c= pu), + enable); + + ret =3D 0; + +unlock: + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} + +int __tracing_swap_reader(unsigned int cpu) +{ + int ret =3D -ENODEV; + + if (cpu >=3D hyp_nr_cpus) + return -EINVAL; + + hyp_spin_lock(&trace_buffer.lock); + + if (hyp_trace_buffer_loaded(&trace_buffer)) + ret =3D simple_ring_buffer_swap_reader_page( + per_cpu_ptr(trace_buffer.simple_rbs, cpu)); + + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F7C43C2775 for ; Fri, 6 Mar 2026 14:36:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807780; cv=none; b=obazArpH+NrA5KTLcF6Gs6k63e8jRSmHUUD779HH7/5GMMWXtpMI2DHg2e7wVIOe+ejBuRi2q9vKTu9GMabwxM6QmftNqeo6lmXWeuLX3D+TaITo0y4UbA88qCxmTkmxshI+K1bsFiQ5CSnnGannmVMAOg3J2Jv5xVFCbruE1qk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807780; c=relaxed/simple; bh=9HqjZKGmCapbm1ub8i+wKOKeCQNhrcpJewtAgL7K6GQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VVx7pra9LOyia6qeGLJ6YhxgQ+M2BavKSe4/rF1cDw/33DL5cabuLuuEQ757YNYBLEdu2TPvOs9dOyoMHLS+l2yt1SEiXMtv2VBAMmBJRzQqMJtrAXPb02aQoObE9KfhplKO8+I+r8oozQq04ngPTkJKRvmlHv58vFYLPUpMUaQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Bn/xmtbj; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Bn/xmtbj" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-b940da8ec09so247261266b.1 for ; Fri, 06 Mar 2026 06:36:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807777; x=1773412577; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sqWYQ9lCo+j6BKFc/ZubG4EbmDj1j9ozKwcXgqRTpuk=; b=Bn/xmtbjtbPiqPeC0MunaFG92ac98BbP2zyx2iY9V3N8P0EFmBuyiG6P/MX9RQKkSK vhVDgRZVb2w2aRS8DVGA3Y8VId3wHzA8XYkNXRL1900HyvZuANi+BDcX/J3WDA2pkGRz 75EQldPvmKpZtWzEePqG4q5rzhsdXuzmJMwaXBvsAuwF/meCVKURFpPZlPnRxkseIIPo tDrAElkKbrWCv/B6/DLo2zDsKKbA1PeTTfw6OnUCADbICk3pVB1yWVy1Yqq2mR8GzyxF FpQvWo8cnoG2svHxouey/cyZNOEE4cTDkA+51bt/G5ZOekwJzOj//ncN1Kgoy3SV74Cf VZTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807777; x=1773412577; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sqWYQ9lCo+j6BKFc/ZubG4EbmDj1j9ozKwcXgqRTpuk=; b=Xo5fYgn4/EOT6fzJHWQe2b6JsshBS993JrX8xQ9Y9F6xltAqcEuagV+urDokf5SOij 3z+KbV1bEfh51wUXzmIbVXBPngO2xl/cmjlbOEGRrr3uDG0areIF8lk3ScFyliulW0ev v3LAqYwnrkyi3tv03b8Qxjjk6my1rHVVBVCFhXWVoTmri7yb78Y/Acbnmy/vmUcEvWL9 cTwYhkl+Ug5MXCsRIxC69D6FLkD5BNXo4plpuEDEv8hg2X4zq1oWX6esT9t2Rk3NyN29 SEkB1c+jf2KeD6OtUi0VX5r+MSjvttDlqhamIIej/XYHYPUEotmJpPXnUow9aC6Yakl4 6qhQ== X-Forwarded-Encrypted: i=1; AJvYcCWRM9cfdVQnz40l53NJvb9zcLc++vY4CcM46WTlTXUVemjA83COg5VQMlDc44V2LgJLsH3SFa6wC4XdQ4o=@vger.kernel.org X-Gm-Message-State: AOJu0YwX81wDLux/x3t12ERhhqTzPRddWeDqeHX9J9voYrK4lNLA76F6 Sgnw+mcMTtKyMp8gUz5wwutd/2R7bIERTI4852LyI6Hk/P3P0428bWdhDIRFC3BL8PkU1u+yi1A pKd1b8X3RRWYEjDe4lROmBQ== X-Received: from edql15.prod.google.com ([2002:aa7:c30f:0:b0:661:5a0b:59a2]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:a0a:b0:b88:8782:fead with SMTP id a640c23a62f3a-b942df83417mr150616466b.47.1772807776714; Fri, 06 Mar 2026 06:36:16 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:28 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-25-vdonnefort@google.com> Subject: [PATCH v13 24/32] KVM: arm64: Add trace remote for the nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In both protected and nVHE mode, the hypervisor is capable of writing events into tracefs compatible ring-buffers. Create a trace remote so the kernel can read those buffers. This currently doesn't provide any event support which will come later. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index d215348370fa..17edfe3ae615 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -75,6 +75,7 @@ if NVHE_EL2_DEBUG config NVHE_EL2_TRACING bool depends on TRACING + select TRACE_REMOTE default y =20 config PKVM_DISABLE_STAGE2_ON_PANIC diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 3ebc0570345c..59612d2f277c 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -30,6 +30,8 @@ kvm-$(CONFIG_HW_PERF_EVENTS) +=3D pmu-emul.o pmu.o kvm-$(CONFIG_ARM64_PTR_AUTH) +=3D pauth.o kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) +=3D ptdump.o =20 +kvm-$(CONFIG_NVHE_EL2_TRACING) +=3D hyp_trace.o + always-y :=3D hyp_constants.h hyp-constants.s =20 define rule_gen_hyp_constants diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 1371f9b3ecea..87a3d28d5f0f 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -24,6 +24,7 @@ =20 #define CREATE_TRACE_POINTS #include "trace_arm.h" +#include "hyp_trace.h" =20 #include #include @@ -2415,6 +2416,10 @@ static int __init init_subsystems(void) =20 kvm_register_perf_callbacks(); =20 + err =3D kvm_hyp_trace_init(); + if (err) + kvm_err("Failed to initialize Hyp tracing\n"); + out: if (err) hyp_cpu_pm_exit(); diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c new file mode 100644 index 000000000000..2866effe28ec --- /dev/null +++ b/arch/arm64/kvm/hyp_trace.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include +#include +#include + +#include "hyp_trace.h" + +/* Access to this struct within the trace_remote_callbacks are protected b= y the trace_remote lock */ +static struct hyp_trace_buffer { + struct hyp_trace_desc *desc; + size_t desc_size; +} trace_buffer; + +static int __map_hyp(void *start, size_t size) +{ + if (is_protected_kvm_enabled()) + return 0; + + return create_hyp_mappings(start, start + size, PAGE_HYP); +} + +static int __share_page(unsigned long va) +{ + return kvm_share_hyp((void *)va, (void *)va + 1); +} + +static void __unshare_page(unsigned long va) +{ + kvm_unshare_hyp((void *)va, (void *)va + 1); +} + +static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *= trace_buffer, size_t size) +{ + int nr_bpages =3D (PAGE_ALIGN(size) / PAGE_SIZE) + 1; + size_t backing_size; + void *start; + + backing_size =3D PAGE_ALIGN(sizeof(struct simple_buffer_page) * nr_bpages= * + num_possible_cpus()); + + start =3D alloc_pages_exact(backing_size, GFP_KERNEL_ACCOUNT); + if (!start) + return -ENOMEM; + + trace_buffer->desc->bpages_backing_start =3D (unsigned long)start; + trace_buffer->desc->bpages_backing_size =3D backing_size; + + return __map_hyp(start, backing_size); +} + +static void hyp_trace_buffer_free_bpages_backing(struct hyp_trace_buffer *= trace_buffer) +{ + free_pages_exact((void *)trace_buffer->desc->bpages_backing_start, + trace_buffer->desc->bpages_backing_size); +} + +static void hyp_trace_buffer_unshare_hyp(struct hyp_trace_buffer *trace_bu= ffer, int last_cpu) +{ + struct ring_buffer_desc *rb_desc; + int cpu, p; + + for_each_ring_buffer_desc(rb_desc, cpu, &trace_buffer->desc->trace_buffer= _desc) { + if (cpu > last_cpu) + break; + + __share_page(rb_desc->meta_va); + for (p =3D 0; p < rb_desc->nr_page_va; p++) + __unshare_page(rb_desc->page_va[p]); + } +} + +static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffe= r) +{ + struct ring_buffer_desc *rb_desc; + int cpu, p, ret =3D 0; + + for_each_ring_buffer_desc(rb_desc, cpu, &trace_buffer->desc->trace_buffer= _desc) { + ret =3D __share_page(rb_desc->meta_va); + if (ret) + break; + + for (p =3D 0; p < rb_desc->nr_page_va; p++) { + ret =3D __share_page(rb_desc->page_va[p]); + if (ret) + break; + } + + if (ret) { + for (p--; p >=3D 0; p--) + __unshare_page(rb_desc->page_va[p]); + break; + } + } + + if (ret) + hyp_trace_buffer_unshare_hyp(trace_buffer, cpu--); + + return ret; +} + +static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *= priv) +{ + struct hyp_trace_buffer *trace_buffer =3D priv; + struct hyp_trace_desc *desc; + size_t desc_size; + int ret; + + if (WARN_ON(trace_buffer->desc)) + return ERR_PTR(-EINVAL); + + desc_size =3D trace_buffer_desc_size(size, num_possible_cpus()); + if (desc_size =3D=3D SIZE_MAX) + return ERR_PTR(-E2BIG); + + desc_size =3D PAGE_ALIGN(desc_size); + desc =3D (struct hyp_trace_desc *)alloc_pages_exact(desc_size, GFP_KERNEL= ); + if (!desc) + return ERR_PTR(-ENOMEM); + + ret =3D __map_hyp(desc, desc_size); + if (ret) + goto err_free_desc; + + trace_buffer->desc =3D desc; + + ret =3D hyp_trace_buffer_alloc_bpages_backing(trace_buffer, size); + if (ret) + goto err_free_desc; + + ret =3D trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, si= ze, + cpu_possible_mask); + if (ret) + goto err_free_backing; + + ret =3D hyp_trace_buffer_share_hyp(trace_buffer); + if (ret) + goto err_free_buffer; + + ret =3D kvm_call_hyp_nvhe(__tracing_load, (unsigned long)desc, desc_size); + if (ret) + goto err_unload_pages; + + return &desc->trace_buffer_desc; + +err_unload_pages: + hyp_trace_buffer_unshare_hyp(trace_buffer, INT_MAX); + +err_free_buffer: + trace_remote_free_buffer(&desc->trace_buffer_desc); + +err_free_backing: + hyp_trace_buffer_free_bpages_backing(trace_buffer); + +err_free_desc: + free_pages_exact(desc, desc_size); + trace_buffer->desc =3D NULL; + + return ERR_PTR(ret); +} + +static void hyp_trace_unload(struct trace_buffer_desc *desc, void *priv) +{ + struct hyp_trace_buffer *trace_buffer =3D priv; + + if (WARN_ON(desc !=3D &trace_buffer->desc->trace_buffer_desc)) + return; + + kvm_call_hyp_nvhe(__tracing_unload); + hyp_trace_buffer_unshare_hyp(trace_buffer, INT_MAX); + trace_remote_free_buffer(desc); + hyp_trace_buffer_free_bpages_backing(trace_buffer); + free_pages_exact(trace_buffer->desc, trace_buffer->desc_size); + trace_buffer->desc =3D NULL; +} + +static int hyp_trace_enable_tracing(bool enable, void *priv) +{ + return kvm_call_hyp_nvhe(__tracing_enable, enable); +} + +static int hyp_trace_swap_reader_page(unsigned int cpu, void *priv) +{ + return kvm_call_hyp_nvhe(__tracing_swap_reader, cpu); +} + +static int hyp_trace_reset(unsigned int cpu, void *priv) +{ + return 0; +} + +static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) +{ + return 0; +} + +static struct trace_remote_callbacks trace_remote_callbacks =3D { + .load_trace_buffer =3D hyp_trace_load, + .unload_trace_buffer =3D hyp_trace_unload, + .enable_tracing =3D hyp_trace_enable_tracing, + .swap_reader_page =3D hyp_trace_swap_reader_page, + .reset =3D hyp_trace_reset, + .enable_event =3D hyp_trace_enable_event, +}; + +int __init kvm_hyp_trace_init(void) +{ + if (is_kernel_in_hyp_mode()) + return 0; + + return trace_remote_register("hypervisor", &trace_remote_callbacks, &trac= e_buffer, NULL, 0); +} diff --git a/arch/arm64/kvm/hyp_trace.h b/arch/arm64/kvm/hyp_trace.h new file mode 100644 index 000000000000..c991b1ec65f1 --- /dev/null +++ b/arch/arm64/kvm/hyp_trace.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ARM64_KVM_HYP_TRACE_H__ +#define __ARM64_KVM_HYP_TRACE_H__ + +#ifdef CONFIG_NVHE_EL2_TRACING +int kvm_hyp_trace_init(void); +#else +static inline int kvm_hyp_trace_init(void) { return 0; } +#endif +#endif --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B89AC3C3C12 for ; Fri, 6 Mar 2026 14:36:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807782; cv=none; b=Q5Y/llldKbkQi+h/4agN7HQmi1VEy74oKB9ktruc3C4lH/zNFNmjx/Dyag1uzQi2AbeqgwI3eFUUJ2btS2uJ8zxwQXEL9cSagh+ztIvtl7iFbgivdV8S+NlGyONK8NKIZnYdTrdAiz1HnHfY67P6hN1VkkW/bADiBMvcOV3gpLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807782; c=relaxed/simple; bh=DpkfWRRk71K7vzUe98Gp4Dw7z1pn7bWrCQfSFvPremc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=q1slhC3pMxHsbUdDhgRDS6VBj2QYycd0XF2O0kV2OzqQp/hLN+OatkO5dq+6mWFs7zTiEkOP5Mwsb8F8+PixaJhUyNCHSz3KgJwc4ZiXIM2jmBUaqtXt6npxMxjEr2NUhKnEvdcqNFgTc5RIL1P3gkPu87c6veIxXmmT1mnh0hY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=r1lI2z0y; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="r1lI2z0y" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-b9417a552d0so179172266b.2 for ; Fri, 06 Mar 2026 06:36:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807778; x=1773412578; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=jnViG4MIOECLt0XEFRLWPIgIOWagU+RnCqtJREr62U4=; b=r1lI2z0y/qworbNL/78kEhoknIGVWelVCx7czaXXCKZVyq/ZI4xN9+zexZLYI+hjoc ka7F1Il7kT0gCmfWAdlqB4uyWOSo9B0l8gO6fEsWGqUq4r8jqL5DmVpMU0ux5tep8lH7 pAqm0eDjW743jaL3Hu9D6wC5IThV0+8nVH9ZjY4O0OLfyoXDaFEOXbIw9IylmO12g0// mANAopY1gia0/mXRGDRcPStOyYK2ivVJGBaDFCZi8CE3Pzdej3tvfkppBjUjxfSNlzVe xU44FuAhwerGY2E8+waJLGS+c/ritX5Q2dtWpbDIJKMlD7XSDIQgzQYB4d5VZiLEo6aO EdMA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807778; x=1773412578; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jnViG4MIOECLt0XEFRLWPIgIOWagU+RnCqtJREr62U4=; b=xAXOLQ1OoiwhUwlqdK8nVXor1/LtMc3y+Am75RuqZRYChanVbW44G0RhZuEWdIWWT3 FbJmDLubNKOSx6Bk9fhM6sFYhnSH0QtG7TqnE5j4FFAkXE7oif5ADO9Eg9ZU2NO/2S32 Kc78XZG9MAExhwlKbG2IYqjCr4Nw2CEtVO13v1YbfMxfcvvx/c1HNiW6czrZbPAgp8g8 Z4qk0+8p4ajteJNrGvfHlB4TJvEfUTD/aqYIJgM+nwxzKqptm56+Y7mSrNX2tWztQU3B EQfGyvHlskHO5XcvkCBSK32l51puaJ9SSiECK0ZGYvSSvkvHITJVyR/B4GDrRXK9C6eC +ItA== X-Forwarded-Encrypted: i=1; AJvYcCWej+/P3HiaPO5AXbn2SiuQMzgWpA9k5OorwLlZlfW1spoEbsmNleyi8k+qBQLb4U75O/e2dXWUXIsgYWw=@vger.kernel.org X-Gm-Message-State: AOJu0YyTnVi0e55ciSOZ7EUl2hLbmeDAGGjPvQPKZhnZYtn27VCXYfqg t5DZC7NzpUT8x4WWbJT8mdvWiPmu37PkD1I5SHSSq2hnn+QpS5urtxGjESCUky1IDqOFm57lXDp NX0ZO2NaFolYd11pHIqDAsQ== X-Received: from ejbgv21.prod.google.com ([2002:a17:906:f115:b0:b8e:a75a:77ad]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:906:9f84:b0:b8f:a5c8:f83 with SMTP id a640c23a62f3a-b942dbaa164mr131460266b.23.1772807777856; Fri, 06 Mar 2026 06:36:17 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:29 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-26-vdonnefort@google.com> Subject: [PATCH v13 25/32] KVM: arm64: Sync boot clock with the nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Thomas Gleixner , Stephen Boyd , "Christopher S. Hall" , Richard Cochran Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Configure the hypervisor tracing clock with the kernel boot clock. For tracing purposes, the boot clock is interesting: it doesn't stop on suspend. However, it is corrected on a regular basis, which implies the need to re-evaluate it every once in a while. Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: Christopher S. Hall Cc: Richard Cochran Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index d46d9196d661..9c4fe3bfbfff 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -93,6 +93,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___tracing_unload, __KVM_HOST_SMCCC_FUNC___tracing_enable, __KVM_HOST_SMCCC_FUNC___tracing_swap_reader, + __KVM_HOST_SMCCC_FUNC___tracing_update_clock, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 7da8788ce527..fd641e1b1c23 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -11,6 +11,7 @@ int __tracing_load(unsigned long desc_va, size_t desc_siz= e); void __tracing_unload(void); int __tracing_enable(bool enable); int __tracing_swap_reader(unsigned int cpu); +void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_c= yc); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } @@ -19,5 +20,6 @@ static inline int __tracing_load(unsigned long desc_va, s= ize_t desc_size) { retu static inline void __tracing_unload(void) { } static inline int __tracing_enable(bool enable) { return -ENODEV; } static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } +static inline void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_n= s, u64 epoch_cyc) { } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index ae04204ea81f..02d5271199d5 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -615,6 +615,16 @@ static void handle___tracing_swap_reader(struct kvm_cp= u_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __tracing_swap_reader(cpu); } =20 +static void handle___tracing_update_clock(struct kvm_cpu_context *host_ctx= t) +{ + DECLARE_REG(u32, mult, host_ctxt, 1); + DECLARE_REG(u32, shift, host_ctxt, 2); + DECLARE_REG(u64, epoch_ns, host_ctxt, 3); + DECLARE_REG(u64, epoch_cyc, host_ctxt, 4); + + __tracing_update_clock(mult, shift, epoch_ns, epoch_cyc); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -660,6 +670,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__tracing_unload), HANDLE_FUNC(__tracing_enable), HANDLE_FUNC(__tracing_swap_reader), + HANDLE_FUNC(__tracing_update_clock), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index 282cba70ce9b..2c8e6f49d7de 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -271,3 +271,19 @@ int __tracing_swap_reader(unsigned int cpu) =20 return ret; } + +void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_c= yc) +{ + int cpu; + + /* After this loop, all CPUs are observing the new bank... */ + for (cpu =3D 0; cpu < hyp_nr_cpus; cpu++) { + struct simple_rb_per_cpu *simple_rb =3D per_cpu_ptr(trace_buffer.simple_= rbs, cpu); + + while (READ_ONCE(simple_rb->status) =3D=3D SIMPLE_RB_WRITING) + ; + } + + /* ...we can now override the old one and swap. */ + trace_clock_update(mult, shift, epoch_ns, epoch_cyc); +} diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 2866effe28ec..1e5fc27f0e9d 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -4,15 +4,133 @@ * Author: Vincent Donnefort */ =20 +#include #include +#include #include =20 +#include #include #include #include =20 #include "hyp_trace.h" =20 +/* Same 10min used by clocksource when width is more than 32-bits */ +#define CLOCK_MAX_CONVERSION_S 600 +/* + * Time to give for the clock init. Long enough to get a good mult/shift + * estimation. Short enough to not delay the tracing start too much. + */ +#define CLOCK_INIT_MS 100 +/* + * Time between clock checks. Must be small enough to catch clock deviatio= n when + * it is still tiny. + */ +#define CLOCK_UPDATE_MS 500 + +static struct hyp_trace_clock { + u64 cycles; + u64 cyc_overflow64; + u64 boot; + u32 mult; + u32 shift; + struct delayed_work work; + struct completion ready; + struct mutex lock; + bool running; +} hyp_clock; + +static void __hyp_clock_work(struct work_struct *work) +{ + struct delayed_work *dwork =3D to_delayed_work(work); + struct hyp_trace_clock *hyp_clock; + struct system_time_snapshot snap; + u64 rate, delta_cycles; + u64 boot, delta_boot; + + hyp_clock =3D container_of(dwork, struct hyp_trace_clock, work); + + ktime_get_snapshot(&snap); + boot =3D ktime_to_ns(snap.boot); + + delta_boot =3D boot - hyp_clock->boot; + delta_cycles =3D snap.cycles - hyp_clock->cycles; + + /* Compare hyp clock with the kernel boot clock */ + if (hyp_clock->mult) { + u64 err, cur =3D delta_cycles; + + if (WARN_ON_ONCE(cur >=3D hyp_clock->cyc_overflow64)) { + __uint128_t tmp =3D (__uint128_t)cur * hyp_clock->mult; + + cur =3D tmp >> hyp_clock->shift; + } else { + cur *=3D hyp_clock->mult; + cur >>=3D hyp_clock->shift; + } + cur +=3D hyp_clock->boot; + + err =3D abs_diff(cur, boot); + /* No deviation, only update epoch if necessary */ + if (!err) { + if (delta_cycles >=3D (hyp_clock->cyc_overflow64 >> 1)) + goto fast_forward; + + goto resched; + } + + /* Warn if the error is above tracing precision (1us) */ + if (err > NSEC_PER_USEC) + pr_warn_ratelimited("hyp trace clock off by %lluus\n", + err / NSEC_PER_USEC); + } + + rate =3D div64_u64(delta_cycles * NSEC_PER_SEC, delta_boot); + + clocks_calc_mult_shift(&hyp_clock->mult, &hyp_clock->shift, + rate, NSEC_PER_SEC, CLOCK_MAX_CONVERSION_S); + + /* Add a comfortable 50% margin */ + hyp_clock->cyc_overflow64 =3D (U64_MAX / hyp_clock->mult) >> 1; + +fast_forward: + hyp_clock->cycles =3D snap.cycles; + hyp_clock->boot =3D boot; + kvm_call_hyp_nvhe(__tracing_update_clock, hyp_clock->mult, + hyp_clock->shift, hyp_clock->boot, hyp_clock->cycles); + complete(&hyp_clock->ready); + +resched: + schedule_delayed_work(&hyp_clock->work, + msecs_to_jiffies(CLOCK_UPDATE_MS)); +} + +static void hyp_trace_clock_enable(struct hyp_trace_clock *hyp_clock, bool= enable) +{ + struct system_time_snapshot snap; + + if (hyp_clock->running =3D=3D enable) + return; + + if (!enable) { + cancel_delayed_work_sync(&hyp_clock->work); + hyp_clock->running =3D false; + } + + ktime_get_snapshot(&snap); + + hyp_clock->boot =3D ktime_to_ns(snap.boot); + hyp_clock->cycles =3D snap.cycles; + hyp_clock->mult =3D 0; + + init_completion(&hyp_clock->ready); + INIT_DELAYED_WORK(&hyp_clock->work, __hyp_clock_work); + schedule_delayed_work(&hyp_clock->work, msecs_to_jiffies(CLOCK_INIT_MS)); + wait_for_completion(&hyp_clock->ready); + hyp_clock->running =3D true; +} + /* Access to this struct within the trace_remote_callbacks are protected b= y the trace_remote lock */ static struct hyp_trace_buffer { struct hyp_trace_desc *desc; @@ -183,6 +301,8 @@ static void hyp_trace_unload(struct trace_buffer_desc *= desc, void *priv) =20 static int hyp_trace_enable_tracing(bool enable, void *priv) { + hyp_trace_clock_enable(&hyp_clock, enable); + return kvm_call_hyp_nvhe(__tracing_enable, enable); } =20 @@ -201,7 +321,22 @@ static int hyp_trace_enable_event(unsigned short id, b= ool enable, void *priv) return 0; } =20 +static int hyp_trace_clock_show(struct seq_file *m, void *v) +{ + seq_puts(m, "[boot]\n"); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(hyp_trace_clock); + +static int hyp_trace_init_tracefs(struct dentry *d, void *priv) +{ + return tracefs_create_file("trace_clock", 0440, d, NULL, &hyp_trace_clock= _fops) ? + 0 : -ENOMEM; +} + static struct trace_remote_callbacks trace_remote_callbacks =3D { + .init =3D hyp_trace_init_tracefs, .load_trace_buffer =3D hyp_trace_load, .unload_trace_buffer =3D hyp_trace_unload, .enable_tracing =3D hyp_trace_enable_tracing, @@ -212,8 +347,22 @@ static struct trace_remote_callbacks trace_remote_call= backs =3D { =20 int __init kvm_hyp_trace_init(void) { + int cpu; + if (is_kernel_in_hyp_mode()) return 0; =20 +#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND + for_each_possible_cpu(cpu) { + const struct arch_timer_erratum_workaround *wa =3D + per_cpu(timer_unstable_counter_workaround, cpu); + + if (wa && wa->read_cntvct_el0) { + pr_warn("hyp trace can't handle CNTVCT workaround '%s'\n", wa->desc); + return -EOPNOTSUPP; + } + } +#endif + return trace_remote_register("hypervisor", &trace_remote_callbacks, &trac= e_buffer, NULL, 0); } --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 879F93A0E95 for ; Fri, 6 Mar 2026 14:36:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807782; cv=none; b=gVwxx/jH++rQatDWXYuBmbwTUUJc/n/T9pcTV4hNiBJxED0DqbxjLEoA6DnQ1gip1dndlzKG4Sd346C7qCSJVQO+B+XreMOvd+9z0jW8VEAN6Xn23lCZl2+5WCYLUT3rh+42WCayuiKy4RPp5Tf2E7MstCGcijsAmaVYq8ddOrc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807782; c=relaxed/simple; bh=uwYQWXJq4cr4nt+LXGOlVB79zrFFf6vy3e6v8doz2/E=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kBfIegHicQ0JkOQweWGhITUEFmN8ErsdwD/MGL3hJjcSuxA5QrJT+2cdRR+bfJ7F6+CX1hrfHWyDF38QcFegvJmPKd1yrfF8kxuWXxJXRdUZGJUUr2XB1ca1whUKupK3Hqgn4MkxoMIPGoh/KUyOKXOKRokQUaLX3I+VE3L5Y64= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3jCnQMhh; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3jCnQMhh" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-483bcfdaf7dso92743405e9.0 for ; Fri, 06 Mar 2026 06:36:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807779; x=1773412579; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=wZNlRO5e/MGzFMVxx7Ks/cRDmNOcF7u1/X5pARmyFgQ=; b=3jCnQMhhpIP8xtEV4vqGqNpyRPA7uHq9lz1XHFzYCu8MUs7pbsJSdT3x1i9dnPGxXw G7dvwx1rFc90p6+14dK/7zs/rwo2xQG6xKnKKKenadlaWoL+ouDgFuFUjVkwpLmMLTH4 +JQbkol/lIu9vBQGvsbS1iqTNuMLNnjdwkNLQpgLFOQFeb0sC+oS17MyWhnTBuGxpv5j ZtDPeIW2md9S0ufXMmhEuOYm++AKDAfQAG8TEf40H2uJh3Wz21qmG0zyg2ON30leE5hq rkdOOqx6yGkAUgEJr5BaMgZGHqrYI6v+De5I8uggfxE4xvHg87pshW3zijgJQLrOc3Zr gokA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807779; x=1773412579; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wZNlRO5e/MGzFMVxx7Ks/cRDmNOcF7u1/X5pARmyFgQ=; b=iEfGwEzzTyffcdcS25AiSR/SC74woGl4XIsvAh6r6hw/LQTG7/kNLygam3SYST1xr+ imLhBw5hsS5grTqcMbmpYuj+NZeNSBCuoqWCl5PTla66ZxF/6e/6RFRMum3Nal2ONphn g7m4v23NY2nCGRWKltyLXkqZxiUOrfvmkxH/eB1Ufc7YRyKPli1NLBEpAWpsb9pQKq1P 21MIbnoZ9vOhmKAoWRzyD5kTR/jxssrxnFj5c1RUmLvuRq35VUxY5UhJ+vrsGC7N6WCe tyzUr86usyoOh7uzOnQxkvtgUeKmm8OMkMWTZgN/+5xYVuUiSp/zD9c/+fzrHctf57W0 y0vw== X-Forwarded-Encrypted: i=1; AJvYcCVlcfh4eNGFL9LYQQyeFSDptYE6BuK4PXAZb6vvWErsaqWXcDbZ27kUdFvgwN2yc1LVVufbc3SfL5vdJGQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yy3YFuYQe+fuJexCVUyR68fvkShs5uFee2SG8QOfMnQ9EpcFnX1 3NDgGb2plEDIc0jM83wKS2dxAQnAoZvjE5EqIj47hxiN493b9SbyvIMCeDP+IPcCDxJwl1ZnUNe Mf6Dlda28OLkCgNl+ZzmzXg== X-Received: from wmbdv11.prod.google.com ([2002:a05:600c:620b:b0:483:7c8d:ed1d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:5253:b0:483:456a:514b with SMTP id 5b1f17b1804b1-4852692f158mr38056235e9.12.1772807778854; Fri, 06 Mar 2026 06:36:18 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:30 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-27-vdonnefort@google.com> Subject: [PATCH v13 26/32] KVM: arm64: Add trace reset to the nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make the hypervisor reset either the whole tracing buffer or a specific ring-buffer, on remotes/hypervisor/trace or per_cpu//trace write access. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index 9c4fe3bfbfff..66abf77cf371 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -94,6 +94,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___tracing_enable, __KVM_HOST_SMCCC_FUNC___tracing_swap_reader, __KVM_HOST_SMCCC_FUNC___tracing_update_clock, + __KVM_HOST_SMCCC_FUNC___tracing_reset, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index fd641e1b1c23..44912869d184 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -12,6 +12,7 @@ void __tracing_unload(void); int __tracing_enable(bool enable); int __tracing_swap_reader(unsigned int cpu); void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_c= yc); +int __tracing_reset(unsigned int cpu); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } @@ -21,5 +22,6 @@ static inline void __tracing_unload(void) { } static inline int __tracing_enable(bool enable) { return -ENODEV; } static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } static inline void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_n= s, u64 epoch_cyc) { } +static inline int __tracing_reset(unsigned int cpu) { return -ENODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 02d5271199d5..9b05f0c87586 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -625,6 +625,13 @@ static void handle___tracing_update_clock(struct kvm_c= pu_context *host_ctxt) __tracing_update_clock(mult, shift, epoch_ns, epoch_cyc); } =20 +static void handle___tracing_reset(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __tracing_reset(cpu); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -671,6 +678,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__tracing_enable), HANDLE_FUNC(__tracing_swap_reader), HANDLE_FUNC(__tracing_update_clock), + HANDLE_FUNC(__tracing_reset), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index 2c8e6f49d7de..a6ca27b18e15 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -287,3 +287,20 @@ void __tracing_update_clock(u32 mult, u32 shift, u64 e= poch_ns, u64 epoch_cyc) /* ...we can now override the old one and swap. */ trace_clock_update(mult, shift, epoch_ns, epoch_cyc); } + +int __tracing_reset(unsigned int cpu) +{ + int ret =3D -ENODEV; + + if (cpu >=3D hyp_nr_cpus) + return -EINVAL; + + hyp_spin_lock(&trace_buffer.lock); + + if (hyp_trace_buffer_loaded(&trace_buffer)) + ret =3D simple_ring_buffer_reset(per_cpu_ptr(trace_buffer.simple_rbs, cp= u)); + + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 1e5fc27f0e9d..09bc192e3514 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -313,7 +313,7 @@ static int hyp_trace_swap_reader_page(unsigned int cpu,= void *priv) =20 static int hyp_trace_reset(unsigned int cpu, void *priv) { - return 0; + return kvm_call_hyp_nvhe(__tracing_reset, cpu); } =20 static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8E2573C3BF7 for ; Fri, 6 Mar 2026 14:36:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807783; cv=none; b=Xr3JHnYxUvyJadLzfgr5Svw2WSQfFFgw7daf1r/531zKTx8TqjEyOaRdKDtEuLrX+YzU+TdtfzNblsbfR2Nq3XjXSbBW/QvsEdI1Bdc99KK2ORgyVYBCiH8GEILgk3kvJizVMklm1hW6uiYPZMPCkYwYpPqrpDmaDjUGv8GLtYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807783; c=relaxed/simple; bh=F9Pe6qPCq7vTOI4V9zPmzGQJ4f+5zUfVHZ1gSyixh0c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EaU2rOq6Yz1Xxlx4Gr4MOv9EEr+mjv0xJBYM/0xg4nE6+e1cRE1Yu3Smvm9xdRqx9kkpUt7VLQzqLFwbGxXY4v1DoD+TPSEgSrYSHHmoZzUzoJPmgBKdp1J8CacmTP/JVyXVPVthKKF4bgluhEGZhjCD+ArM9Rln5wgXF1ePcF8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=KuQ+/dcm; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="KuQ+/dcm" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-66193c8dc3fso841500a12.3 for ; Fri, 06 Mar 2026 06:36:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807780; x=1773412580; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HmthvXhAnztwt2ntQFZwuwObN4kgt7oRrG62c+79Mnc=; b=KuQ+/dcmUmDGUCWrCtzp20ZZ04UAgZPxNyzY9vr0iHzCt/QVqt0C+zuHt07oQ6OFv+ vC2uugt6hDxaKLsyXfj+gZ3OmIwEdQq915O4OuuhBSVHQyum1iBkTTCBKDz8qOWelCkn 6PvHVFSXGFby2hNKWGyXmsQFwtMrEtL89TzWjWZ/psErRlnutUjShgf6Ikzh7p+iw9TP MxHi4OLRlzdhJVC0WYgHRtW60Es/09DIprQz+CBdn9oeg2ZPc3y4YSk/MH0LXxVVZ8/i QTcZgqeSkPQn9jgnGM2cPbiECE94Q31ovIXPCve7BCMwu5Vo9Q1Q3MUwZCFMPIfkR26m kNHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807780; x=1773412580; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HmthvXhAnztwt2ntQFZwuwObN4kgt7oRrG62c+79Mnc=; b=bn3WKW1XrsfduVLmZ64phK3/x3VQ1e0p70g76zcTkPPel3HTQmZNEMKTBlEskTWSqo BKqohurvtv5IgdpVRaWolYAuS3b/peGkOYqEuzTL24VoWzKkzjjo4D8oObMB6tW7sbyN fbUccomWoM6w40qE8RbJIhOCW12P7wsZeyonZWS6H3iB8Gzp6vEEXssi0HAKlH716zo1 KQ3Rr60WU1PCQBx+UGmWwVog12mG4aWaY5sqPaPb9iVO6+2RD2qx6prQwBlv1GkrU+lV C4DgafkYZPb1ez/JZLn6ALDm9ztVaG00gidsw+uafkAyDP4lfy7C5TcJg7vNfZkbNzuk zhsA== X-Forwarded-Encrypted: i=1; AJvYcCV9B0U+wK1HTXnD5HpFr6QFu71d8NgWeusODnurT4wcgfvK7J/+MmZZ/g4aG7GyNMrcMHvbf8jKuis13i0=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4I8o/RQygVbDWC6Gb4yJU1TbEpNb/Oio02LCy3tT9bvjZamue Il8gXuSCasVYgH1Nb0Wa1W/49cVKN+VCL3PY1Z9q9xM8BH72WHwgloXbTgkmNohNNbbb1iYib2j EkUtUJiRDTO9aeOqGmlALIw== X-Received: from edqs18.prod.google.com ([2002:aa7:d792:0:b0:660:a51a:d07d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:146f:b0:661:6ca5:aba2 with SMTP id 4fb4d7f45d1cf-6619d51a09amr1358425a12.28.1772807779878; Fri, 06 Mar 2026 06:36:19 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:31 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-28-vdonnefort@google.com> Subject: [PATCH v13 27/32] KVM: arm64: Add event support to the nVHE/pKVM hyp and trace remote From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the creation of hypervisor and trace remote events with a single macro HYP_EVENT(). That macro expands in the kernel side to add all the required declarations (based on REMOTE_EVENT()) as well as in the hypervisor side to create the trace_() function. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index 66abf77cf371..47d250436f8c 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -95,6 +95,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___tracing_swap_reader, __KVM_HOST_SMCCC_FUNC___tracing_update_clock, __KVM_HOST_SMCCC_FUNC___tracing_reset, + __KVM_HOST_SMCCC_FUNC___tracing_enable_event, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_define_hypevents.h b/arch/arm64/inc= lude/asm/kvm_define_hypevents.h new file mode 100644 index 000000000000..77d6790252a6 --- /dev/null +++ b/arch/arm64/include/asm/kvm_define_hypevents.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#define REMOTE_EVENT_INCLUDE_FILE arch/arm64/include/asm/kvm_hypevents.h + +#define REMOTE_EVENT_SECTION "_hyp_events" + +#define HE_STRUCT(__args) __args +#define HE_PRINTK(__args...) __args +#define he_field re_field + +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + REMOTE_EVENT(__name, 0, RE_STRUCT(__struct), RE_PRINTK(__printk)) + +#define HYP_EVENT_MULTI_READ +#include +#undef HYP_EVENT_MULTI_READ diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h new file mode 100644 index 000000000000..d6e033c96c52 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if !defined(__ARM64_KVM_HYPEVENTS_H_) || defined(HYP_EVENT_MULTI_READ) +#define __ARM64_KVM_HYPEVENTS_H_ + +#ifdef __KVM_NVHE_HYPERVISOR__ +#include +#endif + +#endif diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm= /kvm_hyptrace.h index 9c30a479bc36..de133b735f72 100644 --- a/arch/arm64/include/asm/kvm_hyptrace.h +++ b/arch/arm64/include/asm/kvm_hyptrace.h @@ -10,4 +10,17 @@ struct hyp_trace_desc { struct trace_buffer_desc trace_buffer_desc; =20 }; + +struct hyp_event_id { + unsigned short id; + atomic_t enabled; +}; + +extern struct remote_event __hyp_events_start[]; +extern struct remote_event __hyp_events_end[]; + +/* hyp_event section used by the hypervisor */ +extern struct hyp_event_id __hyp_event_ids_start[]; +extern struct hyp_event_id __hyp_event_ids_end[]; + #endif diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index d7b0d12b1015..d4c7d45ae6bc 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -138,6 +138,10 @@ KVM_NVHE_ALIAS(__hyp_data_start); KVM_NVHE_ALIAS(__hyp_data_end); KVM_NVHE_ALIAS(__hyp_rodata_start); KVM_NVHE_ALIAS(__hyp_rodata_end); +#ifdef CONFIG_NVHE_EL2_TRACING +KVM_NVHE_ALIAS(__hyp_event_ids_start); +KVM_NVHE_ALIAS(__hyp_event_ids_end); +#endif =20 /* pKVM static key */ KVM_NVHE_ALIAS(kvm_protected_mode_initialized); diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.ld= s.S index ad6133b89e7a..273a461c6076 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -13,12 +13,23 @@ *(__kvm_ex_table) \ __stop___kvm_ex_table =3D .; =20 +#ifdef CONFIG_NVHE_EL2_TRACING +#define HYPERVISOR_EVENT_IDS \ + . =3D ALIGN(PAGE_SIZE); \ + __hyp_event_ids_start =3D .; \ + *(HYP_SECTION_NAME(.event_ids)) \ + __hyp_event_ids_end =3D .; +#else +#define HYPERVISOR_EVENT_IDS +#endif + #define HYPERVISOR_RODATA_SECTIONS \ HYP_SECTION_NAME(.rodata) : { \ . =3D ALIGN(PAGE_SIZE); \ __hyp_rodata_start =3D .; \ *(HYP_SECTION_NAME(.data..ro_after_init)) \ *(HYP_SECTION_NAME(.rodata)) \ + HYPERVISOR_EVENT_IDS \ . =3D ALIGN(PAGE_SIZE); \ __hyp_rodata_end =3D .; \ } @@ -307,6 +318,13 @@ SECTIONS =20 HYPERVISOR_DATA_SECTION =20 +#ifdef CONFIG_NVHE_EL2_TRACING + .data.hyp_events : { + __hyp_events_start =3D .; + *(SORT(_hyp_events.*)) + __hyp_events_end =3D .; + } +#endif /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback diff --git a/arch/arm64/kvm/hyp/include/nvhe/define_events.h b/arch/arm64/k= vm/hyp/include/nvhe/define_events.h new file mode 100644 index 000000000000..776d4c6cb702 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#undef HYP_EVENT +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + struct hyp_event_id hyp_event_id_##__name \ + __section(".hyp.event_ids."#__name) =3D { \ + .enabled =3D ATOMIC_INIT(0), \ + } + +#define HYP_EVENT_MULTI_READ +#include +#undef HYP_EVENT_MULTI_READ + +#undef HYP_EVENT diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 44912869d184..802a18b77c56 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -1,9 +1,36 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __ARM64_KVM_HYP_NVHE_TRACE_H #define __ARM64_KVM_HYP_NVHE_TRACE_H + +#include + #include =20 +#define HE_PROTO(__args...) __args +#define HE_ASSIGN(__args...) __args +#define HE_STRUCT RE_STRUCT +#define he_field re_field + #ifdef CONFIG_NVHE_EL2_TRACING + +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + extern struct hyp_event_id hyp_event_id_##__name; \ + static __always_inline void trace_##__name(__proto) \ + { \ + struct remote_event_format_##__name *__entry; \ + size_t length =3D sizeof(*__entry); \ + \ + if (!atomic_read(&hyp_event_id_##__name.enabled)) \ + return; \ + __entry =3D tracing_reserve_entry(length); \ + if (!__entry) \ + return; \ + __entry->hdr.id =3D hyp_event_id_##__name.id; \ + __assign \ + tracing_commit_entry(); \ + } + void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 @@ -13,9 +40,12 @@ int __tracing_enable(bool enable); int __tracing_swap_reader(unsigned int cpu); void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_c= yc); int __tracing_reset(unsigned int cpu); +int __tracing_enable_event(unsigned short id, bool enable); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + static inline void trace_##__name(__proto) {} =20 static inline int __tracing_load(unsigned long desc_va, size_t desc_size) = { return -ENODEV; } static inline void __tracing_unload(void) { } @@ -23,5 +53,6 @@ static inline int __tracing_enable(bool enable) { return = -ENODEV; } static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } static inline void __tracing_update_clock(u32 mult, u32 shift, u64 epoch_n= s, u64 epoch_cyc) { } static inline int __tracing_reset(unsigned int cpu) { return -ENODEV; } +static inline int __tracing_enable_event(unsigned short id, bool enable) = { return -ENODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index f1840628d2d6..143d55ec7298 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -29,7 +29,7 @@ hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cp= uif-proxy.o ../entry.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-y +=3D ../../../kernel/smccc-call.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_NVHE_EL2_TRACING) +=3D clock.o trace.o +hyp-obj-$(CONFIG_NVHE_EL2_TRACING) +=3D clock.o trace.o events.o hyp-obj-y +=3D $(lib-objs) =20 # Path to simple_ring_buffer.c diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/eve= nts.c new file mode 100644 index 000000000000..add9383aadb5 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/events.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include + +int __tracing_enable_event(unsigned short id, bool enable) +{ + struct hyp_event_id *event_id =3D &__hyp_event_ids_start[id]; + atomic_t *enabled; + + if (event_id >=3D __hyp_event_ids_end) + return -EINVAL; + + enabled =3D hyp_fixmap_map(__hyp_pa(&event_id->enabled)); + atomic_set(enabled, enable); + hyp_fixmap_unmap(); + + return 0; +} diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 9b05f0c87586..fc5953f31b4b 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -632,6 +632,14 @@ static void handle___tracing_reset(struct kvm_cpu_cont= ext *host_ctxt) cpu_reg(host_ctxt, 1) =3D __tracing_reset(cpu); } =20 +static void handle___tracing_enable_event(struct kvm_cpu_context *host_ctx= t) +{ + DECLARE_REG(unsigned short, id, host_ctxt, 1); + DECLARE_REG(bool, enable, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) =3D __tracing_enable_event(id, enable); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -679,6 +687,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__tracing_swap_reader), HANDLE_FUNC(__tracing_update_clock), HANDLE_FUNC(__tracing_reset), + HANDLE_FUNC(__tracing_enable_event), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S b/arch/arm64/kvm/hyp/nvhe/hy= p.lds.S index d724f6d69302..7a02837203d1 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp.lds.S @@ -16,6 +16,12 @@ SECTIONS { HYP_SECTION(.text) HYP_SECTION(.data..ro_after_init) HYP_SECTION(.rodata) +#ifdef CONFIG_NVHE_EL2_TRACING + . =3D ALIGN(PAGE_SIZE); + BEGIN_HYP_SECTION(.event_ids) + *(SORT(.hyp.event_ids.*)) + END_HYP_SECTION +#endif =20 /* * .hyp..data..percpu needs to be page aligned to maintain the same diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 09bc192e3514..0144cd26703e 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -318,6 +318,25 @@ static int hyp_trace_reset(unsigned int cpu, void *pri= v) =20 static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) { + struct hyp_event_id *event_id =3D lm_alias(&__hyp_event_ids_start[id]); + struct page *page; + atomic_t *enabled; + void *map; + + if (is_protected_kvm_enabled()) + return kvm_call_hyp_nvhe(__tracing_enable_event, id, enable); + + enabled =3D &event_id->enabled; + page =3D virt_to_page(enabled); + map =3D vmap(&page, 1, VM_MAP, PAGE_KERNEL); + if (!map) + return -ENOMEM; + + enabled =3D map + offset_in_page(enabled); + atomic_set(enabled, enable); + + vunmap(map); + return 0; } =20 @@ -345,6 +364,19 @@ static struct trace_remote_callbacks trace_remote_call= backs =3D { .enable_event =3D hyp_trace_enable_event, }; =20 +#include + +static void __init hyp_trace_init_events(void) +{ + struct hyp_event_id *hyp_event_id =3D __hyp_event_ids_start; + struct remote_event *event =3D __hyp_events_start; + int id =3D 0; + + /* Events on both sides hypervisor are sorted */ + for (; event < __hyp_events_end; event++, hyp_event_id++, id++) + event->id =3D hyp_event_id->id =3D id; +} + int __init kvm_hyp_trace_init(void) { int cpu; @@ -364,5 +396,8 @@ int __init kvm_hyp_trace_init(void) } #endif =20 - return trace_remote_register("hypervisor", &trace_remote_callbacks, &trac= e_buffer, NULL, 0); + hyp_trace_init_events(); + + return trace_remote_register("hypervisor", &trace_remote_callbacks, &trac= e_buffer, + __hyp_events_start, __hyp_events_end - __hyp_events_start); } --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6601B3CA4B7 for ; Fri, 6 Mar 2026 14:36:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807784; cv=none; b=k/ZnGZVw1g+LdA7CSb/MZXAnJhcqPbCAUqK8OWs0zNbzthbAUVGuFYVR+jYH0+oqzApTWtvX2/Le9hmYbLfGW+Ln953wEps78ImVS2ANkbl3EH3tMasu48XwIb8XfiJRjRYYa1+zBJiIQd5/XbxsKSFUq+ndDy/QGxS4R8KhK/o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807784; c=relaxed/simple; bh=YbA8JaPFtz8gRsLTxw2qoGtAW0nAN+sVhk3TUjQu78g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=R7326afmXDHrn0j7RKfDm9OyVYLeMsLbRMU4ySpgRBps+zAq+JN/j27VtbZnC/xUJDCv2/oweB3MYHeaRjlYUFytIgX1TE/D0ZIQ+AseO2bbWyzaHb/pAH5KPTQzZvJMqtqBMCE9aB75+Fwe2EsiC1Bu+IQxZY+ldvSmHfPhe4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=WbtPwY+s; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="WbtPwY+s" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-483a24db6ecso117551275e9.1 for ; Fri, 06 Mar 2026 06:36:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807781; x=1773412581; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=dmLqPW/eDHkunk54emb2m2JdJcZj8L4sjcALmrPjxRU=; b=WbtPwY+sFYxaxCGl61GLr9I5a+99MmwjBJSbnYeTAZFncFIdoR27CnGb5EcvLhaJU8 DNZkcJRns6pu+hCjpXWnK9IA3hmIzEQwXfReluAyOvjAbh+9+btyU9XjL4csQTGaESQl 3iF6RcgHZ1odez8cqVptFe5lIFuovImGWlwj/akX2+EejEq699eDuCH97eP5LHYmfL6M ojYdU9O2DxtBRSYwRzWjfdY5iTP4uoFD6QA2GQPZzGVET5ZFwCOrE/o+FSM7cKVbyC4X tvKXkmKeO3yx/0gymtStl1T2fVRdno2at1EAix6hE5SO9XvTyc1eUJU9hUpwjF86jZ38 KCRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807781; x=1773412581; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dmLqPW/eDHkunk54emb2m2JdJcZj8L4sjcALmrPjxRU=; b=Kxc/mHwlkJ9NS3exGJn8ej1LoBP3If8VKWAiQ4rLHMIY+AASWobHspCBnLpjdVqdPv dOcflbIFEP75qxFPRkliFCpyDVPdABUG15ZnbAxp/RNmbX1uyEw8KabztgIdwSv8/Oma 3k9A5EQFYSy4Oc81DORqaiq//m9srA6iwEi1edmoXPRWF7ydee+vYr+0s7oJs9h5TAmK EQVpgboG2sJbMUTXSlOElzNKyUeVK3bTkOP9CZt1XFnQpQ9RnoR8h7fYuIbcJf41Z1m/ qUsp4XC13sEHtyTbTOcXpMN+b9cRmqOY25kfJPxqzK7m69+l2ZNJtJihbjazaowQj3bQ Amjg== X-Forwarded-Encrypted: i=1; AJvYcCXPNKiwaVEOpk0Jl2vfEM36lCwJzqtB9utNTeMZvwFr7VazbBSBqNkhJdODwPTop8qycJVxNFUCLAjjwCc=@vger.kernel.org X-Gm-Message-State: AOJu0Yw+LJvDgfTrycA2LnYR0R24tVQLKbFX309imJLtyRxLl0IM8PLs MfsNsmZHoil6jNwJWlKt4i/iSWI62OUo2TcRsrB9ur7uFU4ujPtSCrYIsmwRo1I78s4o6SikJRQ wLLhUiAeoqtZtKiUqRmKBMQ== X-Received: from wmmr3.prod.google.com ([2002:a05:600c:4243:b0:480:6bfa:f515]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:608f:b0:483:8e43:6dce with SMTP id 5b1f17b1804b1-4852696937cmr36224375e9.29.1772807780854; Fri, 06 Mar 2026 06:36:20 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:32 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-29-vdonnefort@google.com> Subject: [PATCH v13 28/32] KVM: arm64: Add hyp_enter/hyp_exit events to nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The hyp_enter and hyp_exit events are logged by the hypervisor any time it is entered and exited. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index 2ca264b3db5f..b50ac3bb4bc9 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -920,6 +920,9 @@ struct kvm_vcpu_arch { =20 /* Per-vcpu TLB for VNCR_EL2 -- NULL when !NV */ struct vncr_tlb *vncr_tlb; + + /* Hyp-readable copy of kvm_vcpu::pid */ + pid_t pid; }; =20 /* diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h index d6e033c96c52..221a1dacb2f0 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -7,4 +7,43 @@ #include #endif =20 +#ifndef __HYP_ENTER_EXIT_REASON +#define __HYP_ENTER_EXIT_REASON +enum hyp_enter_exit_reason { + HYP_REASON_SMC, + HYP_REASON_HVC, + HYP_REASON_PSCI, + HYP_REASON_HOST_ABORT, + HYP_REASON_GUEST_EXIT, + HYP_REASON_ERET_HOST, + HYP_REASON_ERET_GUEST, + HYP_REASON_UNKNOWN /* Must be last */ +}; +#endif + +HYP_EVENT(hyp_enter, + HE_PROTO(struct kvm_cpu_context *host_ctxt, u8 reason), + HE_STRUCT( + he_field(u8, reason) + he_field(pid_t, vcpu) + ), + HE_ASSIGN( + __entry->reason =3D reason; + __entry->vcpu =3D __tracing_get_vcpu_pid(host_ctxt); + ), + HE_PRINTK("reason=3D%s vcpu=3D%d", __hyp_enter_exit_reason_str(__entry->r= eason), __entry->vcpu) +); + +HYP_EVENT(hyp_exit, + HE_PROTO(struct kvm_cpu_context *host_ctxt, u8 reason), + HE_STRUCT( + he_field(u8, reason) + he_field(pid_t, vcpu) + ), + HE_ASSIGN( + __entry->reason =3D reason; + __entry->vcpu =3D __tracing_get_vcpu_pid(host_ctxt); + ), + HE_PRINTK("reason=3D%s vcpu=3D%d", __hyp_enter_exit_reason_str(__entry->r= eason), __entry->vcpu) +); #endif diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 87a3d28d5f0f..04c43c9eb764 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -707,6 +707,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) =20 if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus)) vcpu_set_on_unsupported_cpu(vcpu); + + vcpu->arch.pid =3D pid_nr(vcpu->pid); } =20 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h b/arch/arm64/kvm/h= yp/include/nvhe/arm-smccc.h new file mode 100644 index 000000000000..1258bc84477f --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_HYP_NVHE_ARM_SMCCC_H__ +#define __ARM64_KVM_HYP_NVHE_ARM_SMCCC_H__ + +#include + +#include + +#define hyp_smccc_1_1_smc(...) \ + do { \ + trace_hyp_exit(NULL, HYP_REASON_SMC); \ + arm_smccc_1_1_smc(__VA_ARGS__); \ + trace_hyp_enter(NULL, HYP_REASON_SMC); \ + } while (0) + +#define hyp_smccc_1_2_smc(...) \ + do { \ + trace_hyp_exit(NULL, HYP_REASON_SMC); \ + arm_smccc_1_2_smc(__VA_ARGS__); \ + trace_hyp_enter(NULL, HYP_REASON_SMC); \ + } while (0) + +#endif /* __ARM64_KVM_HYP_NVHE_ARM_SMCCC_H__ */ diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 802a18b77c56..8813ff250f8e 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -6,6 +6,18 @@ =20 #include =20 +static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu_context *host_ct= xt) +{ + struct kvm_vcpu *vcpu; + + if (!host_ctxt) + host_ctxt =3D host_data_ptr(host_ctxt); + + vcpu =3D host_ctxt->__hyp_running_vcpu; + + return vcpu ? vcpu->arch.pid : 0; +} + #define HE_PROTO(__args...) __args #define HE_ASSIGN(__args...) __args #define HE_STRUCT RE_STRUCT diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 94161ea1cd60..1af722771178 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -26,10 +26,10 @@ * the duration and are therefore serialised. */ =20 -#include #include #include =20 +#include #include #include #include @@ -147,7 +147,7 @@ static int ffa_map_hyp_buffers(u64 ffa_page_count) { struct arm_smccc_1_2_regs res; =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_FN64_RXTX_MAP, .a1 =3D hyp_virt_to_phys(hyp_buffers.tx), .a2 =3D hyp_virt_to_phys(hyp_buffers.rx), @@ -161,7 +161,7 @@ static int ffa_unmap_hyp_buffers(void) { struct arm_smccc_1_2_regs res; =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_RXTX_UNMAP, .a1 =3D HOST_FFA_ID, }, &res); @@ -172,7 +172,7 @@ static int ffa_unmap_hyp_buffers(void) static void ffa_mem_frag_tx(struct arm_smccc_1_2_regs *res, u32 handle_lo, u32 handle_hi, u32 fraglen, u32 endpoint_id) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_MEM_FRAG_TX, .a1 =3D handle_lo, .a2 =3D handle_hi, @@ -184,7 +184,7 @@ static void ffa_mem_frag_tx(struct arm_smccc_1_2_regs *= res, u32 handle_lo, static void ffa_mem_frag_rx(struct arm_smccc_1_2_regs *res, u32 handle_lo, u32 handle_hi, u32 fragoff) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_MEM_FRAG_RX, .a1 =3D handle_lo, .a2 =3D handle_hi, @@ -196,7 +196,7 @@ static void ffa_mem_frag_rx(struct arm_smccc_1_2_regs *= res, u32 handle_lo, static void ffa_mem_xfer(struct arm_smccc_1_2_regs *res, u64 func_id, u32 = len, u32 fraglen) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D func_id, .a1 =3D len, .a2 =3D fraglen, @@ -206,7 +206,7 @@ static void ffa_mem_xfer(struct arm_smccc_1_2_regs *res= , u64 func_id, u32 len, static void ffa_mem_reclaim(struct arm_smccc_1_2_regs *res, u32 handle_lo, u32 handle_hi, u32 flags) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_MEM_RECLAIM, .a1 =3D handle_lo, .a2 =3D handle_hi, @@ -216,7 +216,7 @@ static void ffa_mem_reclaim(struct arm_smccc_1_2_regs *= res, u32 handle_lo, =20 static void ffa_retrieve_req(struct arm_smccc_1_2_regs *res, u32 len) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_FN64_MEM_RETRIEVE_REQ, .a1 =3D len, .a2 =3D len, @@ -225,7 +225,7 @@ static void ffa_retrieve_req(struct arm_smccc_1_2_regs = *res, u32 len) =20 static void ffa_rx_release(struct arm_smccc_1_2_regs *res) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_RX_RELEASE, }, res); } @@ -728,7 +728,7 @@ static int hyp_ffa_post_init(void) size_t min_rxtx_sz; struct arm_smccc_1_2_regs res; =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ .a0 =3D FFA_ID_GET, }, &res); if (res.a0 !=3D FFA_SUCCESS) @@ -737,7 +737,7 @@ static int hyp_ffa_post_init(void) if (res.a2 !=3D HOST_FFA_ID) return -EINVAL; =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs){ .a0 =3D FFA_FEATURES, .a1 =3D FFA_FN64_RXTX_MAP, }, &res); @@ -788,7 +788,7 @@ static void do_ffa_version(struct arm_smccc_1_2_regs *r= es, * first if TEE supports it. */ if (FFA_MINOR_VERSION(ffa_req_version) < FFA_MINOR_VERSION(hyp_ffa_versio= n)) { - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_VERSION, .a1 =3D ffa_req_version, }, res); @@ -824,7 +824,7 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *= res, goto out_unlock; } =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_PARTITION_INFO_GET, .a1 =3D uuid0, .a2 =3D uuid1, @@ -939,7 +939,7 @@ int hyp_ffa_init(void *pages) if (kvm_host_psci_config.smccc_version < ARM_SMCCC_VERSION_1_2) return 0; =20 - arm_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { + hyp_smccc_1_2_smc(&(struct arm_smccc_1_2_regs) { .a0 =3D FFA_VERSION, .a1 =3D FFA_VERSION_1_2, }, &res); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index fc5953f31b4b..547d63679022 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 #include @@ -137,6 +138,8 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vc= pu) hyp_vcpu->vcpu.arch.vsesr_el2 =3D host_vcpu->arch.vsesr_el2; =20 hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3 =3D host_vcpu->arch.vgic_cpu.vgic_v3; + + hyp_vcpu->vcpu.arch.pid =3D host_vcpu->arch.pid; } =20 static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu) @@ -728,7 +731,9 @@ static void handle_host_hcall(struct kvm_cpu_context *h= ost_ctxt) =20 static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) { + trace_hyp_exit(host_ctxt, HYP_REASON_SMC); __kvm_hyp_host_forward_smc(host_ctxt); + trace_hyp_enter(host_ctxt, HYP_REASON_SMC); } =20 static void handle_host_smc(struct kvm_cpu_context *host_ctxt) @@ -815,15 +820,19 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) { u64 esr =3D read_sysreg_el2(SYS_ESR); =20 + switch (ESR_ELx_EC(esr)) { case ESR_ELx_EC_HVC64: + trace_hyp_enter(host_ctxt, HYP_REASON_HVC); handle_host_hcall(host_ctxt); break; case ESR_ELx_EC_SMC64: + trace_hyp_enter(host_ctxt, HYP_REASON_SMC); handle_host_smc(host_ctxt); break; case ESR_ELx_EC_IABT_LOW: case ESR_ELx_EC_DABT_LOW: + trace_hyp_enter(host_ctxt, HYP_REASON_HOST_ABORT); handle_host_mem_abort(host_ctxt); break; case ESR_ELx_EC_SYS64: @@ -833,4 +842,6 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) default: BUG(); } + + trace_hyp_exit(host_ctxt, HYP_REASON_ERET_HOST); } diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe= /psci-relay.c index c3e196fb8b18..ab4c7bddb163 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -6,11 +6,12 @@ =20 #include #include +#include #include -#include #include #include =20 +#include #include #include =20 @@ -65,7 +66,7 @@ static unsigned long psci_call(unsigned long fn, unsigned= long arg0, { struct arm_smccc_res res; =20 - arm_smccc_1_1_smc(fn, arg0, arg1, arg2, &res); + hyp_smccc_1_1_smc(fn, arg0, arg1, arg2, &res); return res.a0; } =20 @@ -206,6 +207,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bo= ol is_cpu_on) struct kvm_cpu_context *host_ctxt; =20 host_ctxt =3D host_data_ptr(host_ctxt); + trace_hyp_enter(host_ctxt, HYP_REASON_PSCI); =20 if (is_cpu_on) boot_args =3D this_cpu_ptr(&cpu_on_args); @@ -221,6 +223,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bo= ol is_cpu_on) write_sysreg_el1(INIT_SCTLR_EL1_MMU_OFF, SYS_SCTLR); write_sysreg(INIT_PSTATE_EL1, SPSR_EL2); =20 + trace_hyp_exit(host_ctxt, HYP_REASON_PSCI); __host_enter(host_ctxt); } =20 diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/swi= tch.c index 779089e42681..ca60721501d1 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -7,7 +7,6 @@ #include #include =20 -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -308,10 +308,13 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __debug_switch_to_guest(vcpu); =20 do { + trace_hyp_exit(host_ctxt, HYP_REASON_ERET_GUEST); + /* Jump in the fire! */ exit_code =3D __guest_enter(vcpu); =20 /* And we're baaack! */ + trace_hyp_enter(host_ctxt, HYP_REASON_GUEST_EXIT); } while (fixup_guest_exit(vcpu, &exit_code)); =20 __sysreg_save_state_nvhe(guest_ctxt); diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 0144cd26703e..1ad6a55ba95c 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -364,8 +364,26 @@ static struct trace_remote_callbacks trace_remote_call= backs =3D { .enable_event =3D hyp_trace_enable_event, }; =20 +static const char *__hyp_enter_exit_reason_str(u8 reason); + #include =20 +static const char *__hyp_enter_exit_reason_str(u8 reason) +{ + static const char strs[][12] =3D { + "smc", + "hvc", + "psci", + "host_abort", + "guest_exit", + "eret_host", + "eret_guest", + "unknown", + }; + + return strs[min(reason, HYP_REASON_UNKNOWN)]; +} + static void __init hyp_trace_init_events(void) { struct hyp_event_id *hyp_event_id =3D __hyp_event_ids_start; --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A9FAD3ACF17 for ; Fri, 6 Mar 2026 14:36:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807785; cv=none; b=BlktCT8Rk/KHx/Qkl9gygPRumvn3K/X7zDZEcHkGubU/8IFp0ChHNNqaKjerZ9/oLCXoEH8nRg4Abw1eBT/unxt6la4Am34f69WHu3LoivlVUX10YCi4Ksy91EnhDPFqUqEIPM3J1wCVe1reHRhpvh7mhWwskXN1OPcHg7H9BbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807785; c=relaxed/simple; bh=Hq3pw944yEctnZlP5UAA9Ov4xnMxVYtjU2DXhQ3r5cM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=utobt8rUPM1/wHuv25RlJPXscGy41BKPQM7YyXY8IXmxmHO1CkHdIUvW9XjlXOmvCVKOSLD2cS7huGFR9TIENEvFf/wuo5IMHZPqE3273Wkid0mIWUyGWgKNiJ/zVF4ejI1ww4IuDLGXwdeQJeAVeTPKDlwcadm9Zr+pa9VXH5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=j05B1V9C; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="j05B1V9C" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4839fc4cef6so93271235e9.0 for ; Fri, 06 Mar 2026 06:36:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807782; x=1773412582; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=VBnYryU8DAHWNMJIKaPrPbk+603MWk0xgkkJlIYXdOA=; b=j05B1V9Cvhto/mzagoJl47Vm63/8Uf8Bduwm0nWVXr3aYMNRBaarSEADIdSGaSqArV yAqz3B8rFKzMM9wqnRXR74QLIhEZE1RCM8GqZH8kIaEkwrxye83XeKUxN2TAfjCLEeUK /+KROx0xINWjZx6kL+TTxfVO/lAx8oqsQU12H+v0Ba1rsI0mvxuUGh1mTFxBCSi3Gs8Z oPjtaQ8r+cbiT6LiXtpiDD5R+dL9V03F8lUSmNkaJCgmJ3iyPMFB44ewiOIG56JL+eCV SG/z82lhX0e4YU0uSc4OaYReLpvtqK4JDd2fXi7WcFmNxkfU5T5V0tRXg1IPJ9bvO9zU 8Jew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807782; x=1773412582; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=VBnYryU8DAHWNMJIKaPrPbk+603MWk0xgkkJlIYXdOA=; b=jM05VPq+J/tvx7kfgFW2zdU+3RIxFnan04GeNaGrTl+mB0WGGclSNHJwUKUiMpqYYI UQ4Tq0tMc+XrFI8GOH7/CC8T5tMe8JwvfyQeJaZrGZHxJ2jk4Nkdn/fk7p/+/b1VG+l5 ooZbTA8b5jmZuhx3Dixd7ttz3g9UhUxui2EjgY3JyD82diwjkGK+cXc3/O71M7ETHbYJ +DaJhF7ej77NPQa8nHCNb+HMwZZY/OycJSdr+wvfuAPWgcKO/G9ThekX3INSZe2wbkQo 1HQfTHl04g3MOKytDv0h7J/MUXFYT5NLOcGvx/LpEhcS+5f9lH0WW+u0HOeD251q+2Ve VZeg== X-Forwarded-Encrypted: i=1; AJvYcCWU7ekmm4ivQANiQSupXhRYxn8YQfA2vE7iqPsB3pBiyQoQUX160ejnNNVlO7XbjaLqkgMWy/E4DV34X1A=@vger.kernel.org X-Gm-Message-State: AOJu0Yyx10h3xjTi5SRaZvsiFhVmsJNiWhdI6Azs0LOH0uZfCSFdnXce uNsC4xSyIcH54Q3Xdtfoh5AddPKKctKSweRmWDxng+4UOXrPynddM7TD+OI1CZ4lojetKpII+1C FNUVtxTzvuKhl9AvbxtwjZQ== X-Received: from wmna22.prod.google.com ([2002:a05:600c:696:b0:480:2051:60e1]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4fc4:b0:483:6d9e:e4f5 with SMTP id 5b1f17b1804b1-4852671c9a6mr36238685e9.5.1772807782036; Fri, 06 Mar 2026 06:36:22 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:33 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-30-vdonnefort@google.com> Subject: [PATCH v13 29/32] KVM: arm64: Add selftest event support to nVHE/pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a selftest event that can be triggered from a `write_event` tracefs file. This intends to be used by trace remote selftests. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index 47d250436f8c..c8eb992d3ac8 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -96,6 +96,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___tracing_update_clock, __KVM_HOST_SMCCC_FUNC___tracing_reset, __KVM_HOST_SMCCC_FUNC___tracing_enable_event, + __KVM_HOST_SMCCC_FUNC___tracing_write_event, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h index 221a1dacb2f0..743c49bd878f 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -46,4 +46,15 @@ HYP_EVENT(hyp_exit, ), HE_PRINTK("reason=3D%s vcpu=3D%d", __hyp_enter_exit_reason_str(__entry->r= eason), __entry->vcpu) ); + +HYP_EVENT(selftest, + HE_PROTO(u64 id), + HE_STRUCT( + he_field(u64, id) + ), + HE_ASSIGN( + __entry->id =3D id; + ), + RE_PRINTK("id=3D%llu", __entry->id) +); #endif diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 547d63679022..eff9cb208627 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -643,6 +643,13 @@ static void handle___tracing_enable_event(struct kvm_c= pu_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __tracing_enable_event(id, enable); } =20 +static void handle___tracing_write_event(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(u64, id, host_ctxt, 1); + + trace_selftest(id); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -691,6 +698,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__tracing_update_clock), HANDLE_FUNC(__tracing_reset), HANDLE_FUNC(__tracing_enable_event), + HANDLE_FUNC(__tracing_write_event), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 1ad6a55ba95c..c1e28f6581ab 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -348,8 +348,30 @@ static int hyp_trace_clock_show(struct seq_file *m, vo= id *v) } DEFINE_SHOW_ATTRIBUTE(hyp_trace_clock); =20 +static ssize_t hyp_trace_write_event_write(struct file *f, const char __us= er *ubuf, + size_t cnt, loff_t *pos) +{ + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + kvm_call_hyp_nvhe(__tracing_write_event, val); + + return cnt; +} + +static const struct file_operations hyp_trace_write_event_fops =3D { + .write =3D hyp_trace_write_event_write, +}; + static int hyp_trace_init_tracefs(struct dentry *d, void *priv) { + if (!tracefs_create_file("write_event", 0200, d, NULL, &hyp_trace_write_e= vent_fops)) + return -ENOMEM; + return tracefs_create_file("trace_clock", 0440, d, NULL, &hyp_trace_clock= _fops) ? 0 : -ENOMEM; } --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DB7593CCA1D for ; Fri, 6 Mar 2026 14:36:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807786; cv=none; b=G7T9mN1736t8eyDKUTnCyTjmvTpeBN8QMgARqiyg0i94ZNHMqy08CDKJtZA5NgPJOh1IF5k34d0fsJ9XfbUW5kE/z+HEX6F2wMQMi3B9pYl9Wn4rtAhNtFk2RiwgmUjEOov3i43YfTN0L0IF8NIH1NRjbdPXjUr8khznjSTp/u4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807786; c=relaxed/simple; bh=dn97yqhM5JULZE/7AhmPFYcp2Ky9Bl52SQiCDggGIbs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JLxBN42jBTHv0FI9BFjOAIxm5pGqA/xTfFiR9U0hZesQOYKkQNRUiPPHTTHuJ4Krjwyar34W4juXeoxdTWVpmZ9LWQi4UG5DMCfFEFVQq8K9X833nzQXd5mx9t1gBVyg1t432PmJi+3SBbFZ2BDzTYZ7kSvJZPRREn4zI928FXk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=SFZFRL5p; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="SFZFRL5p" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-439b5511d5aso5717311f8f.1 for ; Fri, 06 Mar 2026 06:36:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807783; x=1773412583; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=QsVePr8Brwc4uqDNMxUsa63z10B8xk0sNAC+har7PuE=; b=SFZFRL5pIpye/GBPM6/enhQymd0Tpe1g9kEkI0gPyheCwThhhtPxGDovxJ3DQr/g1U rHiPEhGHUd2Rd8+6GFsOjsp92B2Rltcw9PjFMeRJWjWkeNzjdBba2RGE8OZWHwAyKmUB Z+1RRgNkOte6ERU5r/QNKrEAEjp4nKbAnnevDPaFI6S+9+VhF5+1L80xVlS3JNejKP5Y mk2PaFWbm33w29Y2vTfmsD6w2qk1YGFLIQSlkRwIVStC65W/FgNoVkBBs948iDp24/Lu m7EBm5KDvgIf/n42ccp0leO0oNNdKjExpjOlcLKCdzqG2BpNUFf+3x1qF/XTtZg6PO1x 9oNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807783; x=1773412583; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QsVePr8Brwc4uqDNMxUsa63z10B8xk0sNAC+har7PuE=; b=XB9IE2nAZXx7XOHoBVwupWujsg3Elq+ZKWNc5SS++la5sdyaTv6DyXB2P+xXNYSuwG VBemRLsTSJU0f7pBuAaLXrZVdLUdUB930PHBsEPcbpznLXk0DbBx6gKWIUkDVkAhLBEm nsJJ+w1htqCjEnAQvdi6BypNutRMpv2w+DzFB66kJX/PLdVVOmn9Ee/ZRVCUs0WnREAT AUBOtKMMvpHKs1EqHd2eU+iF/CU8I78eGVyZpGYNHw2UT8ZaN86IivSKPLappSymi/Zl 6MPisoYMJ1fLuTB5I/atjdbaRGnD2OUTs+X6KWjGsjX12XL7S1YxwSLUZHcJjEsMuBsi 8NdQ== X-Forwarded-Encrypted: i=1; AJvYcCU//YS34PU0qXb/O96CGBlt8ZmRhcpzqf5WiH7ugzGBa/nAkdYVwbLbh0VczL8VkRVbdqqTjJczP4Z64WE=@vger.kernel.org X-Gm-Message-State: AOJu0Yy9rpFf3fKHMYlFJ4EVPcjyLQf47b80cUDItPXGMPf3dMeUuwnA 9jrm8VRd4T6FnbugtLzsj5qh4v9ZFvIbFds+/lVGX6EMP2jpXR3lZU+1sB1KzRwLgCvXnhhPVsn +hLiw4n7m81Wdg7DzfxejgA== X-Received: from wrbfn19.prod.google.com ([2002:a05:6000:2893:b0:439:b5ff:8e88]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2681:b0:439:c38e:66cc with SMTP id ffacd0b85a97d-439da88ffdamr3828400f8f.46.1772807783068; Fri, 06 Mar 2026 06:36:23 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:34 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-31-vdonnefort@google.com> Subject: [PATCH v13 30/32] tracing: selftests: Add hypervisor trace remote tests From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Shuah Khan , linux-kselftest@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Run the trace remote selftests with the trace remote 'hypervisor', This trace remote is most likely created when the arm64 KVM nVHE/pKVM hypervisor is in use. Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Vincent Donnefort diff --git a/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/buffe= r_size.tc b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/buffer= _size.tc new file mode 100644 index 000000000000..64bf859d6406 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/buffer_size.= tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test hypervisor trace buffer size +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/buffer_size.tc + +set -e +setup_remote "hypervisor" +test_buffer_size diff --git a/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/reset= .tc b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/reset.tc new file mode 100644 index 000000000000..7fe3b09b34e3 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/reset.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test hypervisor trace buffer reset +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/reset.tc + +set -e +setup_remote "hypervisor" +test_reset diff --git a/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace= .tc b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace.tc new file mode 100644 index 000000000000..b937c19ca7f9 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test hypervisor non-consuming trace read +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/trace.tc + +set -e +setup_remote "hypervisor" +test_trace diff --git a/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace= _pipe.tc b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace_p= ipe.tc new file mode 100644 index 000000000000..66aa1b76c147 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/trace_pipe.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test hypervisor consuming trace read +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/trace_pipe.tc + +set -e +setup_remote "hypervisor" +test_trace_pipe diff --git a/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/unloa= ding.tc b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/unloadin= g.tc new file mode 100644 index 000000000000..1dafde3414ab --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/hypervisor/unloading.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test hypervisor trace buffer unloading +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/unloading.tc + +set -e +setup_remote "hypervisor" +test_unloading --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 61C963CE489 for ; Fri, 6 Mar 2026 14:36:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807788; cv=none; b=jjruf6qpCL4EZ+K/OOL861V4Kijm4JdgrTWWna7mN9nYhgeOYBzcnyZnJCVMZvQXRrFSot2WEivb6eOukhLoHMiqSGvpzrTdOZgWInThbHmOhDbp8ukVaBgn3kkN4eH5zkJmG6xAKi1iuFB78/T3MSX8AhRVgrKqe4KCx9QAQUg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807788; c=relaxed/simple; bh=ea93niBYI+Rj/6YycglV0K0bDZBQ2z3tLiTBTzWOxio=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=OGQSCbUmhHEshJshoCH3DM3Mp+NoQeI7I2W1bRR9fOnKPo8kQ7hlJ8OTyUhKvvKdPZj07Rc4aiGG10trcOe+zpy1kezAyWH76ojz3uxRiwcufQUxE/Ig8aUwdVVdLbmPk7dtkd/3q8sNz6P9iTe31Xw4hNfeOPTKgmkoRdbKwSc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wbKRlYhx; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wbKRlYhx" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-66142e57280so2349877a12.1 for ; Fri, 06 Mar 2026 06:36:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807785; x=1773412585; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=nAzsYfyBwss8qjbiN9KhoiGNV9RHrAQ+UoLBq6ZtFBA=; b=wbKRlYhxNmD6h6zRFQPFqKNA0SGXQ+ZdEwXkVaHxImZDNM6nfM9/tZ+0iIonSRFSrj r9P5UoCeyfwvzpssueE80dVjSuOJn8eDxdXHZUPMmgVlAL61cAP1oScwCVSRfi9hOkU5 CEjvmSlOoYGTIJmFF5nmvW9IKfejUTleUs8JdticbgIN7tDBMQVhNMfjeAWrDNv7Marh J/99+6vreI6kkGwHgBDyJGQ4OxmLj4dQ5eL8L+O+gAT9YWDTZusjZRhce03T5AUhOdD0 yx1agpl/DYx7ECrmyRwhwAl1UeHum5DSLoVtiR4Ts6o8H7EPUBudFEV9UdzpjNpFhk9p UI7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807785; x=1773412585; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nAzsYfyBwss8qjbiN9KhoiGNV9RHrAQ+UoLBq6ZtFBA=; b=WhINz7Kl+ng7ZBnXrJ6X1i70CJEyyiN9RfrPaA3bKTX/WetQAVhPN4nQbw2Hgssmnx 2JeVSvL89uVvDaaK6La6IhCK2NFVycYWMvcl4WoQ2Dtnn03UufcvwPYpp9T01aiA+QHe /twkx1cksAnW7n4thZQuYZrXZuHPYhI/kcWLjpk4tGofVDKBrL/TrwDIqmGH79OXXFef 4257Cify1fEFQjj/yyuu65nMPpfi17a/Yup8i9HpT+JEoURMJLXHuU0gbwnW+AQH7HoM 8/Gj9qqNLcf097kilM04kBtvyDIxR+H1/cE0Oc5qzLYlp2ZJ8jcHq4/J8CAiCwIedUjS BH7Q== X-Forwarded-Encrypted: i=1; AJvYcCVCPPPNO66SvVSBUeawyQ44m4xpNDa6ehwsGoIxoXGchThkJV+mN8y7GT27yq/aFlJGnC1DEonAfV9nif8=@vger.kernel.org X-Gm-Message-State: AOJu0YyHjDzEEKcSepOgzKqwM2DD9TM4E6CftAYY+M2pnhpW0yap3vrg JaTXYSSg0Q6GFRVbxXOBLNneAFz7RLJ1Ge6ht3108uS/fy4ll1WqzTZx3j3A2I7LUu8KLDNR/P1 ozT5JLCq7xYByLguVwPAHlw== X-Received: from edge19-n1.prod.google.com ([2002:a05:6402:a553:10b0:65a:1fe2:dacc]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:944b:b0:b93:56a4:d6b8 with SMTP id a640c23a62f3a-b942e15531cmr137153666b.50.1772807784377; Fri, 06 Mar 2026 06:36:24 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:35 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-32-vdonnefort@google.com> Subject: [PATCH v13 31/32] fixup! tracing: Add a trace remote module for testing From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" diff --git a/kernel/trace/remote_test.c b/kernel/trace/remote_test.c index e5023b9d2611..791128d7fd00 100644 --- a/kernel/trace/remote_test.c +++ b/kernel/trace/remote_test.c @@ -28,7 +28,7 @@ static int remote_test_load_simple_rb(int cpu, struct rin= g_buffer_desc *rb_desc) struct simple_buffer_page *bpages; int ret =3D -ENOMEM; =20 - cpu_buffer =3D kmalloc(sizeof(*cpu_buffer), GFP_KERNEL); + cpu_buffer =3D kzalloc_obj(*cpu_buffer); if (!cpu_buffer) return ret; =20 --=20 2.53.0.473.g4a7958ca14-goog From nobody Sat Apr 11 12:31:27 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 446D03C3C12 for ; Fri, 6 Mar 2026 14:36:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807788; cv=none; b=Cy3MIYlHMjlVsnTwOBKnyNnqgRRf5RDpV/hBoKnIA9kPRQWy6aQeRWdDM7fHhul03WmLAYrslFgcv8Dk7z1gP//rXi1YbZVMs+MPZ4DAbkr1sw9LVft3cZPYb4+nUPCz++NsnMCj6QzhejqbUkjrcuLDv0FwlWJ+J9qXsVpd/Eg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772807788; c=relaxed/simple; bh=ObgOCDMC85s7Bm+uCQyKTE82mofMGHWimv4+K5Z7ga8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jp3CAzaltXfz3vmwObS+SkUs0gyfo+XqMhuCoaVnOUt+FTyQNBfB9IInKr/jr6DhOyGiVajWDXmSkbIqJWw+kllA17Vo5akG4iFp4gwh/jC6lOuJ+f9gAvf3dEg6+PCRjmgUoiaIUxPxppLIugwQfGWOSE9SlUTAOxLsT+W+ha8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=LcJOzHvs; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="LcJOzHvs" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-439cbfcfc21so2455215f8f.2 for ; Fri, 06 Mar 2026 06:36:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772807786; x=1773412586; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=fixqNHIgRdsXrQKd6GcjLA4m1QZ0grB448V81HUxHL8=; b=LcJOzHvsAtjvNSMufZ6xEQEuUJ7Ghzhq5v5NlbXaq6zoLAfiMcr3vagqp24OKokEZf vSAzKu1pY7h87S9qtqtBfugZ6Qhi3500Qkz4TwxSnPZSgRa8u5tP9AvxXjqRvoeM/YrN C40HFf0WP3ttrFudAIRYG1gV5de5AQ65UWFOa7NRi1GV60CSweABDDYxsZg1qMUgQr5q HSuXRbrd8SWSeMnxIp3m93ISYSPbzrw6eOQC+jeGcwVev9dmOaX8SboOwjbcuWkk/wTX jXP0Pc6qjexDLflmUSkPa9AtIoi69bgG0cwRmyOD+yUBA1wDuon4F9hDV8YJBWNEWxDT ceew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772807786; x=1773412586; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fixqNHIgRdsXrQKd6GcjLA4m1QZ0grB448V81HUxHL8=; b=XC4wwoeYSAwXtUo3RBSvgTx67LUsQaS0rasEt0EOjQBBbfNaMkX0Hfl1cd7Ak3zQaE IG9s7j75s94M/Vy8SbDk1ofAVk7KaNbKOZvFnGscuLEi4xsVzhlcQnivnLfA7LPRKXim J+hU2AdksuLqfCy8vofpVHkHgTmwJJasJRTiIHWet6Zhd1sfcvVnNk6T2WiuZj+089fD GmLzeBbg6ZVUg3liCcvfc6BVN1XOg0iQV0zCZrDuaoNkEXvvNgSSS7jlwkCqp59joLJx fmkclJolBINGl+8FThcFURNS5lMEOkFZ87wXQXY2jZ/Cip9hvx3RdbeNuR6I6JnNDjL2 miFQ== X-Forwarded-Encrypted: i=1; AJvYcCU+O5LgFEFvpUTGqzSj3PupxrhXRvKbAqVbJgmRI2TylgY0IL72LDgtJi2kjDoT5kUTeqQK/dzkQSV9PJ4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/vbaMC4FNqpDeFKkctD5OpQLrc5wmsz+LEhoh+VBXGb9/U8Zl 27xZu5XXmKcBKvMfcZILGxXbRaLouJOeUp3EBDLyQTkqEqZ6xDONm7doBrX8C1BkgMjkk7fGbzB TvbG3guCYj8fyeHH/6mNAtA== X-Received: from wmet19.prod.google.com ([2002:a05:600c:2ad3:b0:47f:c96e:8381]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1551:b0:483:43d8:8d68 with SMTP id 5b1f17b1804b1-48526967b79mr40105665e9.28.1772807785798; Fri, 06 Mar 2026 06:36:25 -0800 (PST) Date: Fri, 6 Mar 2026 14:35:36 +0000 In-Reply-To: <20260306143536.339777-1-vdonnefort@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260306143536.339777-1-vdonnefort@google.com> X-Mailer: git-send-email 2.53.0.473.g4a7958ca14-goog Message-ID: <20260306143536.339777-33-vdonnefort@google.com> Subject: [PATCH v13 32/32] fixup! tracing: Add a trace remote module for testing From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" diff --git a/kernel/trace/remote_test.c b/kernel/trace/remote_test.c index 791128d7fd00..6c1b7701ddae 100644 --- a/kernel/trace/remote_test.c +++ b/kernel/trace/remote_test.c @@ -28,11 +28,11 @@ static int remote_test_load_simple_rb(int cpu, struct r= ing_buffer_desc *rb_desc) struct simple_buffer_page *bpages; int ret =3D -ENOMEM; =20 - cpu_buffer =3D kzalloc_obj(*cpu_buffer); + cpu_buffer =3D kmalloc_obj(*cpu_buffer); if (!cpu_buffer) return ret; =20 - bpages =3D kmalloc_array(rb_desc->nr_page_va, sizeof(*bpages), GFP_KERNEL= ); + bpages =3D kmalloc_objs(*bpages, rb_desc->nr_page_va); if (!bpages) goto err_free_cpu_buffer; =20 --=20 2.53.0.473.g4a7958ca14-goog