From nobody Sat Oct 4 01:41:10 2025 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 034122EA165 for ; Thu, 21 Aug 2025 08:14:21 +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=1755764063; cv=none; b=RKNC2vDQ/5hQk3D86y6O+tStWZ9Uvke3rPCDjnbXt32nqg+qGhHa68qcFlrQxo1cYHdtaUrpJpnYsWg55tr3oOhf74pV4+65dDdZDK8qesUg9iNpS/AHMdrZbP/8LaeuYNGnrQtqjtybFTJV/nzoTpMs62xJZiuWQyUNCdOGgjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764063; c=relaxed/simple; bh=qoDF1ovJLicBrzwJxz32Udbfhq4kyqYKtfXv9oULSqU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=syvXa8kAIz42r3+W8p+A2bbL1/IgpZmCQjNhjpmS4kW6YzVyYc6IKnvm63oNejJfIFcruFQaCPflb+2UWIDsoy1j8TX6nfdRYHoIhf5W2lX6ayuCWr/63ZkmeP4UIwY9O90ln11f6JYLw0zlfAL+TxkRgINRJ7Xu+hMD0POqWXs= 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=x0LOF0/a; 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="x0LOF0/a" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b0b6466so4880675e9.2 for ; Thu, 21 Aug 2025 01:14:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764060; x=1756368860; 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=dJOAg2LepmucyL506XIcO8nq6zYHDDz484cJsiMQI5I=; b=x0LOF0/aY0wHkDyRj4bxdvKPkz4as5p6kR8B6Ac9EfX/SGzVlaYd34cBtY2USeTcZA 6uO4HZOCDDM2U+Jn8Ks+vwA+edA1sF248nT/umlKMGF4F4qNLhFxzXlDTpsWUMR4oFGb +aH3cTg/ceJ4g3AKl9vf97PZlBMrXNeuSElLu3p5hjdluManD7K0x2o6/XCj6bS2nCmf RYVUDh09WYtq9ssQapHYFSGUCvnMovmjJYaNgZtlqsrOIx4rVDua/Pfx73dgsZ7J7Soo j3cZ+JTMNVhjwKUT3SG3vmSFXhIAZW+0+zRtN4kwfClVnbh9HFxuuWxI68NhV7NbQHgJ DPGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764060; x=1756368860; 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=dJOAg2LepmucyL506XIcO8nq6zYHDDz484cJsiMQI5I=; b=IFOdi+G1dsy00N/E3g/VT1oFWanlo3BqcPNN0Ec8OC35+9dO3dFiDOuJmmRBS4XK2g OZw/Wsox+2FbCFL4We90gJzu3ANPi/nw9OtlHxTZ7Eov+6WZMgIZ2OaC9rv6Ex6+AK47 MrlpnvISEEVWRXyFGrX7GKRrf7/VQs3vwJXICmHoyNHPmt4zvfJV9hjQGQ9gDQc2+HCh lsxX0W49kKbZd2Eq7r/wWnWxSoINAikK3TMHlFwM1ldffssNTPLl8xaTJEeeH+21fVYs QIOMUUiFHeT5Sppf81+RX+2EbjqgMJpybpgI4C7o1gQ9X+vNK8HYWXz2lnyKzSUk+p+C o5/w== X-Forwarded-Encrypted: i=1; AJvYcCXVhggoIlF98J9oPxXC8uyJQRfz98zYNpHwZcW95fK/uD6HQiUkqwX7ttnsOLiEHRTy36KvZl0c0SkFFWs=@vger.kernel.org X-Gm-Message-State: AOJu0YytL/IKtXcOjfQIC33Ib75JJJikUaISoTYFy7ag+UrsNTqhKriH rzvYs8yxCpmJAXuF6tUNtQspub2d+jivoJgX3suXvET6WYXPX5Zoe7CuJlkk6zwBBARhrqVKNDf w7DqwLSd/eRkeiU8z43M+2A== X-Google-Smtp-Source: AGHT+IHcoqwzyqcPrFsP+sYGNNnfFwMlL/y8NDzxBQBSaC+pxoZobjyvT11sCcSBD4JOgEO+Nyr7sVyBoR8vIUR9 X-Received: from wmqa19.prod.google.com ([2002:a05:600c:3493:b0:459:dbaa:93a6]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:358e:b0:459:d3ce:2cbd with SMTP id 5b1f17b1804b1-45b4d7dd79bmr9793685e9.13.1755764060486; Thu, 21 Aug 2025 01:14:20 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:49 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-2-vdonnefort@google.com> Subject: [PATCH v6 01/24] 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. 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 bb71a0dc9d69..064005c9347e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -6113,6 +6113,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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 E5AFF2877D2 for ; Thu, 21 Aug 2025 08:14:22 +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=1755764065; cv=none; b=S9RWAxFRIgtpl9o0G1OLQbGJShdeoEJfnKYLUkNQ6r74Ryden6ShyP6z9ap9Ee9YnJXEzTC8/BtgB7qgTpeJXTJhVuMZFAiiBfm3LkPQeMrYAZ8dKdVZRyDpkkc3geA0xTNtJ0KdDdRgJEJn4XqYTPYv/KkWuXqHU1cnRkempz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764065; c=relaxed/simple; bh=WQS8U46+ZPuKy+q+D3uEJzmXQYGIK2afvOxvFOk+0Og=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ZAYcPyBI6GuPtV0aXJ3LOJOe3qQSL3KfA6Z6kXLRhs/7xiIvC4YDl6Y9OVcOrq/3PxKyPIb8GtassAt+7JtFS4tUXCyiYA/yrG1+rY4S8f+9CfWPBEaICJAv6CBCT71QNWzydjq4Pm8QnSA0hCITRlg1Ow/Zi2S9E0NNbArKF1A= 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=HJBhoG54; 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="HJBhoG54" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9edf2d82dso356844f8f.2 for ; Thu, 21 Aug 2025 01:14:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764061; x=1756368861; 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=EVXHtblDXG9FsPmiFB9gYQm8DYFqBHLwYgTNpISped0=; b=HJBhoG54vVgLZpSe4tN3IYc82xNeRt0EnoxixilpsereCkpjnD3NEoHb0ou7q1n4ov WOCFZDBl3o86Y6WHcVtvx45sgrU3dxHZlD0siTXk635NASEdsPJbjTuHlix6AUejw731 +mKsGLdYwoPUgPsAqV4wjX0twtvySAHkcKHSmLNVlUDGY2krLxV0uyeiA5tWDehuI7hg JHWo3laW6PFU3UFmebUywWcm4ZyS4XxSzsJUBx96rb1A53M/HtzjKbsozNaT4XBRSltA SZQl/ECQPQrrN4ebQvk9Mij+XW4AI1xz0q2tpT8B2eVuODj45885FMSTyd+4iTIaWnwn ogIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764061; x=1756368861; 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=EVXHtblDXG9FsPmiFB9gYQm8DYFqBHLwYgTNpISped0=; b=Oh2RjsbfiZE/SZ/EHgmCzeQNQ/NKRooOPooFTClz6VlSVQU8QG1DKZ4JEvx2FZGYXK iRHXeH6XFmsmSeBX3F51euUE5VThoQ+pgmUMMA6u1bM429rZF5vd5tpwVDLjQq5QCQXj RU/fVpL5Tg+WRdsm3oI014hdCpfETJDEvdSGp5AaCK83uuRLtjXSYohxVLZve5ybOQ0e 6kx2umU55qqHMAmKkoHczlTSBCGhUv89NDCh1hH9E2M4f02cmjwwAbTf39cMCzzzU0ad eCwtmyw2lgxIUIOq0EeaXgpWTgQpzq+tpOWrU2iqLvxYYHjTT3lKqcRJtSDiXR+FitGT DG1Q== X-Forwarded-Encrypted: i=1; AJvYcCUNGbsqdnlJKS/cFxZ26dRLKGCaYhjLPoNtstLQIYN3Rz3E+fFoJMWvOHIHOARJrboyZPTzrmtH6a9sOMI=@vger.kernel.org X-Gm-Message-State: AOJu0Yz6ePGYPphtgS+6sf8wZ53HeK+TS6/rYtt+z/sqgn5Tp3rYqaFe FxzXtjG/7K94ahe+YkazBEQppSY43ad8Iq26b/gLMCY1WoGA/ajYKbE45hHLVxXmIy0EVNf7IyM 3WKDW2GwLhA02z1Dib9+pfA== X-Google-Smtp-Source: AGHT+IEtjG4efQJZZkGmnF7j6fSwGwT3zGV62Xvty+RuX8fc83FYra+x2+Vx58i3z+edquUqfpCjmAaGjZctgtya X-Received: from wrbfo3.prod.google.com ([2002:a05:6000:2903:b0:3bc:3d2d:b32e]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5f56:0:b0:3c0:2f7c:faae with SMTP id ffacd0b85a97d-3c494fc6e12mr1359974f8f.12.1755764061226; Thu, 21 Aug 2025 01:14:21 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:50 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-3-vdonnefort@google.com> Subject: [PATCH v6 02/24] 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. Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 876358cfe1b1..85dae2193241 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 (buffer_size + PAGE_SIZE - 1) / PAGE_SIZE; + 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_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 064005c9347e..8044cb23ef88 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -523,6 +523,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 */ @@ -545,6 +547,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 @@ -2296,6 +2300,40 @@ static int __rb_allocate_pages(struct ring_buffer_pe= r_cpu *cpu_buffer, return -ENOMEM; } =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, unsigned long nr_pages) { @@ -2356,6 +2394,32 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, = long nr_pages, int cpu) =20 cpu_buffer->reader_page =3D bpage; =20 + 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->subbuf_ids =3D desc->page_va; + cpu_buffer->nr_pages =3D desc->nr_page_va - 1; + + /* 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; + /* + * The meta-page can only describe which of the ring-buffer page + * is the reader. There is no need to init the rest of the + * ring-buffer. + */ + return cpu_buffer; + } + if (buffer->range_addr_start) { /* * Range mapped buffers have the same restrictions as memory @@ -2431,6 +2495,10 @@ static void rb_free_cpu_buffer(struct ring_buffer_pe= r_cpu *cpu_buffer) =20 irq_work_sync(&cpu_buffer->irq_work.work); =20 + /* remote ring-buffer. We do not own the data pages */ + if (cpu_buffer->remote) + cpu_buffer->reader_page->page =3D NULL; + free_buffer_page(cpu_buffer->reader_page); =20 if (head) { @@ -2453,7 +2521,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; @@ -2481,6 +2550,11 @@ static struct trace_buffer *alloc_buffer(unsigned lo= ng size, unsigned flags, buffer->flags =3D flags; buffer->clock =3D trace_clock_local; buffer->reader_lock_key =3D key; + if (remote) { + buffer->remote =3D remote; + /* The writer is remote. This ring-buffer is read-only */ + atomic_inc(&buffer->record_disabled); + } =20 init_irq_work(&buffer->irq_work.work, rb_wake_up_waiters); init_waitqueue_head(&buffer->irq_work.waiters); @@ -2598,7 +2672,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); @@ -2625,7 +2699,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) @@ -5386,8 +5471,57 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *i= ter, } } =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)); + /* + * No need to get the "read" field, it can be tracked here as any + * reader will have to go through a rign_buffer_per_cpu. + */ + + return rb_num_of_entries(cpu_buffer); +} + 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) +{ + u32 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->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; + + cpu_buffer->reader_page->page =3D + (void *)cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id]; + cpu_buffer->reader_page->id =3D cpu_buffer->meta_page->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; + + WARN_ON_ONCE(prev_reader =3D=3D cpu_buffer->meta_page->reader.id); + + 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); @@ -5557,6 +5691,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; @@ -5957,7 +6098,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(sizeof(*iter), flags); @@ -6125,6 +6266,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 @@ -6355,6 +6513,49 @@ 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; + unsigned long flags; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return -EINVAL; + + cpu_buffer =3D buffer->buffers[cpu]; + + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); + if (rb_read_remote_meta_page(cpu_buffer)) + rb_wakeups(buffer, cpu_buffer); + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); + + return 0; + } + + /* + * 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]; + + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); + rb_read_remote_meta_page(buffer->buffers[cpu]); + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); + } + + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer =3D buffer->buffers[cpu]; + + raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags); + if (rb_num_of_entries(cpu_buffer)) + rb_wakeups(buffer, buffer->buffers[cpu]); + raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags); + } + + return 0; +} + #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP /** * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers @@ -6600,6 +6801,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; @@ -6637,6 +6839,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 @@ -6646,7 +6850,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; @@ -7222,7 +7426,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, unsigned long flags, *subbuf_ids; 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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 3FC302EA728 for ; Thu, 21 Aug 2025 08:14:23 +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=1755764066; cv=none; b=VYIgYuqXIr0XvLBoXiIbcaBao2LQN0CQOQB3MkIrdP2mtCkR4xud82TMvWNx34kCSmgyGOgGFDgbHnusEN2IngWufmZVALnPX2AL2fecs6pwVww5TyPs08AJ8W8p3716gfdfxdM2aElZWgMfwn12Lndp6aAY7vi7aatB83id38U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764066; c=relaxed/simple; bh=G0M9kY/CSDS7rpq2ELS4X4T5F9POqAKRF62gWAJVgA4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=b8fFzgIbPQKm624gpVNk5dIcPXkubdAayYBGxavfS1AGmQmMFC71MJF499K5CHgGkTZQMJCzMW0meK+dOhiSXjUosCRX07Sp2XlUbMqVvhvyRP0vqcHc9Da/OS9jO5DSilMq2YcM9NH7qSXlDwLB3PC4Ihd5xV7/irXSoH6zqYA= 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=qG988yLa; 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="qG988yLa" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b0cfbafso4015585e9.2 for ; Thu, 21 Aug 2025 01:14:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764062; x=1756368862; 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=/TBF5A/91YZzcYTJWeKqOEi+q2cOi1diGR9Op3ftiDk=; b=qG988yLaaQEeAXBQEn/1HKHItqzJwrVVof/98zan/0mzkpCl0s6Eers9SMFjIt+AQk 9szTB+WxLRpFuL2q4SgLXSdcyweGhTqTkd8gLQgcxu6hYtJ5HdCDKn0v8hOlL03JuvdV e0+wHy9vmNjKCgYvVjStQexGL8ShfAl95p9ppxQwn+G7Al/ZAx+qJraFPwWVYJP9ev/T 07XFXJsgiYG49Gc/iK+7mrQIssIVTyLufuGDpyKEHCHoM21MXS0jAsurLoF7WFOSycNE WShNSrIqyWq/VEZ6l0VKA0ZPA7dgKsgtYH42vLqFf3o86zSt/QauWN1dtZxC3MzbdjEe gtaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764062; x=1756368862; 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=/TBF5A/91YZzcYTJWeKqOEi+q2cOi1diGR9Op3ftiDk=; b=QORK39Pa6jDI4jaUE1BtoIqsQeghUK3U2GR+JlfBtZ25qZFHe8IArW6JFErLPra46m ZVDwtqiIQZWm1NLZhpXbnGvgc8Uhy/Gvy2C5ce4nq2yWis/72ShF+5srywKT0sHU7cx/ /UV6iKUH+c4E0Aoli/PbumXC7AWeKKViMdmq3ijCPqYGIDYqCZeHUzzmZXUKnEXI4pX3 hYk2DjxIL8F6XnsTnl/qNnzs549eDx7CadBkGhlNaaixdu6A5n5VgyGR0y6ww8YSr2f7 xz27VADqT3H4TE2eT9qjvs4NQuNmQ3IoB4dGXvSJKG/uSDARiG+WT7gLE/Ua0fIs67es YnBw== X-Forwarded-Encrypted: i=1; AJvYcCXCZTNqwHubR9d9N0hZVmcXBp3AULgK1egqDTiNnJZgg+ZQLsJKygZXvCZKp/mEF0jaAXUoc4Wt4GG5ays=@vger.kernel.org X-Gm-Message-State: AOJu0Ywx867Am/uwojQW2H5Dfqx6RMzm+Qw4DKchNsDFAI9AVBoQbm+S EGIZ+JesVA0Y6KpA0VHF41GR7UfOYlwQMpKWdV4aCc1A3k8rzwUxyOrfgYFRIsQo18Eoo9n/VqH 5JrEQ8oRUcK+e+Gtrsoc5MA== X-Google-Smtp-Source: AGHT+IFdkFpRbxMFks2nYePijUM3BjPUz1erddqr0s/Dj69fxitO7EAj+773cv9BnM8LIrPeUDxGJxcpArjrQqIT X-Received: from wmbex21.prod.google.com ([2002:a05:600c:8315:b0:458:c0b7:b936]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:458a:b0:43d:fa59:af97 with SMTP id 5b1f17b1804b1-45b4d85d764mr10152965e9.32.1755764062435; Thu, 21 Aug 2025 01:14:22 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:51 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-4-vdonnefort@google.com> Subject: [PATCH v6 03/24] 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. 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..de043a6f2fe0 --- /dev/null +++ b/include/linux/trace_remote.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_TRACE_REMOTE_H +#define _LINUX_TRACE_REMOTE_H + +#include + +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 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 d2c79da81e4f..99af56d39eaf 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1238,4 +1238,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 dcb4e02afc5f..6dab341acc46 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -110,4 +110,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 4283ed4e8f59..b4654ff1b07c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8939,7 +8939,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 1dbf1d3cf2f1..56fc8f109e65 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -672,6 +672,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..1a4786b7970c --- /dev/null +++ b/kernel/trace/trace_remote.c @@ -0,0 +1,518 @@ +// 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; + + lockdep_assert_held(&remote->lock); + + if (trace_remote_loaded(remote)) + return 0; + + remote->trace_buffer_desc =3D remote->cbs->load_trace_buffer(remote->trac= e_buffer_size, + remote->priv); + if (IS_ERR(remote->trace_buffer_desc)) + return PTR_ERR(remote->trace_buffer_desc); + + rb_remote->desc =3D remote->trace_buffer_desc; + rb_remote->swap_reader_page =3D remote->cbs->swap_reader_page; + rb_remote->priv =3D remote->priv; + remote->trace_buffer =3D ring_buffer_remote(rb_remote); + if (!remote->trace_buffer) { + remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv= ); + return -ENOMEM; + } + + 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); + + 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 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; + int ret; + + if (remote->nr_readers =3D=3D ULONG_MAX) + return ERR_PTR(-EBUSY); + + ret =3D trace_remote_load(remote); + 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(sizeof(*iter), GFP_KERNEL); + if (iter) { + remote->nr_readers++; + + 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: + trace_remote_try_unload(remote); + + return ERR_PTR(ret); +} + +static bool trace_remote_iter_next(struct trace_remote_iterator *iter) +{ + 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(struct trace_remote_iterator *iter) +{ + 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); + + cancel_delayed_work_sync(&iter->poll_work); + remote->nr_readers--; + trace_remote_try_unload(remote); + kfree(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_next(iter)) { + int prev_len =3D iter->seq.seq.len; + + if (trace_remote_iter_print(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; + 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"); + goto err; + } + 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; + } + + if (!trace_create_file("tracing_on", TRACEFS_MODE_WRITE, remote_d, remote, + &tracing_on_fops) || + !trace_create_file("buffer_size_kb", TRACEFS_MODE_WRITE, remote_d, re= mote, + &buffer_size_kb_fops) || + !trace_create_file("trace_pipe", TRACEFS_MODE_READ, remote_d, remote, + &trace_pipe_fops)) + 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; + } + + if (!trace_create_cpu_file("trace_pipe", TRACEFS_MODE_READ, cpu_d, remot= e, cpu, + &trace_pipe_fops)) + goto err; + } + + return 0; + +err: + if (root_inited) { + tracefs_remove(root); + root =3D NULL; + } else { + tracefs_remove(remote_d); + } + + return -ENOMEM; +} + +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv) +{ + struct trace_remote *remote; + + remote =3D kzalloc(sizeof(*remote), GFP_KERNEL); + 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; +} + +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]); + } +} + +int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t size, + const struct cpumask *cpumask) +{ + int nr_pages =3D (PAGE_ALIGN(size) / PAGE_SIZE) + 1; + struct ring_buffer_desc *rb_desc; + int cpu; + + desc->nr_cpus =3D 0; + desc->struct_len =3D offsetof(struct trace_buffer_desc, __data); + + rb_desc =3D (struct ring_buffer_desc *)&desc->__data[0]; + + for_each_cpu(cpu, cpumask) { + unsigned int id; + + 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 sizeof(rb_desc->page_va[0]) * rb_desc->nr_page_va; + rb_desc =3D __next_ring_buffer_desc(rb_desc); + } + + return 0; + +err: + trace_remote_free_buffer(desc); + return -ENOMEM; +} --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 C88032EA49E for ; Thu, 21 Aug 2025 08:14:26 +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=1755764068; cv=none; b=W6rF+m8qTczWdOCTFRAnQqG+l75J6daWtUR6OgvvVlC5HO7Njcvw1FjgcxZQKC6eP+HL3GbxE+Uey/aOdUOF7mzMsgp4bT8vUbH29Ib+HWRw+riOUKc0khPFNJKJ5VWMunX4pmscHFUdJ/nl93r411o0Kqw1hWnoa9V10suUYWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764068; c=relaxed/simple; bh=9xXiwmLgPnWsrqQg77YhaqS7pkQvVJu7dXOCGMAPWTw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ulTO47wp4mDXxZfsOJ84ypTxHjYJRa0NcLTzlCHXX2ywMQRS9oGxAE1C9Zk202vxG+Y90ypw5mSefzWD7eMRDyKyDC/9BL7hA0DaKh+ooWPYumk4Qg0oupNVwt8WsjZi6oS+CxPQQca/aNAnpHkyGRtexeyfvRtV8w8cCq81gtk= 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=ykyxvj0n; 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="ykyxvj0n" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45b4ab71653so4686795e9.1 for ; Thu, 21 Aug 2025 01:14:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764065; x=1756368865; 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=NJcUPeC8ocB5+j9OXdNiMliYvjrJgSIIHWHJsqMgtN8=; b=ykyxvj0nLkPJyi5XSwTXTvkOmygp9nYoNT6VBFoip+3M3MId6vUNlGL3nmVpHoX/YE A/KDhXbajmlwnEeSwpeW6spkbbbzYnIOeCNVuS7vQ+JSklGFKxTVVkvLwzLdAuUgsS+C e26/b7Bx+Hz7fOq1GFO3vRSZ/dpKReYv+0Gl0aVoUMv7TO+GkkY3Z2TbLs87Z0E+YfhL c6OA4I0wPXys1CKtCaaK5P6RFpItDHipmBNdFguEGobo467psfJQ95z3D3UQjO/ZpxX/ J8JTjonyFh7cAdnv3SjLaG//Twg/gDfcYOjBE//dF/Zfv71MYJ+r1//ztA1jVhRNXVKd 3G+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764065; x=1756368865; 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=NJcUPeC8ocB5+j9OXdNiMliYvjrJgSIIHWHJsqMgtN8=; b=Gn+UguTM779icR5NLG9PlatjIhWHqd31EtRk89GcPB4cM8d7WAJey51i+VFAIpCPIn 1YAi0XPCgE0f0k7M5jG9QueTEmAtIOwXmukb5TiWWZ0ueoyGyVfW4iSxPOeUo5IV3IQO YU8WXQBiOYUSp9qinKWkVveialMWsHynDoWOJigMRua4nzFLX/8YrEON26ScPLWShpj3 M3jX6nkobRDmpfs2gwhU0QSv7kcEuuxd+5uyKwWgpbkX6SoN+mM7UXSkTLisMr8jSAdR FeZaGK1sEDbs9dFXkNuoGcP11t9tMCrG9g8I0DcXr2l/znpopMS3sJkz7cNPeR1alZwV bj8A== X-Forwarded-Encrypted: i=1; AJvYcCVRfhNO/M1hRVi6DAD8Vlw5Z64yyr1oQ8GJAsbJOddZR7FGX9uwlWw5ZpxqHLmtGKw+o85GOYRZn8uj80s=@vger.kernel.org X-Gm-Message-State: AOJu0YzmN17Nb4al5yN/N1qtTOL1CxPyKWP4K75IW/tUbXgLx7QT3u59 muhP/9T5nNNN0VuXNvQHVeMEDDwQnhY0I1FcB+YKkfbZtqJQP+mTgmLMF2EZBURWQ5iewxaSoBu p4KoNyPfpWHNOpS/7ed+aUQ== X-Google-Smtp-Source: AGHT+IHxHGYd1KeGVGM3iasiEuHwtuNNyEruew1KNtvROKmeBVTKi8SlkdS/376itCy6PY0wJZqfEhcdRnlQxCNH X-Received: from wmbez8.prod.google.com ([2002:a05:600c:83c8:b0:459:e17c:3572]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1f0e:b0:45b:47e1:ef76 with SMTP id 5b1f17b1804b1-45b4d86c5d6mr9909145e9.37.1755764065317; Thu, 21 Aug 2025 01:14:25 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:52 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-5-vdonnefort@google.com> Subject: [PATCH v6 04/24] 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" For standard trace instance, "trace" files allow to do non-consuming read of the ring-buffers. This is however not applicable to ring-buffer remotes due to the lack of support in the meta-page. Nonetheless this file is still useful to reset a ring-buffer so let's add a write-only version. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index de043a6f2fe0..1aa99da3c96a 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -11,6 +11,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 1a4786b7970c..18b2930186cc 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 remote->trace_buffer_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_remote(rb_remote); if (!remote->trace_buffer) { remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv= ); @@ -136,6 +137,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) { @@ -370,6 +386,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; @@ -400,7 +436,9 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo !trace_create_file("buffer_size_kb", TRACEFS_MODE_WRITE, remote_d, re= mote, &buffer_size_kb_fops) || !trace_create_file("trace_pipe", TRACEFS_MODE_READ, remote_d, remote, - &trace_pipe_fops)) + &trace_pipe_fops) || + !trace_create_file("trace", 0200, remote_d, remote, + &trace_fops)) goto err; =20 percpu_d =3D tracefs_create_dir("per_cpu", remote_d); @@ -422,7 +460,9 @@ static int trace_remote_init_tracefs(const char *name, = struct trace_remote *remo } =20 if (!trace_create_cpu_file("trace_pipe", TRACEFS_MODE_READ, cpu_d, remot= e, cpu, - &trace_pipe_fops)) + &trace_pipe_fops) || + !trace_create_cpu_file("trace", 0200, cpu_d, remote, cpu, + &trace_fops)) goto err; } =20 --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 7B8F72EAD13 for ; Thu, 21 Aug 2025 08:14:29 +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=1755764071; cv=none; b=nCQcMkzVQzwgMSOuUoCNZzoP01vuBAcKfRWHe7pDZRpwMrj/yuzWezilsrsqX+UC2KckF5Pfks5FvxbTMwPsK2a+zWzyMhXIaMkv7RJdHlATNFfKK5NfMBDba7Y9LMvOe9LRJ4Dq40QcBgF0M6muwcxky6EaY7ejkCCSwyVqzBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764071; c=relaxed/simple; bh=MJnXwlr6sqtBLAgWRkDhxOXeIwiyUFY3sKB4i+iHGHs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LIH0WYKDy9uLmksUFFRwxdmYjmXjXoRM2WjHILsyvsDAZzaaDYdtw8lhBEXgkgPf+YfWLvemG1fLh4h1hTTEHbmBn4YD/cKOvNcCUdjIUBvkhCeM8W7E9rVJh4/8nca0z6WX23/32ijoj4EtvI+C5jn3bErVaRvI+z/Xr3gUMvU= 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=SySG2Njy; 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="SySG2Njy" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9dc56225aso450864f8f.1 for ; Thu, 21 Aug 2025 01:14:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764068; x=1756368868; 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=UeiQbqfd+7HFGphDDhTnjWkKTWOQraz9qW3YNATpZfI=; b=SySG2NjyTm92/ixhZeUPxPL+8jOoVevAYmrdJoyVXieOB33cTqQn9FEytN04pcFNRI CsTTSdWmqhHNapeH+nmmbdlzqVtAL9lCs26GY+lMiBF9Qyavxb2z4wtUU8VBejraOQoG JWnhK7bWCbpONh4CWoANVLiP8qDYI7pR7Y578fYJ66CEDhvAjfrfNR4q44r7lPOkTb7Q VaDq5AVx7fCFDFIyiDnYHqiP5piamyxMkJadLxEjblNMCTcSa8kOOmPd2mgu1ouxozuH xXT8e/FpHbNXN5qNN+p36YmHsWi1U9y46aqT0sIWVhxqM2xiVOhul4d6GOOLQdUF4/Hr L4TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764068; x=1756368868; 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=UeiQbqfd+7HFGphDDhTnjWkKTWOQraz9qW3YNATpZfI=; b=BWpNtAVJoxmZN2GDtOFrsUaOvh6x2fL8kfvZD9HHUyov0FHmgr3ixOep6WbU859JcG 4V0rNJc0z4OEVMLfidOTIBR99DQ6dF6bPloKrQqZODFXxFyM+2wkl9QrOPTcN1KH/V7l jEgKZYMHw2tgtXl9tlVj0C09m1+NFv2JZqy6TEeZAl8wqyj77CYq3vYncdHD1dlrcDgT 9xKSmYs1X8/nXIw69oamh9NqhOYExbBzSHS+fnXtNVZmDChcXw/3IngUWiQ5zf3661G4 +qc68fAjwNIYLYC0qN7L+ZOM1CUKxtj6lwcAicdN4F2TITjrsClgB37YKARoPCaa7/dX jl5A== X-Forwarded-Encrypted: i=1; AJvYcCUFBsiW3uv1jk9dSz2FnEKCJrrNYXdg6aPA+AhpOce6Ad4/Lwh8qMfy7widjptFpb+ss1zYDTBdlXn9qsI=@vger.kernel.org X-Gm-Message-State: AOJu0YwpgJc8RTIZcaNz3JYWreKJ7LozZpF3fK6bxLmMg31w4AfrClBv nvIlzsmuE0v75g+1+EmTMnboK4cVXNPHhcm+0Xcf/Xmnnoiz3YiXcZNScmrrQ8SqYV9BGgjrpiV aYOZOHOjSDvUXw3ewDJZp5Q== X-Google-Smtp-Source: AGHT+IGPZ/UWfrK0SR54G2w2/hGND79Jxl9Aw93toJ+uqNkdy6qzcC80bA5lVYDqpW5CNdXw1Cx3m0UW7vJbU9iY X-Received: from wmqc21.prod.google.com ([2002:a05:600c:a55:b0:459:dbaa:93aa]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2f86:b0:3b5:e714:9c1e with SMTP id ffacd0b85a97d-3c494fc5dbemr1259176f8f.12.1755764067796; Thu, 21 Aug 2025 01:14:27 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:53 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-6-vdonnefort@google.com> Subject: [PATCH v6 05/24] 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. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 1aa99da3c96a..82d26d97a536 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -3,9 +3,11 @@ #ifndef _LINUX_TRACE_REMOTE_H #define _LINUX_TRACE_REMOTE_H =20 +#include #include =20 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); diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 18b2930186cc..8f8eb1f1e889 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -482,6 +482,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(sizeof(*remote), GFP_KERNEL); if (!remote) @@ -498,7 +499,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; } =20 void trace_remote_free_buffer(struct trace_buffer_desc *desc) --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 153472EB5B8 for ; Thu, 21 Aug 2025 08:14:30 +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=1755764073; cv=none; b=UwZuo6iDBxXeP6gptOKXiuCbJvVrAzX93oh0GfjeCe3fc3GwEvm+YHVJNmVsplCmPZvyitbqXF8rfvw+Vae6gpQcm5j4ZVj3hhiRrLOGc1hXDWQNk/xoEe18ejpTZ4HdIeLkYgC272wgD3ua5sy5g/j9K+A3dAvZlKlFlwLZndM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764073; c=relaxed/simple; bh=5+w0BR+W06Wn0JgcJC9Us0FypC/rTpbMEqbisGDqnVY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Drs2gr6S8T1Pu73SFZ7CaQ4B8oJVHtiov1HcwWQRu29BjTW3BCjVPOKbXpKrbNu9ePQMBpcGdScuhGmV0rz8GlP/ri7Ic9ztRWYx3iN5X6YfZi5hexkOZnpHuHy8djNTgpEkKOxTXds0APKCUW+bW8n81lFovOl4l0265CmXxe4= 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=qsinkaDB; 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="qsinkaDB" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b04f817so2963775e9.1 for ; Thu, 21 Aug 2025 01:14:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764069; x=1756368869; 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=W22EIU0wPmFpDoLsMyxYOVfGPptW7NH7wCZxoNxRvyE=; b=qsinkaDBP/h8VtHZSoIfL+zYLAJTibH2piRSVJk62qwCHM5lXwJBuZbeJusM1a9sbp 975w3f+2jf14Xzu+eC6INOQzucy+1D7+jkLi/+xLLuQ3lEbOpE53LS2V9/x5ubnBx18r O1bsXZyRxVw7nbGo+Zcm2SLFFtgr58DIXsDthqLokZbq7mUXAPuv5V+9LaUWyKS2REKe pYTrTdQQpgOxSXm7kvz7///Q0wjzSeTxxZTrJbu8zyCe9CY8W+R7B5TD4ewplRw+esDr FHAZSatUIdGEwV6RvMYMBK0l1a4ujigLhsiLdHWeC5Bv0O2nJAclg5kbbtLFTnntZ8Zt 39Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764069; x=1756368869; 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=W22EIU0wPmFpDoLsMyxYOVfGPptW7NH7wCZxoNxRvyE=; b=AyVbK48kcyOKS9lBsHQApbSjFIHzfFuvg7jPe7DWQS9ewKZVEOucFPe1UlyIJlUI5s 6Mi0SxL3S1x3z7RgdfLyBd62NaRA5qZLneHVNSJ8jVloo6+8SbwYRoEcLGN+Fa2Etzf3 mm3M1oLFDPD2EhGXuWmSNj9g/44CQWv9wD9ajq6LApADNAjgsu/3+PGkz+E6Y5wEPXEt 8gwJ17Pa53K6UN1C1y4C6isVPuhhGQLMArIWU4FdV0+grIP8w5EP+i/BfYguIB0jPDYW 7J07R5HPF9DSWCnnPWOEZdmqespT+jzuXmPjk28qWXAfibSf5iIccG1b0uE7dZKA/YFg GmWA== X-Forwarded-Encrypted: i=1; AJvYcCVF1Oh98Qm/pFmAdoJhLdocK3q4Ypkix/W92lg8YjCHdoOTUJe89Fl0mkdehpqBA4MCrOn3aRPtll6poZ8=@vger.kernel.org X-Gm-Message-State: AOJu0YxZvAa/Cc/9vLj9+/X9Rfh9kSfH0qjrn7Ui8Rr/LehPv/tjTnwE YUYEQdresRZiW4gXZva0C9dJsxqGeTiAhZ03pnKk4xtzWnxhavpGWzp8HlMJkpWeXTUD4I0eM5c W4988vdq/DeG5NVZpBUg6iQ== X-Google-Smtp-Source: AGHT+IGI2PiIkbSjwFuAaWOED7yQoO70q9rCSdloyFzMisfBtQbkBFdm8+ayz44OpgWngOd+05LdDZJ9I7+dIhEE X-Received: from wmqa19.prod.google.com ([2002:a05:600c:3493:b0:459:dbaa:93a6]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1d22:b0:43c:fe5e:f040 with SMTP id 5b1f17b1804b1-45b4fd1fc01mr922155e9.23.1755764069522; Thu, 21 Aug 2025 01:14:29 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:54 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-7-vdonnefort@google.com> Subject: [PATCH v6 06/24] 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. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 82d26d97a536..4cf8efa83578 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 { int (*init)(struct dentry *d, void *priv); @@ -14,9 +15,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); int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t size, const struct cpumask *cpumask); void trace_remote_free_buffer(struct trace_buffer_desc *desc); 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 8f8eb1f1e889..822cdd76e334 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -24,6 +24,7 @@ struct trace_remote_iterator { struct delayed_work poll_work; unsigned long lost_events; u64 ts; + struct remote_event_hdr *evt; int cpu; int evt_cpu; }; @@ -33,6 +34,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; @@ -155,7 +160,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 @@ -184,7 +190,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 @@ -265,16 +272,19 @@ static struct trace_remote_iterator *trace_remote_ite= r(struct trace_remote *remo static bool trace_remote_iter_next(struct trace_remote_iterator *iter) { 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 (!ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_events)) + rb_evt =3D ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_ev= ents); + if (!rb_evt) return false; =20 iter->evt_cpu =3D cpu; + iter->evt =3D (struct remote_event_hdr *)&rb_evt->array[1]; return true; } =20 @@ -286,7 +296,8 @@ static bool trace_remote_iter_next(struct trace_remote_= iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) continue; =20 - if (!ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events)) + rb_evt =3D ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events); + if (!rb_evt) continue; =20 if (ts >=3D iter->ts) @@ -294,14 +305,18 @@ static bool trace_remote_iter_next(struct trace_remot= e_iterator *iter) =20 iter->ts =3D ts; iter->evt_cpu =3D cpu; + iter->evt =3D (struct remote_event_hdr *)&rb_evt->array[1]; iter->lost_events =3D lost_events; } =20 return iter->ts !=3D U64_MAX; } =20 +static struct remote_event *trace_remote_find_event(struct trace_remote *r= emote, unsigned short id); + static int trace_remote_iter_print(struct trace_remote_iterator *iter) { + struct remote_event *evt; unsigned long usecs_rem; u64 ts =3D iter->ts; =20 @@ -315,6 +330,12 @@ static int trace_remote_iter_print(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 @@ -466,6 +487,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: @@ -479,7 +502,11 @@ static int trace_remote_init_tracefs(const char *name,= struct trace_remote *remo return -ENOMEM; } =20 -int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv) +static int trace_remote_register_events(const char *remote_name, struct tr= ace_remote *remote, + struct remote_event *events, size_t nr_events); + +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; @@ -499,6 +526,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); @@ -561,3 +595,220 @@ int trace_remote_alloc_buffer(struct trace_buffer_des= c *desc, size_t size, trace_remote_free_buffer(desc); return -ENOMEM; } + +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_id_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 *id, const void *evt) +{ + return (long)id - ((struct remote_event *)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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 2A8CD2EB85B for ; Thu, 21 Aug 2025 08:14:33 +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=1755764074; cv=none; b=PEJ3ZA8otEEoUJj91omhT7sK36ovualKJOqZBYNe24LD33JrtlCg6BzgQvlfTFjS3jouKDwGFjEPi++IQCAjHN8OLThWyGSihrQPglt+DcRwP8Kak0b55SnvwPWbaZPPyRIc66WopEikMaTkOQgxlGsVPJAKGkMr+O1bCvbbibA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764074; c=relaxed/simple; bh=yNjrtYzdqxSOJA8JMtlyFP25XGNSVeq6WWnFHimuLUg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aYoi7iTfTFPWe0bBdECUObBz0MMAIZ9ZYHW0VCfs0y8s3WMO78RLxMrhEwIA5QIkgck5u3V8tA2w2ouwZqt/HXfQWeOaExLHCaaNBU9VMqWxleMEu0WiuR28XdEQI8awemN+UxZ3k9AxnZp2kMkhpZsPQAPh8WGGbucJGlwoZN4= 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=JC5P7Fk6; 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="JC5P7Fk6" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b0d221aso3258195e9.3 for ; Thu, 21 Aug 2025 01:14:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764071; x=1756368871; 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=7jqXM3IQFmwL7/KyPBrOmBEtNR7claVQSXPHpFSy3Pw=; b=JC5P7Fk6biVaElue1q+F0hNtCsrmMwRaWtWv9XdQ4XaE2vypeEgKsqLAMDJNYBSHlp u3WeYXfLvsEnzrt62joxu8DXa1Oxb8foaO7hI2mmoha9oFQPuuID0uKxgwg1W9MjuA40 H2swyPo4ZVOEtant+AbNB3i2eqBARbdTNErUGG83Ibl8IIFTxWvs+BuUEUjHHVAPMKi3 z8aqS2jf0x6uuahSuF8kXWlpti7TOozQdxCGvQvHBsLDEA0iwmc6dchSZ3MZcC+NKt1P OqL+DXo+Z6hSqkQhxSiNemyfzxYwbAwt4enY0dLxJSDwzmHyshFUpUL6OI/N9SL+1z/S PDbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764071; x=1756368871; 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=7jqXM3IQFmwL7/KyPBrOmBEtNR7claVQSXPHpFSy3Pw=; b=uEajBkAh4qJvEJMOBH4v00zrUfjWDM827iKdzPI7zycg/NkdtBaz57TTdEZZJnojXG m/qO7ZIjzB8KKF08D7znS+U1O0VeAXEin46QCQTZP8taRtIstfK1f1jwJWtUODreu0vy yI5aGRZkx+uKqonb5dMVB39KWdBp/dJOc5dsx7TaKHZzV0CCEGVpGEuIGcNZVrcX8l/n WbPr4xLeN72dp+JVS3P3Kh99FEpuBqJY8QiwkB8FMO7i8ehrXi6+PperLw8ueEKFJxc9 Bh4u/cRBe+bgwL2kBmJDqIxH63u740m5EEDm9FozBEg32he9BIY8k1oaVtddOgQDPuQG nMaw== X-Forwarded-Encrypted: i=1; AJvYcCWpS5o8pJaa7yR127ZNqvbZwSnH/yP8BRVdny7o76BrxhVoDJj8jJFzNH9WWMDRKRNHbe4gM3F5PUXk2Kc=@vger.kernel.org X-Gm-Message-State: AOJu0YxPawI770He8bm2TQ1RfejPYgub0GT1o7WHDTweVsU43nX+tiYu UdRnYPqCfic3V/GsOSphQnYy1Dzy6nEOLQ2qbc+Y6NdYPAw723ROKp1wRq3Vp7j26LYJrvEhDYc CHqZIkO/6loJx1hT34zC2rw== X-Google-Smtp-Source: AGHT+IE+BeKNnnBgP2hFtel0lnCMgkmekl+cgM70ekcw14+86Zb79b7FW6ixmJANsDqQXBnK6UuwhPfLQJtGZ17a X-Received: from wmti5.prod.google.com ([2002:a05:600c:8b85:b0:458:715c:51a1]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:19cb:b0:456:1e5a:8879 with SMTP id 5b1f17b1804b1-45b4d7da9b7mr13059725e9.9.1755764071698; Thu, 21 Aug 2025 01:14:31 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:55 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-8-vdonnefort@google.com> Subject: [PATCH v6 07/24] 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. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 8044cb23ef88..17f77653b926 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -604,7 +604,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 822cdd76e334..5065b162c8ef 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -710,10 +710,118 @@ static int remote_event_callback(const char *name, u= mode_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; + u8 enable; + int i, ret; + + 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 const struct file_operations remote_events_dir_enable_fops =3D { + .write =3D remote_events_dir_enable_write, +}; + +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 0200; + *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", @@ -729,7 +837,8 @@ static int trace_remote_init_eventfs(const char *remote= _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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 E4E0B2EB870 for ; Thu, 21 Aug 2025 08:14:33 +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=1755764075; cv=none; b=k+q30OPaHHsjH07o+CTOTZ+WaF06OZiuXOpaAZ34H+zx64ZfnSRAjeQ5G+UJSc5A9/ISg5kkBFp8dJJ+JiJ/ewHL0CQNPxyzdXX1bLSbFdRdIqYyG2ktB1wixfWB9n17alI8N76nxNQIpvAvlAstpztMe/sRv9tmksP+IsKt0zY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764075; c=relaxed/simple; bh=P/7XvxR4AvpjrdbDgKKXlLWIX5BZ4WYCJ7N32BrK4/s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fREQrn9pOBTcX4Lxz1P1gnEzWE1U5ercNyqfrr6UeugTrs+n3VV3yhCzBNPXlpXuYmuskC5vQ0h8t3VSenRhcI0G1IVUt/sJc1dVxMAl1wf8KdLG8oAEHD4Gcu12+LNQvIBELIhfOb6YI8shc+oeF4HZk59yrG8IS1eLMRyPym8= 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=Zj324s8v; 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="Zj324s8v" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b00352eso3711235e9.0 for ; Thu, 21 Aug 2025 01:14:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764072; x=1756368872; 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=4iWuJzzxP4gVw/2ZCfCXIAaNe6s3pd3DhFDuZCx99Fg=; b=Zj324s8vQdElPoph3t+AF/llsmhnairLTkbkFb6Fy9wJpT9/ozvM+yIpdVXCJhrH4j lSk+2XNqNl1Xj8znoalAtZ7So1HK73sVYhkJ4uPSuqEhmYnA1kLdwIXyjwt2+kg/yqE0 VHPXBExrFi1ESdQ5RyWSetYZZioJpFBR7p45Jmf4ShGl6UkhVK8q2lCe2+xCUk7aCCcy ZwdkL9ZqE2ZC72DXDzzsEMrPBVkOMFHwluLAhKeey8su0dqKfM1gMrQu2TTuRknuLTsE H+dUGipG9vVShvOanze93Km2VyHD4IZX8XP7jNGAPeRBK6lW10irJHax6uTyf+7bDaId SKDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764072; x=1756368872; 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=4iWuJzzxP4gVw/2ZCfCXIAaNe6s3pd3DhFDuZCx99Fg=; b=twoyObaNkfqz+86jmIbY+plioKyqiYTaSpl0n6fSfJyIpdzzLkBBOZoc2Vu69LCqiG O7+al39QX3PBqcyJy1BzLBmBoDCecAJ0fKLhIOfZzdEeyGlIu2SSsrY0iZ/22V1ZxwTo byWLLYtQdKG4kqLZHMv8GLYP7eXWkIzp1Q88tGLTlzme8vSKdbsJg1wvmQWHcX4Z2Md1 mI6jPxNjImR9d6x92GsDfMr4ggT3b+2JN4BBpcMP5AenYA8E88r4QuDIOpI7bo1A4f7C zPs4qG23bO7geNZUoNkOASBINYO8abH3sI8M3xS3z6ATD/aczBMCyJfivlec33IIdx4y 0emw== X-Forwarded-Encrypted: i=1; AJvYcCUxE/A9R/Mf1I7l83v3oMYsYKkjvFK1CgY+iKcBiFzPL9XsLPSqM4YrpB3FXw8su1lSYRjTiMp6NcpUdTc=@vger.kernel.org X-Gm-Message-State: AOJu0YwqoqDg1z+8hjpVnPZ9u6c6akcr8EKiYX7gJEgwgk9/FPyVBHNW Zek1So1RhoHyxgUIy2bwqQHyQvds3E9eyXJIbZ2AhQ3KzyTshGjoQE5ebJqEKYeqI5haN3Nx+Yt +RZ0oW/HegnP5wJq2DgJ3kQ== X-Google-Smtp-Source: AGHT+IG4Q8cp6jOORVXZXkfWOgrpfZ0eZv6m/uotMvvZvAtj714DTAyhspN3LAAa+n5V+47jBjIVsqxX1AfiCyxk X-Received: from wmbhj7.prod.google.com ([2002:a05:600c:5287:b0:456:111e:4717]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1390:b0:456:161c:3d77 with SMTP id 5b1f17b1804b1-45b4d7f786cmr15535985e9.16.1755764072496; Thu, 21 Aug 2025 01:14:32 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:56 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-9-vdonnefort@google.com> Subject: [PATCH v6 08/24] 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) ) 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..03c9f5515c5a --- /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(_0, _1, _2, _n, __args...) _n +#define REMOTE_PRINTK_COUNT_ARGS(__args...) __REMOTE_PRINTK_COUNT_ARGS(, #= #__args, 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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 EF4642EB849 for ; Thu, 21 Aug 2025 08:14:34 +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=1755764076; cv=none; b=AF4tWlJLA7E+Vz8sNKAYZRsFK5thRDGxVBElSWQlDsCy7y4L1wQpNH/rkqvtctpepOmLYwPUyInpbj6mLFuMs4n5blRISoju7sDgOGNNbmpK8qR2NSebvLg17fNFFEFUu9WAaeFfQgEbSV6Qvyq8o4scp0q+b2tXxAS3/TaehM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764076; c=relaxed/simple; bh=95klshcx1eA8ITSZ6yKOt6Et2Dsxed0eu/S+STTsgow=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=L2U5r3mZJnsTeiyd2zdDWVmGNaY0LfN9JAFYp0SGeB68mOZmhRwvrebBgJiyVf52ZvuXM5reDkvbAQ2UkRL4BgO8cvLNW4ZxU5brZdGi8ix3TwpVo7fIyjuDouoqLjrdpz2oE+IeAGSADQTd1hqLLuFlmyC6qQd0CaSgS3srubo= 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=wZP/TNEV; 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="wZP/TNEV" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b00149cso2854605e9.0 for ; Thu, 21 Aug 2025 01:14:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764073; x=1756368873; 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=lidjLhay00eIJzNqp9y3fdvOXQROgJQ6gBPaAYL/6So=; b=wZP/TNEVBIqQU7fgQSXKk5miggJAkPKteXSYCgBxGXFkXqU8P09f7fUk0CUkwXJVZp wufwX/vZ3gG5FowOnIA2Bo3EyatEsSIhwO8wZ+7AoJTYf9X+4vuHO4JCUZstE+UCd8vH X0neEmQT01dblMB7SVk9DnBo1VCAOK/yGWzsvH951A6Hf+97HHuDdzLCLuOlFU3dewhr x78dbKh5k+RTnB/2wDho/eWUdTFEqQScjVKbm0dmrN6fJhXrle5U1Ugge5cxLUyAMtAO iN2D0ar/ALXIaDnlZHRyogifLtuvknvIiu3jzZ/SmBrregMI8ZJb2QJISrukfd2A5USm 6Pqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764073; x=1756368873; 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=lidjLhay00eIJzNqp9y3fdvOXQROgJQ6gBPaAYL/6So=; b=AWdENN28y4+hFY0HHzqhg/hJhgpLlOWFJQwYYCQMMh7ge3GZbuF5Z4KGE4q7UOfvsI uIin/RWF4/gokbJkTEZtJtRz7NOJf3nMhUA6TFGM24ZSoChsX442/9MmLOVDmGkfPHbx M0sd7DHHOCvflUdCx2qvKIPhZSWDb7+fRYcQhbhRCrtSZdDX6mM7dXUTHhRi/Or7GHT3 G6/7T7NS61ESJrq9SU5VTgqY4ylC1W0o6PF/l6e4B9Sn8JjnNMh+YsgFKmmN6msoyd8s gbHweUQp7wMgQrYDE/IefP9/rD+3utbJWuuXMAqxW45d5ue2cdy0Wsmuum5GFYycOgLV awVw== X-Forwarded-Encrypted: i=1; AJvYcCXCN1biVKxYlP9o6tEKqNVw64v1hOWb7KssTwn8sfqB/HWEFKrlakk9yJEgHmjbu8xfQurSZQ7Zc/wjIko=@vger.kernel.org X-Gm-Message-State: AOJu0YyPGBaVoV+0finFXcDQDymzIvrZr0zSViiR8i4SFOVvPCD69KzR P5mIy4JieE6LunYevDRmRFw380wBerPEIEJwrnBvrkxVrDSornXr6yWWqxjTY5d0j25hqWy6/E8 QLnNVP7rCHBW3mPlD92Qkdw== X-Google-Smtp-Source: AGHT+IGUYeZjzebzCwGkqmxmIs4OLf1N4Wtv2KCQU5S608mV1VSpQPSnOJrtt34tlE8F6oeRRBN+N84WhKQvWceN X-Received: from wmbex21.prod.google.com ([2002:a05:600c:8315:b0:458:c0b7:b936]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b56:b0:453:5c30:a1fd with SMTP id 5b1f17b1804b1-45b4e4f5719mr10261825e9.8.1755764073268; Thu, 21 Aug 2025 01:14:33 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:57 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-10-vdonnefort@google.com> Subject: [PATCH v6 09/24] 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. 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 17f77653b926..c7405b5e55a7 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 @@ -156,23 +157,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 @@ -315,10 +299,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; @@ -337,12 +317,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 */ @@ -401,14 +375,6 @@ static void free_buffer_page(struct buffer_page *bpage) kfree(bpage); } =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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 58A6F2EBBB3 for ; Thu, 21 Aug 2025 08:14:37 +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=1755764079; cv=none; b=n1pINq91cYKFSbjYiBDOODy4e3S72LzJ5EiDETCYnBpZu+PrTmpEiRjMJsXysdQODFa9UsjAXWwK8xhUWwSiDNvqbE6nVdwiNr/6agk/te9Fs92w8Tqwjcc0dRU5fLdBguvKIPoxEt2igxG8SICuTlm2w0vsXL92xO3gPF9mp9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764079; c=relaxed/simple; bh=tDwkzXWnH6tgflSExWhKKHXZebxR4zI92cCyIMifjFc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SDrSHT5Q6MqtsvZQDf5yJ/wJjc/YehwmHL1xqZdTAP8eewsZKpuWby2cbxBoavW4HwH2DFEoE9a/ibYthy+YyZRe1Vcre5QZ35bYAYkFf07LC1JafEjsoOXA1EqhC2v00W8qI6CTbnkroDqsELkDvM0SybCltjaGJb41PFR2sDQ= 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=mwZajnXc; 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="mwZajnXc" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45b467f5173so4428535e9.3 for ; Thu, 21 Aug 2025 01:14:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764076; x=1756368876; 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=24vtXolJgWFlmCc1c2PtYNQB1/b0KRqdJsndd7gSEog=; b=mwZajnXcFO38z5Ji5PExqP8Aa8m+dIfw+5jRDInEwtWWvXzGulHzUyE258jDem4bEZ pm7L4yev+le4cKgRhuLFFyIVslQuXsF0BVDGdfRypyFahFumL4lXSGwxRyPgwYvZsjz1 EKMIGL4idFJX1N9V7BihyJxIGlAoJwGwD4Nws/bbsaATnWGMJgX7GXFe4AecpGtjyGPX 1EuI4g6zlzxqZtwTHNMCrBOcJiDJ50X9dywAnW+ct5+nst43zPAhx5KQpUqb5xB2BxJs F8p9lBagZFpmwcJ7lANJAhEirgKqAeWPGcdG81PUrqY32dIHj6ckANX0xG/m64DdDehH REdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764076; x=1756368876; 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=24vtXolJgWFlmCc1c2PtYNQB1/b0KRqdJsndd7gSEog=; b=i86Cm2LCkP2GI9Mv6sHvDn71AJ8HnjC2NLyylg9TH1oXYSd1JkWpIaMw0vGHrT5Jrb UCntgstcrXURvaru/6LIVx9cA8Ql9hC56KcZbERyDtRrDSVgLDam95RyASFfEthU2fXY F9Ti0f6kAY42QvlFbACn3LNUYibHswvW5lDKpRV4uOdnBRoqt1H2zcslIT+aY3KF0k8/ DJW8nThBYJKVr0c5qkvwUDMhbgEFIYpZXMaAwgnJ4Co75hL7ZfGMvT3AiwWhGH6a1LFG ++sIXnaXR+YWvyjpj0BNuWepjLwqnlBgLDBwhoU2369TWBO8p9WLKir/1S75x1KfpQHe GDEA== X-Forwarded-Encrypted: i=1; AJvYcCUtf9m6h9f/JMWAllmU70kOHmnaCd95xQMpwTFu3iOvC4BXLtnS80U/lnG5pxmlGxBoHwQLHk+VLcQ8CXc=@vger.kernel.org X-Gm-Message-State: AOJu0YwiSd4CNg2wrKZGv/x+HTm85R6snej2StY5+4KH2IwR/dFjkLL1 yQXPmuAexzie+1b9tOuSQcgN58sYmijwpmkX/svWN85TZBtEtXmTpPLcdMurFnbHGjxZqDzDMOC YzMYBuVdJRdly0fFzP0K2YQ== X-Google-Smtp-Source: AGHT+IHAfe25Nzx29A/y2LL6JJzOD7A+0ndWQGxZWD3Px5TYNBB/VZ64SUhiRwSLkKQTuJ5qsZUG1SQClaOlNRTi X-Received: from wmnn26-n2.prod.google.com ([2002:a05:600d:15a:20b0:459:d639:5949]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b4b:b0:45b:47e1:f5ff with SMTP id 5b1f17b1804b1-45b4d85e112mr9547115e9.35.1755764075850; Thu, 21 Aug 2025 01:14:35 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:58 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-11-vdonnefort@google.com> Subject: [PATCH v6 10/24] 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. 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..d6761dc2f404 --- /dev/null +++ b/include/linux/simple_ring_buffer.h @@ -0,0 +1,50 @@ +/* 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 ho= w big they are to allocate + * the memory for simple_ring_buffer_init(). + */ +struct simple_buffer_page { + struct list_head list; + 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; +}; + +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); +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); +int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable); +int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); +int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer); +#endif diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 99af56d39eaf..918afcc1fcaf 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1241,4 +1241,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 6dab341acc46..03d7d80a9436 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -111,4 +111,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..3efdb895d77a --- /dev/null +++ b/kernel/trace/simple_ring_buffer.c @@ -0,0 +1,360 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include +#include + +#define SIMPLE_RB_LINK_HEAD 1UL +#define SIMPLE_RB_LINK_MASK ~SIMPLE_RB_LINK_HEAD + +static void simple_bpage_set_head_link(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)bpage->list.next; + + link &=3D SIMPLE_RB_LINK_MASK; + link |=3D SIMPLE_RB_LINK_HEAD; + + /* + * Paired with simple_bpage_is_head() to order access between the head li= nk and overrun. It + * ensures we always report an up-to-date value after swapping the reader= page. + */ + smp_store_release(&bpage->list.next, (struct list_head *)link); +} + +static bool simple_bpage_is_head(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)smp_load_acquire(&bpage->list.prev-= >next); + + return link & SIMPLE_RB_LINK_HEAD; +} + +static bool simple_bpage_unset_head_link(struct simple_buffer_page *bpage, + struct simple_buffer_page *dst) +{ + unsigned long *link =3D (unsigned long *)(&bpage->list.next); + unsigned long old =3D (*link & SIMPLE_RB_LINK_MASK) | SIMPLE_RB_LINK_HEAD; + unsigned long new =3D (unsigned long)(&dst->list); + + return try_cmpxchg(link, &old, new); +} + +static struct simple_buffer_page *simple_bpage_from_link(struct list_head = *list) +{ + unsigned long ptr =3D (unsigned long)list & SIMPLE_RB_LINK_MASK; + + return container_of((struct list_head *)ptr, struct simple_buffer_page, l= ist); +} + +static struct simple_buffer_page *simple_bpage_next_page(struct simple_buf= fer_page *bpage) +{ + return simple_bpage_from_link(bpage->list.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->list); + 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; +} + +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; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + head =3D cpu_buffer->head_page; + reader =3D cpu_buffer->reader_page; + + do { + /* Run after the writer to find the head */ + if (!simple_bpage_is_head(head)) + head =3D simple_bpage_next_page(head); + + /* Connect the reader page around the header page */ + reader->list.next =3D head->list.next; + reader->list.prev =3D head->list.prev; + + /* The last page before the head */ + last =3D simple_bpage_from_link(head->list.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)); + + cpu_buffer->head_page =3D simple_bpage_from_link(reader->list.next); + cpu_buffer->head_page->list.prev =3D &reader->list; + 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; +} + +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)) { + /* + * Oh no! we've caught the head. There is none anymore and swap_reader w= ill 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_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; +} + +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]; +} + +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); +} + +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; +} + +int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer) +{ + struct simple_buffer_page *bpage; + u32 prev_status; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + prev_status =3D simple_rb_enable_tracing(cpu_buffer, false); + + while (!simple_bpage_is_head(cpu_buffer->head_page)) + cpu_buffer->head_page =3D simple_bpage_next_page(cpu_buffer->head_page); + + 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; +} + +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 one head */ + if (desc->nr_page_va < 2) + 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->list.next =3D &(bpage + 1)->list; + bpage->list.prev =3D &(bpage - 1)->list; + bpage->id =3D i; + + cpu_buffer->nr_pages =3D i + 1; + } + + /* Close the ring */ + bpage->list.next =3D &cpu_buffer->tail_page->list; + cpu_buffer->tail_page->list.prev =3D &bpage->list; + + /* The last init'ed page points to the head page */ + simple_bpage_set_head_link(bpage); + + return 0; +} + +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 0; +} + +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; +} --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 5E2C52EBDEB for ; Thu, 21 Aug 2025 08:14:38 +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=1755764080; cv=none; b=PB6crFChnpIW1r4Aa1WD/0ib3md8r1Gqx/HwIFzvOLIvl05kbRkdFdMZp7Fx0GI8qBtnv/VEcuhRA18bw3zm9BTzHQNMeDhDizQdMLp496hFemo2pTZLtPOvdN7zpq1wYjTObdgcrbtHkc1wGutOQishrEMXLkwM3UZl2NECWEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764080; c=relaxed/simple; bh=//1C5R4DthAxGm8JMNjmAFCgr8hZt+T9yu21+eu5nDU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=CnJtbstohIHcRncDSBTBXUhJtimB0kK/njRpROibIaU2h7/cu70J3JOPxHjV/C0DmWEpSaozlOFiEbZIci/BxavuXA7+PMiL3b4kDNwlNEw8wNHr+zrpGrMogKzLQLiNMDBG/Id+B8toHMHOG1SL1sP+6iCrFM1ziE87Qbp5kbU= 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=bHtXE5a0; 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="bHtXE5a0" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9e4157303so486700f8f.2 for ; Thu, 21 Aug 2025 01:14:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764077; x=1756368877; 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=XIkumAY+Qa+CLy3aOczQdeniGlNqiyL93/I+4NSc/RU=; b=bHtXE5a0llzol+ehYJ/27j5pYjrg9HwIeZ4tm3vRnYiFplOaD7270NaKSwGmoqnPGt L4CPF7I+B80njwFSDwkeSLwyMdCel/t3IkQaq1sD8fPAHMLSsMRydirT8iaR8b3eDG7P 8F2ZCeIXghN8s0rJbpgdNC104rnkhNRX2CENIdQk9YzBaMF1zHVlPfwCyNA/viPCb/86 /Af7iysUtTPyPhTw5UpRzPsc9UqS639qYmf43uGKpFisdp6xqQ+XqkJ7IZQlzfGCx0Wk QzedrIcxDZzuhUmiKR5HZGLQUMUBSg/7qQZjyq+Zf8wfayj7aHQN+ozYaGqD5SB/Rvpk o+yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764077; x=1756368877; 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=XIkumAY+Qa+CLy3aOczQdeniGlNqiyL93/I+4NSc/RU=; b=YHwo10SY1yYKv2hNCPzHu0HpqtBZL2bTvkFAoyESM7F4sfpDY2hOa4oxpX7dInN00h WKVokZyvpgwN9AcakDLsTl9kgCs3hNhbkfQ5eAtzq2DUOHkOEMbjkJU6zM2koBi1X5M9 YsSlvqvwhG8mWq/sf+Z0QAMJ+vt+a9PMV5mNcWHpOi1np3YKj+wxHNMTffqYkK1iHzfW dz5BgqHMDzVbdEI7Cy1e9JQ0L2ir9ZpTLjkd0TloJapKfe+xvflgUceobFtzt44k9dLQ UBNR26GaXoOQUCxWwWLqBOOM0YubPC7lQt1itgM/Ew7Le25JkEU0Y+jEuqTVSsaNd80j REXg== X-Forwarded-Encrypted: i=1; AJvYcCUFceUtLGHFa2vVmVMqoYjotky2DBzmkM8xaEESwC5Kcy6tRnl5AoSgZIQPX7ypwkPVSA720JghrfcyMh0=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2AKFspteafrY6YBbFDtfUMspvlJrpXHJsn5a+xCD0LMjpGFf3 H9XJPtsIE2dtS1cBvUaVO8EKoqwKUgXUr2H6dyr1laelAx5hk2bLxf1POAch4DU3ed4Wii/qXF3 pkcBgcdOcf5ly13x/vYhgjQ== X-Google-Smtp-Source: AGHT+IE2B3XpASX09u97oWLtmj7+DKYyjygPNdcC74JBMjS5y3LNop0tkSYmf/aQQm/kgIZulSB2bKIgmPvhviGD X-Received: from wmbex21.prod.google.com ([2002:a05:600c:8315:b0:459:d8e5:aead]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2c04:b0:3b7:8338:d219 with SMTP id ffacd0b85a97d-3c49405d778mr1324920f8f.3.1755764076780; Thu, 21 Aug 2025 01:14:36 -0700 (PDT) Date: Thu, 21 Aug 2025 09:13:59 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-12-vdonnefort@google.com> Subject: [PATCH v6 11/24] 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. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 918afcc1fcaf..52131d89993c 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1244,4 +1244,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 03d7d80a9436..53534447e70b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -112,4 +112,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..f8506d95ef3a --- /dev/null +++ b/kernel/trace/remote_test.c @@ -0,0 +1,263 @@ +// 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 kzalloc(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; + + guard(mutex)(&simple_rbs_lock); + + *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); + + cpus_read_lock(); + + desc_size =3D trace_buffer_desc_size(size, num_online_cpus()); + if (desc_size =3D=3D SIZE_MAX) { + ret =3D -E2BIG; + goto err_unlock_cpus; + } + + desc =3D kmalloc(desc_size, GFP_KERNEL); + if (!desc) { + ret =3D -ENOMEM; + goto err_unlock_cpus; + } + + ret =3D trace_remote_alloc_buffer(desc, size, cpu_online_mask); + 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; + } + + remote_test_buffer_desc =3D desc; + + cpus_read_unlock(); + + return remote_test_buffer_desc; + +err: + 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_unlock_cpus: + cpus_read_unlock(); + + 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); +} + +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 cnt; + + 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..bb68aac4a25c --- /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%lld", __entry->id) +); --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 E8B622ECD12 for ; Thu, 21 Aug 2025 08:14:38 +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=1755764081; cv=none; b=DpDdbG6+k391leVH0jakrOmP8cclF/hIi+uT5NI9+vxdPnoIchgRfczT1viy+b2cLbP86t3Jjo0LftYzHaolnV3+PRupfOE/TtfW/JLnqjT7IpPTZVQl2fKkwaY9DOELZ2ufYe71G8i33Lhf5oo+9wtuINdG7u3TVU/4PovWnzU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764081; c=relaxed/simple; bh=Zido7BGGyCct8PB7xiBoqrYPrOfJP7X7Fr0Wiblezzg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ogWikzrO5dz6NY0U+ZNZ5g806wVv5b9rPk2ufdCY4MFzcF6FCze1L+v9hxQypcO5lnKmkVACr7CWPI5jp4zJ7rKG5GTxyt3E6OmkdG9KCUnP4M/GLqODbjsr0V5Fb692ByM8RyFFYPjtREYkst1BarjzFMLJenvlMX1u3xPIUvQ= 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=D4p3WyuL; 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="D4p3WyuL" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b05b15eso4986095e9.1 for ; Thu, 21 Aug 2025 01:14:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764077; x=1756368877; 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=YuQZHh/5I/+ZxLcLKvlHxM6rBuApcg0gP5KQuEHQPgA=; b=D4p3WyuLfmCbbl28JdE3F2Pu0BEe7rmkWhLIr9yR/2TWi6a6CI9tVAPuIrlIe4otUB BZCWUkfIa6q51yQ7NOEWX1heYeH+BjLdlbzGx3JYN3mzZacKDXnASWjCuESkfH0USBTJ Cevh2X4PXo25umkTZSP80zqQzwXJowM7ytj0Paix7/dGU6uMdFrqcJY7gH8Bx/aPgxVL 8q4PEqmCscP59qECW/uYmm6AgUtMkqNyjwxy6eNISyeaA1u5bZJ4h5dQ9FUXtNDLm8KC R+EPEwvb8WFcUMddjaAi7pEuTHfnk8VJXGf+Bo6PJYN50dnhsFLAg6L91pI5gA+FlwlE 6VrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764077; x=1756368877; 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=YuQZHh/5I/+ZxLcLKvlHxM6rBuApcg0gP5KQuEHQPgA=; b=t9z78IISGfIBaouDXhq8DV5CeWJzUbopCglMaam++m6+wX5rIjZjnaEAW9F69fAtYx IVgxaer9jH1eVym1qsHd9bHMxuQyqoMEw/9Ug2niEjHy+Lag/x87DCccKWGQ1WQJzFSD JZw1ZYHFKU8WefOmJrgf3xvRo5U5zUa8QjAiV2R2AKMsbEGhN7u9lTsp0lWxhxrwob6E onsATgnBURN92tcU9pCJm/gdQuFkux1p6s6l6iioV2yhSG4q/+J3R44jswORI8b64gLf owo17BBbF+nJ+r+MuMQJSd2qZ8Bn4zmxm1qoySXEsy7aX78CFUrMBydR4IEcvyHBCrCo 0Ekw== X-Forwarded-Encrypted: i=1; AJvYcCX/EmE9FibkJAMmszmk25SvXVc3QzfuOEE7HS0+qfD1B4xk132MMLctNxlE4iq2mVCZEdiHPd6cLhaA+II=@vger.kernel.org X-Gm-Message-State: AOJu0YxuVSn77SA/E4/H2e2/Em8580QAwKrE2LZR8ji4ekX4I0cxK1d9 bGD9NE0kXK1ketCvJUIp7rerelrXqCq3JsEe6v5lpADsE+rx/0/JOLbFVKC4Dn9x0hoxJ48D0lr 1KD468aC+5qBihJg/x+d4ew== X-Google-Smtp-Source: AGHT+IFMMEtGICfKL2zb2gyZ0RFhYHt6HTY8hUaeQd7Rm7nNHdZUXNjhKqLZBjHKkTE99BTV5Bzs4Nkm6UF9G/4v X-Received: from wmqa4.prod.google.com ([2002:a05:600c:3484:b0:459:dbaa:93b0]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b19:b0:459:e025:8c40 with SMTP id 5b1f17b1804b1-45b4d7f0ddamr12544005e9.10.1755764077591; Thu, 21 Aug 2025 01:14:37 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:00 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-13-vdonnefort@google.com> Subject: [PATCH v6 12/24] 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) * event integrity (trace_pipe) Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org 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..60bf431ccc91 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc @@ -0,0 +1,24 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote buffer size + +. $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..504a495b3b1b --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/functions @@ -0,0 +1,33 @@ +# 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 +} 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..93d6eb2a807f --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/reset.tc @@ -0,0 +1,105 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote reset + +. $TEST_DIR/remotes/functions + +get_cpu_ids() +{ + sed -n 's/^processor\s*:\s*\([0-9]\+\).*/\1/p' /proc/cpuinfo +} + +dump_trace() +{ + output=3D$(mktemp /tmp/remote_test.XXXXXX) + cat trace_pipe > $output & + pid=3D$! + sleep 1 + kill -1 $pid + + echo $output +} + +check_reset() +{ + write_event_path=3D"write_event" + taskset=3D"" + + clear_trace + + # Is the buffer empty? + output=3D$(dump_trace) + 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) + test $(wc -l $output | cut -d ' ' -f1) -eq 1 + grep -q "id=3D7890" $output + rm $output +} + +test_global_interface() +{ + output=3D$(mktemp /tmp/remote_test.XXXXXX) + + # Confidence check + echo 123456 > write_event + output=3D$(dump_trace) + 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) + 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_pipe.tc b/= tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc new file mode 100644 index 000000000000..f4bd2b3655e0 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc @@ -0,0 +1,57 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote trace_pipe + +. $TEST_DIR/remotes/functions + +test_trace_pipe() +{ + echo 0 > tracing_on + assert_unloaded + + echo 1024 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + output=3D$(mktemp /tmp/remote_test.XXXXXX) + + cat trace_pipe > $output & + pid=3D$! + + for i in $(seq 1 1000); do + echo $i > write_event + done + + echo 0 > tracing_on + sleep 1 + kill $pid + + prev_ts=3D0 # TODO: Init with proper clock value + prev_id=3D0 + + # Only keep + sed -i -e 's/\[[0-9]*\]\s*\([0-9]*.[0-9]*\): [a-z]* id=3D\([0-9]*\)/\1= \2/' $output + + IFS=3D$'\n' + for line in $(cat $output); 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 $((prev_id + 1)) + + prev_ts=3D$ts + prev_id=3D$id + done + + test $prev_id -eq 1000 + + rm $output +} + +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..99f97e100fde --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc @@ -0,0 +1,40 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote unloading + +. $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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 CB5A72ECD36 for ; Thu, 21 Aug 2025 08:14:39 +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=1755764082; cv=none; b=M1ut2wHTRO/7USozV0yT8XDAN+MPePbOK+Uyz3Y9lFEADqh5m0Ady45nnjIP3+cRiiayDe4fslI3NcHYyKCNBAKS9Pl82jo08KiAxpws5Bvtb+6MRcF3MKkkCibHVNkk/VyielDvq42sn/vpkPjZ0mxqk8urlOqw8PteZl19xxY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764082; c=relaxed/simple; bh=tUO2Q5kcwgj+BpbC4GHZDePvRqDVxj7pmPuQyegxsiM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ZzBv+cqY1/fuCw2h0gqQSd/ihSj7bH1lt0STZkFlMG0oroyfUhPjFAWzoPaCeMTBDtNjO5e7NiCsXoZCVrFAGZmFc+ijz+Sh5A8EQ0bypEu85E32ZkholwL3OPISkAvcGMz/yveMBI01ApwJ7e/DSazo4ThKA/9do412QGt6DY8= 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=jLbyTcOy; 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="jLbyTcOy" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1ac1bf0dso4185125e9.0 for ; Thu, 21 Aug 2025 01:14:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764078; x=1756368878; 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=zFT6WngKMwHZUnIYZ6NFySqzw0d5WuAMHkLFTx3V41Q=; b=jLbyTcOywAXCmlqwkK7rCz9RYh4pHSQ0ayZb0ltEY6+aioSbgFe+5KbC+3YSVYoUDo F9SwLwGzB6vsfODM9qbi0M38o+dcRrUM/k2HT1Ma5wy/kepFe5awm51A41KQQEfxvNwe gqI61zpZg8y+Suygsjcc6CW//csNg41iYSJWx1aJjUvoZ5MiRnIPPxShgfR6VMhl3MU4 NdRssbMQb04yyZHHS1+IxpIeLNqeYNjzhvf0/Xu9eWG90DOYvJ8Ytg1ZZZgaOx0LXdhO uhTA9GpKeUaH0ix5pbBTedGaV2mWNKSGvPNenyCu7bnbZBpZV8XqoWFqDFfZPss5m18Q uVnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764078; x=1756368878; 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=zFT6WngKMwHZUnIYZ6NFySqzw0d5WuAMHkLFTx3V41Q=; b=sEydEWb1ya/M9Q6m2njMgFrcx9gkFBQF4E0s/l3vU8d7SKzvv7wyifMd3NsfP4w+sA N+oeGOF/zlHkyHwVvrbs99NJ39hywXJS3YBxSXDIcw9fnjdxqapmc1zhPU5idnEiT3K1 fUQP2Yz66ojyS9ti1VY+DQmigUrSxPdOHPL6SAOT9YeD9pSvyYQWh5+YSrvR7eTAcJGl 8qZyz1v1v0X+NngFFCHxjfC3KZO/19Zr3xrWesjdy1XL4amBye+Q8arEik1gVIN51KRB o1CmuMuNqeD5RAv+ZkKsJdNgkVDGhqjsPAzVqHd4soCR5WwWS9wmB0BRzKoaZDuGP3We Z6jQ== X-Forwarded-Encrypted: i=1; AJvYcCVQj4s115a6+hoyaFiaDJSkvjeWyAB+qisDPxYXot9GiHIW/bCRvdBt91P0jDqM+YdmdshntCR0baxmgBQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwLiV23hwftXbajbCbQ/rSoAXODZlF1UVg60pfLAnQVg95kzoLb LQ6UyN2RSo+HIs/EtI4/WDbZ2/rOy/kAi94NwZYDJPU8uLo6cXoQLCkfC2fmV19YG2ssn7RBG/d rsZMwTnsdqt6iRaLpz5OsfA== X-Google-Smtp-Source: AGHT+IFAQlXPyTnG3JiChKe5DFLBDr2rP8AXh2IodHFt8ePrOH2SUaDoS3AE4kl8mvBz78HTv39+GgQn9/pGZ7FM X-Received: from wmti5.prod.google.com ([2002:a05:600c:8b85:b0:458:715c:51a1]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4710:b0:456:189e:223a with SMTP id 5b1f17b1804b1-45b4d9ea7c9mr10900275e9.10.1755764078269; Thu, 21 Aug 2025 01:14:38 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:01 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-14-vdonnefort@google.com> Subject: [PATCH v6 13/24] 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. Signed-off-by: Vincent Donnefort diff --git a/include/linux/simple_ring_buffer.h b/include/linux/simple_ring= _buffer.h index d6761dc2f404..e74707f10b93 100644 --- a/include/linux/simple_ring_buffer.h +++ b/include/linux/simple_ring_buffer.h @@ -47,4 +47,12 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu *cp= u_buffer, struct simple_ int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable); int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer); + +int __simple_ring_buffer_init(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(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 3efdb895d77a..56b4701979ba 100644 --- a/kernel/trace/simple_ring_buffer.c +++ b/kernel/trace/simple_ring_buffer.c @@ -64,7 +64,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->list); bpage->page =3D (struct buffer_data_page *)page; @@ -290,10 +290,15 @@ int simple_ring_buffer_reset(struct simple_rb_per_cpu= *cpu_buffer) return 0; } =20 -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(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 one head */ @@ -302,15 +307,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; @@ -320,7 +332,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->list.next =3D &(bpage + 1)->list; bpage->list.prev =3D &(bpage - 1)->list; @@ -329,6 +347,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->list.next =3D &cpu_buffer->tail_page->list; cpu_buffer->tail_page->list.prev =3D &bpage->list; @@ -336,19 +362,46 @@ 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; } =20 -void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +static void *__load_page(unsigned long page) { + return (void *)page; +} + +static void __unload_page(void *page) { } + +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(cpu_buffer, bpages, desc, __load_page, _= _unload_page); +} + +void __simple_ring_buffer_unload(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 0; } =20 +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +{ + return __simple_ring_buffer_unload(cpu_buffer, __unload_page); +} + int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable) { if (!simple_rb_loaded(cpu_buffer)) --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 D34E82ECE87 for ; Thu, 21 Aug 2025 08:14:40 +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=1755764082; cv=none; b=b7FKG9TqWSXGzGPZbNh/i7qJ+8dlcN4eWEH04lyC47WLxZgqctFCYysjcpTmnfoESGNFO2vXbftmJ+5G9rcbfGzKN1UaMsv3CfquIO6rPvxe068o46sFXqBp5eWXUrJdh7LXzV/9MWuy9AvNZImNV4NbTXJ42uGKQ4b0BqXajAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764082; c=relaxed/simple; bh=QTf+X2xLBmpOy4zyRAuMjGmCvLxjicUtPQoHjzlz3nE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Nx6x9VLQhYsLIWOXZSYrDGHSLZXxFAksfrc0GasfOBwsbE0T8Lz3geNkLHrHKuAXAUl8YEtlE4AGFzIspUXzsQ8p6U4LCnQIVCJmFaacKkEqWsChlnUuXjSzT3MxunBJF00keg+MyIpXZUbZDSCHqAneW8g6h94Kc0n1DyP8pVM= 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=zVi95W7z; 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="zVi95W7z" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b05a59cso4469455e9.1 for ; Thu, 21 Aug 2025 01:14:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764079; x=1756368879; 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=P1WnKbqGJMz5GKuhjASXO9eryfCuYBOVak1j8VKvvaQ=; b=zVi95W7z0N43mgJSkA4FexmhCNi0ROKa6/bG9br7PurabWZc+YLM7aFFJEqNATA1+4 ACRkSS3iwMmsOAU691q4VUPuVKugD4epXNmEUdf4hJzfuGI1Q2a4QWqa22ZJ1GN5+fcT XsaHiOf9fpYh0AdggIe8VDhUJ0Q4zII2zRIxgy+bFaE5enEK1cJL0OFkMq5ttLaspDr3 fMOCtn/5+WkzoZVvfafrRxCX3ygphBouZxN4S2itxKkVC4AdEAUtVb4rVUFJox3t5fKy UPzwvm22kBJltPtZEU2/rxbhU+iW9MW/a0Y0pxxehKOdANRD/HOk0VLVggE/G6IWogTj ccYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764079; x=1756368879; 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=P1WnKbqGJMz5GKuhjASXO9eryfCuYBOVak1j8VKvvaQ=; b=EbqlEvuj6CpZkUhSTgwI8jXbV1qPXoCnlLILivw3MaIRB/kmsoOJJn7WH1q8Bj4niC 8IgZBon2rWYHjFvC9xgayNykU++fFUFRgW+2P2GhbRKoMYgN0DKl2ouj8LoB6O0jzZLn MRYR+lg/7c70LT7I5BgJWQTfgbTbHdAUb7t5oOhFqKu4u+vKd93mUqMSGgfJuNLxcayh 6PDMMexl+KLaT0tjKCOyAzPSMrUjB+ZM2xcQRPBC6lotnUXL2ohE9YT2FAqa3VcAl0tE LNU2AgsLIHv8XEbS6rdQon0fV97Dxl8A12GvAu4mT0dsmaeZC+TBOxdi8g3uouf8f7Zd urjg== X-Forwarded-Encrypted: i=1; AJvYcCX4yzS1Ie2jscmBHNhpsZ/G1hIuCvNqvZzCmXOPf42wdYyiE5zp8k6Dw0Oin8fl54BZ9ii7kfWhYXb11no=@vger.kernel.org X-Gm-Message-State: AOJu0Yy9/LurKfeHyk1aUE7TRZ6GAczww981lL2NL2rhmWtIfdsNH18B nnY/6k1BiD/TYfBkJMtfaUOVsbS7e2sRzfdmv0uEsjAlV6FeHyf/Xm2vEArxaXPzbk26WCHzO1S OvkNYQ9k04ls9AEeoBGHpdQ== X-Google-Smtp-Source: AGHT+IGDwbMV0G2Q6eX5Ty92Ruu8G0gWgsOI3nyPGZY41v04cwU8/dEgbGIM8RR7KNaNp8Qt7tiVh+uNmLBvDtT9 X-Received: from wmbep22.prod.google.com ([2002:a05:600c:8416:b0:459:d776:c35d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4e51:b0:459:d709:e5a1 with SMTP id 5b1f17b1804b1-45b4dc74ff9mr10294255e9.6.1755764079281; Thu, 21 Aug 2025 01:14:39 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:02 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-15-vdonnefort@google.com> Subject: [PATCH v6 14/24] 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. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 53534447e70b..38523ea2e19b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -114,4 +114,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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 9AA4D2ECEA7 for ; Thu, 21 Aug 2025 08:14:41 +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=1755764083; cv=none; b=d1yZTZJIF3Hx87yMXFgSSG8rWGyVgsadO9LQ8h0ucI/JTVBLotdaEA5FtsRTXkim0ubNS6JiU+e2oW4dFLtCUe3pmyWQnaZy7+04t+shKBBq1s1R1oUY+pbKCXuDnCAYkkWCygiXf3mUYjGIPLSUMdIyHI5wciuD7re6zqzjEIA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764083; c=relaxed/simple; bh=djyw3UFCiwMzV7bmORQp1O1b0BX5/uC4F49iUhOQOjY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Gae7QbGM9RJxF3TSdjaL5X6clcqBQIlI5FncXDPVI8VdqK1pZI1UBk1cZ4UwVo+53CrX1nkyZVZO6c7H8VkQV8MSZ/kvWXLrEQomvfW7UL17NUhRV4Rq76ieUYIdkL2pWlddSAONFC+RdsgnMvFY9ZteeXFRH3armsF3rEyUP0c= 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=PHk00zVN; 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="PHk00zVN" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3b9d41b82beso487394f8f.0 for ; Thu, 21 Aug 2025 01:14:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764080; x=1756368880; 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=MPIqYp3UxnrgGl3qJNmgFxP+ej/sPqPAZCQlcsmkZcU=; b=PHk00zVNN9qJbN+a+QOfJ16QzCETjAAhoWsPVSmkAPIuZBV5ABRICEtEAhDqVB8RXt 0VnI3euFT9PSSk+L6ADA7I1tuqdnHJZzcYuCBHlfP1y5uxe4dubVjh9h4/zaLstlWMLn +XBovied7lKnmpf90us6A7xDL1VfYM0L6jktxpijlWKB8vpTx6vwxUHgsItynJIUydjd 5l10uuIStEbW5fKNVAGSrvputRA/35AXzV8lk/Ezrgpi/RM3YOOpsfxLNesZjS1dPXc9 TvYHMpWtNw7fU43UkL7wOz452echRcEXAgiHpQpH5tVeS+JgW3p5BigPxc0TPAS6QTrN Fz5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764080; x=1756368880; 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=MPIqYp3UxnrgGl3qJNmgFxP+ej/sPqPAZCQlcsmkZcU=; b=tAwmVkUVyR0XG88sgaKb2dccUhIFlI8b3afAnF0uhSQA/MJaiireApkhIRB2voAccB f6JqbqqVl1VT15YqU9JAyuOZeJdqXh2/jgUD8JAniiZPZTGpczMjEZgwTjjAvIFJmWal m1zsa/l2f2Eo9/EPhpjRnS73euw8lWSniGVF96xWyfrl3aWplicNbnSwtMkUrN8HiMnd wRaGZNION9Z4lrM+CkB85ohCXmzlBvklUwxN9s87xIycQwLEa7Y11nDA1x42Zbugt9uJ 8b8/4uLzO4Fku5yosfLFGqxzRZ/A7ndI36PXxa4HeEMPyz6Z46uFYyWvZCwagt+FMBRT c6zg== X-Forwarded-Encrypted: i=1; AJvYcCWMPe8B5GGK22tAGTgvNXZ46ZGpFKd572VOyuSG7vsCwz/d6KfcVtQR9K5Mn+h4SjdjnCatnw/1ON8qAss=@vger.kernel.org X-Gm-Message-State: AOJu0YwFt86U+omHiBGCY2tY1Qnwo4nQsvoHaVEl9V9wY3E0ooBWWIta Wh3v9f2khFEln6+9HyICbHAcEPwyaJGi7K0Ultb02Efq1hMjJxP+FuRKagrgzeJ6Lx7EuyZcRz6 uhnNcuny5OiLMfajQZ/GCig== X-Google-Smtp-Source: AGHT+IFW0oHYaYpDIBDZYmTqCX5wHO/vO6Eo9gvoYMFEfcVe8Gc0SJN49mBNwuBaONnBa7e5yp3hTafs+zGb5o3m X-Received: from wrno12.prod.google.com ([2002:adf:eacc:0:b0:3b8:e019:9f6b]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:220b:b0:3b7:8412:4540 with SMTP id ffacd0b85a97d-3c49596dddcmr1244691f8f.27.1755764080019; Thu, 21 Aug 2025 01:14:40 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:03 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-16-vdonnefort@google.com> Subject: [PATCH v6 15/24] 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. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index ae8391baebc3..75014dc7d82e 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -239,7 +239,7 @@ static void *fixmap_map_slot(struct hyp_fixmap_slot *sl= ot, phys_addr_t phys) WRITE_ONCE(*ptep, pte); dsb(ishst); =20 - return (void *)slot->addr; + return (void *)slot->addr + offset_in_page(phys); } =20 void *hyp_fixmap_map(phys_addr_t phys) --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 33A242ECE87 for ; Thu, 21 Aug 2025 08:14:46 +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=1755764088; cv=none; b=ePyp6ooAplzDyflO9ItXkvnznBFa5yyEU92tJvzaBBSdtyVpj/jjetO580TFGob/oUWyYAI4R1LcClnoW0/HNx3rBlZ5QNQX54MpBC37ZhIAI3p20T2HZN2OXgTe0lNA9+zemqgKZu7RshyzQKWHrCJCaersHsmSBZvt6UbYvXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764088; c=relaxed/simple; bh=ssX6pnv/BMHDiEMq3MmpaclSzI29qITuu1YF5wLH5RY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=duzsGk5bF9jJvu+dD2vYJD9sBMvhmunPbv21lxovBzjiEkt3/uv5lj2h6F3KG1Zivj3hIbIMEHf3MBCNFDpBwFWEs8uQZRRIbY2YNcLROVar/ReNWglzGbhDmLbY2XEICdPygNB3SAqRMJ5zCt4g81ca71R/vgocWnlRxBqdIb0= 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=rNqeDHQk; 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="rNqeDHQk" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9e4146902so284910f8f.2 for ; Thu, 21 Aug 2025 01:14:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764084; x=1756368884; 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=J6PqHQ+VSrJuXFil8vRzl3n00OmPsRbJiS1vDm4o6lA=; b=rNqeDHQkimAUlj+uYuSBK3YH1mLaL7eCdR/saeEeNuuF5Nwky1J1r0sATitJo3p0tw ijHxulxRWb6mOtfYj6fUIf1oVZOLA7ryhrjSbhgfJQqOmEC5b8MNo9LYzVUkc7YlRual 11vIwqmFxx8HWY6pE8QliW6JC1x0k53mqe9wnBykSlqhi2mXiBUuOKJufKjIiKW+l85k eqW8YTnkRqAxby/0yaVkpn2Ui+8pj44Dhe2Sd2Z2l/ie8Oy15PpG8oGQ/PSLL0RICOUe wzr0LDM9nyCSwEH8bPYHOqPt4zEZLkcwPz8PadpWufoi9SNNUJpKWrQPbQcN1q6hfrIr xnug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764084; x=1756368884; 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=J6PqHQ+VSrJuXFil8vRzl3n00OmPsRbJiS1vDm4o6lA=; b=w2xr85GybSiYYqOpJgCybWfalQE9vuTvmNF5zyfc0BLzlt3KSVdEGcM+51s+Vf8wqB Q1qNvePRljh7tJx8THfak+69+WpJqj29+rwxunjVpMhbtT7Wq7ZRoRa/O4ZMzv672OSm 286SWXHP+haAKU5AIYkFbAVtj/vIk+HldtXrqEaG9MIhVVlNF4Lm9ZWYsyfM2atTPFeE gMpdzqZzRSr3PPnRGmKJOuNcaFhROBZz2GR3C1sLQAKuJ2M54OWPVl+9mnnrnbW20qGh c1vxWaS6/gsgGIfc3KrVEoFfcGmKhnQtTyIz1/WBoNK9Ar/LMBoDXVP1R+sdBnJBRkB1 y+hQ== X-Forwarded-Encrypted: i=1; AJvYcCVP4jnBiXzBeX1WVVUyklxhYordcWtpR2JwykSed1L2zTAYdapY+elz6UACUmu6SPrCNfbrN7wua/NJses=@vger.kernel.org X-Gm-Message-State: AOJu0YxoVIMASy5M8aw31TKJMH8/fqUvV1uAl4y8OaXS3w3ZH3GHOM4Z Rb30OnUCjX9FSShnXUyz0B771d99Zo1oEuY6UypO31KAvUOEhV63AkN4LWcK6jwhFosDJAIqS/x pGPD00kHz1OOeO9fPvC0u6A== X-Google-Smtp-Source: AGHT+IHjSHmggKyPUo9IkQhNfhc+5LXvr/ll1IavLoHjTMFXBwqe1Lx+YS0W/l095EMX48jc3sXU+Ed9/HB+3KTX X-Received: from wrar28.prod.google.com ([2002:adf:b1dc:0:b0:3b8:fa02:c0b5]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2d82:b0:3c4:edc0:2895 with SMTP id ffacd0b85a97d-3c4edc02d24mr532633f8f.62.1755764084544; Thu, 21 Aug 2025 01:14:44 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:04 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-17-vdonnefort@google.com> Subject: [PATCH v6 16/24] KVM: arm64: Add clock support for 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" By default, the arm64 host kernel is using the arch timer as a source for sched_clock. Conveniently, EL2 has access to that same counter, allowing to generate clock values that are synchronized. The clock needs nonetheless to be setup with the same slope values as the kernel. Introducing at the same time trace_clock() which is expected to be later configured by the hypervisor tracing. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_= hyp.h index e6be1f5d0967..d46621d936e3 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -146,5 +146,4 @@ 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); - #endif /* __ARM64_KVM_HYP_H__ */ 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..9e152521f345 --- /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_PKVM_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 0b0a68b663d4..607357e36026 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 @@ -28,6 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o +hyp-obj-$(CONFIG_PKVM_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..600a300bece7 --- /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); +} + +/* Using host provided data. Do not use for anything else than debugging. = */ +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_cntpct() - 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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 A63842EF669 for ; Thu, 21 Aug 2025 08:14:46 +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=1755764088; cv=none; b=BYkyBTKTRWqx+D33LHL+f/NtpdRR4YtSIYGKmCP8nLeIMCjjYgDmNDcU5LHKxEvVVpmh/o+SzaB9PMb580TtdLrzRVeKH7VqpKBL0lKjjSyL6sfjYsbD8Mjm+CqE9W1LyyeIAZt31+CXBnR3M1Ryl86MPPEWNHK5wvk8GeBsTfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764088; c=relaxed/simple; bh=VnO5uxAZypvZ2UWGopIwLeZsUhhqxjVgw3yRWhiEeJs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=F6zOjPIItCQFQmyivwsg7ru0I8pkXB8C072gdTKpNBaWTLfGPcNE9iZ6P9EUnT0bLyVV5ofgbwLkAd8jXyUGrx2394S8gfRhHiYp89BLW4xORZ2xFP1UcSOOOCxthORsNEBtglsMMJiWzRizufk2LUsDjjCZqLeIC90Xc7SimZA= 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=uCC0B0N+; 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="uCC0B0N+" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b05d31cso3268415e9.1 for ; Thu, 21 Aug 2025 01:14:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764085; x=1756368885; 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=7ayTXlePj2BFNkEq+sWtJoZ55v9PCeLPmdCVhKrV+hA=; b=uCC0B0N+Mt0Mu75Z3umdx91aAuCWawWFmauXF/twXoLQYEVwCGUZTt07TzwHfJa/8c LG2Wi9DeZ5PjUkH+TS5JMZwhnvLZIyFaZAm73PqHVOGu7OOdQS9An6HhlquE9lIKCWPj SzGIfidUncLEQ0A5c5Kud7ndSS/brFuR3NrzEOgvMdepkL23b8eCw8EIFIa7Cv0MPFBT Wz5zECvvLt9GIt09nMxpDUoBauereXKxCDi/AvQi1WZdITTGG6JWCBfAnV18cUc5Qag3 09orVBqalzX4MIF1pXgDALzdvvmnBY8nEWkN2AvbO2Xkyfb2kcow6PxBRaqB/726p691 F8/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764085; x=1756368885; 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=7ayTXlePj2BFNkEq+sWtJoZ55v9PCeLPmdCVhKrV+hA=; b=hjiXC7C4qRBfee4w9B3C2s8jV+E38MP7H8zOgiI7qlocvVFvIKk3hlbVs8LGxdmtJ4 WiZyEcS5ETekYiwxxdKrUo07/AS+5tU/vAfRBfId9Hgn6NlLM9KJIRA+5IPwB/OKcQr3 MmzbI1zhCPQUcIv8vdqWkqPtmMrOQ/1w7n3cGEn+wJStS0bSURlsHg2mkOHZTIAwouuh qL1SEg2YINXmr+gq32W2aqSZ9a88/v7nj66GtBVamJunvWLhU39uMPbVD1uiTnV/unl6 0EzJB7YVRp5DaRZztHnSVW7VmffIf6nfQIAOrfW/+m4SEicRX9xc5YwlL/0wYJzn3dVg 71+w== X-Forwarded-Encrypted: i=1; AJvYcCWoWc+o2NOfhMMFFAu1rOiBT/WV+nP8a4zA2MoU+9/kLdzOWcoKh1OM4gLEhUTREG3RQSLM65+9K0vpZPY=@vger.kernel.org X-Gm-Message-State: AOJu0YyD2sUmZi7HEv7i87VHurEjtghbkB40lIy5s2HsKuMPWmPoR+2P R6k6RFW+ERGgrxf4qcKL+KZWemQL2pmIczhsJVDALm17RnhS6jFDeKf10Y66Gnb6wpxniISnTWO ZgANS83S7CtBAtuifnwdC6Q== X-Google-Smtp-Source: AGHT+IGJcQsJw2xCT8Ka9WpqqAMGLTb8DX8n1699YgsQ2l/bWtYk3YiUzY/UJzq9mNicwWCB9XjdYINkfgkNTmH3 X-Received: from wmqb16.prod.google.com ([2002:a05:600c:4e10:b0:459:e027:2d9b]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1909:b0:43c:ea1a:720a with SMTP id 5b1f17b1804b1-45b4d7cef1amr9070235e9.1.1755764085260; Thu, 21 Aug 2025 01:14:45 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:05 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-18-vdonnefort@google.com> Subject: [PATCH v6 17/24] KVM: arm64: Add tracing capability for 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" When running with protected mode, the host has very little knowledge about what is happening in the hypervisor. Of course this is an essential feature for security but nonetheless, that piece of code growing with more responsibilities, we need now a way to debug and profile it. Tracefs by its reliability, versatility and support for user-space is the perfect tool. 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 bec227f9500a..437ac948d136 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -87,6 +87,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___pkvm_load_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, }; =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 713248f240e0..06e948d066ac 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -82,4 +82,11 @@ config PTDUMP_STAGE2_DEBUGFS =20 If in doubt, say N. =20 +config PKVM_TRACING + bool + depends on KVM + depends on TRACING + select SIMPLE_RING_BUFFER + default y + endif # VIRTUALIZATION 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..996e90c0974f --- /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_PKVM_TRACING +void *tracing_reserve_entry(unsigned long length); +void tracing_commit_entry(void); + +int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); +void __pkvm_unload_tracing(void); +int __pkvm_enable_tracing(bool enable); +int __pkvm_swap_reader_tracing(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 __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } +static inline void __pkvm_unload_tracing(void) { } +static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } +static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } +#endif +#endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index 607357e36026..e640f12808f7 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -28,7 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o +hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o hyp-obj-y +=3D $(lib-objs) =20 ## diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 3206b2c07f82..02b2fdd9a8e4 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); @@ -573,6 +574,35 @@ 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___pkvm_load_tracing(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 __pkvm_load_tracing(desc_hva, desc_size); +} + +static void handle___pkvm_unload_tracing(struct kvm_cpu_context *host_ctxt) +{ + __pkvm_unload_tracing(); + + cpu_reg(host_ctxt, 1) =3D 0; +} + +static void handle___pkvm_enable_tracing(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(bool, enable, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_enable_tracing(enable); +} + +static void handle___pkvm_swap_reader_tracing(struct kvm_cpu_context *host= _ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_swap_reader_tracing(cpu); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -612,6 +642,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(__pkvm_load_tracing), + HANDLE_FUNC(__pkvm_unload_tracing), + HANDLE_FUNC(__pkvm_enable_tracing), + HANDLE_FUNC(__pkvm_swap_reader_tracing), }; =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..f9949b243844 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +DEFINE_PER_CPU(struct simple_rb_per_cpu, __simple_rbs); + +static struct hyp_trace_buffer { + struct simple_rb_per_cpu *simple_rbs; + unsigned long 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 hyp_trace_buffer_load_bpage_backing(struct hyp_trace_buffer *tr= ace_buffer, + struct hyp_trace_desc *desc) +{ + unsigned long start =3D kern_hyp_va(desc->bpages_backing_start); + size_t size =3D desc->bpages_backing_size; + int ret; + + if (!PAGE_ALIGNED(start) || !PAGE_ALIGNED(size)) + return -EINVAL; + + ret =3D __pkvm_host_donate_hyp(hyp_virt_to_pfn((void *)start), size >> PA= GE_SHIFT); + if (ret) + return ret; + + memset((void *)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) +{ + unsigned long start =3D trace_buffer->bpages_backing_start; + size_t size =3D trace_buffer->bpages_backing_size; + + if (!size) + return; + + memset((void *)start, 0, size); + + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(start), size >> PAGE_SHIFT= )); + + 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); + + return hyp_pin_shared_mem(va, va + PAGE_SIZE) ? NULL : va; +} + +static void __unpin_shared_page(void *va) +{ + 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(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 (struct simple_buffer_page *)trace_buffer->bpages_backing_star= t; + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) { + ret =3D __simple_ring_buffer_init(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 simple_buffer_page *bpages =3D (struct simple_buffer_page *)desc->= bpages_backing_start; + struct ring_buffer_desc *rb_desc; + void *bpages_end, *desc_end; + int cpu; + + desc_end =3D (void *)desc + desc_size; + bpages_end =3D (void *)desc->bpages_backing_start + desc->bpages_backing_= size; + + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) { + /* Can we read nr_page_va? */ + if ((void *)(&rb_desc->nr_page_va + sizeof(rb_desc->nr_page_va)) > desc_= end) + return false; + + /* Overflow desc? */ + if ((void *)(rb_desc->page_va + rb_desc->nr_page_va + 1) > desc_end) + return false; + + /* Overflow bpages backing memory? */ + if ((void *)(bpages + rb_desc->nr_page_va + 1) > bpages_end) + return false; + + if (cpu >=3D hyp_nr_cpus) + return false; + + bpages +=3D rb_desc->nr_page_va; + } + + return true; +} + +int __pkvm_load_tracing(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; + + if (!desc_size || !PAGE_ALIGNED(desc_hva) || !PAGE_ALIGNED(desc_size)) + return -EINVAL; + + ret =3D __pkvm_host_donate_hyp(hyp_virt_to_pfn((void *)desc), + desc_size >> PAGE_SHIFT); + if (ret) + return ret; + + if (!hyp_trace_desc_validate(desc, desc_size)) + goto err_donate_desc; + + hyp_spin_lock(&trace_buffer.lock); + + ret =3D hyp_trace_buffer_load(&trace_buffer, desc); + + hyp_spin_unlock(&trace_buffer.lock); + +err_donate_desc: + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn((void *)desc), + desc_size >> PAGE_SHIFT)); + return ret; +} + +void __pkvm_unload_tracing(void) +{ + hyp_spin_lock(&trace_buffer.lock); + hyp_trace_buffer_unload(&trace_buffer); + hyp_spin_unlock(&trace_buffer.lock); +} + +int __pkvm_enable_tracing(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 __pkvm_swap_reader_tracing(unsigned int cpu) +{ + int ret; + + 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)); + else + ret =3D -ENODEV; + + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 102222EFD97 for ; Thu, 21 Aug 2025 08:14:48 +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=1755764091; cv=none; b=e5F7DRfhSqodCFmV6d9KfuPSgDhCQqJLftKrpRVc1Lnz0Fa7ZH03+qZBrtnc2WQqzShUucB7BmY16AQbmZDCZdQYyr8DudeBhrcY8kVE/VK3NnwSnznPiCZO9W1HduEe2CNsCdpJBcqn+8mVpim93R0FxnOiWGjKD/MbKpE4CUQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764091; c=relaxed/simple; bh=FUH6imkxDCi4I3gFkz3ck34IbFuTrNiyu9+mRmpR7pQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=imP/Jk8zpjf12y5I7qIe1fVl7mhTxfOyPzJD6/ENE+eizloPTmzV0GGIG2duWVkfVfWyI+cGm/4W8jvsfaKPnVXdUs1Ar4pVMyC8o5dR4cTpwtZBqFABB25Av1Tu4A5Px8CHfHke+ncthWVIjjd7+aj+EpurS/Sj1UQoAgDzRj4= 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=mfLJL/+Q; 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="mfLJL/+Q" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b0511b3so3702305e9.1 for ; Thu, 21 Aug 2025 01:14:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764087; x=1756368887; 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=tgkxYrB+MpIo7tw/aQObu59Lalm+q5EVJWz2nMWRK+g=; b=mfLJL/+Q8SKe//Q6vZpVZpAq0VVm6b4PAQs3Qv62HoypuSCVdrVdu1rw6bLHWPBy8a L56QYOHfA0ViVXgxJpqj4Pwh5pWsh8jXZpXK4flm8bwek3j422RD6j4/eS8Ep7On4aFj X6YrV5VYov9m7ypjALGtqpEegBkGN6RsxkhDEvxclUBmnfPGgMUkgnYdCicpXl9rcgmU 0hCwp9gKzeGeddDUsmYoLTB2DwfgVJnzvQOg84buZ1jMQpVzOJMpZihy4nAM9C6TN2Dv GVaku6YM3uFhhipgfBpvRIzJeHgb4ex371KgzytTNcxB583hrginfdGMTTU0A4UdXmK+ RjQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764087; x=1756368887; 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=tgkxYrB+MpIo7tw/aQObu59Lalm+q5EVJWz2nMWRK+g=; b=gcnbwiW2iqiKN7cRAaCUmRYlrCmI8BgYCpbMqJDNxMhJXxqxaqZn4KFF2txz5o+t/H TmxX4QQRlY6yBifoB6jjiR+wmSTtssC+Kao8Us2s+x/zwnafiHs5113UXk5+tarXvA2h Zquv5oVHyqEj5k6KPge4Icha72JIiQom7S3hI53XB6AmQEUo6eLwrxm+11Wli24yPuDB RW4osgWDLGHW7XQoM3wUtWrP0urNdOdUwGTONXiILdRMh8F8AGoQR6F1tp5/695mc2Cw XyIljpQD00H0iq50GAGeCu9AjJnXYzuHJgMcPtowoFKZAT9Pe1gEIKGtq9FwvBpHwpG+ ilyg== X-Forwarded-Encrypted: i=1; AJvYcCWzCq9rMDZIhqPBgUGbBXarpVUerNA1JBMSRsbfQ6I4/MxAw8uzO0bEETncHvmONjbSAIZbeNJOT/zJ10M=@vger.kernel.org X-Gm-Message-State: AOJu0YxcbkgU964LFS9r0torlm7IIlX+s4vK4Z1Yr+UQiE2kUZzv3E6U YALOpB8xlA0BdVR1yzqbq+fPqBwufXtH5cBsz7+8IJ+IeV0/QgUcWdi/rVl/ubpK2vztWRZ9m4+ jAoVt2vrfexajcwneRZK+iA== X-Google-Smtp-Source: AGHT+IGt/d2NUX5G25ppxGElC4inwJH5FSrkUdzwn20XDXOEyGgXcOMKEYA78W6pZtQaW85IHJi/puRRcvNAH0Pa X-Received: from wmbep22.prod.google.com ([2002:a05:600c:8416:b0:459:d776:c35d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3149:b0:459:e3f8:92ec with SMTP id 5b1f17b1804b1-45b4d7dbb5cmr11461535e9.10.1755764087430; Thu, 21 Aug 2025 01:14:47 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:06 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-19-vdonnefort@google.com> Subject: [PATCH v6 18/24] KVM: arm64: Add trace remote for 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" When running with KVM protected mode, the hypervisor is able to generate 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 06e948d066ac..e06358aaf1af 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -86,6 +86,7 @@ config PKVM_TRACING bool depends on KVM depends on TRACING + select TRACE_REMOTE select SIMPLE_RING_BUFFER default y =20 diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 3ebc0570345c..2c184e3abd8e 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_PKVM_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 888f7c7abf54..f1cbd0a09958 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -25,6 +25,7 @@ =20 #define CREATE_TRACE_POINTS #include "trace_arm.h" +#include "hyp_trace.h" =20 #include #include @@ -2330,6 +2331,9 @@ static int __init init_subsystems(void) =20 kvm_register_perf_callbacks(NULL); =20 + err =3D 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..ccac2ecaf96f --- /dev/null +++ b/arch/arm64/kvm/hyp_trace.c @@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#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 */ +struct hyp_trace_buffer { + struct hyp_trace_desc *desc; + size_t desc_size; +} trace_buffer; + +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 0; +} + +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 int __load_page(unsigned long va) +{ + return kvm_call_hyp_nvhe(__pkvm_host_share_hyp, virt_to_pfn((void *)va), = 1); +} + +static void __unload_page(unsigned long va) +{ + WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, virt_to_pfn((void *)va= ), 1)); +} + +static void hyp_trace_buffer_unload_pages(struct hyp_trace_buffer *trace_b= uffer, 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; + + __unload_page(rb_desc->meta_va); + for (p =3D 0; p < rb_desc->nr_page_va; p++) + __unload_page(rb_desc->page_va[p]); + } +} + +static int hyp_trace_buffer_load_pages(struct hyp_trace_buffer *trace_buff= er) +{ + 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 __load_page(rb_desc->meta_va); + if (ret) + break; + + for (p =3D 0; p < rb_desc->nr_page_va; p++) { + ret =3D __load_page(rb_desc->page_va[p]); + if (ret) + break; + } + + if (ret) { + for (p--; p >=3D 0; p--) + __unload_page(rb_desc->page_va[p]); + break; + } + } + + if (ret) + hyp_trace_buffer_unload_pages(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); + + /* + * The hypervisor will unmap the descriptor from the host to protect the = reading. Page + * granularity for the allocation ensures no other useful data will be un= mapped. + */ + 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); + + 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, size, cpu_pos= sible_mask); + if (ret) + goto err_free_backing; + + ret =3D hyp_trace_buffer_load_pages(trace_buffer); + if (ret) + goto err_free_buffer; + + ret =3D kvm_call_hyp_nvhe(__pkvm_load_tracing, (unsigned long)desc, desc_= size); + if (ret) + goto err_unload_pages; + + return &desc->trace_buffer_desc; + +err_unload_pages: + hyp_trace_buffer_unload_pages(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(__pkvm_unload_tracing); + hyp_trace_buffer_unload_pages(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(__pkvm_enable_tracing, enable); +} + +static int hyp_trace_swap_reader_page(unsigned int cpu, void *priv) +{ + return kvm_call_hyp_nvhe(__pkvm_swap_reader_tracing, 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 hyp_trace_init(void) +{ + if (!is_protected_kvm_enabled()) + 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..54d8b1f44ca5 --- /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_PKVM_TRACING +int hyp_trace_init(void); +#else +static inline int hyp_trace_init(void) { return 0; } +#endif +#endif --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 B39762EFDA8 for ; Thu, 21 Aug 2025 08:14:49 +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=1755764091; cv=none; b=thC8gr/WupfiiANDAfvygCCyfp8oJphbaPg/tUpyOXzjcODRu5EAvSceZWAzQNBlmg6Pjh1Qbp4oki2/EqbJtJXVKPvhLtNa+UoSoUAjugQxlkZhq3Yc4rzkLLBFITHNhYVs01CBNQWoPUuprOG2gKxdOoboMwLg3Fymwkr1bQA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764091; c=relaxed/simple; bh=ZXS69v8edIZ26QIhI7me1CrGw+npC1oaFT+S08Gd0Oc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hYdC4zDOsH7Ssyr+mqWfhT4tM8hVnYT1HnTGD+drO0/xtaANCQCim0BTL+Ais1ZPgsHP7DdNDmEqv05Q3beNxUs4mjThTmLZS7obZdwaLmpIR29ps/xV+Lf9rtCDB6ZM+hgvJIKysZy79npM9sHgw+cTe4teI/Oewdf19PAsiLg= 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=gpBwvT3/; 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="gpBwvT3/" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b0b14daso3161685e9.2 for ; Thu, 21 Aug 2025 01:14:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764088; x=1756368888; 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=bw6e+GCDTHY52oVDlwJDbxbyIfuCcjYQhqZ+t+m5jN4=; b=gpBwvT3/9AUjgdPrkdwacno9AiKncBHHps1Lqm4WI32Hz+V3by3C4mssRtzYXkKWlJ XCdZ0zyjR/IocWKNm1bBhCuBs+V7O6Y6b8DTSsXXTNiLlF+nVF7E8i2o5WX0Z7CvR4Mx 21MxwpOLJy7kY8eXk+LTll9DBrYWFmidoybvGHALphzuYN9mHNFUJAYH9ngPL4YHGrUo krPF1an3gp4/TPP37lzspsxfJf4xIiQoVm60DOfPTHejWN4PapkWwsxOeSy3/QpUkv7a 6DkvXj6HtDhDptrhlO4lXv3WblWCNYYY5rfRTSLi9ETFMhpbSGVjLmYxobDi7ESf2SHF 98pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764088; x=1756368888; 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=bw6e+GCDTHY52oVDlwJDbxbyIfuCcjYQhqZ+t+m5jN4=; b=MgmaAp6c7BM3EiSwXGWaDZZDXsl6kzXgoiZ7xZuXEa7VwTFMDD2JxRbJKfSE0wQn4r jqvOYThiJRftQlICrwidV2BlmgNwEA6cbSAHe8mnV6oZiGAbrrSOxqk6Unm2I3sdJsnv 7NeC7XNvfy70FO4F6vrHitfT/WBg2ZkpC3Md9WRH7Lz3VFoUjpepbuHYIlqJi3S4ng5B fKyQA/jJ+LKiMTuoERb4atu8vWTtSqxRO9N2hWWQrdJlvTE78vLTPbOcMbTh8FGk97Qi j9ZJYI7B9NfSO58uuw1P/dIdLZFjRAdpGF2SqK99BNHqVwk4a3+7sASAePNM9D17m4t5 D5gw== X-Forwarded-Encrypted: i=1; AJvYcCWf6EGVQB4C4NcIGqIsM2T3nQRzxGc2vIYPd5AexZ5hF3tjtwofvYUieXgp3kkjWNX5kkicZZRIBsm7Xt8=@vger.kernel.org X-Gm-Message-State: AOJu0YxfBC+wANbzhxyBL6lQkiPsNvTYryZKbzGMR9RGvnVC+p5suORa FPk9fHtMk28WuWajUK1gFg8MKzG0w/Ikantl1oCzyuLmKLRHnNRqKtMctGVNcbbLqSE/UARqQlp TkEnSXfpr3s6nyl/sztChqA== X-Google-Smtp-Source: AGHT+IGPzyA25qFjecHs0gQ3AC9lDwQuyNkudvxzGh8C/ChYR9CdWPMy/jduzoJMim6RpSGZ0sYZZUZnqx/s57xK X-Received: from wmbgw6.prod.google.com ([2002:a05:600c:8506:b0:459:d8e5:ae88]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1c86:b0:456:1e5a:885e with SMTP id 5b1f17b1804b1-45b4d7d4dfcmr12828505e9.3.1755764088239; Thu, 21 Aug 2025 01:14:48 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:07 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-20-vdonnefort@google.com> Subject: [PATCH v6 19/24] KVM: arm64: Sync boot clock with 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 , Thomas Gleixner , Stephen Boyd , "Christopher S. Hall" , Richard Cochran Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Configure the pKVM hypervisor tracing clock with the kernel boot clock. For tracing purpose, the boot clock is interesting as it doesn't stop on suspend. However, it is corrected on a regular basis, which implies we 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 437ac948d136..d122d79718a0 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -87,6 +87,7 @@ 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___pkvm_update_clock_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_load_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 996e90c0974f..4e11dcdf049b 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -7,6 +7,7 @@ void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 +void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc); int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); @@ -15,6 +16,8 @@ int __pkvm_swap_reader_tracing(unsigned int cpu); static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } =20 +static inline +void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc) { } static inline int __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 02b2fdd9a8e4..36a263422e4e 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -574,6 +574,18 @@ 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___pkvm_update_clock_tracing(struct kvm_cpu_context *hos= t_ctxt) +{ + 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); + + __pkvm_update_clock_tracing(mult, shift, epoch_ns, epoch_cyc); + + cpu_reg(host_ctxt, 1) =3D 0; +} + static void handle___pkvm_load_tracing(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); @@ -642,6 +654,7 @@ 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(__pkvm_update_clock_tracing), HANDLE_FUNC(__pkvm_load_tracing), HANDLE_FUNC(__pkvm_unload_tracing), HANDLE_FUNC(__pkvm_enable_tracing), diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index f9949b243844..32fd889315f0 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -249,3 +249,19 @@ int __pkvm_swap_reader_tracing(unsigned int cpu) =20 return ret; } + +void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc) +{ + 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 ccac2ecaf96f..a6664a03f8a9 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -5,6 +5,7 @@ */ =20 #include +#include #include =20 #include @@ -12,6 +13,121 @@ =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(__pkvm_update_clock_tracing, 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 */ struct hyp_trace_buffer { struct hyp_trace_desc *desc; @@ -173,6 +289,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(__pkvm_enable_tracing, enable); } =20 @@ -191,7 +309,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, --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 3E20A2EA478 for ; Thu, 21 Aug 2025 08:14:52 +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=1755764094; cv=none; b=sZ8pMjrU2RaLIy3MYYM+IOIOQ/WeRjk7ihN4r+HwgqcxS0R7aDHPMKw0RF0drJxMm6Wy2I97uPIYmTMklRLXJPKzrze0mjrL38ScLWSZymHR49B+QObhMwgEWGLcfy5zY08Gj+1DlJzxKcx68nxE9WuUGkvqlAkMv7eBBitYf94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764094; c=relaxed/simple; bh=jypk5uOzFJnzT2qErsq1qKMfgdBOaynt2C5kV5nnb8k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=W1C0IzKQ2LZBb1sQVYJjR+aRlKxucMjI1GVCuPTrxWkguilCi09mfY/8BV4gK1iXwFVYiGerPWg7vjRNBEk8hBXBaYMmlvFHWMtcYwwVIVBLVHNpp7HebwT7WMMeYYTIU3tRAfszBWhOPKZM6p3denyIKyiXvLjaQ09zx788M80= 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=FpbwLB8d; 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="FpbwLB8d" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9d41bda7bso563287f8f.0 for ; Thu, 21 Aug 2025 01:14:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764090; x=1756368890; 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=Anc7yfsrkZjtmAwVlWu/raMXGnSP49ufLfjdUKF9Bzs=; b=FpbwLB8dYmMXIs5MFMix0S5p12Vu4pHfAyeWhXqBLzJ3U/dhgQQHGTUaAcqWbpAyAp vt/F9PzzMQS8jS515Q5HMaJfIYz5PmFxOqIO3gGgx0o7IKOGG04bQuGy0fxjb1+ToyMP 0W1QHt+KjYd2BP5FsAp0XTwQv3vAusAqS5BVLpcNpChsEEQ/N1kYlGWgiJ1M5zCE01gW K+TtttceVmPlaZUiGZQWB7ob7Td5vlsxcakvx72defLbJ4+arr4yF+DACaG+zmcy+j1V UWJjtrSEv/0LNRG2xeRf4jMW0aBx0iz74RL9IK6WTLS48a65qUQWdSJL4w4awGmBrmnj Lhgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764090; x=1756368890; 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=Anc7yfsrkZjtmAwVlWu/raMXGnSP49ufLfjdUKF9Bzs=; b=Wy4lT/i8HOHmeN2mBoyIY8rKR/WkXwdxMc8oU+Bowh9yDN/wsBj4JfKp005XNLhHN8 NMoGhGBixN6CPeVilBvXx1KB497z/IXZwDP/VZvFUTH/E77hUqrouHJg8BV0dEMh3w2E Y00qktumxzWJcY9e2vxOjVeRUcBqIz4/Ff0TLVPFGLDZYh4DHzB5zSZjItUPynCf9jGs e2HrQ7OUXiO5TPyraCLnWao7upNNUPdj15nFHv0OjYG3+l+R+0u2prdaqhNBcj9HBWGM /pCyLHyqn9JA9T9byNgnib8m1hzs5nxjNu9RRYh6+y8DifTDxMv9qXV4K3JpKEruRuiU R9YA== X-Forwarded-Encrypted: i=1; AJvYcCUSzYo6WvvK5L998UvAb8EeKgUt9r8VSx1q1NdAodvK+JZ7eQdWUs/EPnn9RKvAwmFwCEd9RabqeZhzKYo=@vger.kernel.org X-Gm-Message-State: AOJu0YzWRFua2GukoyvHjUWtFb3KEnVUa9JaWUXBhN58Z1To/yZCucCG yVReUzenh+Vlfpe/dCvXzqdXgbdwrEIYnW2Uyp6xiyw4sracnj4L6hcWWB8ZVoEE3Q+7yoLi/LI bw4vhFl/IwzNbqy1qWjaS0w== X-Google-Smtp-Source: AGHT+IFe/ozybAk7VIdtcz4OiVN8ypSFB84+/HqOqWcPlIw7lP5kraFDV++Jsyd/28g3gn+e5nGHBsqAwfa7Z6+X X-Received: from wmbet4.prod.google.com ([2002:a05:600c:8184:b0:459:ddf8:fed5]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:1a8d:b0:3c3:5406:12b8 with SMTP id ffacd0b85a97d-3c497836ba0mr1259766f8f.60.1755764090639; Thu, 21 Aug 2025 01:14:50 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:08 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-21-vdonnefort@google.com> Subject: [PATCH v6 20/24] KVM: arm64: Add trace reset to 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" Let the hypervisor reset the trace buffer when triggered from the tracefs file remotes/hypervisor/trace. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index d122d79718a0..c40820a4b049 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -91,6 +91,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_load_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, }; =20 diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 4e11dcdf049b..0d2732f0d406 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -11,6 +11,7 @@ void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64= epoch_ns, u64 epoch_cy int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); +int __pkvm_reset_tracing(unsigned int cpu); int __pkvm_swap_reader_tracing(unsigned int cpu); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } @@ -21,6 +22,7 @@ void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64= epoch_ns, u64 epoch_cy static inline int __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } +static inline int __pkvm_reset_tracing(unsigned int cpu) { return -ENODEV;= } static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 36a263422e4e..a7c5e9fc27a0 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -608,6 +608,13 @@ static void handle___pkvm_enable_tracing(struct kvm_cp= u_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_enable_tracing(enable); } =20 +static void handle___pkvm_reset_tracing(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_reset_tracing(cpu); +} + static void handle___pkvm_swap_reader_tracing(struct kvm_cpu_context *host= _ctxt) { DECLARE_REG(unsigned int, cpu, host_ctxt, 1); @@ -658,6 +665,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_load_tracing), HANDLE_FUNC(__pkvm_unload_tracing), HANDLE_FUNC(__pkvm_enable_tracing), + HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), }; =20 diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index 32fd889315f0..b6d97237a7a0 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -230,6 +230,25 @@ int __pkvm_enable_tracing(bool enable) return ret; } =20 +int __pkvm_reset_tracing(unsigned int cpu) +{ + int ret =3D 0; + + 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)); + else + ret =3D -ENODEV; + + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} + int __pkvm_swap_reader_tracing(unsigned int cpu) { int ret; diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index a6664a03f8a9..5c115c3a26a1 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -301,7 +301,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(__pkvm_reset_tracing, cpu); } =20 static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 3CCDD2F1FD6 for ; Thu, 21 Aug 2025 08:14:52 +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=1755764095; cv=none; b=olIGy2/GRv8BmKSU+tdoc6yxz45innxz61JgioxANnraoi9AC9vGc4de+5iG9OLvxiYT05xdZ/VauEcdfl9//+hPTNjjAGRCtLSYPLsR1IsTDCLMoP0GVhRGADUYpVYGC0Qwu6wAiDRh7XZBkh2k8o1N9Ek+Et9kcGpdQPyRczM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764095; c=relaxed/simple; bh=xCjP4UPoae7h1KHET481f8F6AEah+yJZ+afWMmAaRE8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=V/j2MTrxafltRPldAliEjxgGM88KeHq5bGQT3nRXCBeshR3YxUQxQD1ooYe+rXH6qL3DJf1Nke2gPhlEgYbrBG56nqHjvu11hxP8absxWeeGHVHBubbCIEuEbolwLMRQ5Z0RfQLHsmbY2+cRKhAOarMC7Hks1TZcdCpwOUnPQ4w= 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=zjdITSEb; 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="zjdITSEb" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3b9dc5c2c7dso293311f8f.1 for ; Thu, 21 Aug 2025 01:14:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764091; x=1756368891; 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=RvlkOof9BhdULODFcFYZLZ0zkKVYmrrnaXZnqMcZLiQ=; b=zjdITSEb5VHTE3j8qgO3J1utMetxEmLQPg/9WxTmKDBzAj9nVhB7hFkUsKi0SuAvwJ 6WsVnuM3PpZifqFt4JJN5NNxM5meinJMSO1YFlY32+X2YFWHJAPEtzC/zcUbE3Q1L+xR +Wiz9kjExhPh0bDV2psdRXZfFOByGJEHIiS68a7yD0bVEqjz9hQuFteuxnd7am+GcTSQ vIEiOh86nmwS2HSAH/ulZ/hi49t7WT4h9PwdcDGC9xZH9yU2b41bCpcla2pSVEZBaANb pV7enRZq9eFz3d/BRAQnMYfEsVXpcGdWG6xeOddhmVact/9HUvnXuJbF0G04rw1Q/qrz HFCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764091; x=1756368891; 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=RvlkOof9BhdULODFcFYZLZ0zkKVYmrrnaXZnqMcZLiQ=; b=Sa890m8l3W3ycxvr8mTWRT2f0mEfUvpkReObTp8RASa2f8J8ynM8cbgHyMVqSzf70T btCtCRI6D3V12qbJD+R5TTn3vtA+VryLk25iamo5H27wIcK993E2bDZ9AfVlaj40vELM mjwOTa8qcbctQtbUPA50B2LFeqIUN947ip2HXoak7yE3gA7kqVZtmaWl/1Ed7knTOdf4 BUp5cmwsaMWpXRl3ZpFzCX4Em4A2j7Hti+P0CSjguhWRSLdHP9KRg/9MzUOUJ6OkxZjy G5wRZbUGXAQD9YOtQyIOFPDZMXKfqo/klhLY6xVPWRKzkE4oipktfwW3V16nIVIRX2H/ miRw== X-Forwarded-Encrypted: i=1; AJvYcCU+qMgRZp62lQ+nneQ78XWfM7DXUUvbzh26QqrQM90azTBrTUzihuv4484zrmyiuBFTqm5fWgGGqDvnksU=@vger.kernel.org X-Gm-Message-State: AOJu0Yx32MYaCb316+tuJ8J2clDXFohHIxPkAmjZ3Z3eYaZ8JZ6dy1WH U5K1WRZ4d1ZobdCHbFWMNV2j9D5NGdtUy/4FRiK6CQ7++YeX/uP1+EyE+SuNfD9WRxFFm8/AjMH eDWHbcBEeyl1mGyoy4vIDcg== X-Google-Smtp-Source: AGHT+IH9bUuIY/+B3HVQ/HDva67v8CDnFdrOCAq/yK7DKHdq1j08ba1nbcMIkwUPn616fbydzz2N/zeC4KI/Lvk+ X-Received: from wrd27.prod.google.com ([2002:a05:6000:4a1b:b0:3b8:e18f:57f8]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:22c4:b0:3c0:7e30:a95f with SMTP id ffacd0b85a97d-3c497741c5dmr1226742f8f.60.1755764091369; Thu, 21 Aug 2025 01:14:51 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:09 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-22-vdonnefort@google.com> Subject: [PATCH v6 21/24] KVM: arm64: Add event support to the 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 c40820a4b049..79019e11f529 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___pkvm_enable_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_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..0ef5a9eefcbe --- /dev/null +++ b/arch/arm64/include/asm/kvm_define_hypevents.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef HYP_EVENT_FILE +# undef __ARM64_KVM_HYPEVENTS_H_ +# define REMOTE_EVENT_INCLUDE_FILE arch/arm64/include/asm/kvm_hypevents.h +#else +# define REMOTE_EVENT_INCLUDE_FILE HYP_EVENT_FILE +#endif + +#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 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..d6e0953a07d6 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; + void *data; +}; + +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 714b0b5ec5ac..c1dbf0d317db 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -134,6 +134,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_PKVM_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..0e201a3c8de5 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_PKVM_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_PKVM_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..2298b49cb355 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef HYP_EVENT_FILE +# define __HYP_EVENT_FILE +#else +# define __HYP_EVENT_FILE __stringify(HYP_EVENT_FILE) +#endif + +#undef HYP_EVENT +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + atomic_t __ro_after_init __name##_enabled =3D ATOMIC_INIT(0); \ + struct hyp_event_id hyp_event_id_##__name \ + __section(".hyp.event_ids."#__name) =3D { \ + .data =3D (void *)&__name##_enabled, \ + } + +#define HYP_EVENT_MULTI_READ +#include __HYP_EVENT_FILE +#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 0d2732f0d406..f7b286e92853 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -1,21 +1,52 @@ /* 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 + #ifdef CONFIG_PKVM_TRACING void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 +#define HE_ASSIGN(__args...) __args +#define HE_STRUCT RE_STRUCT +#define he_field re_field + +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + extern atomic_t __name##_enabled; \ + 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(&__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 __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc); int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); int __pkvm_reset_tracing(unsigned int cpu); int __pkvm_swap_reader_tracing(unsigned int cpu); +int __pkvm_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 void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc) { } @@ -24,5 +55,6 @@ static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } static inline int __pkvm_reset_tracing(unsigned int cpu) { return -ENODEV;= } static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } +static inline int __pkvm_enable_event(unsigned short id, bool enable) { r= eturn -ENODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index e640f12808f7..09bb8dfa7ca2 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -28,7 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o +hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o events.o hyp-obj-y +=3D $(lib-objs) =20 ## 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..5905b42cb0d0 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/events.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include + +extern struct hyp_event_id __hyp_event_ids_start[]; +extern struct hyp_event_id __hyp_event_ids_end[]; + +int __pkvm_enable_event(unsigned short id, bool enable) +{ + struct hyp_event_id *event_id =3D __hyp_event_ids_start; + atomic_t *enable_key; + + for (; (unsigned long)event_id < (unsigned long)__hyp_event_ids_end; + event_id++) { + if (event_id->id !=3D id) + continue; + + enable_key =3D (atomic_t *)event_id->data; + enable_key =3D hyp_fixmap_map(__hyp_pa(enable_key)); + + atomic_set(enable_key, enable); + + hyp_fixmap_unmap(); + + return 0; + } + + return -EINVAL; +} diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index a7c5e9fc27a0..aebed41f7de7 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -622,6 +622,14 @@ static void handle___pkvm_swap_reader_tracing(struct k= vm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_swap_reader_tracing(cpu); } =20 +static void handle___pkvm_enable_event(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned short, id, host_ctxt, 1); + DECLARE_REG(bool, enable, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) =3D __pkvm_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 @@ -667,6 +675,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_enable_tracing), HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), + HANDLE_FUNC(__pkvm_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..a68411bf4bef 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_PKVM_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 5c115c3a26a1..70c0939ebc6a 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -306,7 +306,7 @@ static int hyp_trace_reset(unsigned int cpu, void *priv) =20 static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) { - return 0; + return kvm_call_hyp_nvhe(__pkvm_enable_event, id, enable); } =20 static int hyp_trace_clock_show(struct seq_file *m, void *v) @@ -333,10 +333,27 @@ static struct trace_remote_callbacks trace_remote_cal= lbacks =3D { .enable_event =3D hyp_trace_enable_event, }; =20 +#include + +static void 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 (; (unsigned long)event < (unsigned long)__hyp_events_end; + event++, hyp_event_id++, id++) + event->id =3D hyp_event_id->id =3D id; +} + int hyp_trace_init(void) { if (!is_protected_kvm_enabled()) return 0; =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.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 BCA7F2F3C2F for ; Thu, 21 Aug 2025 08:14:55 +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=1755764097; cv=none; b=rwFz1FygXLLxskTLnV2wchUfGVGZq5yWdNWEhWsJy4v+77oaZdQF3pjnEb7TDbFnxHuiY9ptlPZWS8hhGMVgShwANK4k+LD/e/NYWK2N158DoxF11a1b3x/soQJ9VoMkNbkTfv4tGQx7vs+j+V4EJvO29X0XcqODgyGfgQTVMtw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764097; c=relaxed/simple; bh=GYhMRL/4BrKlzUJdbWBycxCFy/OOj1KxnU0mfovQ03k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DH7Hp1GT4asnG975Kd2FuHjREn0R893Zp2PCAr09K27REZTTQA0Uq5HD/U3d+NkmGUIEZx7yoDz8nOO2V1acLIWHCrpfKfSeqO2SXRHWVdbYFs5SJzy9RS5m6Tgw1vKclvct/NKmfrntP0cp52NtLJE4L+JoaB5W0A7KnZ/BRK8= 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=2MqKVAdR; 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="2MqKVAdR" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b05d8d0so4076355e9.1 for ; Thu, 21 Aug 2025 01:14:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764094; x=1756368894; 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=VJuYw9YtOUTxOKcJe9GYPUdg6A5eauGTuxfSWUfKtck=; b=2MqKVAdRgLLeGy1UPVZEXsfuCy8vJecuUR29EV8FBifjZxuBtPEFHhxgeWIznlXk6T RvtWxHW6InR0UA+9+rn6DsMmhhUqve4E1XUeu62D/7ql42uyY5TUdyFHxqQh1jhh8Tdf 5Vp4OfYrf7L+PgyI+hKi5q6r+A8VSpfoDap7XbtDIGCV+lLYr4h+UZ+K9bLbwuSmxDYP gvtj587nVkp77BMlcFh9S9+6R7w0HzD8/UPPnWF7niCP7tLjY7yhq7bOVd6mMeLH7huj oirMbXUNV7kUKWIWFZ95DW/sm9DMGVNurl+7oSRO0nI44sTfojIaUBsm9WBwhVjtGBv2 YoYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764094; x=1756368894; 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=VJuYw9YtOUTxOKcJe9GYPUdg6A5eauGTuxfSWUfKtck=; b=BDuNQtk+xh0iGp0dJfD/2g70IjVDmd+0dEpT7g/WgewTmbiXFqcHIJGpIeOYqdedld n6CzAp969KNE9djEFCPQfIr2zb8oKAjw4AkCJyI5/Olf/sjUybhWmghXmrvoVa8aobIL 3kJ9Av8a3lxbAphDUx6DE5t9qel3qto+Zbn9464JzvYwRO4n+nOakt+TDI4Sr50M1hGI +jFcdw8dXZyIsegTAeZtgK//L5Q/xfkGjFpC5SLJUq0j02KTf4VJ/E0YnjBOw29CuC8m FNkhCC74ukW+V+MxsLouQRi5ofcIF6OP4olvEK1vPaziFakmyKN1i6V7ICKfG78xUn9b kblA== X-Forwarded-Encrypted: i=1; AJvYcCXQhqWtXRvzx9Z2v75QRSvTiDuzX0hGJabWctA0Bm/1n2AIzqAmVtWDTr7YWQozOd5BGtp8Zu0Emh51A2k=@vger.kernel.org X-Gm-Message-State: AOJu0YyIvPa1rBSVvzlWLzPNq5fCEnRdaWAkD4nc4OBZ6ga5h/c0Yups /k4QcRZmuQ28cnIhZj+cU2o5ETaFslVyQmINfnJMPms4VROeTRrYdXhKnU8IDU4HB4O8W2oaE25 Ezv16nImCDwsxlSKcwRaLvQ== X-Google-Smtp-Source: AGHT+IEinA++oc/gQDS+j3wuYMFfToMe5DnZzzdAdhRTYs5/w3tHItN2vCEdHVa+TZ6bcaADQEZqE25FZvUvHW2b X-Received: from wrbcm4.prod.google.com ([2002:a5d:5f44:0:b0:3a5:648f:da85]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2404:b0:3c3:973a:fe3d with SMTP id ffacd0b85a97d-3c497838009mr1125897f8f.59.1755764093978; Thu, 21 Aug 2025 01:14:53 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:10 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-23-vdonnefort@google.com> Subject: [PATCH v6 22/24] KVM: arm64: Add hyp_enter/hyp_exit events to 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_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h index d6e033c96c52..ce3953bc884a 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -7,4 +7,21 @@ #include #endif =20 +HYP_EVENT(hyp_enter, + HE_PROTO(void), + HE_STRUCT( + ), + HE_ASSIGN( + ), + HE_PRINTK() +); + +HYP_EVENT(hyp_exit, + HE_PROTO(void), + HE_STRUCT( + ), + HE_ASSIGN( + ), + HE_PRINTK() +); #endif 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..4b69d33e4f2d --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include + +#undef arm_smccc_1_1_smc +#define arm_smccc_1_1_smc(...) \ + do { \ + trace_hyp_exit(); \ + __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__); \ + trace_hyp_enter(); \ + } while (0) diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 3369dd0c4009..e00931fd194f 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 diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index aebed41f7de7..f8361520967b 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 @@ -716,7 +717,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(); __kvm_hyp_host_forward_smc(host_ctxt); + trace_hyp_enter(); } =20 static void handle_host_smc(struct kvm_cpu_context *host_ctxt) @@ -740,6 +743,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) { u64 esr =3D read_sysreg_el2(SYS_ESR); =20 + trace_hyp_enter(); + switch (ESR_ELx_EC(esr)) { case ESR_ELx_EC_HVC64: handle_host_hcall(host_ctxt); @@ -754,4 +759,6 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) default: BUG(); } + + trace_hyp_exit(); } diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe= /psci-relay.c index c3e196fb8b18..64d1d418df1d 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 @@ -205,6 +206,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bo= ol is_cpu_on) struct psci_boot_args *boot_args; struct kvm_cpu_context *host_ctxt; =20 + trace_hyp_enter(); host_ctxt =3D host_data_ptr(host_ctxt); =20 if (is_cpu_on) @@ -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_enter(host_ctxt); } =20 diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/swi= tch.c index ccd575d5f6de..e51f431e8b23 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 @@ -302,10 +302,13 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __debug_switch_to_guest(vcpu); =20 do { + trace_hyp_exit(); + /* Jump in the fire! */ exit_code =3D __guest_enter(vcpu); =20 /* And we're baaack! */ + trace_hyp_enter(); } while (fixup_guest_exit(vcpu, &exit_code)); =20 __sysreg_save_state_nvhe(guest_ctxt); --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 904262EAB80 for ; Thu, 21 Aug 2025 08:14:56 +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=1755764099; cv=none; b=GKC827jKZTzUTd9dh1CNdjYEhlmVNGDLFYqTCYeXfU4wCIEhHpP1RSBedD3YxkfGgco54Bi6G5EY2OUq+Ro5uvHfwBR/5U437YEpqriiwZ3G9otisFAwiq/1/vJc3c2AQpBah9cTyk1RKSFMSJDIMz9KCU4GjC2XKiCO3M8G7dw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764099; c=relaxed/simple; bh=VN6dK6H7Zc4iEnBzTtDQa6gXAMoJpEbsVnVKSYbAq0g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RfSfxzq0+THsnw0mluhLSQB3EuTpCNetsCmPf+clxbNkmhY+bDNwF+hRW4HVYYldp66j1EmF268IFHWbseDKr8c7hYsGKjqHL1I6lZZzqZ/QbkUT65BaQNVSaidJaj1Fv2s2/YENeVzBMzOH/FV+Zv7W/AKIaiPJ1zuF+hi26w4= 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=XI32oti1; 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="XI32oti1" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-45a1b0c5377so3307295e9.3 for ; Thu, 21 Aug 2025 01:14:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764095; x=1756368895; 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=eOFNDacMW6nvsJMgDPU7r8kmdvWL23ZcJqIAku3JKRo=; b=XI32oti1wJVXAOuCJQ87o5JbxzELz9R29+CTZZPMdrvnHsIPWm74Kq9wMPTajg1jt8 Cmab8kfqYcWyZfp49xx4J3q21ZQ6DfunMAHuhczUYc976W3OGv6nur1jfti7EyqYfG6c UcHSBNXXRzCHQrRaiFHLxlkOAOf8v8HNCbVcGlONea6dgSnfd3UP6+9euSkIOu4s8vtY aShc58yfL4kVED2vRHIeL6Geth8/3G5O1eo4G3lnBRCXVzDByNNaCMNsDzS6MZgne5JT qWs63H8dHd3Ib+YS39XN6kJZo6nAfzmFkzGK+VuLHxsfTzvGjIoGTWXxLZwRO5sRUVsN D6BA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764095; x=1756368895; 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=eOFNDacMW6nvsJMgDPU7r8kmdvWL23ZcJqIAku3JKRo=; b=HJv5Q1D0Uuk/nzyA3QweQDvkLa2ROEwZ0i9I173dfBZbgoRk3zHeYgPobauX35wV/+ nmuAjv9RcwOUIfJCVmzvZ1OJk1T1O3HJJgZ7UbFy7jgsILiAvYefWhW/tCdokVCa/GA4 Cz/F89y46o83K6UvD1Rv/8967izjWSdCdjNXmfSEZhfrTkCLNZsq7WWz6fDWxp+at4sP PTXizNTGfFRCrqazSUl3/HDNFI9hsEgPpXhVw0DrjqLesp3uzB72dIMM5t+P3icwCUZl 8Bf4kriIkVJOTMZuLMa8MOBNWzgFgxhmkVx0UG2aFz+9zLDPezMDucuD1bemkq36aX3e cULA== X-Forwarded-Encrypted: i=1; AJvYcCVM/q86G+kYwr6FhifCrWqbKcRgLThE8m0uXLd8q3oexHqgR4NsJ8cPeOTZy7R0DILkNV0Qm37/LDg+KqA=@vger.kernel.org X-Gm-Message-State: AOJu0Yxcwgr44L0OVlRORciJLAR/8L7GVECLEARP0TOJPIdBB524ZGtr hW0wgTZ5p45+6qlaTNlzFHaufB3QPa8k6/pAVD+vVaBvONC2w5tAuNl3hk0M7/nxW4TAIKLOVfx broAvl9BqhDZvNJOZyMdfNQ== X-Google-Smtp-Source: AGHT+IFBwm4nsjQFbZ2TuWuaXuLzNFlXoEJJyhjLRg44n+oKsrUh+xl35jfaVRxhiG9z7P8qTxgzFlBgbH+883qw X-Received: from wmbes8.prod.google.com ([2002:a05:600c:8108:b0:459:da33:b20c]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b84:b0:456:1904:27f3 with SMTP id 5b1f17b1804b1-45b4d85b22amr11092705e9.18.1755764094894; Thu, 21 Aug 2025 01:14:54 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:11 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-24-vdonnefort@google.com> Subject: [PATCH v6 23/24] KVM: arm64: Add selftest event support to 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 79019e11f529..522cccef32b7 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___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_event, + __KVM_HOST_SMCCC_FUNC___pkvm_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 ce3953bc884a..3d1244972869 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -24,4 +24,18 @@ HYP_EVENT(hyp_exit, ), HE_PRINTK() ); + +#ifdef CONFIG_PKVM_SELFTESTS +HYP_EVENT(selftest, + HE_PROTO(u64 id), + HE_STRUCT( + he_field(u64, id) + ), + HE_ASSIGN( + __entry->id =3D id; + ), + RE_PRINTK("id=3D%lld", __entry->id) +); #endif + +#endif /* __ARM64_KVM_HYPEVENTS_H_ */ diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index e06358aaf1af..dc2ac3049428 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -45,6 +45,7 @@ menuconfig KVM config NVHE_EL2_DEBUG bool "Debug mode for non-VHE EL2 object" depends on KVM + select PKVM_SELFTESTS 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 @@ -82,6 +83,15 @@ config PTDUMP_STAGE2_DEBUGFS =20 If in doubt, say N. =20 +config PKVM_SELFTESTS + bool "Protected KVM hypervisor selftests" + depends on KVM + default n + help + Say Y here to enable pKVM hypervisor testing infrastructure. + + If unsure, say N. + config PKVM_TRACING bool depends on KVM diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index f8361520967b..81d8628a9047 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -631,6 +631,20 @@ static void handle___pkvm_enable_event(struct kvm_cpu_= context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_enable_event(id, enable); } =20 +static void handle___pkvm_write_event(struct kvm_cpu_context *host_ctxt) +{ + int smc_ret =3D SMCCC_RET_NOT_SUPPORTED, ret =3D -EOPNOTSUPP; +#ifdef CONFIG_PKVM_SELFTESTS + DECLARE_REG(u64, id, host_ctxt, 1); + + trace_selftest(id); + smc_ret =3D SMCCC_RET_SUCCESS; + ret =3D 0; +#endif + cpu_reg(host_ctxt, 0) =3D smc_ret; + cpu_reg(host_ctxt, 1) =3D ret; +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -677,6 +691,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), HANDLE_FUNC(__pkvm_enable_event), + HANDLE_FUNC(__pkvm_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 70c0939ebc6a..5b5d17a47ecc 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -317,8 +317,34 @@ static int hyp_trace_clock_show(struct seq_file *m, vo= id *v) } DEFINE_SHOW_ATTRIBUTE(hyp_trace_clock); =20 +#ifdef CONFIG_PKVM_SELFTESTS +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; + + ret =3D kvm_call_hyp_nvhe(__pkvm_write_event, val); + if (ret) + return ret; + + return cnt; +} + +static const struct file_operations hyp_trace_write_event_fops =3D { + .write =3D hyp_trace_write_event_write, +}; +#endif + static int hyp_trace_init_tracefs(struct dentry *d, void *priv) { +#ifdef CONFIG_PKVM_SELFTESTS + tracefs_create_file("write_event", 0200, d, NULL, &hyp_trace_write_event_= fops); +#endif return tracefs_create_file("trace_clock", 0440, d, NULL, &hyp_trace_clock= _fops) ? 0 : -ENOMEM; } --=20 2.51.0.rc2.233.g662b1ed5c5-goog From nobody Sat Oct 4 01:41:10 2025 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 E767C2F5334 for ; Thu, 21 Aug 2025 08:14:57 +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=1755764100; cv=none; b=t9U9E94qp77zVrl9MJLmMNsZQNTDpLekqKOPp8Vh+8R8l/E3raijaXIfNUfb6tvK85PcmBDwRT3i9m5V5sAOJ8CqFQAuc59QS1pFBOP0y7Pg6NHYweP5ithJuE24YkHyB747r6v/6yyOV4bMlACWPGmnPYe7DnqgCSOyt8qD54M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755764100; c=relaxed/simple; bh=3KMoWYrKCS9iXFyZU23vQdmkGsH1bjakmfocPm6yigk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sM7p2yN0g0irgKwP1uyea5SCxzqHjK02h4zqTdvRZzE2EjtNIqMFHCUGsvjHjdx6VyRZtK4hUvz0bKMGBByEUH0kGn3wJN7vXcMksffe9eXzmTcZyBqwaoD3zXeyNEWxH/YoARTXS/m3M6zseNwytPXhihg5guJgM+/fCie1oDQ= 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=hM0UtY8/; 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="hM0UtY8/" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-45a1b0511b3so3703475e9.1 for ; Thu, 21 Aug 2025 01:14:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1755764096; x=1756368896; 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=lXmeaJhI9e99CmL9wkkDfiednrjI4qTS7gtaFJx7Vrs=; b=hM0UtY8/PDxLvU684ct/gumgTLbeTeQm8/iI37L77iHdMsdCmx9css7YopzJmmniVO 1R4pd6QNIM1fu1o1z9kyaLS5DRjS9Q/FN4oI2TPopv+2erXcwNtRpfVTOc0USIfFbGYv 3yWqg2+c0mmPKsbEbF6wO56HneUz/I3aX8b727tmFomieVEKKGglITHu3HfRoaZV9zfR nXYnMNy2JPggizwZfD6yLr+skdPBeRYHSaJsZkH51cDuCCWbfPNrouze1Qb++Q23jcWT yXvrtWq/HV+NDArRW1sAYevoN/Qk46HEzFFCU3oNO1x5ukH5HzvjU3+TX5VNwCApSKNf QwHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755764096; x=1756368896; 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=lXmeaJhI9e99CmL9wkkDfiednrjI4qTS7gtaFJx7Vrs=; b=s6yGpjaELkEQgD3EBF2D8EaJB1vSIIvMD1Li7lskq7grCzUCxl23yhTZWT4mZBHlK0 Zxr1PhTbhewV7zbD2GSCz7iGrcCPIdBskf/RhQiQz3v4HELZtJw3oaA6dug//9b7bbux OSTIHXl216Tx2BjK4fjVZ08GdmoKnGgBBDIr3psnBEh9uarBexad58TucHSbOjzoUfk6 rSNS7w2OR9LcO5mt8MJCBh6Twoa08V1wqLj7EBRl1Xl34w7Lm8KznmiZR9nO33oYa0LC PdYfiYO0ncz3JTI4i/Geqj5w0XeKIFRteAXT4Cx2WLjrBPPNDH2mDdW2BhHaLpjHEuId BT4Q== X-Forwarded-Encrypted: i=1; AJvYcCVtlLuyLflkJfq5IGysEanbMj/EvVJjprKfoMRsy8SHbQtdvHsEIplW1jxRq0KFsHdiSsZfEyLqws6jU2Y=@vger.kernel.org X-Gm-Message-State: AOJu0YzwPiJQ1nbPmSvvjN4XEpg6xeqUX1pum8i+ZK+fui0uZlHS4baz WgmPURdEBdL8mU+4VXCAvehd87JAqVPg7M04yvezRpYjJ20i437NG6UXXjXSFJt4pS3ye7sZuyO QkCnU/1UIONFxtUEClOPqcg== X-Google-Smtp-Source: AGHT+IHVkLSbuPXaBGbeYxLB8Apzj2J/LjIQ1ACzqcVV+IhVmKpANZi8n0fKVREaY1XDOmHvrY0P+LX9S3g8rjan X-Received: from wmcn3-n2.prod.google.com ([2002:a05:600c:c0c3:20b0:45b:4777:8063]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a46:b0:45b:47e1:ef79 with SMTP id 5b1f17b1804b1-45b4d869ceemr12017085e9.36.1755764096134; Thu, 21 Aug 2025 01:14:56 -0700 (PDT) Date: Thu, 21 Aug 2025 09:14:12 +0100 In-Reply-To: <20250821081412.1008261-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: <20250821081412.1008261-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.rc2.233.g662b1ed5c5-goog Message-ID: <20250821081412.1008261-25-vdonnefort@google.com> Subject: [PATCH v6 24/24] tracing: selftests: Add pKVM 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 pKVM trace remote "hypervisor". Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Vincent Donnefort diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size= .tc b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size.tc new file mode 100644 index 000000000000..383ef7a84274 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size.tc @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor tracing buffer size + +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/pkvm/reset.tc b/= tools/testing/selftests/ftrace/test.d/remotes/pkvm/reset.tc new file mode 100644 index 000000000000..679e31257d0b --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/reset.tc @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor tracing reset + +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/pkvm/trace_pipe.= tc b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace_pipe.tc new file mode 100644 index 000000000000..4c77431e884f --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace_pipe.tc @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor tracing pipe + +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/pkvm/unloading.t= c b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/unloading.tc new file mode 100644 index 000000000000..059c7ad1c008 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/unloading.tc @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor tracing buffer unloading + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/unloading.tc + +set -e +setup_remote "hypervisor" +test_unloading --=20 2.51.0.rc2.233.g662b1ed5c5-goog