From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1F888283FDB for ; Tue, 6 May 2025 16:48: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=1746550123; cv=none; b=OfpINBUsaPlY0xzVUEzgRoahXsz5N9xrN+HXUedT2OxzSXNj275SfN+nJj7DCnD7HbQJAvg/OA/ENw1NkqITj9bHwZ5IxSt0SCZadWUf3qdPkZ7TV+9JVlR+29IIshkfP1e3xTMjMgaK9niA3URLXKFh5gx5e4BJ4uD+hNXJQwk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550123; c=relaxed/simple; bh=uSA7aZY+z8hl8mgHtorRGMJ/O7R5BzUyjcDQRpVm1vw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=dQV0MFr37taGttwdfcoVAz21tQdAkKEaKld1ZOIxX39CK6tjPIqFrA1pPmi18IQUk6vvM/WF/VLu399S4ZeHPf5PY1kSIMcgY23uGybKjsVGZbAh8IUKsAFiwU0xILezFKuA2JBl7yMLRBs5fhIoMBHZxbZY9OdwnreWPGfGtKE= 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=agkmsES2; 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="agkmsES2" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43eed325461so32708965e9.3 for ; Tue, 06 May 2025 09:48:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550119; x=1747154919; 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=DLqX+U6KC5XuCkJn67ap9ma3ZxQvqhTg5Cu1cd+kgu8=; b=agkmsES2v+JqHXiDs61hrbcyVeLCTNYJceyvcw3w4576aGiKAbMKWMaG2WxOxteW38 aSzqJR5KI3zEcirwxrOh14uNSIWg47WsLQYVpTTq2Eo8FWVmJPm4RLG+FqUvZEu5d/CL XTt058aNCjxFdgD+ft/PZroHlrrI9qaUYUEuYjKQvUgDuXk8SO8OU42igdinn6hv7iV1 B7/CMi0BFZEDFYNvj2zqlaga4JCE/xXzRwJ18TWKGgkSpXNDoFBAA+Il0MzaJ/brx2lB udETS4InkxI1BcnmXNB6nMdd3sAA2oL/DW+dOzvi+e9JX/4hZvi4BmGAUiX1qkuU+mqH B9NQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550119; x=1747154919; 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=DLqX+U6KC5XuCkJn67ap9ma3ZxQvqhTg5Cu1cd+kgu8=; b=gr3r1ovDHzFdbFcGXJL9/r6n9K/qpSdSE+uWm1P2D2iGFWM7V/3papHC2rdK3trCV4 INyEfcSK9a+u3tBbYzpFv5+BSdzs4X4Nn5O0kUIi2piKBaM7hHng7SbMSKeP+KJMZdla /ObveDDWaJpLjDRNCu5/hqUKHKbG5EYiEUWoyWSzpVr9zeE3b7T0WjSB3DcG7blXAtqY //fzZYoElkGhtTj/Q/tGYN8TN6lGAdwTf8yyiO3VCX9NZ6rk3PoYJa6DKqgGccBEWEtd xzJSeSfTO7tBCqoi1IL68okAyPOXVRsHjfPU77W+Jna7wIha/ZsL6/ZXgbwIIBK15Vt1 l3Aw== X-Forwarded-Encrypted: i=1; AJvYcCWTny3tP4Dht18TQkO+Iu4on1+JlNMSRAH4bE0+YvSZeSVeFLYVOJCI0QePGgEyxZG6oHfOdWxRKlEVcHE=@vger.kernel.org X-Gm-Message-State: AOJu0YxRlfow++7IVBjFK+tor+dtgGcEUdgjUuWJ9lKT/GLYOkp1QAQJ IT9/afPVd34AEzJFlXT+ib8dbjI6MLojg8+pBfsK096V34nzH/s5TgVdNjesrobmPC+OltMz/cW KlYke1qEZTOhUFwNVzA== X-Google-Smtp-Source: AGHT+IHL/sNCxNOHRhTS6oTIVa5sfoqWbd5ej9wKybTNG3/n2Z6yTk1YBNocQmTo2EsZ2HHkWXZm3cQp1zUyP4GR X-Received: from wmben4.prod.google.com ([2002:a05:600c:8284:b0:440:60ac:3f40]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3d18:b0:440:94a2:95b8 with SMTP id 5b1f17b1804b1-441d050b1ecmr44941085e9.16.1746550119630; Tue, 06 May 2025 09:48:39 -0700 (PDT) Date: Tue, 6 May 2025 17:47:57 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-2-vdonnefort@google.com> Subject: [PATCH v4 01/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, 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 56e27263acf8..c0c7f8a0dcb3 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -248,4 +248,67 @@ 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); + +#define meta_pages_lost(__meta) \ + ((__meta)->Reserved1) +#define meta_pages_touched(__meta) \ + ((__meta)->Reserved2) + +struct ring_buffer_desc { + int cpu; + unsigned int nr_page_va; /* excludes the meta page */ + unsigned long meta_va; + unsigned long 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 (PAGE_ALIGN(buffer_size) / PAGE_SIZE) + 1; + struct ring_buffer_desc *rbdesc; + + return size_add(offsetof(struct trace_buffer_desc, __data), + size_mul(nr_cpus, struct_size(rbdesc, page_va, nr_pages))); +} + +#define for_each_ring_buffer_desc(__pdesc, __cpu, __trace_pdesc) \ + for (__pdesc =3D __first_ring_buffer_desc(__trace_pdesc), __cpu =3D 0; \ + __cpu < (__trace_pdesc)->nr_cpus; \ + __cpu++, __pdesc =3D __next_ring_buffer_desc(__pdesc)) + +struct ring_buffer_remote { + struct trace_buffer_desc *desc; + int (*swap_reader_page)(unsigned int cpu, void *priv); + int (*reset)(unsigned int cpu, void *priv); + void *priv; +}; + +int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu); + +struct trace_buffer * +__ring_buffer_alloc_remote(struct ring_buffer_remote *remote, + struct lock_class_key *key); + +#define ring_buffer_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 c0f877d39a24..a96a0b231fee 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 @@ -2196,6 +2200,41 @@ 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) { @@ -2256,6 +2295,30 @@ 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; + 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 @@ -2333,6 +2396,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) { @@ -2355,7 +2422,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; long nr_pages; @@ -2383,6 +2451,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); @@ -2502,7 +2575,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); @@ -2529,7 +2602,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) @@ -5278,8 +5362,56 @@ 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(meta_pages_touched(cpu_bu= ffer->meta_page))); + local_set(&cpu_buffer->pages_lost, READ_ONCE(meta_pages_lost(cpu_buffer->= meta_page))); + /* + * 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(cpu_buffer->remote->swap_reader_page(cpu_buffer->cpu, cpu_buffer-= >remote->priv)); + /* nr_pages doesn't include the reader page */ + if (WARN_ON(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(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); @@ -5450,6 +5582,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; @@ -5854,7 +5993,7 @@ ring_buffer_read_prepare(struct trace_buffer *buffer,= int 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); @@ -6024,6 +6163,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 @@ -6259,6 +6415,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 @@ -6510,6 +6709,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, unsigned int commit; unsigned int read; u64 save_timestamp; + bool force_memcpy; int ret =3D -1; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) @@ -6547,6 +6747,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 @@ -6556,7 +6758,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; @@ -7138,7 +7340,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, unsigned long flags, *subbuf_ids; int err =3D 0; =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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0610C2882C7 for ; Tue, 6 May 2025 16:48:42 +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=1746550125; cv=none; b=WUwRvcoQu1tlgF+9Y/ITnnrV568nFegIHnasic4VnMIcTiYMndjXfGsNhbmS2Go3SL3fpBthbEDUkmZ+sXxMlCj/vVUITc21k96OryI0z7KFbYHoBFHi8aFtqBVgRVeOcc4n2JIUqk9hX9iGFA+Bf0wXwnaG/yXTFImYN36OTfk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550125; c=relaxed/simple; bh=oj83OuU4KuMYzT431lF/NNdFN1TQo049F4W66nq8/DU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rJYdGOzAWqGUl4zTCI+o+WIn0/O5V+IcYXqfRMYLgihbEhnOFrr00tEsVbu43wWpkJDXr2DCExosBjAimgsUFZs3x6yQWasQu/mK55xdqaiDBj4F6cmyZJJPPQAG0T+8T5m+xE/VbgVgwa/apeR7SJW9OsjDQi7mEWqeWeWPt2E= 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=Nz51g4lT; 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="Nz51g4lT" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cf3168b87so25847625e9.2 for ; Tue, 06 May 2025 09:48:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550121; x=1747154921; 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=OKWyOGAlXORaiA/P0E1AIGhNbEzjEVMhNVB4e1Sj078=; b=Nz51g4lTJ+EBLnOHAIfJmlG01XE4CX7+VvtyKOkGQODyweTnofe1rO3MQ/Ix9jxuEP y2RU2H+9iEpUsohBfKSgxKk1uHbS7mijgw+LLeS4PrGdZCsohoV0rcXT1fv6MVlofCp6 PChDoGy/1LP5EgqYheYm1fWVdZCGEao0LD+9FflBP9USLyPQZmr1dm7haYKen4ePBBuD aPTL9s2Q/XrU1yp31vXArJVscm/rLfvEhlqPlLtU0PZM9FYyU7QzkwEEaLLOndPJGAz5 b4Vt9BQlo2NfVBphFKx2/QUbbLiIu1DQP2dyaYlA5Nnn1AYDx80lN8Xru/EezycPLUUq Bjmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550121; x=1747154921; 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=OKWyOGAlXORaiA/P0E1AIGhNbEzjEVMhNVB4e1Sj078=; b=PYdi8bOYU9jXfk8wi1qrWHOIGhmhC3JfI6dFT4UWVADCnoFYPetre6pS0MovGBDQBg jCzxZD1D57I0ZsfZjeTTyXrb+3ldYmeLCle8rqdP36QZSszi0cdaYng4y1Xs4Xld8XKc 5OuChwXahqbcqwaKPa9UrF1bzAnUZjqnOCTjhVGA/+vCSVGKarSYY4FuQ3DF2zpOmfYE 7vll2zaUebpnuvAWTPhtkWmIsscBK6f69pIjIv1elatIKW5GpgzU8xfJUnT5Msa8nzeU 7YFSPf9k4q5xmtspDX9cPUu/UqJMt52mncEWDQtHkcccW3HWTZ75w/kH0rrsiz020xDQ OQlQ== X-Forwarded-Encrypted: i=1; AJvYcCXS0mIFoi9jphA2ozfZ3v9aPHiC6wqgQaNyBZrGNWZNghPKnSi94uAZ37pGolApuSC0VDK/xC7kKOuTFFU=@vger.kernel.org X-Gm-Message-State: AOJu0YxJ/uHpDFpRVYRlR0zwN7mAkT0TOIA0Py5fXGteSD2pu2xm/RQQ EOMNcQ8JtYTSNbkeGCfNSs/SNRRQ8Og8GklRVjK64LO8Y90JHo4kUmYIRLHIimfaICBlQpoZZPs oa/S6Vx8CPzdBQYcDNg== X-Google-Smtp-Source: AGHT+IGJSWH50oT8sZnIMXUxyHsSpxRwVdLnll32bOXU1q6CZGTnH4DqF6h8pDzFKgc/b9t+9AF2tPUutFs/WX/2 X-Received: from wmbfl26.prod.google.com ([2002:a05:600c:b9a:b0:43d:55a1:bffc]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3ca5:b0:43b:cc42:c54f with SMTP id 5b1f17b1804b1-441bbed4726mr163937645e9.14.1746550121344; Tue, 06 May 2025 09:48:41 -0700 (PDT) Date: Tue, 6 May 2025 17:47:58 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-3-vdonnefort@google.com> Subject: [PATCH v4 02/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, 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 a3f35c7d83b6..2fcc86c7fe7e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1215,4 +1215,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 057cd975d014..b8204ae93744 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 8ddf6b17215c..6ced57e089a9 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8839,7 +8839,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 79be1995db44..f357e7e1ae71 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -670,6 +670,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 int tracing_init_dentry(void); =20 diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c new file mode 100644 index 000000000000..462c2d085a08 --- /dev/null +++ b/kernel/trace/trace_remote.c @@ -0,0 +1,517 @@ +// 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 bool trace_remote_busy(struct trace_remote *remote) +{ + return trace_remote_loaded(remote) && + (remote->nr_readers || remote->tracing_on || + !ring_buffer_empty(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 (!remote->trace_buffer_desc) + return -ENOMEM; + + 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_unload(struct trace_remote *remote) +{ + lockdep_assert_held(&remote->lock); + + if (!trace_remote_loaded(remote) || trace_remote_busy(remote)) + 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_start(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_unload(remote); + return ret; + } + + remote->tracing_on =3D true; + + return 0; +} + +static int trace_remote_stop(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_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_start(remote) : trace_remote_stop(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_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_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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA769288C3D for ; Tue, 6 May 2025 16:48:44 +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=1746550127; cv=none; b=cHcgECQctCMw0FZgYVPrkEbS38/LtDFrx/+1h5WCpG0wxPc+j57cIYjU97Nj0zPyUWn8ETSp3FANTa4hpXQn7Yuae1S/Gl5bgSP/pH0SjbLzYfbRHP0wIrz0W4nmacwIu5SD5yRMuhwX21qfmL6IkRW350chV/flBlJQUiQW/EQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550127; c=relaxed/simple; bh=wQBFYyELFNvHLzXQ+9NDItNJua1krR5kq62o/pGyp00=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rBSpKA12XjJhGJybNhaYYFkq7a58LG9MykML5UBPHCYxSpwSWoRNQ+ghKbQF2xR4uUjKUg3szcaOFcoVba9hwQiT4FbVDDqODkoo7Or+XWMkcw+8mk4yhBo52ZAtOgG9YdD5Z8MkewRf0HN05sqv3DSiupu2zugRRrX3Gsh+qXU= 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=bR9JYyrv; 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="bR9JYyrv" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d00017e9dso31813995e9.0 for ; Tue, 06 May 2025 09:48:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550123; x=1747154923; 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=BsA8D4HjHlecCQdG9p+xY7qsrnVwx8gbv9XN30ZeOP4=; b=bR9JYyrvUSRjjHakZMmh4XDVWz2izyU7VdR5W3vueye2bDCYALbv2nw0QYjuu8OpJT qjgWNs5PLPntopdZhqh1UqRLj38h4IcI77ELmS31x89IUrFfmXqwVUm6sPXgK2/Q/iO0 5zj9zLDCTKdhF+4zQg9q+r+rJuP5+kpn2KJigVkIa0Bl3g0ngNdVkWEZ2Claaxu+NS6v LPR/LnX9OCqVPB+ve/CvYvwwe07rPQ0Z9mwDgRLhyPHeDyKW5IGDChuVDZSS27AujT7C 0fjUbWpXKFtgJOFYahEDkbuWtTJN1SBZxIt0IbgKxwDoC/mF5U02Ns/HeHH4BXBzRCIR /LCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550123; x=1747154923; 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=BsA8D4HjHlecCQdG9p+xY7qsrnVwx8gbv9XN30ZeOP4=; b=V76wVvekTYm2qnw/3KO5hMNA6TFZZhsl1T/Dqv/rZaTWW+5c8hbV+rX7zBc6U1ckv3 XHB49w/7k8JrGSoQ3jXJ/noJCLjyK9CI6tq7OYshBBL1uxOTdzGS/kNHrCfiv7kDgwXL xVfAgCF3fF+jBrP7DoRqjqPTzahajjOKc6eRiCVEZYDMtuOP3zkq/cZE1HrCh+0ry1tj MmKVSRI/jonGhsMWmCEpRM+EG4tXOQK/0PyXtNSkxytD6MXcmUWNBkL7ZphalB1rFP4D CS5yHnnSqVnwaJbtdDhuwZDy+168tQZps12nEwauIbz/F4eM7kQOTqZyE6mAZ3CaMvHL p6Yw== X-Forwarded-Encrypted: i=1; AJvYcCUMqRNSx2Y5kOOqVPTvBKZLlg/8F+kXE2Bar9yRhedEKFLgqJ8tyRd0loHRMmA1NMhLg+rMulwBAAICr0s=@vger.kernel.org X-Gm-Message-State: AOJu0YxGvy1+JAe0Xe/C1cabc0vGxCj6JNHdm1pmDiyrRBf9ghAQICUn pc8fubHoyURbanjMof32EVSasHr3HAp4aGJocEZv3zIOW5t1YVqeiVzWns+9e/urATgIIoxMUpb BqIFSLh5sLJKkLaNoTw== X-Google-Smtp-Source: AGHT+IF5PMMWTS3cwH1oB8k42s2Xq6vSAGn672jUyunHJnJQKljjoLiBSvKPyhszSFei8WE+2z41aT3Hv72Lx/Nf X-Received: from wmbay23.prod.google.com ([2002:a05:600c:1e17:b0:43d:522a:45e8]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:5105:b0:43d:1840:a13f with SMTP id 5b1f17b1804b1-441d100a9edmr34417665e9.25.1746550123251; Tue, 06 May 2025 09:48:43 -0700 (PDT) Date: Tue, 6 May 2025 17:47:59 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-4-vdonnefort@google.com> Subject: [PATCH v4 03/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, 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 462c2d085a08..2221705f65f4 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -70,6 +70,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= ); @@ -135,6 +136,19 @@ static int trace_remote_stop(struct trace_remote *remo= te) 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); +} + static ssize_t tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) { @@ -369,6 +383,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; @@ -399,7 +433,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); @@ -421,7 +457,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B635A288CA0 for ; Tue, 6 May 2025 16:48: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=1746550128; cv=none; b=fHpUmdN4LHf8wp6G1LbHWacg16FmsN9Pd4LPU5WHu2Xzagb5bVziy77We9nv6km/vemQnGNC62MrUYqH+hy3Wh6UqElgGSXgxsUYMwNSVgOtkgB6G5tQLb9RPSwxE14MuJETgqCagddS8b39MGwGybkuT2CPtttlsgeUNMtU8nA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550128; c=relaxed/simple; bh=l3cyRuYF81wunoJ7TifMvH83r4i55FQixMLbcy3lwME=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ono2+NjSnqKyHdlLaC/EEg7RTlE/1vkCMe3dvHkNcR+PlVCWt1TKTxlFI3zGtmjBENrK9D5hX/mp6egH2rjIYCRBuBHa3gvvOYHxewPdZ/lhynF8H6898rMkaJ/gSppTDjkNuK8QY7UOrY8os7UtWihuQuCZZpsD9VhbylftX+E= 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=RE/y0T3O; 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="RE/y0T3O" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-39141ffa913so2911726f8f.2 for ; Tue, 06 May 2025 09:48:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550125; x=1747154925; 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=ulR0t05oQC1aYq/PHkhH5FZiwJoFyTXIHcnk/CuN1Ys=; b=RE/y0T3OQ/eziv7mmJ0MwguaDxQ6HlPabzAzPBhc2ofZynkJWaWPnyApioLxuzTf8T FHorYK9j5HiZX1ibqzQKHABbWiUsAYChHQ84bl/otbUKlZN1GxaYx2/JSKCrjDtKMHe8 //2rO8mbarHzUK9DkvjsrZFUu/7mdq8tqQDBq+oQcvdLrT1hlxGFKxb0+uXeQuYWDuTx P2eQXDbveBtGY2HeIxkOxWayG+0ZjwxmJjgaPz+QeIfP+vCuYZPj05hQgRmmPTP+ud62 Kp+ai53MleOXaxnkT6Xp1XoFkV3jTcghvjEToPAbMZg1kdzVpwR4fuZKhIRwR9e3JnHX kNFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550125; x=1747154925; 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=ulR0t05oQC1aYq/PHkhH5FZiwJoFyTXIHcnk/CuN1Ys=; b=ZkHamGYcyfBdX768mJm6yDXK420kB98TLY2ceROcl6vUGHhUmW/C55r5wvJXmJ9Cvg hssh3lC/nhBPLuIeQlTLsuHyJBilt5bx/QM3DbyJXsuTeIhcpRBw71iMbxPmwpdUmv2m G+5Ot/NyHNOkHBQWXJD/feW4DWppsM2UPKZL3LAzHNHjm5BzcWFtPnzxhb1hiqWX8e6b DqX0Rc3+do7tLKJf6T3I28LCPiQjXNth0uhE06l9dRrxtrj+sEpAKEO8QXB93WERzIOG Ej7GRj4aW4nwZoPGriiW9c6itoy6FYVvYOaRfCttLJMMM7cjbjsjsusKJy+AKLWNci6+ aLyA== X-Forwarded-Encrypted: i=1; AJvYcCUemyzDCbNcsdvZv2YrGuPBxRwkxhIBZp5xm+/w43iV6bm5qmalfVylkVAjDyEgt5HOswdbsdDknsVfxMY=@vger.kernel.org X-Gm-Message-State: AOJu0YxcCzEU7wpRORjzmOyd60X51C0PCqHUlK4gexgX2QdBKK4InvjO f528mWXRiqkiU6uIu0RKkVMaJCRz945BDQCv6X34YtwS5x6aUR/cJOEm8Cnpgd+jK0bCsb6T5lM HtBoKfkfe8CMwNVeDjQ== X-Google-Smtp-Source: AGHT+IG1v09/s12usa8mhNe5u/61861N0/kCY4NkyY380pXa7lF6ETtkjTMmugXHCVnG7wZDISxXe9P8kKhSjb56 X-Received: from wrbbs23.prod.google.com ([2002:a05:6000:717:b0:3a0:90bc:bf72]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:47c7:0:b0:3a0:8352:775a with SMTP id ffacd0b85a97d-3a0b49b5e48mr195832f8f.34.1746550125284; Tue, 06 May 2025 09:48:45 -0700 (PDT) Date: Tue, 6 May 2025 17:48:00 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-5-vdonnefort@google.com> Subject: [PATCH v4 04/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, 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 2221705f65f4..6f4b921f6955 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -479,6 +479,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) @@ -495,7 +496,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5EC8288CBC for ; Tue, 6 May 2025 16:48: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=1746550131; cv=none; b=pQRP1YgPUXvBhzB1GD3AzrM+XOZuCm81w0UjN7oykQWy/sSpW/mMuNO43AoA6o+K5wLPkPsPkQZNuyMGEjC89QA2+oxtBpF+dm8qTxpzJDOCrJ4uraW3hJUEBl74iV4O0PVyw9dtF71QHGK+xpvqJnHylmTb5DDhaEfOCghvTyM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550131; c=relaxed/simple; bh=MYgRvz6Sx6XRNJZnlWQMJpm/jYaActtsntX9XN7CSMY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ns00QS93SEMdXJI5AZhpeUcF+8HEDBITSX5hVM7Ivesg90Lrr6FU3icl71+N7xmTzSAPz3FbnEsq3itGp1vFtCO9h/ENUZlDgwmoxqWbw0RS4d+aM3E0/VveM7lSYneL0Wtu545ofhI9ubRQFjkkzIKBpK5QPjMARMpAK2m+8Z8= 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=GvWRWb5C; 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="GvWRWb5C" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43efa869b19so35214205e9.2 for ; Tue, 06 May 2025 09:48:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550127; x=1747154927; 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=YryICoMD3Le6bQCsIDGRMpjRXwTPENAcpB4PnEyl+F4=; b=GvWRWb5CmuTPh8cVn4Lt2BNU/HHNEqqn0JvqxeQ8UpsMAFqS+r6GpEGlALrMoTfCMJ Q7Arxso3uu4CkepshSeA0Vq2QXNTNKyaO9AOgPAPomuo5ZW23qmz5KbLfq/KrUhmMBnG 7n69/a0rYYNV4/uYafAiRZXqHRwHtWq8+YEfWcLCyAv4M+KDeDZ5sFFxwybdwc06Dqmm Bpf/i6uDgDaIKJJG0RLPRWIYWgM4u/h6DvMv14GKdJRMIJqdMj3LyBko5btV64NQZcp3 a09t/IR+cwLnyp06sVa4uD8GOVfIftOi4cCpW++amDTvqSDIU/Gcgl/VTiKHKu0Oc/jo PRtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550127; x=1747154927; 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=YryICoMD3Le6bQCsIDGRMpjRXwTPENAcpB4PnEyl+F4=; b=uDEprfzt3eVTngDXZbCEs28vR6MZrHXt4YYxTjeGUgXiERJOF1NXMBv4BmgzhVLRL4 isd2MaBbIyZEifZO94XN5vciXzH4VguLE272Z2q8vLXplNa0ivG+G6eg0f4itRRkk/+8 QcQpUFTxV+Ti4Sli+9ImupwWZBvxR0G0UfUS3oh59dAGzV97VPQ3iUCEF04z6e3olUej dU2UHtSgg5P++DN9Rj5vyujGCXYcIUa8hE32pSXVfu7UFPo2q27w/WjryJ1AmI8Wza2/ IWUt7dwdV4xKa9DhXyv7niPIqbKiUM9pg854MGnYU1NR7ch3bqKI1B5+hx9aJAoFNwLT MTPg== X-Forwarded-Encrypted: i=1; AJvYcCXS585iYBCPiMXb4C2nkJbzIvnpgiv6Ffl+wflucK5BQdpad5BkAMmITMJAANJHoNvUS3L3W3UU0XFFtZQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxrEA58nyK9YS36aXhNNXPNdpkRqLPnS1EIzmiKgBsQiMKbtXwr dn6Sb0bD4DqE2COCn1YTYc37SayWC+yLNJua0VRjDG9yJqWSXakFP4oUsHgNIMFc5meqeyi3xbH jrWOiHAmTCFR8sVK5EA== X-Google-Smtp-Source: AGHT+IH+ddNYS15Z8lrn1rWxjPsAUbPVyUBb7r/P4plGFUvU6oPhNz5dC44bqtmwnybLR29a9sStIThir7uekEgg X-Received: from wmbhc5.prod.google.com ([2002:a05:600c:8705:b0:43d:9035:df36]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1e1e:b0:43c:fe9f:ab90 with SMTP id 5b1f17b1804b1-441d054c860mr35273565e9.28.1746550127399; Tue, 06 May 2025 09:48:47 -0700 (PDT) Date: Tue, 6 May 2025 17:48:01 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-6-vdonnefort@google.com> Subject: [PATCH v4 05/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, 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..621c5dff0664 --- /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 29 +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 6f4b921f6955..00ef80da043b 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; @@ -152,7 +157,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 @@ -181,7 +187,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 @@ -262,16 +269,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 @@ -283,7 +293,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) @@ -291,14 +302,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 @@ -312,6 +327,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 @@ -463,6 +484,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: @@ -476,7 +499,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; @@ -496,6 +523,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); @@ -558,3 +592,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:%lu;\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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-lf1-f74.google.com (mail-lf1-f74.google.com [209.85.167.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 91B33289E34 for ; Tue, 6 May 2025 16:49:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550143; cv=none; b=poQxPgxF3el06NCHGlCer2adjPIs4FuI4u3GGMF8LStGiwflg3RGaTOesA2K29ZJcRhj+GtYKxkteMFH4Zyl7OqvClDWicJNVjDyf6H5UQ4jX922o1+4f7kU9cqmM+C7E5GHf83XMWMfBKRQkZU9i34ftBvfoAAxRw9KDjm3+Zk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550143; c=relaxed/simple; bh=TjaTEjsg0+DXvyUXwwBtev0LdVcHX9+wqh45SuZo7+Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qhddExnKquRd6Smb+zNZjQNQKVRz8GkwpHafXD2Q26FmRcCH9T750o4oBH0XceFWIIDOf9ai6lfqe9i16mCV7irqulm3E7govtWn+D0EZPwO2vScG8lpnMeBe5Kt/cPNXf6wmepTcQx+03dMO/uLGxgcpX45tMA3PekoIYxopxI= 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=AM6VtBmN; arc=none smtp.client-ip=209.85.167.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="AM6VtBmN" Received: by mail-lf1-f74.google.com with SMTP id 2adb3069b0e04-5498963ebc3so3057873e87.0 for ; Tue, 06 May 2025 09:49:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550140; x=1747154940; 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=/Jp1lLJLaGjaKoXy64OEgzLoF8SWUPuFbMZNzmgUGvY=; b=AM6VtBmNZzshHyEtMTlaoOzEyKyt3H4x3kTHf38DaA4oJXpqK/L7DckswcTrzanOu2 FC6CWt6LlwuiAN0CgAD7dQ+LhVHWLSjx4oYSfhIKgaJieTqzSt4PCaP+Am2bsa1AfCxF j015/Rirk3Xj7vRDW9wOy3d0cGQsxDRxzJrcnnTzCXb0lJJOtmUN/DRjRagiAWGn3L8m d+j7LRlybIbmKbrKIyrmyvj6FLXzNIim8fr9EO/rw0u8fGC0V62ennUja4ziSxJjhrWw joU84LeW53wmwXtWJ+KQTRlXNbDLA/xePwC1EVGWHJmeXc99BJ9nP4l+ULWx9HgCdB5r xhww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550140; x=1747154940; 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=/Jp1lLJLaGjaKoXy64OEgzLoF8SWUPuFbMZNzmgUGvY=; b=nK7c9NgE9eN/LJ2l0EexEBO8lpUon/ZKZkfMhhadG/uh1dNzEO7mSyWtPx5eUnc0bd 6KiV9liS4Y4bp3oIc32KdxmPPSPHtEw098KFjsNHaucdtAdnaNcX3ZZAdC8bziCxS+zy wXQJl95q3KVtaY1Jh0hRxJF3CDr5XYkZltmLXXFrkWFVf8U4N/3yXumGNi8uERH+9xqv E65pI3xsznuWgetdkE9RLfD/p0yLcGBgeBGWec1/3q7rhJAPuInUHgOwjrrN6jc6Flt1 MW/89g/37w5Fes6eSZiE5xsMwvmwDcicu8Rb6kCha+iGVELlxxR2dyQs+aSd9hbzmjb6 LTeA== X-Forwarded-Encrypted: i=1; AJvYcCVGI5p+Oc86g08+iINaAgEWbxfSMHpah45th3ohKp6vFg7Ot4MgFgUR83J8SgOR9Cfna1MelgxoJ+59n6Q=@vger.kernel.org X-Gm-Message-State: AOJu0YxiWjYKa4VK1rDcpXyrzn4lNLd+0gSGFC+DmRPDiXssuqWoWGVG ppITeEyDzRAHURAnfpMitXzBallSUAOlS/A22zOUXpZc3eTlpNdBKK/GbfAK0mkXhckaeEPfBVf XkUUFh5SOh4TGPzUnTQ== X-Google-Smtp-Source: AGHT+IGiXAgVMRbfLIS8SOyIvtLGncb5XoCWTw3YHC2KCY3kpynNJbuNPStX2fauF3TpS7pG9j8sT4PCVtP6V84+ X-Received: from wmbdq15.prod.google.com ([2002:a05:600c:64cf:b0:441:d228:3918]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600d:1c:b0:43c:fda5:41e9 with SMTP id 5b1f17b1804b1-441c4933d05mr112672305e9.31.1746550129253; Tue, 06 May 2025 09:48:49 -0700 (PDT) Date: Tue, 6 May 2025 17:48:02 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-7-vdonnefort@google.com> Subject: [PATCH v4 06/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, 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 a96a0b231fee..cff1e700d4b7 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 00ef80da043b..5c9f2b07941f 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -707,10 +707,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", @@ -726,7 +834,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9567B2882C7 for ; Tue, 6 May 2025 16:48: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=1746550135; cv=none; b=Bds5qixlnOliSDV+SYIFa1FdKRbup9WC9CHbsAsXGNgsrLGGfiUKEKzxnid1rxdUAg+Ymt2MAAMwJyEnloValAeqlO1tNk5oFdqSEU/TaWmC9+u7Q5pKbCirQABU0nxUTelDTERYdwnu1Zm2cvtIP9px5XbyVphWFSxE1ctWybs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550135; c=relaxed/simple; bh=y8rcnohCNx6fnvmwXaaVmdXgnbol8xb6JsiUxsOpG8A=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=AvcdD/kcDoLyR/e25s+Lay0K1ZsE++vLyhLJo/hZY6vsjWNJ74H4N8mNoqPss7QamXcH6bJdN3WFHmmoaNcn6JzsLDgoJxIVPlQaKha29uqp+b+wbbBp3u70SqgVMXEyNMAoswPRsYdSUlfjz5DC8YXdYM7oMI/PewFXVOmBjiY= 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=17ozlMEZ; 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="17ozlMEZ" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3a0adce033bso330740f8f.2 for ; Tue, 06 May 2025 09:48:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550131; x=1747154931; 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=UccoAy7t6DYOqtAFght6GRLYbDtLDUJp2RBCqm6XV8E=; b=17ozlMEZFLaOtjn4OBIh/yMTAwYJB+jQfwRv+tNEwlnsgkmPAxfIphIKHxX1lYMZU5 bI5IO/37262GSLeeVWaS+z7R37JkSImNWzl48AxSeuM8Jqoaa+lHRUzyOg3x3qyy+ZSx nDtDXdjjzFsLPtZDC7Hu2ri2SOb9stBPenCjcPuP8YwThBzSI56d74TZ9Bdmr5Yajcam DMHaI9lK6u1WNwMrNRZgx7htZXKP/I8B/57jxt2JSsVk0gRuDwMZjtrmKAKlbmwBkgE+ bdhkKtRBoWqal1GTy40J/ydNXSI33YMoLVIURpeaRqerSV781/Wju381eE+MDbRIj+RS fQvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550131; x=1747154931; 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=UccoAy7t6DYOqtAFght6GRLYbDtLDUJp2RBCqm6XV8E=; b=EQ8ARAU2c/0ohTWfcB54A7+i2WwOqGMLD3ONBG7CXgLtogG2SK34QugN/9Iz6tJLy7 rPh16idcZy7+fw0CWUrvnsVdVhjyKlTZbFM5CN9bJVEHKPGNZE2ykNzRTV6QActZuRj7 GeoaG/KfbSvcYWFKz73Q7a3iSqopCrLN0ro1VjOFObkrdHHdbWG0kxiFxRa6J/L/vMOr w0zNdtnzO0tboN+Iz0xS/uj+2mmmn2Z91vKyWKFJh0UpVOB2mrqjsutNmqCkPTIzrghE 7eQruD98hOCtAbZJGP9wGq7B3Miq6h78YGIFDCMDhQFaCIeuOH9HeAM3rO17ogZCKK47 nqdg== X-Forwarded-Encrypted: i=1; AJvYcCWmURHKOqoxF5EaTISAFwiqETyV6lP5PzFnTzLz4uOCGFrOm3plMfP5LDxXn68h1YWCGd2dKhfTb1J172k=@vger.kernel.org X-Gm-Message-State: AOJu0YwNIbu6RMJboc2M/aQ43QZX0zwyHCr0C6pmVxiXHUc0LStE4UJb Fqnt4yjloCdB10zEnuBwb9Y36+2MY2N9+/es8eLXaHz+0mT+hryBHvya6mSSNFfUbsZ3W+SvvOh FzDmWG9c0nol7oYlL2w== X-Google-Smtp-Source: AGHT+IEM95jiwlSfZQ54wnNuqC2fl6D7aBnxwDMPr9V7cIV+4uN83c8dv1x96zRkvBxrXCRdBy2/bVIFl9Y7AHEs X-Received: from wmbek12.prod.google.com ([2002:a05:600c:3ecc:b0:440:5e01:286b]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2a6:b0:3a0:86b0:5f63 with SMTP id ffacd0b85a97d-3a0b49e5583mr173846f8f.34.1746550131142; Tue, 06 May 2025 09:48:51 -0700 (PDT) Date: Tue, 6 May 2025 17:48:03 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-8-vdonnefort@google.com> Subject: [PATCH v4 07/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, 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 621c5dff0664..d00e85d2a633 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6E89289817 for ; Tue, 6 May 2025 16:48:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550136; cv=none; b=oICjS7qvL+DhQrpuwmPcSqqj/Ij22rAr9d0F3MZCpCPqFWF2a+VJwSNx8Ut3aoRmTYGrBVPAVF3ZKSsfdgdqOzi87NNssumR+i/nNgq+xxVaxWUxOLU6oFae8tTRkUvaV8abyHYGI2DqtktR4apGjv+kaJ8eCePTjfTFVPrGbXg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550136; c=relaxed/simple; bh=P5fqf7GLSzb7bwzSSyJnj5fukWX4Yfbn+JGf94Z5P6s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=EqjG4KkTpKCrpmRmptmUHCZ6whX2cThvruwpSt7YbiTnHbWkslyQJrIJ2Gvbi+ELSYEBhWunC0V+JjKzfVEWoANdRR/U0PaiINlojqNS6L8YFR7UxcGaectFo9+ooiEmDLICxjtgT5QWrcHjXw9ga73tsm0IWw2RbGCXTn3B6/A= 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=CswxNSwK; 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="CswxNSwK" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d734da1a3so27600475e9.0 for ; Tue, 06 May 2025 09:48:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550133; x=1747154933; 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=Z0lEPcVl31Ep+ZkAHQCvo9hIAtaxt0RYlv/tYPLRXN4=; b=CswxNSwKFoeimDAXRNDCNAaQRsTyzyKybaQ+pda+mxRIHoQ7OLi0PzJbjfG4tA7Gvx f3lORSA7DVSuYXwpnhXxFjZPuiBL4UpLjD4avSJLP4Qoym9nJkV9rzV2w/Je6enHRL4K P1mo0KxVPJYwSCY37FIsGZi3NlQIWzpbp0dVnHaJ9MgdW9CwgAhJC9WZHv2WlkL2jmu2 cqwar3941GWV4jIvfj3UTvOwiccNvWM8A5X8rw5yM2oFiLdD4U5Pzw6vTYH0thf9hzP/ 0eBKuR5j/3RaKsPwyB8LfTwV8wb6T47zqNac9RpKDJYn8xClFsosGgBXZvMqGNiQmlSW sJrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550133; x=1747154933; 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=Z0lEPcVl31Ep+ZkAHQCvo9hIAtaxt0RYlv/tYPLRXN4=; b=TlBpBZhHPbdz8wVGj/Fd1jpzzH3OhWdpQvaxXi3gM7rGymWPt/e6Ptz2OjvWKriqkt tHG/mdFQR3MVN3ozEqvqYzkA7ldhnrR75dSIc2vyZIikasIh+HLilK52eXrvKi6DuTpf k2W/PT2Z7U4yt7feISShrBvOKEwA3st05+Ua4srrJ+P57DV7cEWP8bJrxj+39iIq+nGr olMGWZtRKTIxuxePf4fwmyCWl/JwUR+xZFN7Cj/MQzCHO2q3KT2MSm9p2z6Mkws524o5 UKj/9fcRHJsCeBu6gLBKc8KnEuAweYbZensCDut9z/UZneJXC4wTfgCpijzp0ZONVUR4 /flg== X-Forwarded-Encrypted: i=1; AJvYcCWMtGkjdEBEDqyhanzvbYLfPvzKoSHcMrQtl77RDebQBV9YLD2yqDEBwwkeeoYCgJI7A8tgCEsFc7zuJqY=@vger.kernel.org X-Gm-Message-State: AOJu0YzQ0TTr0RM3eLqXbwtyJUpRcEK7boFovxGPEr2XUX++wZY16Pta RE8GzAtbI9B5tf5MP89t/wOZ9TdtfIVAl1BRybIZ78WtcyWArw4tK+TUUhqypnnChMarAItE3z+ 2RaojN6RWnj3jWGtX6A== X-Google-Smtp-Source: AGHT+IGq1vAJ+GKWhJtsv/JkxJGIe/fYEg66JYCRx2JA9lFVNOYu2CXLapcz44nyPnWBPM6MV8fK/V35DhKZhEiX X-Received: from wmbfp20.prod.google.com ([2002:a05:600c:6994:b0:43c:f5b8:aad0]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a4c:b0:43c:f8fc:f69a with SMTP id 5b1f17b1804b1-441d04f45b7mr38855715e9.4.1746550133269; Tue, 06 May 2025 09:48:53 -0700 (PDT) Date: Tue, 6 May 2025 17:48:04 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-9-vdonnefort@google.com> Subject: [PATCH v4 08/24] ring-buffer: Expose buffer_data_page material 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, 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 write of ring-buffer compliant pages outside of ring_buffer.c, move buffer_data_page and timestamps encoding functions into the publicly available ring_buffer.h. Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index c0c7f8a0dcb3..c26fba4a643c 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -3,8 +3,10 @@ #define _LINUX_RING_BUFFER_H =20 #include -#include #include +#include + +#include =20 #include =20 @@ -61,11 +63,46 @@ enum ring_buffer_type { RINGBUF_TYPE_TIME_STAMP, }; =20 +#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); +} + unsigned ring_buffer_event_length(struct ring_buffer_event *event); void *ring_buffer_event_data(struct ring_buffer_event *event); u64 ring_buffer_event_time_stamp(struct trace_buffer *buffer, struct ring_buffer_event *event); =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) + +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 */ +}; + /* * ring_buffer_discard_commit will remove an event that has not * been committed yet. If this is used, then ring_buffer_unlock_commit diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index cff1e700d4b7..e99e8d4ab615 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -156,23 +156,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 +298,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 +316,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 +374,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE3FD28983E for ; Tue, 6 May 2025 16:48: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=1746550139; cv=none; b=TvJuOjJHyCVioVBLbOHPlB+M48GQU+HGZNSKhUxWmOTq0gNZP18+VzzNo3s6AB8EYVnRUlCAguxZviaEpdmrkZx9CY64gzGE92X5GF5IQLKljOVDUXhPWGx0yyIL0vuzb+JVzDjobpODQ16McMEM/t7RLb1NeR5n+LE1PBl5onw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550139; c=relaxed/simple; bh=6tVYi9wq0QDTJvHZifVYWJnoCc2mQ4xXVx7F/bVrHTo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cBONtFBplbISyA+noQKQfZDPEdW9UaEMGiSLzKYs3Ap9WCFW5iAmwA85qN7/85uCObCwNTV2EnfkpINaWwLK0B1Jl0UvkKQEwdU2oHXPSsFsCJV3lpSnw3vDIsFWLMeUtR7d9z4T81Rx22CWMGPW+pU3R5UMMjoO/u7ihqWrecQ= 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=y+R75s/c; 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="y+R75s/c" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cf172ff63so28784275e9.3 for ; Tue, 06 May 2025 09:48:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550136; x=1747154936; 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=icNV5U2xFYpleTGHgYYCWy62cTNgpuaCWjv8l6wElo4=; b=y+R75s/crMvaUIpzRAfSK/o0STe0GnOHi1xPcE+FfUl8n6iGUEuei6VqzkKAh8NtX+ kRUXn24sQwK5bK1i6BSvTXQP5wG3NJ7a+vy8mjHrDa2AxPk5fRx0Par5cpcq4KCy+F7M bdI8WnMgQmUg+qY01JFAyaJwPnEQMNZSzI8sgHPjPJBJ2poKzna7Vm8MtRxZN84NpVUs IN1W66k6LWjE1vcfFOQkz3EmR9uvKr3y2qZ6xtA0ClW/gr5AaL9c9vCBfTUb8UEpR0E0 P7VcVNUFXMjih1goSbE5Xn572Jpcay75Mw3OASvyB82Xmv5tndd/iihqRG96bn1jJga4 vmRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550136; x=1747154936; 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=icNV5U2xFYpleTGHgYYCWy62cTNgpuaCWjv8l6wElo4=; b=AFtBxj4pIGtzRzaRREJGpBFHRoD5LfysHMeH3iEWqtfjDYeq9J6i/i1j7QjaL+dYLN I7UouceBcE5o9PHWszdL4etwpiZiZYIBb1tUp5BQ/sUogIZCxk0vP/3AAzOikTfVjBSc LT4DGW2h07T4l72AfNCFY9/oYUIpD19NBGSsLCEM4NRGKC5zz3uBZtLE9PXIPdhqXH9Q nhfM4nfInXMzivc4e0S5wv3V1JYI3c1b2NvF4vXDLeRonhpgte+hNcbtO6meC7P3U0cX 6Lh8fqVwG04oUeMhKJ2zxQzds9i7ZJ/DlRsxQyoxr5OsqL7+Ll6ciRtpKt53Am8InE8A lLpg== X-Forwarded-Encrypted: i=1; AJvYcCV5BBAM19RgFi1R40mA2Z79oYhUYDZu0UxYOf5A9C9TjcVKetHBkmdCp2HWdJ3Kp3j5i2RHKj0jL+hK6mA=@vger.kernel.org X-Gm-Message-State: AOJu0YzLhRikE4nintHtfYryFmKaJ+5B/p89e/JiG+Uzrtb42uAAWCnb OsUkQguBBFZiyNDnq6e+gGOMaT01k6ND2OVGgmlrRZM+lIbNa1t5v22wQWUiWB6RQF8/b1u//lj KOtuvc3IvJ0RQ8QhXIA== X-Google-Smtp-Source: AGHT+IEH4tPyJ0ZU3wW2oaZpaqyI/xkGYNcY9ZlBfHwhBFWBjVxs23c/ZL5Hxmqhh7GmoIZxN6NOq1t9uBcbwofO X-Received: from wmbhh15.prod.google.com ([2002:a05:600c:530f:b0:43b:c336:7b29]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1c91:b0:43c:fe90:1282 with SMTP id 5b1f17b1804b1-441bbea0cdamr133138885e9.7.1746550135231; Tue, 06 May 2025 09:48:55 -0700 (PDT) Date: Tue, 6 May 2025 17:48:05 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-10-vdonnefort@google.com> Subject: [PATCH v4 09/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, 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..6cf8486d46e2 --- /dev/null +++ b/include/linux/simple_ring_buffer.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_SIMPLE_RING_BUFFER_H +#define _LINUX_SIMPLE_RING_BUFFER_H + +#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 2fcc86c7fe7e..407cb05cc8a0 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1218,4 +1218,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 b8204ae93744..cece10b1f97c 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..da9ea42b9926 --- /dev/null +++ b/kernel/trace/simple_ring_buffer.c @@ -0,0 +1,352 @@ +// 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 bool simple_bpage_try_shunt_link(struct simple_buffer_page *bpage, + struct simple_buffer_page *dst, + unsigned long old_flags, unsigned long flags) +{ + unsigned long *ptr =3D (unsigned long *)(&bpage->list.next); + unsigned long old =3D (*ptr & SIMPLE_RB_LINK_MASK) | old_flags; + unsigned long new =3D (unsigned long)(&dst->list) | flags; + + return cmpxchg(ptr, old, new) =3D=3D old; +} + +static void simple_bpage_set_link_flag(struct simple_buffer_page *bpage, u= nsigned long flag) +{ + bpage->list.next =3D (struct list_head *) + (((unsigned long)bpage->list.next & SIMPLE_RB_LINK_MASK) | flag); +} + +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 bool simple_bpage_is_head(struct simple_buffer_page *bpage) +{ + return (unsigned long)bpage->list.prev->next & SIMPLE_RB_LINK_HEAD; +} + +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 */ + while (!simple_bpage_is_head(head)) + cpu_buffer->head_page =3D 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_link_flag(reader, SIMPLE_RB_LINK_HEAD); + + overrun =3D smp_load_acquire(&cpu_buffer->meta->overrun); + } while (!simple_bpage_try_shunt_link(last, reader, SIMPLE_RB_LINK_HEAD, = 0)); + + 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_try_shunt_link(tail, new_tail, SIMPLE_RB_LINK_HEAD, 0)) { + /* + * 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(meta_pages_lost(cpu_buffer->meta), 1); + + smp_store_release(&new_tail->list.next, + (unsigned long)new_tail->list.next | SIMPLE_RB_LINK_HEAD); + } + + simple_bpage_reset(new_tail); + cpu_buffer->tail_page =3D new_tail; + + simple_rb_meta_inc(meta_pages_touched(cpu_buffer->meta), 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; + meta_pages_lost(cpu_buffer->meta) =3D 0; + meta_pages_touched(cpu_buffer->meta) =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_link_flag(bpage, SIMPLE_RB_LINK_HEAD); + + 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFEF3289834 for ; Tue, 6 May 2025 16:48:58 +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=1746550141; cv=none; b=J/6myz7ol2J1HVHWqtdQPsNRwVxunvNS4xhDM01CbcWd6gUbuojqK3DxYfdKoqx5xj1GMRPB1tA8EG2kaG6lwFaWS/foX1dfnDJUjHh8niO7S4TmtzU1v/n0Loc5N7vHGbZLbeTcOygrJiZSH6gEwFJvywnhzOxjsT5WvKFGxkI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550141; c=relaxed/simple; bh=iuQhFRef46J5MkexbFZGx7vlrdeCQfDMXYmqnqqtQ2E=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pzliwAydoJBtz2vjU7uWLwwA3w7Ibh2icRNVaYSlLbTsKdCQpiEy/QZG0FndksWBWbAihHHS5zRlQf8OdSJrpTIkPjX9YZPY9cRbuESzx+EwEhLWaCcuDWI8U2nKD4CGoD3i/WI22QgTA6oTZ/1F9JJDgcddQlUJhwBRyyBkUvM= 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=ueN/hm9l; 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="ueN/hm9l" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3912fe32a30so1858964f8f.1 for ; Tue, 06 May 2025 09:48:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550137; x=1747154937; 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=uUEhUY6y+yq4hnPAgSB4Z9pgwwb6EfBVQ/uoSljwjUs=; b=ueN/hm9lDhNtkulexxgjzlEqzpTF2lJAL82xZRwMKk+CXk3/uA6/ewiS8tbpMPDfPW fEOws+zEAYKO8G3JGXmOI7cwS5tF8yFznfm8h5EGHkupMccyp1AKONMMo3bYqBlYPQIh JijrClhSWAi1DUVrqzb+E0/ZwmpRo1xB9ozvzAcQLuvF3uAsyy0hz3Kv+2+S2xjtPRS/ EV2115vQa7EwiqjvBCIBA4roX/nB7GMseBM60+wO4Ws5o4K722Hf7GB7lCoeCyTqDTMG VWdzJbhGKuVhTRoOqwjYCrEex+/3blSBsEX78vTJn7bue17E+hJvU1awghZ9kkdLYWR0 GdAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550137; x=1747154937; 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=uUEhUY6y+yq4hnPAgSB4Z9pgwwb6EfBVQ/uoSljwjUs=; b=n5dYgb+Mtg1F0OMfDYexhqPbWHE7p5jJP1FGxrpLMQlt26D0+Q29evvY1/iyS9RyzO a+xEZb9t7llilJHUi9crQHkyLBhXwMd/ejuE4CVYWU4Fx+0rAiShODp106E6DxG6BKi/ GLUcI9XIot4wEueFiKyHAcq8JmGb+Se+Wt8BqvdV1wOvpkwOMqckFDVxzDo1M9ciSzzk xpornmhENU4TnLmxF9PoWQrpAqsOii+EVhbQySevYHi5w6ijyh7oExUWZZ9UnsYzlO8e WFpYnr0x7MLn2abDd11c+ei7BjndOXAvUAYOe40KGcMyWwDl70I7mOBrXv+DxgRFt+MT MwIQ== X-Forwarded-Encrypted: i=1; AJvYcCU0xsV9X4/Qs/pTSMGnSvEFKzYEsFaEhdjV9xihULSX4uHL6ZgIrvFdOnyKxkisakQzdnTidpAyFzMz+C0=@vger.kernel.org X-Gm-Message-State: AOJu0YyaWC7g+MEmCGvBMyprSSSdy1+J1yUR82cxRza9G42gP5CWg2zV 25GuhYHLTr6UnGX4wdcRmPPYiotEge0RGwXn1dvY1IJ8QzIG2UIH6OB2YFqc80YfFUalXPajX5Z RofdGrAmdraM9A7VeEQ== X-Google-Smtp-Source: AGHT+IFsuDLoQRKLKmWQ5FaaPQkguDjVQpGkgUMdm86U7WBeGkKEJmPriD9uujpKK0RffgNbuMzCI/zCmJHFIlVx X-Received: from wmbz7.prod.google.com ([2002:a05:600c:c087:b0:440:59df:376a]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:4210:b0:3a0:8020:c5c5 with SMTP id ffacd0b85a97d-3a0b4a4d575mr86047f8f.58.1746550137291; Tue, 06 May 2025 09:48:57 -0700 (PDT) Date: Tue, 6 May 2025 17:48:06 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-11-vdonnefort@google.com> Subject: [PATCH v4 10/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, 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 407cb05cc8a0..2e27d9d1799e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1221,4 +1221,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 cece10b1f97c..8f5e194eba71 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..05556a879ba7 --- /dev/null +++ b/kernel/trace/remote_test.c @@ -0,0 +1,259 @@ +// 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 NULL; + + cpus_read_lock(); + + desc_size =3D trace_buffer_desc_size(size, num_online_cpus()); + if (desc_size =3D=3D SIZE_MAX) + goto err_unlock_cpus; + + desc =3D kmalloc(desc_size, GFP_KERNEL); + if (!desc) + 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 NULL; +} + +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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B0AB4289E21 for ; Tue, 6 May 2025 16:49:00 +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=1746550142; cv=none; b=IJFBXaOa4ZANSOo+Mk2xYXhzIfDqoAAR0WJ23ZIqoZsCUkINxFa6roY84q+4TkH6Q+uble1MbsNTmkOaR8H1pMGap9zZO62xm72g104QNHFf73ZWGhdZkeUauiTcqW4ozfNC8kkGIeUnOMt891VN4lvaNSubmmCewMpzG4TytF8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550142; c=relaxed/simple; bh=vrxwY51veO2nmwISDVtRUTFBRfA0vMJKQGbSsl41OUg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LkGpu+NSX/Nx6q3S0xoV/x3tdiYhpOkZempspfUbr+QEk1ySYeFf94rafi2SCq0M/U2a7xbvavdpMbeXGeA0r986JSsDi5DzJRTUjdisn0Fvh6dxlOinKG+RZKezlgapWGf4xcaTJwIIDZ/8FTrZPcLFC5eiCUnIeyXteZK7UVc= 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=OmYeZ0lP; 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="OmYeZ0lP" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43cfda30a3cso29164455e9.3 for ; Tue, 06 May 2025 09:49:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550139; x=1747154939; 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=StZLsBHNOuNl+tKb9Vl4bYLuw1HG3lhuSVUqOiGX97k=; b=OmYeZ0lPdlvHGaXv9ghs2J6ba938CLzQNhRbVId+Dlktlzv0iBbGtJFemvkhqN06Aq l8qHwESMfyYFZv7mshiQ2ulsKcOGhJfUTwhZfGPSndgrTI0BsapWo52DZVi9lU4ieLvI ehjclmnH9bnlsQAx7g2jJXDRidkigVapGHVA9FChk5hY6QiUsJJF7pZfSDlpOe3nfKkZ WYfvekuqXxPKkLK2p8fiXKYrpdDBQ8JS7gs+2tEkd48kdgqsJZz8eZcfN7kOZLaPeQLJ SD6SdDn+tz2pWv7ioksUK14tVxWNsnHx/N/fFuFKl/A3s1SO/xyccIzGRHe1f8w5XpNR JIHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550139; x=1747154939; 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=StZLsBHNOuNl+tKb9Vl4bYLuw1HG3lhuSVUqOiGX97k=; b=Gm3dj0qT0qY98bSQyokqse5iSLUCeqPSNiqX5ZKZTTYlc7QFwVaON6Pa0XxxK2xUKE tSwvecCFuxiTZGXHSQR0Zo1zT71BiY4jfrmfhRXE/PZy7WLqYsvkyBR82B7hXRRLFeYH oAPXPk9I9gGdSakKqkx/eY/dpDnA7fu7OwELB0z44DDUzlL3xML541JxFAzG/ANobeXL lTCrLS0R5WKrXuC4P9iJE4Chj9eyUY9kh40Tgdwd+/QqvIuTpN1rXo8k5s7yR4/wVnUf j9g/8TMhy/m/T/BTHIBVJV/YT5yO5Lv/yecY03370+ZMd+6RFNS8GJcGAS//7IoXIh+4 yv4Q== X-Forwarded-Encrypted: i=1; AJvYcCVsFgQxbXOWSKIpIEEagfa8gYRg+kTj5DGQ00G3bR8nZSIETbilaeN4fJE3cyZrxeFMZw+H6mpYajxCi/Y=@vger.kernel.org X-Gm-Message-State: AOJu0YzrzWFzc/EmKDl9I2tKwbv7BL5kGZSGLP6XZ5v879IBAOiy0Dsf pF+/IgreWy0UkU6tTwXmKxwWS5FTZGiO8LPmgEdG4yFtOBqmLxgEoLQFcQaXx448npIZopqLCgk cbNgP/SL2EIHnVtwOzA== X-Google-Smtp-Source: AGHT+IE4iNBpupyaQ3P75QFzmU9O/zuYSK3OEQZ8J4G0/UVK153ETEX0RF18FXE6x2Rnf6IDgYTafM4dkGCo96Dx X-Received: from wmhu9.prod.google.com ([2002:a05:600c:a369:b0:43d:1873:dbaf]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1914:b0:43d:47e:3205 with SMTP id 5b1f17b1804b1-441c48bca55mr85552645e9.11.1746550139272; Tue, 06 May 2025 09:48:59 -0700 (PDT) Date: Tue, 6 May 2025 17:48:07 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-12-vdonnefort@google.com> Subject: [PATCH v4 11/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, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort 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) 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..05bb21f80e34 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc @@ -0,0 +1,36 @@ +#!/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 +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_unloading +fi --=20 2.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-ej1-f73.google.com (mail-ej1-f73.google.com [209.85.218.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7EB728A733 for ; Tue, 6 May 2025 16:49:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550155; cv=none; b=HjUldbaWWI8aY46/oxvnHnyn/p0Ba8SfhQeLu1jDKq7KhEu4BEL4+xB3MNqc8YWZSf+CBeOXPqLLLD/WugDWrcBC/dhkPlaFVztiYzmB11jYo3/jlSxxGBdBTfTrmRdRGIFmPPfyFdESXSeiU7wrrebNhJTsUfcukUVU10AJiQY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550155; c=relaxed/simple; bh=NVCqxcX7WnR7NqGIbz8oFzTlAHuhz7dhxcMS39AX+eI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NEsIVdH0sfCs8vk09FSefVI/IecQgqq4miLFfkYowDskGsGOQ3NzNmbWVHEMQVDIXdNpQN15dFA5pWnpa6Mmu5/bTjzkYuJmUtw2Hq/dhKpKg9yfHXT0DNwFqck8iaKEVWjmCd5YKdxh4AtRGvh2VdxRXEMlcxJUQTIa00iIWGo= 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=R0EoN6i2; arc=none smtp.client-ip=209.85.218.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="R0EoN6i2" Received: by mail-ej1-f73.google.com with SMTP id a640c23a62f3a-acbbb0009aeso439371466b.1 for ; Tue, 06 May 2025 09:49:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550152; x=1747154952; 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=PbofLrSiYoUrDKR0IcYz2ighpQm3HY6HT+wQFKaRR8E=; b=R0EoN6i2etnLP7sgV94YjXD1CWPOWb4fHiPvaEEnU4jCmFUQK9ebvy1e2S4O/4cI6S z4+MIbEe2RZ0jNAvJEKFhaIisWAZo1yHVmy4PsOcuffH/MsKgbGBooZ52JL+rjysZ3y2 Gfwefbo1jinr/hJIYO4Wjn7TkWa9g9p2jMWh4HKn3bItzNkx2krug5wvXVUewkDgeCNr QJUQMA5tfd47KEBCOTBzAS/DlgbrvneZLAFiSLLbCYoQomTHAMvNYRm+DC/anc17MZxG KkB1IXucfZ9jEU0xjaxcplq9QhnLX0yS1GGDFgysrDXVb3+Llrm10071WxvaEn6Womge KM+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550152; x=1747154952; 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=PbofLrSiYoUrDKR0IcYz2ighpQm3HY6HT+wQFKaRR8E=; b=cK7Z9cW/Y8Nr9C3nPg8ZpsHdp9QceG4mCuaJkhlvBCDMmAmaz0k8Pcco2Xd0SWFWjF 9dbV53vRd/bB3jvkydPrvpn8pGcBbHZLQi5OOAL27sotf92qLB+owioa2EWpJxpid57G kN319/pGSYjHc6N7O9pezuLsrMvrcY+Nl2BmiVLctKadE18R5/yWcvLR61gDuR4Y/kBy ldXHf1pWf8S+MrLNQ9ETtjwlLeO4FB3XUDO9V+qXU0otGM6yZ54/r+8CbIXCdc8jxTLy jNEzJm4951PZCI98p8N2GeyNYUeau2x/bCPq1auWgE4aujbddqq/HESFOKBx2F7ijz+m CdZQ== X-Forwarded-Encrypted: i=1; AJvYcCVf8mqbZ0dQsH4hU+7Th3RARFhm8gzmPUu9lk3aHZEGWVWH47+j8ijednzsl6dmqhRZYQltzUkHaVoH1kc=@vger.kernel.org X-Gm-Message-State: AOJu0YxDoVf/ed4fVWcPrIzFCm05o7qYt0fOhpK8zsZSYzVikA5wV7Jk FJA4eKPepgzaOAoGtJTNAVKNMG0iupOrcO5Kvy0N118zKvenffWd9CFqRGrIrk2GXVmMndPRmad 6JwQDM3hZ/CdmDCf4Sg== X-Google-Smtp-Source: AGHT+IGGoAXb1vdJDEqbvbocLN2nVo70zjIZSaJaSUPxR2r33LndiIC/nG5doi1ZsnzpfOo5CHFpJEQ9HbbmWv/E X-Received: from wmbhc5.prod.google.com ([2002:a05:600c:8705:b0:43d:9035:df36]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:698e:b0:43d:7588:6688 with SMTP id 5b1f17b1804b1-441c48b672emr115738045e9.12.1746550141291; Tue, 06 May 2025 09:49:01 -0700 (PDT) Date: Tue, 6 May 2025 17:48:08 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-13-vdonnefort@google.com> Subject: [PATCH v4 12/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, 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 6cf8486d46e2..10e385d347a0 100644 --- a/include/linux/simple_ring_buffer.h +++ b/include/linux/simple_ring_buffer.h @@ -46,4 +46,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 da9ea42b9926..54c8f221f693 100644 --- a/kernel/trace/simple_ring_buffer.c +++ b/kernel/trace/simple_ring_buffer.c @@ -55,7 +55,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; @@ -282,10 +282,14 @@ 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 */ @@ -294,15 +298,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; @@ -312,7 +323,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; @@ -321,6 +338,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; @@ -328,19 +353,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_link_flag(bpage, SIMPLE_RB_LINK_HEAD); =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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 913B928A1E6 for ; Tue, 6 May 2025 16:49:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550146; cv=none; b=lE+iH6qkncXeOAjSv88toCzUIQ4pnkMJyuxOlCB99+9gNn0vCQ9p5GHMYme99yFPLMPdmhchWNrnOxa/e9lnCCmomPHPmSkUJscre6uNu101pmTnAsiyDTTDEXkhdsSjS+65XYX3fNWBslYwxSyYRrrxZwPt8IJwP+uqdb9qjTs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550146; c=relaxed/simple; bh=PgCe5Ig4Hz5VA3Et4j2ZYh+G8htR5m2rXa4V0St1e+k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=caC3X62rXiHNodZUVmhDQ/E2CBeKOGpOJSZjeqI6JWQjeS0hPAE7zwfRZx7mqOQS40M9+tfKYu8oLR9UH/6yTmxTok1cuDgQhj4t5PyJgfvKT8uYPs6+PZDYhka9xoQM+unIbH08W4O1PTW6ph4zwkp5aaxHoTX3Z4d1Vw1YtBU= 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=LM8Hb4uU; 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="LM8Hb4uU" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-441c122fa56so13740255e9.2 for ; Tue, 06 May 2025 09:49:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550143; x=1747154943; 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=njQ3TmZpiHbN0W0T2NSyLt6EnFI9+R+BtiPGKvCoesw=; b=LM8Hb4uURESSM4OGvSD+GBhMfl1CIrdzpU3rNWSN6xMzj583v+pGf1udRFmVOsDBTr RAWpdWvCYamC20pUSfAXtwcrba81ZLnsoM0Z47w0BUOtbngOC15UapWHaheVfIQxGZRc nqG0Z6dJBC94sB8U99SQtrnriqOgArYTHjH9eOOoSAzYM6ee08tj0qj/TYMKjtEDStr6 OVeHdwRSALxbJTxWPRHExz3ivBoVdFCfmdam/0LNIAQtlBfh1/mAXVbSG6eFEVNVk/sh nspP86MKyvxA8tDQSqbQ7n8gUZ5FCNm1/Yd1wJkqHHHiTYbQHPxViXquhb69qy/qIGo3 CIyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550143; x=1747154943; 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=njQ3TmZpiHbN0W0T2NSyLt6EnFI9+R+BtiPGKvCoesw=; b=FZ8pR0OIoaBOGGlFFbxuSdZcEjzuHpb2WA2Yyqf/jFsx4koJ1KWQCCGIgVDCJYRd1r YU6yE1BRzn6ByiGcrLEmgQUt58J/vi1uSgYLvmQR62GZHj/3nXl6kjTQIR4cVLnacxvo /4e6NWhR9zCAfBTBrQs3dC8plNA8DpPrOEQLTUPWHsLmtLLTzzXjKOuHaFqZPLat2Tv9 D3XNYZK7gN086KmUP6TC4GyZNlpHKws6g3aoV2V6CuKfFCbSYiMs9dsNOrhdAXPQyiru K6ZoH8cXcOumzn1mPVaouqNsV8o1W5/ZFfc3l7pLpPJLlwwINFc7CqhPDusoJo+DYrhY F7NA== X-Forwarded-Encrypted: i=1; AJvYcCXjvKJmgBErMlRJckeKGVob/W39zd9+68PqvBEIHosbGzjztP6z0ejQxh3wneTiJ5YubqJYY5dpH2uvoOc=@vger.kernel.org X-Gm-Message-State: AOJu0YysHF8pCZlGreGkmSqj9WcLMkqmafAC69Dw4DElCQZvhXytiwha hKRkj0nbS3afzjlCdZ+KNOfVI/wS6PZDB3AotT7xNY3g+VEpN5RDGxD7keiHfyEaNkXD7LvkIb3 cfpEjSiVRUz03VwelYw== X-Google-Smtp-Source: AGHT+IHF02PKPiIhJbOE1ndD3uShLpPGP1nAp1HVPAQRz98xV5Rm4WeCONHAOCoe603i2rkE7H3ckkLeK9deDeKS X-Received: from wmbay12.prod.google.com ([2002:a05:600c:1e0c:b0:43d:1dd4:37f2]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:154a:b0:43d:42b:e186 with SMTP id 5b1f17b1804b1-441d0fcc750mr28382805e9.8.1746550143106; Tue, 06 May 2025 09:49:03 -0700 (PDT) Date: Tue, 6 May 2025 17:48:09 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-14-vdonnefort@google.com> Subject: [PATCH v4 13/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, 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 8f5e194eba71..a2f1489e11af 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -114,4 +114,19 @@ 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 alt_cb_patch_nops +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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3486928A3EF for ; Tue, 6 May 2025 16:49:06 +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=1746550148; cv=none; b=u1PRjW0X2/W5mlX6SvYsZrc/WdTEbunnUxAvGrY6S3/syQKuVzPX5aHiZpspO9/EeStAKIlVCbUU1faNRJm4QAVR5LDRGIMLWvCiCz1ZXdHmKsABvrF8uw0ax/CKRbVsPREBhqh3edcE7tUI7PxahXbE4yZpkVO+HNvQhw1VuP4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550148; c=relaxed/simple; bh=6nhV7XpN3WZyy+/QohB9tJlpXsrab2K78OgulSH7QaM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LCOyg6QT1rq3CoCGATa4eEOCkiqiNhki5aEi/LnTu7MhlkAUE1dDc5/sqa1l5eHZgOvp+yaQyjC9DdT6p3ttIjzLTrJ+qYvAWFcdFDsIp69/spcaMI4jZGrvcRLM7OxDYXV4qoqv2DL03Fk9DkLCcKchJjBW+nFlF0UvJdpbgm8= 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=z/vXQ5SG; 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="z/vXQ5SG" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43cf172ffe1so37656725e9.3 for ; Tue, 06 May 2025 09:49:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550145; x=1747154945; 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=Uwe9TWcp7UhmX4oZw7S8iXQCB83ssWQWzCZsAER4ojM=; b=z/vXQ5SG2Lb5FFKKn4S6VlCJcTBsktJpLTo4sveARv1pIA8GS9+Ql075PF4DWp+lrF Hq7d4NcdYz9nfCZh0X0OZduTofy9NbG0czHwbaBEixnGxP6zjc7hpBYPQQ11UhXQnktl og/d/+1I+242Vooh3ZYJy2IpmR7ajfHT2pkIegNi/PKMp9hB0eF5vIHdRLvPcFLxrBaz oSeP/VYvNVp4K/6OV8K5d592mW5iCtowOF2khMEvS96vty50J5mgO3NhF3R2XJ2DCbMz DX77G0zwAk+vyBUGPUVCWDqwDO+zVcuIJ4447Xv9Hszr5T9bFtQPeXr65eVNF+ALi6k0 U9sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550145; x=1747154945; 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=Uwe9TWcp7UhmX4oZw7S8iXQCB83ssWQWzCZsAER4ojM=; b=bxa+efWm0Ll+TEnBMzAvg0zKquUPrglh33jUsqCInq1UBlXcfXj2Cs0oD4j5JCShrL oyP/i+VPNcHJweR3FKhDUqKmlKm6ERIey7jw1ZkcJVew/Zqx3b83N+KBJFduoxkfBC3k LcInom8Mngywz26VJF8JaJc+Kb3bGO8L8ZRB08XmTtmFQ+iPCtGrCWBxMNzQj1EGwHQC g8qLjlbQOwX/xcJEWXuZ/bV00hGrrZKHvs6Eyq7Kbqq0dOH/GHUCu2NdzKyv2i5Q3S1h 0NFombtMcpjaR2nYY4lS5AA3ZxG35dkHGK2taYZLZYMtcaAy/h90/EED1xM4AQzhKqb1 2okg== X-Forwarded-Encrypted: i=1; AJvYcCUelkVtHU89R0p0yGQoN4wD/wpeHamTr2yBeSwfKL8uS7sQeFLc7qs0QQn2N+l6glnjdY0pHqlsl3ndvJc=@vger.kernel.org X-Gm-Message-State: AOJu0YxoHJS+MOwAR3w18Tnb0aVnUTneSrgcdeA58oxnAE8uVmx4DDCq WmtHu90e4oHxEeA8d+IUd28r626kpnSLCMwd3TFZj1CWRRN0z4QJHmPBFuoo/kRQBwn+nSgFwJg PXEJdC+s0cEg6QwcZdQ== X-Google-Smtp-Source: AGHT+IFD0lWDGk03I/L52reS0E96znl56Cu/MfnVewrpbgBLyMFf/ajBPFdbrDJBI3q4GHyXoNdIe4tdhRJb9WFi X-Received: from wmbz22.prod.google.com ([2002:a05:600c:c096:b0:43c:f6b3:fa10]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a03:b0:439:9424:1b70 with SMTP id 5b1f17b1804b1-441d054c884mr38006405e9.30.1746550144942; Tue, 06 May 2025 09:49:04 -0700 (PDT) Date: Tue, 6 May 2025 17:48:10 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-15-vdonnefort@google.com> Subject: [PATCH v4 14/24] KVM: arm64: Support unaligned fixmap in the nVHE hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, 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 f41c7440b34b..720cc3b36596 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -240,7 +240,7 @@ void *hyp_fixmap_map(phys_addr_t phys) WRITE_ONCE(*ptep, pte); dsb(ishst); =20 - return (void *)slot->addr; + return (void *)slot->addr + offset_in_page(phys); } =20 static void fixmap_clear_slot(struct hyp_fixmap_slot *slot) --=20 2.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 409B928A411 for ; Tue, 6 May 2025 16:49:08 +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=1746550150; cv=none; b=TLmPkpZZ4X8azDyA/fAghdWBzcRyOlgHj52/WWZncOmnox3ftRWygTEMyJQQkm9T/JnyD33GqL5HkyRVdyOepHKBZILydY8Pw4Mjes8qJY5T5IgmaLKbtE8vKwSEocxUlxj95RiePOYnaz7jqd0GmQ0cqG50fWOv+p9uw4+NXhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550150; c=relaxed/simple; bh=zOYY0EGgrjFCfJ3HkINdv7HvNCnJ1uSFQ5N/H5vv7dw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=pIDjy3uyslcIlUmxU4Dn5yz9WZqtig5jSpMQQXcyJDIrqUBPA69dBMBGM0DC6Xk8nnZhWYzDfWZri/O1c7WXDqq/BwDIjrtARkjt+bZosfY9SJ3vFOTOBwiiYRdkQlyRqREh3xJ+G+Gxg/1QMLCK7iJuMwx/88nxgL9/GgHFnO4= 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=YrOjUYRm; 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="YrOjUYRm" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43eea5a5d80so32398995e9.1 for ; Tue, 06 May 2025 09:49:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550147; x=1747154947; 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=7C3WPuCy+qpuZZVpz27zDoZpe8zx2Xoj4eG92N2KUaM=; b=YrOjUYRmlxp0Uvu0QD5qoz0MDekAtzjYytfhO/b19m1/YdoYSKwxKJpGbYUySCRwOX bJ50NAf0nle6AKhT/J2kCH+FGOgzUhL9OZjd+zBtrAL9WrS5ck4WUMMBoGWWhq/4u7Cu OgesCcvCWj8zkeEHjDud2NlfdyNXfdZs+rKk/4lg4Vv4ND43nUo7e8t+Pw82ysOpBfXW KrnPeeVO7By8LiAAcSxvAnINv5V18wMmVqYt2SSyyecZnaB5dIhy1xweaag4IQI/BtNh voHXg08p604HbjaRrwuhNd1FplxN613XJUfvQaDLryw3zr76MFftCLRIPTq19S3yFzGy 46tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550147; x=1747154947; 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=7C3WPuCy+qpuZZVpz27zDoZpe8zx2Xoj4eG92N2KUaM=; b=fWWAfVSJY24S82e0iagWfbw+jMNFTVdvpaguYr3XYTnrPDoLhuQSoXviQFn7J8IHi9 yNsbJ7oH7UFPiC12N/iuvxh3sxRtssRNqwCGoOMRXZUOZmTVvJ6PYsImDi2tNTIUzncY P4Kk6+quYQchwKNqu8CJbaCmvI8Iuj89ao6RrhlrH+rbrvdky0damDh3wFnXPLEnmR60 KI6S2nk5yZraUZkYB7fPH36sxwpWInmlo3/CKLSQoaFbSdEmUpEZ5gGH1F89yWPiaMoG 2+TFcg0hpj0k+g0enYTmP5pMCZDsNcApFjWzSIMADSPa8tolymg5ov5zGYyDXUBlb8GL SMSg== X-Forwarded-Encrypted: i=1; AJvYcCWz3vA0igjUY/uf0sS5h5ICOZC1ntnQ3ttdBkHnqk8e63QTdJcM3UkJe77NjX4qOJhupaEhrgY3ghs6+us=@vger.kernel.org X-Gm-Message-State: AOJu0YwHAE+ItEiiWDOPPm7dwBaj6kSL9aQJkR1/0FnENIdJ5xJHnJD6 GzOMyKtVDI4U8UbHSSBcKHQLad5Zl/roSz5OOdAPF7xASHkLDeTtvhOqhRIWF09aG1ptjOfyL68 xPe56q9Bw/4DcoTLOZg== X-Google-Smtp-Source: AGHT+IF7ojYXqkZ5V+iTaYolJ/Z6/ACckxfH3IbRRaRpxwKWSi1sy6gef3xj2zw6+90icnL5SP+LXnZpGd7RLvBG X-Received: from wmhu9.prod.google.com ([2002:a05:600c:a369:b0:43d:1873:dbaf]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:870c:b0:43c:f61e:6ea8 with SMTP id 5b1f17b1804b1-441c48b0293mr115167875e9.2.1746550146800; Tue, 06 May 2025 09:49:06 -0700 (PDT) Date: Tue, 6 May 2025 17:48:11 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-16-vdonnefort@google.com> Subject: [PATCH v4 15/24] KVM: arm64: Add .hyp.data section 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, 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 init of non-zero data in the pKVM hypervisor by adding support for the .data section. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sec= tions.h index 40971ac1303f..51b0d594239e 100644 --- a/arch/arm64/include/asm/sections.h +++ b/arch/arm64/include/asm/sections.h @@ -11,6 +11,7 @@ extern char __alt_instructions[], __alt_instructions_end[= ]; extern char __hibernate_exit_text_start[], __hibernate_exit_text_end[]; extern char __hyp_idmap_text_start[], __hyp_idmap_text_end[]; extern char __hyp_text_start[], __hyp_text_end[]; +extern char __hyp_data_start[], __hyp_data_end[]; extern char __hyp_rodata_start[], __hyp_rodata_end[]; extern char __hyp_reloc_begin[], __hyp_reloc_end[]; extern char __hyp_bss_start[], __hyp_bss_end[]; diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 5e3c4b58f279..9c5345f1ab66 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -131,6 +131,8 @@ KVM_NVHE_ALIAS(__hyp_text_start); KVM_NVHE_ALIAS(__hyp_text_end); KVM_NVHE_ALIAS(__hyp_bss_start); KVM_NVHE_ALIAS(__hyp_bss_end); +KVM_NVHE_ALIAS(__hyp_data_start); +KVM_NVHE_ALIAS(__hyp_data_end); KVM_NVHE_ALIAS(__hyp_rodata_start); KVM_NVHE_ALIAS(__hyp_rodata_end); =20 diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.ld= s.S index e73326bd3ff7..7c770053f072 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -13,7 +13,7 @@ *(__kvm_ex_table) \ __stop___kvm_ex_table =3D .; =20 -#define HYPERVISOR_DATA_SECTIONS \ +#define HYPERVISOR_RODATA_SECTIONS \ HYP_SECTION_NAME(.rodata) : { \ . =3D ALIGN(PAGE_SIZE); \ __hyp_rodata_start =3D .; \ @@ -23,6 +23,15 @@ __hyp_rodata_end =3D .; \ } =20 +#define HYPERVISOR_DATA_SECTION \ + HYP_SECTION_NAME(.data) : { \ + . =3D ALIGN(PAGE_SIZE); \ + __hyp_data_start =3D .; \ + *(HYP_SECTION_NAME(.data)) \ + . =3D ALIGN(PAGE_SIZE); \ + __hyp_data_end =3D .; \ + } + #define HYPERVISOR_PERCPU_SECTION \ . =3D ALIGN(PAGE_SIZE); \ HYP_SECTION_NAME(.data..percpu) : { \ @@ -51,7 +60,8 @@ #define SBSS_ALIGN PAGE_SIZE #else /* CONFIG_KVM */ #define HYPERVISOR_EXTABLE -#define HYPERVISOR_DATA_SECTIONS +#define HYPERVISOR_RODATA_SECTIONS +#define HYPERVISOR_DATA_SECTION #define HYPERVISOR_PERCPU_SECTION #define HYPERVISOR_RELOC_SECTION #define SBSS_ALIGN 0 @@ -190,7 +200,7 @@ SECTIONS /* everything from this point to __init_begin will be marked RO NX */ RO_DATA(PAGE_SIZE) =20 - HYPERVISOR_DATA_SECTIONS + HYPERVISOR_RODATA_SECTIONS =20 .got : { *(.got) } /* @@ -295,6 +305,8 @@ SECTIONS _sdata =3D .; RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) =20 + HYPERVISOR_DATA_SECTION + /* * 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/arm.c b/arch/arm64/kvm/arm.c index 68fec8c95fee..58e8119f66bd 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -2604,6 +2604,13 @@ static int __init init_hyp_mode(void) goto out_err; } =20 + err =3D create_hyp_mappings(kvm_ksym_ref(__hyp_data_start), + kvm_ksym_ref(__hyp_data_end), PAGE_HYP); + if (err) { + kvm_err("Cannot map .hyp.data section\n"); + goto out_err; + } + err =3D create_hyp_mappings(kvm_ksym_ref(__hyp_rodata_start), kvm_ksym_ref(__hyp_rodata_end), PAGE_HYP_RO); if (err) { diff --git a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S b/arch/arm64/kvm/hyp/nvhe/hy= p.lds.S index f4562f417d3f..d724f6d69302 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp.lds.S @@ -25,5 +25,7 @@ SECTIONS { BEGIN_HYP_SECTION(.data..percpu) PERCPU_INPUT(L1_CACHE_BYTES) END_HYP_SECTION + HYP_SECTION(.bss) + HYP_SECTION(.data) } diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setu= p.c index d62bcb5634a2..46d9bd04348f 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -119,6 +119,10 @@ static int recreate_hyp_mappings(phys_addr_t phys, uns= igned long size, if (ret) return ret; =20 + ret =3D pkvm_create_mappings(__hyp_data_start, __hyp_data_end, PAGE_HYP); + if (ret) + return ret; + ret =3D pkvm_create_mappings(__hyp_rodata_start, __hyp_rodata_end, PAGE_H= YP_RO); if (ret) return ret; diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 0f89157d31fd..c462140e640a 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -262,6 +262,7 @@ static int __init finalize_pkvm(void) * at, which would end badly once inaccessible. */ kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); + kmemleak_free_part(__hyp_data_start, __hyp_data_end - __hyp_data_start); kmemleak_free_part(__hyp_rodata_start, __hyp_rodata_end - __hyp_rodata_st= art); kmemleak_free_part_phys(hyp_mem_base, hyp_mem_size); =20 --=20 2.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8600628A416 for ; Tue, 6 May 2025 16:49:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550152; cv=none; b=kFqA6QuvRXwuu93SxmqondpSS/g+yBLaOm7SnPuG0xoRwUHI3z9fIKND5pn/WTmRgrrl4KKQckEIFQoQFAW6S7NP3M/0CWi8gFVpJ2YM6w50snMaaUbTqsLA3S/yyD7uloz2JrsXKNUwOfmpt5My7DxrHhZhj7MXWq98Z3J4PQI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550152; c=relaxed/simple; bh=uK5a0ct2ICnUqn9DjzHC3LReJzEGHdu5Q2c70Mx74pA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mdDDZsfZu/u0sO1yHjI5bxLoKQRikFCv3kndDXbrdg0oCcyRVtDzJGFHZSqArbAyV0Dk1fHEaitvuoyyOHdZ3WERxv9tnxu/iyvp7gQrCX7fvQ/6uSkKZ2QC1ZiXmAYJkdGolhh4vef9GDyuiz4lHe0UFI8cGhQ1OR6LFaJV5Fs= 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=z4RaSyxm; 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="z4RaSyxm" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d007b2c79so36459125e9.2 for ; Tue, 06 May 2025 09:49:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550149; x=1747154949; 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=PTKmizrXds5p9DE6J3WP7/kKkm1zSi2V0hVoZxXRS+Y=; b=z4RaSyxm+PFjNai2Au6r3FBzNiXbeB7tC3g1PelnEE3o5kWaWMsaZIhZgmyiXRROAM xKo+xRtHk+BUEa1W2iGYQR1DQrdy+H0sD5MDIsgbjiJRJMhoPA7FSrlDFJg6M0Qx4XV1 CHs44+WuFK7k21YYpBuJtptHxLs0aJQjW5WekiO0jvljA6UKPXjkSv+TYVe/FG+To5Ry 6QFZMnh1p8IPea46QqwCmHTo4x+KtiZnYeXAnjtrko6NRnw6SwExDg40111ipUubhtW6 cVbBgxfTym83TmQY8d06OrnSnc8bVvURtvj3mzTtiGAF5vevJVzF4P8VQjSxvHXEdzhD 5V1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550149; x=1747154949; 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=PTKmizrXds5p9DE6J3WP7/kKkm1zSi2V0hVoZxXRS+Y=; b=Wpxc11QHdy4nGOmUC+sa+eZlTjZzTp2729Ft6XD76KYbD9PZ+jYRHfLrMF7B37oUnP PciS2OszTKsfJpDlHuto8l6zr4LBw0TWh1dxG+dZ/BJAmiS3Ue/mgO2dWKqlk3KKFCLq OtpQzXNU2htO7wv909+5T7jxidbUTwzpuTtVaf/8ZhNYVM48BcGjrEWlBs/0jYuR/ffK dap6d3Qc0gI6KMYy0IneVK+5CmpCIp1KBju1OUl1Ehyv4rbHHhr3hj4cfULZ0K+Oq1Yp tIq5PAgqn8LXf/e7Lzd7OdYABaIfAPtiHzCuFY0pNifNv1IMT4bdFnJxaZb/9cc2vXHS +Rcg== X-Forwarded-Encrypted: i=1; AJvYcCXT4d8PRX9woNEM64/2xPvuP1MnSsmiAlPK/osSQ1lNCavWFa7hNJbvZWXKEMk70y2Dn/07ZcVMFk2kFaE=@vger.kernel.org X-Gm-Message-State: AOJu0YxSm4+1T8g/QUbiQsCzSXcObB1f5OOmo7yBLnvp8634ZpWfLTy+ 9v4INP2Kbo9W+7jiUVhPqowteaKbezYaGfEbwS8gqg8zm/Fl6vxzBm9vEihAC+dW0h/JWJEosSh qIK+rXmckct/G71r7Wg== X-Google-Smtp-Source: AGHT+IE2t1cIjH9YYJy8Ayf9wJ/0y3Ak3eh6UWYMS00LUPr9De3lPaQ9ChoJojhjdULWg+br9k0N5dgvgMI3890q X-Received: from wmben3.prod.google.com ([2002:a05:600c:8283:b0:43e:9aac:5a49]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3552:b0:43c:fc04:6d35 with SMTP id 5b1f17b1804b1-441d0fbd626mr38701485e9.4.1746550148999; Tue, 06 May 2025 09:49:08 -0700 (PDT) Date: Tue, 6 May 2025 17:48:12 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-17-vdonnefort@google.com> Subject: [PATCH v4 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, 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 b43426a493df..68d14258165c 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -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..879c6b09d9ca --- /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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A6AC28A727 for ; Tue, 6 May 2025 16:49:12 +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=1746550154; cv=none; b=qp89DB+9GyJb2qrJHcFgLAkbzW5qAIKtmmKV2iswhdONpWDiQSR720GMRMWlypZ7izMtxqgfJ34+Jn28TU9gJXht2OjmDxLKbAXletmvizmMDXKvw9hQHNRqGfCiu4jg/Gg9gT/e243OY2r0yUIsIiSRbRB9JF99tZNak0XSPYk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550154; c=relaxed/simple; bh=twR1EkvF+4dCiaWjfam2iKVcdGyVXXUe3ObQURDvCSI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=D+hcdnryeIHuOJcAXkbARjLTZikf9nf11R7KwIc9x2NBPKTGAVjmGUld1YHVSLbRngVv6X8tApvuSvZNwoVs53DcMlq7mAenCGwMGWQSaj2AHSZIwS/UyAImhVpdOsWR042KqzqZTtMZgRS14/K9BnhxLyvn+kDHNC1xNvLbnTw= 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=EWLTplhx; 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="EWLTplhx" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-43d08915f61so30373115e9.2 for ; Tue, 06 May 2025 09:49:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550151; x=1747154951; 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=lAAlyi8i5QHrR6Xk4GSGpf1oHcTMIawd8GsRl0y4wEQ=; b=EWLTplhxPlwsR2JKcETLslctWQE88zi9mfc0tlfq7kgGBfU+yZZ1wO685qgOqxsN5e crEUdzrx/c17KY/+gfiEGKSfnA6+nuIjjuV1uM21eXg5Y0ws1f/8wJ0dBNeHfqrzFhj9 SFGKOgtyglDxizCuwWjB+fdRr13R34DAmrfuwqxlMOJDHROOMliHVkezq5dEZN8Dn672 wTf5jIISSNuWXQJPZysVBnnMw47lJURagRaYw7fOjpEDYR8c1oPdXec/CceEWmpLue95 W+uHPuvG8dOPTDXKstLYh72yk36eqN/DMT7VqiPXO1eIzE2tbGAbnQUTSgFQ3LoaApcv itvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550151; x=1747154951; 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=lAAlyi8i5QHrR6Xk4GSGpf1oHcTMIawd8GsRl0y4wEQ=; b=muCpto/ebwJvm5FiD5JmDJuDevTtyv0OVQmXfLtkixup+lwbsk87Op0sMbMeo3fDMo 2qTtupxBYjfhL2oqCoo1lX0OwegbvCoZXBIySfK8j5XJfeXq6IH9cXQdBwMF6e3UkG/1 26Lea99splLxCyOWvpo8K4uhMh2AWFFbtRa3oi7DKc0sncWHre6N5H544f3whwpXcES5 VpP76KmeLI9IUY9QnouRkHmkSJtAjgQ6ddnjwKOr8V5k0Y51xNsUdPLcZot8ZPP7GHXl GdBZXSqEHTJLzR5mxXXdDbQPDW7KPVwWjQvYrlew17MOS9r3ALfEuzJlyz2UQHYm19dS zYvQ== X-Forwarded-Encrypted: i=1; AJvYcCVrjg9BWQc/rw0pVn9LusRr5XXuV5HNqgbKoGF8HlbAQIobgKtq7o46+HMoFj4vGya7U6XCxaYjp36h9vo=@vger.kernel.org X-Gm-Message-State: AOJu0YzuLNZcJ6uOz/20/VO3r+ZueMt4AOdQ7vJ0ASz7P+JCJfj1PjJ8 lDz1Ct1Ig6rvH/OLVcMsfLk0HQqESv5jIzrJkTAbTUrdLIz7rwEl3C4X5gEQpS+DqTDKZM6rglG NZLCV0MEoawIkQCBilQ== X-Google-Smtp-Source: AGHT+IEMzaH6ziyZosbsHwdVlNhIcRDkSOXaTA59uflinYqKIQxGwXZi4w3vk8MhWJyj2vdrkeTXx2YsboucL30W X-Received: from wmbel14.prod.google.com ([2002:a05:600c:3e0e:b0:440:5f8a:667c]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1d8f:b0:43d:7de:16e3 with SMTP id 5b1f17b1804b1-441c49237f4mr105082435e9.24.1746550150829; Tue, 06 May 2025 09:49:10 -0700 (PDT) Date: Tue, 6 May 2025 17:48:13 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-18-vdonnefort@google.com> Subject: [PATCH v4 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, 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 096e45acadb2..f65eba00c1c9 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -83,4 +83,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 68d14258165c..6d92f58aea7e 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 2c37680d954c..68b98547666b 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); @@ -570,6 +571,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 @@ -609,6 +639,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 168DF28A73E for ; Tue, 6 May 2025 16:49:14 +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=1746550156; cv=none; b=hQPcXv8X0jYuv/QEC0YYJYDh04YoZkYCh2EfUZMyCwOYtjG5JBLhXEjtWRA/9ngZe+oUEEaAy7JZMBjNOjvcYiHyLhtgIKpTdU6LHaEfNAw/E0Rw907c/N7douxh3uwp3Eq/y+ajRGkl2+aD2RWE1pK6YNuNQBy05lTF7fVbIzk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550156; c=relaxed/simple; bh=4kpDY7VA9GH/QiTj9sZ30jiQCPNvr0OCO9mC2vYPvr8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LXjLOC2/LYKHHpAd7lCaUVeD7Dz1djFtPFqvcXD67fADdrZLtcXsIQfVAARFmnzqS6JQqO1AK3tP8Ycc2+vigzir2TMtR/H4sTmXj/mDA6Hc1QGzOs83IrmDd2rG3CjmZskz5SIFNRwa4wRywK2dMuvV5z2sRmUmlDd16hKXh+M= 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=xGUERMGZ; 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="xGUERMGZ" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-39143311936so1611282f8f.0 for ; Tue, 06 May 2025 09:49:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550152; x=1747154952; 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=W9MwmVHyjbiE0UGKdOkG/nKnXhGzmuj5oAsbld+rHvs=; b=xGUERMGZS8GyGvIDuKjaRawe94idfMG7FcdbyQbKxRxrOvkg9p39lmZCKV9RHQO8xx 482ILhTqL7WqsS5BkSXtN4/1jlfkfhGi1Spi4SVTk4a5M3d1EyWc8/Z4IbarN5BJJ0Ti /JabpZVW/SZsXzELt6w6918U3oz63HFI4597INuacFMvOCeirVo6li1XJqzvYVYNj+8/ N16wz0VfYX8UEN0sR/wi6UyCn/Yd0oMBJPSWWUUU7stifhdn92H+MUBzg+kEOXZHLcZn t0F7TeWF0jrueMZnNhgibg7bvI4yQ8WJjwQ8J2we7XQzUky173XD3wAE8LihVzS0PhGB Ysyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550152; x=1747154952; 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=W9MwmVHyjbiE0UGKdOkG/nKnXhGzmuj5oAsbld+rHvs=; b=XNV682HFnHu7uySxQcVISGG7kQmsuwCwgBem45p1JRc7/nckmGis3v6zk5VYR3gtTa 30wj48cy3vzZmtIEiO/65drkmO8jLfPvRWJZ1Q7k1Ia1QX0OYkAWzEfyDlrX1Yoy0z76 UHXo21+rPLEDKdvIPTShLXVH/GxVtzMRpsWAXZ8LBbqUEdIItKn/6BUct+sctpzyg+HN n74QuHnFhvdM0BqfzR/wlcfj2uv4NEIp3hsMEoKIttvrITLrNEKriQZ5hciW9WHDlgZu ShQn+KMiGnKmg+3BlUC5FaJtidblL6p0L7ya+emBK6OCPiWknqoyKYRBzGomq6oW9w4W qH6A== X-Forwarded-Encrypted: i=1; AJvYcCX8T3N7uV81uJGJqTD0iOtV+fPCtmWDswFFP8FcEXhFiaFQHsE+du5/DELqDdKhptJimGRaYQPRtnXBNaA=@vger.kernel.org X-Gm-Message-State: AOJu0YzE0z1vVC/bAGpqvaOj9NWGjqQWhgz4bHTf0uik+8jxtKvxS6yD G8rivNIwflKiNyYsHRN8FY26nEzO2IBwo8ct19YjiCJQeUkj0nRqvGO8GEE/4uuHrbNS4n0G7ir +RAcYGJySNBYOfVkQMg== X-Google-Smtp-Source: AGHT+IGiKCS8wdkD9tOBTL+nED1QNv0Onsf2jiW2FFXnwD+M/CDDw5lCerIFtYleGxjGbo8PT5lZ+cBBBAXTu/Zq X-Received: from wrbfu20.prod.google.com ([2002:a05:6000:25f4:b0:39a:be99:a101]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2af:b0:391:3157:7717 with SMTP id ffacd0b85a97d-3a0b4a2369amr156953f8f.34.1746550152797; Tue, 06 May 2025 09:49:12 -0700 (PDT) Date: Tue, 6 May 2025 17:48:14 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-19-vdonnefort@google.com> Subject: [PATCH v4 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, 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 f65eba00c1c9..f7d1d8987cce 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -87,6 +87,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 209bc76263f1..fffbbc172bcc 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -29,6 +29,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 58e8119f66bd..bb800cf55cfd 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 @@ -2355,6 +2356,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..6a2f02cd6c7f --- /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 NULL; + + desc_size =3D trace_buffer_desc_size(size, num_possible_cpus()); + if (desc_size =3D=3D SIZE_MAX) + return NULL; + + /* + * 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 NULL; + + 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 NULL; +} + +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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D880A28AAF0 for ; Tue, 6 May 2025 16:49:15 +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=1746550158; cv=none; b=k2aRcKyieQnQ7vbw/TBJY5awVjTTmcGK6rFM93MxrUloTQWSESXuARIOzfmFqncQ6+sgK8S/X58M/fK2ldSKI3t8Rg4XkpVO6XrNlxfFKRUjZS4WW5/BAA/cyc9PyViHM+4gfSLBn5mFK77GNNzgHiRv1gQ/qFwhLRLzb0BK5C4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550158; c=relaxed/simple; bh=3BIqRbp7l/+K+M0fkevSpC+6+UdZtMpJ2B/pjcLE2Ts=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XHpX1NJ7ExmKpKuWpW8rwaJAIT9ndxB3lw+cezD8q1Td3PadN+Pmrls7CIYGCbdmwEYz1pZFpB+eubli3rB8BWxmpv9AANoymgGbU4BPirw2HaQdVvbBsfTa9G33J26ERjy6U33isHSoRGmrpu6uqEva9lg1kd9XS/weZp+b9MI= 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=fKx/Nc4v; 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="fKx/Nc4v" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43cf327e9a2so43592715e9.3 for ; Tue, 06 May 2025 09:49:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550154; x=1747154954; 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=YKk1FdHAJ3QZ9gDgZu6MsnjKVYmcvIJLKFW7U1IpSww=; b=fKx/Nc4vXgI+9Lfj30JXPxazDsvDBq2EUSjYn3qSn/RGiOD8CcfdUt/imlAD/ItkkS gIBaaxe/dJLmvtYSd6dbvYnb5XM9Pup6MUvRMdlD3i4akIpoM7XYHVkOlt1IZtV52hOY wJUuhfTwqX8mGMAgOJC6vNqapRwikdAlWp16oaDSm11eH4UF0cXx28yqy3xyNAY9oQSq UaWbQfa4PdeFzh8yavCNBID3Eow8wwxpCdITlwJ6SLJMxAqCIMvHslQgtcjzPGp0SwqZ JnS26uOOMH1Y5yReFlIsMMHsgYx5RlPoDS5UZxqLGwAUmfh7efe2g13S2zdy5YYty9Dr nzMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550154; x=1747154954; 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=YKk1FdHAJ3QZ9gDgZu6MsnjKVYmcvIJLKFW7U1IpSww=; b=ACrBejkrNrlJEqZQUGjlv2PAVgVaa1PaTKgoU8PqW4R8QuPVUOYTfDbTjhUQZxMRf3 KtuiFQE6KWbGA2Y/w+8U518a31DSvjqoWKtIIv6uOF/jAF1e+MAVYcGGmmLybsPxngwi jTV6vGgXnvkjtGGHVDHMm4ZjFjA0D3gzfjBkdMDejEmSsbGjp1Pede3eijHt7RzqOHlX 705p9VH8g2eCN5ob11yJJa8BhSGm3dfNbxdl2GrW49Ud14vu0JyIccIOCRGDvUbk4z40 EFmYANIqTXBDE+b0fUv6LBTlwDn6TkTqjebcyEC6Kbkq+R5W7dDLj0Y++pXa7gzKeVoD aLlA== X-Forwarded-Encrypted: i=1; AJvYcCU51Zq7mfFgM+hsykeqqddBtiTwGZgHyST41j59QfzMrJXgJj3RkOP0zX+NRJ4gsRwo8Dl6uniT1XNPYjM=@vger.kernel.org X-Gm-Message-State: AOJu0YyIHgcjPVKqDb2RiujY+si3mScoXCw+1nHYbo5WRVMcvg4prYJ7 6LZzoWyNt8Hxdifsz++5JpAQiMBhy4FTVP8Qyop81zjmpmFLxBDsFfxpEJ9sAw3RgbvaV/xUlLX hsTTE/ZeU07AOXrWfuw== X-Google-Smtp-Source: AGHT+IGamB1lemyB+euLqAz2hGwpijdOegeg334sXoXBAv0AU9+GleU/+cXxDvHulTTHjqg0FawlQOcinY7pvQ7q X-Received: from wmbay23.prod.google.com ([2002:a05:600c:1e17:b0:43d:522a:45e8]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3ecb:b0:43c:f64c:44a4 with SMTP id 5b1f17b1804b1-441d0fccbeamr31223855e9.8.1746550154653; Tue, 06 May 2025 09:49:14 -0700 (PDT) Date: Tue, 6 May 2025 17:48:15 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-20-vdonnefort@google.com> Subject: [PATCH v4 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, 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 68b98547666b..c73229fb5e1b 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -571,6 +571,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); @@ -639,6 +651,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 6a2f02cd6c7f..516d6c63c145 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B55E128AB0F for ; Tue, 6 May 2025 16:49:17 +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=1746550160; cv=none; b=rw3DurJoZdxA6SHjELvT5zdMDHWtIrqJIJjLYURtNorCD2ofG0pPct/9MuLXMWZCxWxG3hLuFXsFCKyzsSP/hKG9+uySPFtzhGQjBNTttnrbI84BkZaY2VSAvHKBcV0ufBje0wTxNLzYZSJmiJzgIZV8V/G7VKXjdv35w3mbCVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550160; c=relaxed/simple; bh=HWOYbsDUxc8qUhWnwL3PLIP7jzejBZmuG99iYYoDR8Y=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=OjZP59Mz4qmFh2CQFzw/1XMXLBamsHg1GbAEDyTVEYSDiC7XNqZMaR+7hv5VAovVIvnTeawokGAdQH9GfwYbXe5QaVl8UvaweQNL/aiHJpG3WvM9M8wvePlPUWfgLCA5+2QZoy8eklY/+Dx6upt3jiH9hioyjS5QTpZu03jE3Ug= 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=qJe3mQT4; 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="qJe3mQT4" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43efa869b0aso39478125e9.3 for ; Tue, 06 May 2025 09:49:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550156; x=1747154956; 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=ePdWTj+f7Kqu7+m9jiLxrLe0rAI9On0cOEvt/oNt0Dg=; b=qJe3mQT45f8N8x9qY1+sJ46axQAT8l80KsFYHDjYkMZRDtDZsVvdY+RGlTx4fe89zy SQnm532hmjIQeYre8X4iiHt+m8bfc1I+LGLpQZ0ATROjRKJPX8ESCOl2NLbyLEv2v2TH XyTQa1G0NKYml6iRoOksHTaMupOShI3pSqpRmYz8aYLKtoyWr8y4MzP7kSNZfmkIRRiE 31O4yTNBoJsJz5Oijzw0Zh5g6b7Mf5Ibx5ovYKGcKwSG4eqQCPRsHx2HLDli3t8SiJbl wI3rmNbCGnumgs7hWUROC8iFcQ+eu7ACLoctMOSWI3fuSUQl9NH3HIJj7cy/MjHVusBL hZCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550156; x=1747154956; 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=ePdWTj+f7Kqu7+m9jiLxrLe0rAI9On0cOEvt/oNt0Dg=; b=R0lvT4KDKkDPKotwMZ2aTq+1N6Fdkv+ERh7RdKhWLMGfRMi7NDsm8wbksd1IOTAttk OHncOpX4DVBjH22qs0RvE9WEz7q+83+RnuIYd3SvU2vb1tdi4NrHePC8ofkwK7rHBUZG BTh0nOWB+osiJVkJE/9o51X3qVJ2NHzFWt5EDRpN537MhsZVE9XeiVgek3c3+GCAFHAu rr8Mx32yLKbcgwxWKzkrmYIxI+3jP7ezHqJkZXbXqnAWYMB/I47SsVokssZD3rQvPakL AIRieL2bWonN4LRYNoQcznUOKqd/GI+AN4+Ym2+q+WX1klWZYktNyxRSLnnrWke/Q7oD m0sg== X-Forwarded-Encrypted: i=1; AJvYcCWUgm7MBY9K7wyIKKdZ3TlLF1BvwGAESr+cES/pHSKv2cCwRwC+HRQJyhULMzB1aLhW5VMKQd2yOgzZ1E8=@vger.kernel.org X-Gm-Message-State: AOJu0Ywv+kgiMuXSdeU5xNdSHJFInuuMs6lqaI5uWancSe2FGBCdn/Ca ues40OyM8ph1mn34DzOGTiqKApdn2PfZd2tS0FNSfo4LUtvUF63JGfODUMlBvYIKy5O4/mDPZW9 p3299AD1OS+ay/zW8rg== X-Google-Smtp-Source: AGHT+IE88CHvP/t9XPxkguhLrXPQmG2IBHH3TFTt5TaGD8MyAacD97EJhOSmz1XBYyXVpAsyCZjhZpA0WwLhBaP+ X-Received: from wmbhg21.prod.google.com ([2002:a05:600c:5395:b0:43b:d6ca:6dd3]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4e48:b0:43d:98e7:38dc with SMTP id 5b1f17b1804b1-441c48aa36bmr110506395e9.5.1746550156444; Tue, 06 May 2025 09:49:16 -0700 (PDT) Date: Tue, 6 May 2025 17:48:16 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-21-vdonnefort@google.com> Subject: [PATCH v4 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, 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 c73229fb5e1b..65260bfd33ac 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -605,6 +605,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); @@ -655,6 +662,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 516d6c63c145..c7ad36212a7d 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D768C2857F1 for ; Tue, 6 May 2025 16:49:19 +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=1746550162; cv=none; b=QB/SqCTtGLjPbeP68Nns6qyb2DDLO4fUxQut59x33YYFTvIFk+niN6QVAzvjEwnjCjT4B6hyZKClwYuIl6mGM4T+mMPaBk3gjOS3RaVStcRQI44XUCVcjru+PqFKpfrwg1UAYOpNNPfUldtNk6gneWJufGH2ti3VWrZcs+xz3CI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550162; c=relaxed/simple; bh=ALx/PW7FLHSIjTfXPexouR+n5HBrP9zgi0897V52lu8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=roTL29z/VpRHblZQyNZnTNRXZ982lwtJait6CDg4+29c/KH+Fz0qN5wasfjCZuYB6my6oJUl3P53M8xk4WdfrLuq6gGJpO8Du3HqeIeNI+aBRlJq+yvZTn1FeY+QbUxyzFfJ/Pt8D7dVveNo0xqu3QeSbvobKUU0q2IbI0L0BI4= 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=ikN3EHbv; 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="ikN3EHbv" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43d209dc2d3so27642035e9.3 for ; Tue, 06 May 2025 09:49:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550158; x=1747154958; 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=AhqBcSQ/v7yG7x6b74IrhoArAfr1M4atT8I+RiFMj5c=; b=ikN3EHbv0xWkopeUORpddvHd/yqWUa+9Kp+Iz3Lik6wcias+MiTvi5MrqQcO3Fw/SC 7yy7aMKICdmFpnFMwklJkGaEHx5rDmhfQpfYEktWE2s0XIl+zfEWhjweHp9CBmeHEtVP bonkF2KRJWr6Ufe1dU2hoJFtvQ8mVyrCl4WjYcLjxQudxwsE7iNEXQ8ObsZQMQQpNTYq 29nZ2sMiEnmp2+DzG7vPJZTiPhd4bX7a/0O/66DO7F7jTXM3GIbx2LJXe0hyLAESt4Z1 djkPX6dPAFTy/Joig9+gJtjM5VysXHqOGnqoccm/CR4R6JdVTEX/TRNGCkyscbDJzhlv 2DXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550158; x=1747154958; 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=AhqBcSQ/v7yG7x6b74IrhoArAfr1M4atT8I+RiFMj5c=; b=HpzxjH8P4kW3k/DOVO9zl7ivYSv3jv19TKgkZB+jOHxUo42zh3x+pXV9K7bkH89keM LdwJSyLLb+ITiA4ZJmtz9pttqPNf6UTWuxZYwJhPdsWWjPox9QR88HbfMDvpL0b3IxLh /BFDREsxw7cmMjMg0cW93NGNo/yUrVDUgqRqaMU2zY6FJsuADXVrKG4PkurilVMjTrBI PCSkYnFZQwjnd422wK3/TMgdvEYUZF/orGkxZd5902PZFFaobYGUrCyLYJVLGIjVefOV nt5Ry4Xe+5na7bXWcdf9pxtgSnKIYKG2oLc5vnQTsUX6mLfyNzBIdAbhZ50QICJEDi8m M3TA== X-Forwarded-Encrypted: i=1; AJvYcCVe6LpXOn3pvjE9iKRfohslHpEJYjutK2QabNjTcuptgNavFcNMnOYYrM2oMNs/ijv50EgnAntnVXXoQRo=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6DNfraqy1aXnYalE1WyXqnM7bTt9CcorhDPjXCE3xdoiQqpuD MeIsyP+6ln0hAqK3CCuSEZlCnWou3vKy4OaSMZCl1wI81KQ42gPycZq2akVCnfWdwL2SFBd+6Qh T8Ydp2u8/kxH506hoNQ== X-Google-Smtp-Source: AGHT+IHVPnnFyhsuDgD/edqz8SzmkFgOGjzAl9qJEZTkau5UqBVfPHTuapj0/9ixNRRppMrePMhn5eJefdgB1SPd X-Received: from wmbhh5.prod.google.com ([2002:a05:600c:5305:b0:43b:b74b:9350]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4ec9:b0:43d:7588:6687 with SMTP id 5b1f17b1804b1-441d0fccd16mr32642725e9.12.1746550158258; Tue, 06 May 2025 09:49:18 -0700 (PDT) Date: Tue, 6 May 2025 17:48:17 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-22-vdonnefort@google.com> Subject: [PATCH v4 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, 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 9c5345f1ab66..7466630ecb10 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -135,6 +135,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 7c770053f072..c9baff9d6f3a 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..09abbc8113ca 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -1,21 +1,51 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __ARM64_KVM_HYP_NVHE_TRACE_H #define __ARM64_KVM_HYP_NVHE_TRACE_H + +#include + #include =20 #ifdef CONFIG_PKVM_TRACING void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 +#define HE_PROTO(__args...) __args +#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 +54,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 6d92f58aea7e..1467c9f28558 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 65260bfd33ac..3d36be6d94ca 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -619,6 +619,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 @@ -664,6 +672,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 c7ad36212a7d..1a4313362aa0 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A516528B41F for ; Tue, 6 May 2025 16:49: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=1746550163; cv=none; b=YPS2Fb7im45iZrhRkDkgULCUrlmzoRji/ZIuifT9VSIBjY7+oAKvIObl/3WPg+SgytIi9ofoCrow//0loq0o9GCNzglzUnbwfPg/Ygnkqm0phGvh7a2ScufZyIhv0RtXrBnHSnym5hkdy+EJoUyqa8VVdTsaNeUeAX0nuENJIQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550163; c=relaxed/simple; bh=torEYCq9v46z/4CnJ0hFeX5w0LCijhb9CNJxYaNikPo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=itKy8xyMI3VfpEIIZLsDZgj+yafkOhHEc6B8GZVbt+MlAY3bzL4imCg8ckRIeJvJ/EpZmdvPNafp79KSA4xYsA3+KFY+dW12So+oTymbZ8V8dNrPBUETpksMhcd+o8tBmI24DwpqBhOIK+yATzU3axCBjY9rGpPHyzQdB4nVnr0= 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=gma4B5++; 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="gma4B5++" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43efa869b0aso39478635e9.3 for ; Tue, 06 May 2025 09:49:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550160; x=1747154960; 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=sP0+o0uEsWOaDtIvEsCo5unr0sfd3Il5igHJZ3qKciY=; b=gma4B5++r9jhYde2foiUjTEK94LfAg6Eess6cId4jzwIclu4KMeCpw9wuxTz0T/XXu mAWPrv98VO+fHguksrph6cwzCHt0H3948vCpJFgi6IKP6csxX0rcpsjAT+TXri4/W1ds uTM/38CCnUhf81YXbKDnHtEJryDiofLA/RfrL3vADU8SUmBfB8mXKQLr9fnew05rTkVK G2CNbUiW2+ZX/LRvohl0nI53qhc+ejLdkBSqawCrvU8v3n7PCxh3s8gC/qCRtJ/6Ti9C 81oxIqAVxRF2TacaxI5ep4CIltJHLrXqn1krRYndabT6IdahQ2TVnVwj/ZVQlhc9QPUW A7GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550160; x=1747154960; 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=sP0+o0uEsWOaDtIvEsCo5unr0sfd3Il5igHJZ3qKciY=; b=utUFP9ABUuOPCIWEXe0JcnV05Wn+Pdv1rXxtSG/FWETurUtVbGJgesjMNoXwHeOe4R 64Ktz06KN1kv7LQRjeVKbd1MnHf2O7sdGIEtezzgPryfQg62zX+uFFRfeB4d2V8Ky656 kGBWhtZM2Wp6l1Xp1LT73JscsRRfvgqGYxFHIeryKkQaRjjtHjbwVDilK/iyNjOzUbO5 9dRdrvsrTMSF3YOrj9em7Ic+Riu3KlZht8QVlowImoqH7vOtp4YYHrk2fVYksTPKjefe Wo5pFsLChhc6jEZgOQ6AiJ/GKAo8k5xaUS3L7PGNewz5MCPFNQsQRLc7le9a6NHhCGYE vm9Q== X-Forwarded-Encrypted: i=1; AJvYcCUN9oSuHr7B066fd876x7+3qPiiaWZGZPnCwvIitOwFcBK+xvGdioTGvuDEn/+QFw0GiurDmlgu8YVOao0=@vger.kernel.org X-Gm-Message-State: AOJu0Yyk7gcYYGoLtk3/89D+q3665gY43zqscjaS3pvU+fPxJn12zKmH bvrX+VoPS3Pdm8xthtH8C7ImgCII1/aS+gG6KSbxSxhTqeW9HI0LPq02KOnIfOjqmWlzMuNPTwp iGscRjaiv2+JobhL2rg== X-Google-Smtp-Source: AGHT+IHUuqs+r3rhJxv97f89Ad2Z2eXd2asFXzm6hFHj+5AyVi1/wxB573CGibob8tbRu/wOxVh8rL3Ar7Iep4nH X-Received: from wmben3.prod.google.com ([2002:a05:600c:8283:b0:43e:9aac:5a49]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3494:b0:43c:f5fe:5c26 with SMTP id 5b1f17b1804b1-441c48aa314mr122683335e9.4.1746550160430; Tue, 06 May 2025 09:49:20 -0700 (PDT) Date: Tue, 6 May 2025 17:48:18 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-23-vdonnefort@google.com> Subject: [PATCH v4 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, 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 3d36be6d94ca..7d7d0c07a6d4 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 @@ -713,7 +714,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) @@ -737,6 +740,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); @@ -751,4 +756,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 7d2ba6ef0261..bbe035acda89 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 @@ -349,10 +349,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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 904A428B4F8 for ; Tue, 6 May 2025 16:49: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=1746550165; cv=none; b=MbgZVssK8+S6L1o6bBWCj2nPWMENNe2hWey3kzBLPc16iUPf6OvEwHK39XG6G06f4S03Ak+RjRSO0GA48Fe2Dx9/XbHfWkjwPIyT0oPEMs9VF8IPpC4j3ajtGXn1MtxJFr6Ke2sehYpyQWfnaUvXIs4Qjs9dvXk3DDdEbBTKs/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550165; c=relaxed/simple; bh=SXTqbOasp/TqdqW1YsbgPK8z8iSOzKeN6sV6qzo9fec=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=ILVK4o8eVb55GKi2GJtAYCyOIQxNdQxQDkFw+TCA/ZM18MpxyRYqNbjJEyLZx7IRhG5XXXhwU8/FMaxBiqb40/CsoH31KCLIAiWIfdAhLiG1CkMcw+WVTgp3EnGiHs+KqXRHH7EhZq8tec9XhSfctzPW9NGk90L8ikZ4k1pYxJY= 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=Kd4Cfzdo; 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="Kd4Cfzdo" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43d733063cdso43215835e9.0 for ; Tue, 06 May 2025 09:49:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550162; x=1747154962; 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=BvNkBXky1rMWTOoRULydoN1R7LqdNRvlY7olOpHHYgM=; b=Kd4Cfzdo6owdZV5zSiiCHqS65T/StNPB8GMGzV1mCuK1MDOLs018mWpNqaJe4T8RXM zeaLAPb6jiA705OPIF28EfcvQLnwswJ5FZEpCCEiIxpg6jLIgYqsyoPPvun7BgK/c99z xorvTGtybQ0T3yj+67BqVd5oidySZxifR2018euihT2emIJOGi2WWs42twdRF+/iOesp uajrLrU0ReWvzkDBwuNCQgW4juxZ48lCxILgzfqlb7C6m7fVf2WXBGYMTERiOlkLxP2J xhl/5M4fU/I3XgluzVLSnLIvA2j7tK8/4UdeWCLD7XL0EKcB4demRBa+1tAv/bNn5abZ mOhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550162; x=1747154962; 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=BvNkBXky1rMWTOoRULydoN1R7LqdNRvlY7olOpHHYgM=; b=WUjlrsw3XLhs7XumRkThkB9+4uL8fbfBNEzqY4ZzKD0gwjiPFGLb5qQRrajSxPx1bX JJV1KEPq5ojF4Bpb1yiAKfAo36LHJSQpAiXw03F73qSUWgA/mteHw5Fea/zeOMDdatj6 uI4bFPBcs422ltjiGCgP7PI/dVfoZOZp+axoS5rUY3tCp9DFNQxS0Lgg6PxWGq9OGyAs ssmUwxSOnSygcw8DGHhgfVZn4o/5UibIrCbO7mQwXfFWsB7HL+Qxye+5pHBuhsTfsd8M aCvfXqlMoQiOMYbWP6PPuAqDYPeTaAOo1+In11He43V+IW0J+SvOycDLYnB5FWHMpfkt i1mg== X-Forwarded-Encrypted: i=1; AJvYcCXgWp7SwCjoC0tbBArkqGt0wQhWvWu0zCchnGVvWwgxhqaKbrsc0MJLRm6Tz6h9IRz+8k6OvmHwIP8DU+E=@vger.kernel.org X-Gm-Message-State: AOJu0Yyax+INjQ57xludUXxAZ3cKbr7VevmiOTXQDtg9Qnj7wyVpzxe7 9uzINi8HiESlVFPs9bRqiiWcH3oQcRUF6LzOm0zlGluaC0LQEuXCXYu/2RSinDafgicO/KgHdVP fcn+1zvwcYyrY9rTU1A== X-Google-Smtp-Source: AGHT+IFKrv9e+xqEfJtd2WRNi0C/3aV9GxXet9wyyDu73BVkgka8qgyhXibytzzFcNtjbq2/6XJRmSf3F2kX+J4p X-Received: from wmhu7.prod.google.com ([2002:a05:600c:a367:b0:43b:c7e5:66e0]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4f01:b0:440:6a37:be09 with SMTP id 5b1f17b1804b1-441d0fd26fbmr38538295e9.16.1746550162319; Tue, 06 May 2025 09:49:22 -0700 (PDT) Date: Tue, 6 May 2025 17:48:19 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-24-vdonnefort@google.com> Subject: [PATCH v4 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, 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 f7d1d8987cce..333824325c9e 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -46,6 +46,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 @@ -83,6 +84,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 7d7d0c07a6d4..e6b45631c48b 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -628,6 +628,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 @@ -674,6 +688,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 1a4313362aa0..ee3af685d8dc 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.49.0.967.g6a0df3ecc3-goog From nobody Sun Feb 8 21:17:56 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 785FE28B517 for ; Tue, 6 May 2025 16:49:25 +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=1746550167; cv=none; b=XONBMohvev/D4k+y69lBflf8pvB5sy+CertiwQ97wstZlDxoqLpFZ7isn35ZY38A5GhR2CuIJ0lckIufJKBaZXppz820QrqGQXqDaAwdosq1Y20SBvLNEDYftsAZqvFG3FviF5VbU12WPrv/s3KXgPXg01M8wADnJW7pskqQ0K0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746550167; c=relaxed/simple; bh=RUCw8tASqS+xDOl6+m21B7MoC2GnYKahCqfxjmK6wVI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=d5DAeapJzyCDIIQNlkmU/a0C0HqiaHp3AnxMoEf3m4sH5v1tvCT0SkgFNGayt2PgGblH8k9PQRxxWU49YBBIZrTodKnl5ntXvCVom0qphFl7928VF8Qc/IGc2yKkcuNXbbTZoD9ZqUBhvcfOUmiVkpX/cWs2RKVGyuL/0UTKJpw= 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=2Nk/NPQB; 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="2Nk/NPQB" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-39c30f26e31so3465775f8f.3 for ; Tue, 06 May 2025 09:49:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1746550164; x=1747154964; 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=Zaqt2aF+R21ZLRZCmibO0BCKtkQEu5NrJjYtBghM3iU=; b=2Nk/NPQBZLGiLd+j1OMus+upc3opOayALg7QgdSZ0AURVrUJusoh0AfyhY9/mi+PCy 9Gj1uKpudgiFLHmxjn7RQcaYz9JPnZPKg7qSyEsH8vwrPYKuPMCh9VXFUvKgI0EQ8n2l tYBzbjCHyIWChS9yJRyi4wWpJ2za/8KJSNP1VsZUjoUA10ifyx48vEeGJdM1PiXAnPLK w2fvuWVwF/pgK5VpQsw1bJMplUS3cIv3/Ph1QSt+3b75uBnxTlfVQRnQpknL+k6t/LvI xqeBW9keiJpHcliuC/TmvrGTdLYlht1e8f9KV/BH2t9uGvLvAa4G2F2MY66IqEoMOqnf h7QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746550164; x=1747154964; 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=Zaqt2aF+R21ZLRZCmibO0BCKtkQEu5NrJjYtBghM3iU=; b=CoYtsLtAkjQIc3N1VTQd+bbs3jM7Rx30HAgtTYvgvhYv7fTrDI6vT+4clMIJ7qrCpK IsHG0RI9ucVLpoeKktBn5bmIfPecEz65xOwo7mTxLS/KtdEefW6Nlhh6M07lX1RUtnml XGd0JFxcnsOnOmRc5j4FQL4EZDYlcJ/y0JdfU8VauJkIrqQacdGfK5Y1g36PaJV3aVbb HpjQU74Kznf5hVSXXRJpRRcfPLWzCfPwXJ2p4vGkE/b8xcvQcF9LaRWv0wQyjF8y+N8R f+J5kw7D1A8BIRKUrhrVGpSts+OxZELvqfQOkkwE7s/0X2FKEwRufBFAPICeNuyV4xJ2 Ig5g== X-Forwarded-Encrypted: i=1; AJvYcCX5p3BPRnUhJispcs50+i68j0fRLXdxg/KVXcIlgD6etam8pZvH3DjQJubbmZa32mW42KFYsT4ux46WcAY=@vger.kernel.org X-Gm-Message-State: AOJu0YwWpYLk/l/xe/eoqKRPWaRbyoWfYf5lgfJZYK/44EkU/NOGqC6/ YhdqVUYrBlr2/0dcoAMVdzBHpUICYyRSvesVa+tQaUCDgUDtCMpV7VcXNe+oY9vPkEW/nY9YT03 FekYvu9VpHjgCAasijA== X-Google-Smtp-Source: AGHT+IFrqd+H2SeGnXjM2S5QS5+AEOUz3d6c3+Xi+kOr44Ta+o3bbgik0UkwmDoNUTqqJhmyWDUfjboZeaZZM1Ft X-Received: from wmrm12.prod.google.com ([2002:a05:600c:37cc:b0:440:68cb:bd4]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:22c2:b0:3a0:8098:b6c with SMTP id ffacd0b85a97d-3a0b4a186c4mr138331f8f.14.1746550164127; Tue, 06 May 2025 09:49:24 -0700 (PDT) Date: Tue, 6 May 2025 17:48:20 +0100 In-Reply-To: <20250506164820.515876-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: <20250506164820.515876-1-vdonnefort@google.com> X-Mailer: git-send-email 2.49.0.967.g6a0df3ecc3-goog Message-ID: <20250506164820.515876-25-vdonnefort@google.com> Subject: [PATCH v4 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, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Run the trace remote selftests with the pKVM trace remote "hypervisor". 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.49.0.967.g6a0df3ecc3-goog