From nobody Sat Oct 4 01:39:24 2025 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6CEE51DE887 for ; Fri, 3 Oct 2025 13:38:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498741; cv=none; b=SzDSAUtE8NxUTi0mUz5dhqykxVtCyfqGLBlFEJ/lk12X1RIcrSXBj+Al8sRBfsHXSZ98xtkUxG1dLpTIVtrzG2+1uFm1ZmZZH2Z7mkuSEJk+srZxCnu+k3+yrrtGJK4vq89el7JGbr8AIRfaQ3aXflGQFF8bssbs34yklURoCJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498741; c=relaxed/simple; bh=jCel6UdKVBBhusHDhXdBf4Elma0H22ACWTajZaCTXDg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=aXA0+SeTjnqbEUERkKPl+C4QSOnIgvoZ2x0LMJ1vp36fT354OJVGEyh+mQoWCLPkvEOlNH4bA4UQWFynQPtNXb2AzMVLWmY4awWKcfnYFkQ1HWF3p8XdYoBDKxfI2+0eTQ9q8BaN2VNFFXJb+y3D69W7D2t2mn149q9A3ZR6ft0= 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=pZL5hGgV; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pZL5hGgV" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-afe81959e5cso338925766b.1 for ; Fri, 03 Oct 2025 06:38:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498738; x=1760103538; 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=5yvbWhTiB0g5MKRQJDvE9eSL8LzKl9DcqfgxeSAHNnQ=; b=pZL5hGgVtXOj8DYdG+wWnFQtZ7wsfe1k7fMfFpw+DA0Cr1WxDZJ+UCfWvzpCf4dTXJ glAxoOD6mZDy6rtCVIIwjUxCrM3pnwbWUk69Az2MVlzO73Xzc4MGz3libKAvbnERMQ0r wp2JwdgWJyy06aoGoE93aUbH9m+keR4CLoHel0R2do9vvxce+OVnIOdFBbET/FXgdTkd ZdZkcskBq0Pge4DyJBZzmpWzFw+ljI5V1Iyy0a3DpKdeCgGsWxJt6pfBa7AlMLce9H5e IrtldTrnsT8rYFz+Y+sBe6nVUnPb1IvmScIG+b++B2P7JOBHhnH1jWI6owIwmHSTrBH4 bDnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498738; x=1760103538; 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=5yvbWhTiB0g5MKRQJDvE9eSL8LzKl9DcqfgxeSAHNnQ=; b=QrrwvliGVd3p+O9zcD/Q9Pw4DMxHmEUTIuTNAKK3CLgLf15KlfSe+Bv6ztpXZfTY/I lRipw2tHf6eN0Fwp/nbHCy6kauh0Z3qreaiXwDNxiuMvwWhJ56VUogo1PKNgQjQFzKkL D6nLxu2NyVVY80m9OPyhB5LqYSPCKKBzWpoIA4WsOV6cKg2D6df5GyMRFbHs6YkvqrTh n3SY/1p/QxkaMmyM+fLDa9j9OOgGOGn+yfOjWJn65ClLBWLz+9kmASYgA21b8Qp1Wm1d H833zK09pd+PsOIxAZjoVx+jR/OwZrZZINDurYgiDkfLtuvd3som8NwltSmp4EcNgFzN h9sQ== X-Forwarded-Encrypted: i=1; AJvYcCXXJMblqoXatIxBfzQ7O5oysxlTj/vMpXbH7zp++1T5k70QGoPr/zHlxuoPfy155ky1oOPnw+7UNwZ1GNY=@vger.kernel.org X-Gm-Message-State: AOJu0Yxx0CpjzrPPXXy20bnByoRvVpkcTAVukRQivYGoqKAwY39dpNXz 2wSQFpEXfaIc/lLBXklUc9t4x5Yui6o7kQoWXXRYyYto/FCwh34T+CbvVlmxaVzas71d0jZmSF+ 4azZJhe2ojVXrNh+dzi5w+A== X-Google-Smtp-Source: AGHT+IEDmCVx4kHhiREAX0skvRTb6ED4U7OtfqA8ZOw1gh/kLPh63qYxbg7uCqtcVIZm2PCNUon2JI3FP9RVn5iq X-Received: from ejcsa18.prod.google.com ([2002:a17:907:6d12:b0:b3b:b79e:764]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:906:4789:b0:b04:1249:2b24 with SMTP id a640c23a62f3a-b49c3933062mr408664166b.37.1759498737576; Fri, 03 Oct 2025 06:38:57 -0700 (PDT) Date: Fri, 3 Oct 2025 14:37:58 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-2-vdonnefort@google.com> Subject: [PATCH v7 01/28] ring-buffer: Add page statistics to the meta-page From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add two fields pages_touched and pages_lost to the ring-buffer meta-page. Those fields are useful to get the number of used pages in the ring-buffer. Signed-off-by: Vincent Donnefort diff --git a/include/uapi/linux/trace_mmap.h b/include/uapi/linux/trace_mma= p.h index c102ef35d11e..e8185889a1c8 100644 --- a/include/uapi/linux/trace_mmap.h +++ b/include/uapi/linux/trace_mmap.h @@ -17,8 +17,8 @@ * @entries: Number of entries in the ring-buffer. * @overrun: Number of entries lost in the ring-buffer. * @read: Number of entries that have been read. - * @Reserved1: Internal use only. - * @Reserved2: Internal use only. + * @pages_lost: Number of pages overwritten by the writer. + * @pages_touched: Number of pages written by the writer. */ struct trace_buffer_meta { __u32 meta_page_size; @@ -39,8 +39,8 @@ struct trace_buffer_meta { __u64 overrun; __u64 read; =20 - __u64 Reserved1; - __u64 Reserved2; + __u64 pages_lost; + __u64 pages_touched; }; =20 #define TRACE_MMAP_IOCTL_GET_READER _IO('R', 0x20) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 43460949ad3f..2c157cb86989 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -6113,6 +6113,8 @@ static void rb_update_meta_page(struct ring_buffer_pe= r_cpu *cpu_buffer) meta->entries =3D local_read(&cpu_buffer->entries); meta->overrun =3D local_read(&cpu_buffer->overrun); meta->read =3D cpu_buffer->read; + meta->pages_lost =3D local_read(&cpu_buffer->pages_lost); + meta->pages_touched =3D local_read(&cpu_buffer->pages_touched); =20 /* Some archs do not have data cache coherency between kernel and user-sp= ace */ flush_kernel_vmap_range(cpu_buffer->meta_page, PAGE_SIZE); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92FF71DC994 for ; Fri, 3 Oct 2025 13:39:00 +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=1759498742; cv=none; b=Yn8cdjEz954TRHzKH9bzeTe2yxe0HrIEmCWgplMsH1AWRTp3KT1uhXDc7WxKTMbOdMYZpLM4umcbu424KF4PIIntxE4BxCXTBD9OX8n0fzIrY7EnV9Up/AK0pK3Rasm7MELikrs+V/97sxBMWoDnXNJAOK6oEITia4vpHw+EFsU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498742; c=relaxed/simple; bh=Axj9ASylM0oaMpSPEZroxhw8H/MRLAYh+XigJLXbiIg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qMC8lS4V9RuXUVH6Bz17+9lV8wkBWnZNTkHHa3RV1ahxNCTIZfA2+D79SwYu3FlbzjpQ4MmIeuKcUaJHjpL3D743ol2AwfGZ4v11HRdRB+GMQuGTsSYNkZMAI9WQCyFdSDuLI6rlda5yMSPh+LwXSV9iT3k4lAsPYKgVpaRVT+w= 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=EQ1WSkI7; 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="EQ1WSkI7" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3f44000639fso1382583f8f.0 for ; Fri, 03 Oct 2025 06:39:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498739; x=1760103539; 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=bc6LimOXID+Bku1FEoRJ/EirmTeTKYklVJFEb8YK50Y=; b=EQ1WSkI76iMHAlNQe54SNrwp4z6XB7qf9T1+pwmGNkQTQL18oHoqlRH69FH7np1rtb ZWEEXQpNlktuFamKnAOImcwWC5I72DJ48TfoxKtjVBumayOZyqQILBjG+nWzZj7kM0YG 0r8a19FI5Adv0uRkzBxJcsVue+Ox2/cLyBx1AGXZ3ajdH0eb3mpTf5PD/6oMgyR/NEeA eZGMqy/wUyJfSz5v3cZO31sczXSzf2pwUIjT5PXz+unFOpTBkU1nklgQZANX5KPazNCs MwooH1VEv7cUK900BAbu+VyCHQpLeLXtff/3+GN39JA+KPP2TfwgJZKj7iAXJZHIVtsw aDAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498739; x=1760103539; 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=bc6LimOXID+Bku1FEoRJ/EirmTeTKYklVJFEb8YK50Y=; b=PizIq20pOYD9kFhW6mBdMp7nU8bDTHcxIZsHp6gfvM2c+A31YUGjjI6ojoc3ebsaZB gH/sUsFoDr34n2p4rTiaHudXMEkNyp+Qm/nPS6FamfDdTxetpbX9BIs46ap5qCMGG7aj u+2jXlxJK3bLs8MT3o+1TlkZKIUAb3q1wrNUlmCui7AYFj6hmq2ihugpm3z8mYitdlyZ xllsKbXklcL+bXi8DHPB4pnap+02oJA8PQalT9ui0oo+/lPO+CGePUTnzKIFx45jBTD/ 7qvKb7EbEDryG5XYVjnD6XPG/GlH2LLYMilQjJ5dxHOI+jkgN1Pvh8Wi/cH22nSU4zid AKLg== X-Forwarded-Encrypted: i=1; AJvYcCX0c7kv7ybhH4L4rDapr2yBhgPzR4vOroNn4yjsP+70ixH6gzWtCrvy6jRwuPoz1otXuXXho65rlj2meBg=@vger.kernel.org X-Gm-Message-State: AOJu0YyJgY314BJYEri+9ShMPzGgUmKeAAGLDPjimppSt3pYyLn77jvL /z+PmKRL5m7aIb8RFXAOlO5q3QgXMr9LgDKhg6T18t9KlEgTg4xyce2GwE2Cn1Y2Jb3+ghMm8om vqunf/2f50DowgXahCRwf0Q== X-Google-Smtp-Source: AGHT+IFA6VPDBbC1e+6gIWe9mwwubSc0dOt0/SMKjx4g1e9RJBwOm822bx7bReAGfXOd+prKSqJyKXuvGPwSOwjw X-Received: from wmbjv25.prod.google.com ([2002:a05:600c:5719:b0:46e:2640:aa83]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4fc8:b0:45b:7d77:b592 with SMTP id 5b1f17b1804b1-46e7110adfcmr22140975e9.12.1759498738728; Fri, 03 Oct 2025 06:38:58 -0700 (PDT) Date: Fri, 3 Oct 2025 14:37:59 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-3-vdonnefort@google.com> Subject: [PATCH v7 02/28] ring-buffer: Store bpage pointers into subbuf_ids From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The subbuf_ids field allows to point to a specific page from the ring-buffer based on its ID. As a preparation or the upcoming ring-buffer remote support, point this array to the buffer_page instead of the buffer_data_page. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 2c157cb86989..e5846f8f3c07 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -519,7 +519,7 @@ struct ring_buffer_per_cpu { unsigned int mapped; unsigned int user_mapped; /* user space mapping */ struct mutex mapping_lock; - unsigned long *subbuf_ids; /* ID to subbuf VA */ + struct buffer_page **subbuf_ids; /* ID to subbuf VA */ struct trace_buffer_meta *meta_page; struct ring_buffer_cpu_meta *ring_meta; =20 @@ -7002,7 +7002,7 @@ static void rb_free_meta_page(struct ring_buffer_per_= cpu *cpu_buffer) } =20 static void rb_setup_ids_meta_page(struct ring_buffer_per_cpu *cpu_buffer, - unsigned long *subbuf_ids) + struct buffer_page **subbuf_ids) { struct trace_buffer_meta *meta =3D cpu_buffer->meta_page; unsigned int nr_subbufs =3D cpu_buffer->nr_pages + 1; @@ -7011,7 +7011,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, int id =3D 0; =20 id =3D rb_page_id(cpu_buffer, cpu_buffer->reader_page, id); - subbuf_ids[id++] =3D (unsigned long)cpu_buffer->reader_page->page; + subbuf_ids[id++] =3D cpu_buffer->reader_page; cnt++; =20 first_subbuf =3D subbuf =3D rb_set_head_page(cpu_buffer); @@ -7021,7 +7021,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, if (WARN_ON(id >=3D nr_subbufs)) break; =20 - subbuf_ids[id] =3D (unsigned long)subbuf->page; + subbuf_ids[id] =3D subbuf; =20 rb_inc_page(&subbuf); id++; @@ -7030,7 +7030,7 @@ static void rb_setup_ids_meta_page(struct ring_buffer= _per_cpu *cpu_buffer, =20 WARN_ON(cnt !=3D nr_subbufs); =20 - /* install subbuf ID to kern VA translation */ + /* install subbuf ID to bpage translation */ cpu_buffer->subbuf_ids =3D subbuf_ids; =20 meta->meta_struct_len =3D sizeof(*meta); @@ -7186,13 +7186,15 @@ static int __rb_map_vma(struct ring_buffer_per_cpu = *cpu_buffer, } =20 while (p < nr_pages) { + struct buffer_page *subbuf; struct page *page; int off =3D 0; =20 if (WARN_ON_ONCE(s >=3D nr_subbufs)) return -EINVAL; =20 - page =3D virt_to_page((void *)cpu_buffer->subbuf_ids[s]); + subbuf =3D cpu_buffer->subbuf_ids[s]; + page =3D virt_to_page((void *)subbuf->page); =20 for (; off < (1 << (subbuf_order)); off++, page++) { if (p >=3D nr_pages) @@ -7219,7 +7221,8 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, struct vm_area_struct *vma) { struct ring_buffer_per_cpu *cpu_buffer; - unsigned long flags, *subbuf_ids; + struct buffer_page **subbuf_ids; + unsigned long flags; int err; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) @@ -7243,7 +7246,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, if (err) return err; =20 - /* subbuf_ids include the reader while nr_pages does not */ + /* subbuf_ids includes the reader while nr_pages does not */ subbuf_ids =3D kcalloc(cpu_buffer->nr_pages + 1, sizeof(*subbuf_ids), GFP= _KERNEL); if (!subbuf_ids) { rb_free_meta_page(cpu_buffer); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5AAA81F239B for ; Fri, 3 Oct 2025 13:39:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498745; cv=none; b=tSEvWGDkqVrmurMgWQ/7j/m8RacyObhX2G2oxD3hk5EBGHtXKvNqXeB7oOiFm7KuZXeLPAQhCS3bTNniyOqxWkI69UMQD2N9/Q71Uqo9ezozE3LLSJVWdaQYDYNStvAEP3pEDPZ8aPc5GLgztMI4YuQqX+18HnVfgTChiaJAK9U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498745; c=relaxed/simple; bh=WhHiN3T6nqkqfrujmYbSQhQdZnFH6oQ7rARrajYrZ1w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=C0ylr89wntDJM547So6/E6TN5p9Lq3f1s+LvOAoBP/Gdxq+NicyrPoI3x2vSxgSbXWQFZGKqC2/2RPVbchiJcBi8WT3aPXjoOQ+fFJHR1aGJNpk5Y6G6r7DUXeO2/yyDfgkltDfwl5ul3Ev/o4HSXs1YJQAyV9fqFcgh9cko8bs= 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=sOCwxKAJ; 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="sOCwxKAJ" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3efe4fcc9ccso1124185f8f.3 for ; Fri, 03 Oct 2025 06:39:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498740; x=1760103540; 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=fvRjHOrL5GqcRwZMV7e30Iup6J04sIy9qb33M/pVPkA=; b=sOCwxKAJJgG1Bu2/HTllw2ubhbD82V9EIX3zk9g6IHNmF8GTXhmnm8YewXj+l5LlBj WNyNk0ZDYv/xsjG9iKJafmu8I16CSeKVWTS7LktGY/z99+iFVv1mNA+rIORQAPBAycQS SUs4KY+yrK14uOB8Kp+h8zVgfW5DMkEjJWOP2THcLvS4+sV3Tf4022HMU8PVxpKXl376 KRrx/joGnCy5KU+UYVgeSE9E5Z1M4BOjlDkpjwr9PDE29Gv08vVMPRPUHeQj6voF2lma Ir5fxu4E9V6+uUlPadsUHe7iK1BkEN4u/3FAj0pLo4TDQLXBJhcxFCFVT6AJ4aBGPRvi HneQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498740; x=1760103540; 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=fvRjHOrL5GqcRwZMV7e30Iup6J04sIy9qb33M/pVPkA=; b=UUcX7CyRxjeHzFRanOsvr2Lw5CAtkUHJAEqENxRv+nJUO4Nl6YkXufLtV0ipcjnnuM NfnPkIZtQzAbfwabNuuG+HWvT/Y2zKlxpRLE8QtbsalLs/GCXvN1gk5K68uJrhGyYRgi V3sISnA+35d/lZo/heST+2GxckrxKGUYzx0Sn0pl1DsqxqUgUwO842SOVJzpxmHRI0Mf 6+IjfdJJ4rsjeT6X43a8oeR7p+oUfSU7p8z52KwjzfEYbLxB+icAqy1iw28fiUhGBxpu gVkLGZqOueAVUYzF4VafACSPVfKDrIXLeFWCHZNYcnJuFGfFGYAbY0TVUY4b7usOvS/t KVow== X-Forwarded-Encrypted: i=1; AJvYcCX3IexeGjgjYxxO5jepfwyIUIxeu+WIoEvd8TCnjLg0jAjsbI42FFso0ESU0YYNXrlzdIjDLBRERtRcSTU=@vger.kernel.org X-Gm-Message-State: AOJu0Yz2w1ZKmPET4lVo6/F+/zrNm0P1Y1wnxAv+8byFijSs50wS7eVu agOqnwA3jYYfHumXEYT3IjeCnzIK4KtRyIlzwkJpoy2Xx+fOqfshKQyNwzZW/ARrloyRf2jHZPs PEy1hUTQZJ2AI7wBDBI8EHA== X-Google-Smtp-Source: AGHT+IGbkOg03wLg9dZFczP/mAzk3emwrjkmr3xY8+u9FbGlyq7Xfo51NqcihsSXoVsU1weViliK38kP5MB/pCSL X-Received: from wmht10.prod.google.com ([2002:a05:600c:41ca:b0:46e:34af:fbab]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:354e:b0:46d:996b:826a with SMTP id 5b1f17b1804b1-46e7115d49dmr24176875e9.36.1759498739629; Fri, 03 Oct 2025 06:38:59 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:00 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-4-vdonnefort@google.com> Subject: [PATCH v7 03/28] ring-buffer: Introduce ring-buffer remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A ring-buffer remote is an entity outside of the kernel (most likely a firmware or a hypervisor) capable of writing events in a ring-buffer following the same format as the tracefs ring-buffer. To setup the ring-buffer on the kernel side, a description of the pages forming the ring-buffer (struct trace_buffer_desc) must be given. Callbacks (swap_reader_page and reset) must also be provided. It is expected from the remote to keep the meta-page updated. Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 876358cfe1b1..41193c5b0d28 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -250,4 +250,62 @@ int ring_buffer_map(struct trace_buffer *buffer, int c= pu, struct vm_area_struct *vma); int ring_buffer_unmap(struct trace_buffer *buffer, int cpu); int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu); + +struct ring_buffer_desc { + int cpu; + unsigned int nr_page_va; /* excludes the meta page */ + unsigned long meta_va; + unsigned long page_va[] __counted_by(nr_page_va); +}; + +struct trace_buffer_desc { + int nr_cpus; + size_t struct_len; + char __data[]; /* list of ring_buffer_desc */ +}; + +static inline struct ring_buffer_desc *__next_ring_buffer_desc(struct ring= _buffer_desc *desc) +{ + size_t len =3D struct_size(desc, page_va, desc->nr_page_va); + + return (struct ring_buffer_desc *)((void *)desc + len); +} + +static inline struct ring_buffer_desc *__first_ring_buffer_desc(struct tra= ce_buffer_desc *desc) +{ + return (struct ring_buffer_desc *)(&desc->__data[0]); +} + +static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned i= nt nr_cpus) +{ + unsigned int nr_pages =3D max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) = + 1; + struct ring_buffer_desc *rbdesc; + + return size_add(offsetof(struct trace_buffer_desc, __data), + size_mul(nr_cpus, struct_size(rbdesc, page_va, nr_pages))); +} + +#define for_each_ring_buffer_desc(__pdesc, __cpu, __trace_pdesc) \ + for (__pdesc =3D __first_ring_buffer_desc(__trace_pdesc), __cpu =3D 0; \ + (__cpu) < (__trace_pdesc)->nr_cpus; \ + (__cpu)++, __pdesc =3D __next_ring_buffer_desc(__pdesc)) + +struct ring_buffer_remote { + struct trace_buffer_desc *desc; + int (*swap_reader_page)(unsigned int cpu, void *priv); + int (*reset)(unsigned int cpu, void *priv); + void *priv; +}; + +int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu); + +struct trace_buffer * +__ring_buffer_alloc_remote(struct ring_buffer_remote *remote, + struct lock_class_key *key); + +#define ring_buffer_alloc_remote(remote) \ +({ \ + static struct lock_class_key __key; \ + __ring_buffer_alloc_remote(remote, &__key); \ +}) #endif /* _LINUX_RING_BUFFER_H */ diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index e5846f8f3c07..54f3f47b392b 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 @@ -2197,6 +2201,40 @@ static void rb_meta_buffer_update(struct ring_buffer= _per_cpu *cpu_buffer, } } =20 +static struct ring_buffer_desc *ring_buffer_desc(struct trace_buffer_desc = *trace_desc, int cpu) +{ + struct ring_buffer_desc *desc, *end; + size_t len; + int i; + + if (!trace_desc) + return NULL; + + if (cpu >=3D trace_desc->nr_cpus) + return NULL; + + end =3D (struct ring_buffer_desc *)((void *)trace_desc + trace_desc->stru= ct_len); + desc =3D __first_ring_buffer_desc(trace_desc); + len =3D struct_size(desc, page_va, desc->nr_page_va); + desc =3D (struct ring_buffer_desc *)((void *)desc + (len * cpu)); + + if (desc < end && desc->cpu =3D=3D cpu) + return desc; + + /* Missing CPUs, need to linear search */ + for_each_ring_buffer_desc(desc, i, trace_desc) { + if (desc->cpu =3D=3D cpu) + return desc; + } + + return NULL; +} + +static void *ring_buffer_desc_page(struct ring_buffer_desc *desc, int page= _id) +{ + return page_id > desc->nr_page_va ? NULL : (void *)desc->page_va[page_id]; +} + static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, long nr_pages, struct list_head *pages) { @@ -2204,6 +2242,7 @@ static int __rb_allocate_pages(struct ring_buffer_per= _cpu *cpu_buffer, struct ring_buffer_cpu_meta *meta =3D NULL; struct buffer_page *bpage, *tmp; bool user_thread =3D current->mm !=3D NULL; + struct ring_buffer_desc *desc =3D NULL; gfp_t mflags; long i; =20 @@ -2240,6 +2279,12 @@ static int __rb_allocate_pages(struct ring_buffer_pe= r_cpu *cpu_buffer, if (buffer->range_addr_start) meta =3D rb_range_meta(buffer, nr_pages, cpu_buffer->cpu); =20 + if (buffer->remote) { + desc =3D ring_buffer_desc(buffer->remote->desc, cpu_buffer->cpu); + if (!desc || WARN_ON(desc->nr_page_va !=3D (nr_pages + 1))) + return -EINVAL; + } + for (i =3D 0; i < nr_pages; i++) { struct page *page; =20 @@ -2266,6 +2311,16 @@ static int __rb_allocate_pages(struct ring_buffer_pe= r_cpu *cpu_buffer, rb_meta_buffer_update(cpu_buffer, bpage); bpage->range =3D 1; bpage->id =3D i + 1; + } else if (desc) { + void *p =3D ring_buffer_desc_page(desc, i + 1); + + if (WARN_ON(!p)) + goto free_pages; + + bpage->page =3D p; + bpage->range =3D 1; /* bpage->page can't be freed */ + bpage->id =3D i + 1; + cpu_buffer->subbuf_ids[i + 1] =3D bpage; } else { page =3D alloc_pages_node(cpu_to_node(cpu_buffer->cpu), mflags | __GFP_COMP | __GFP_ZERO, @@ -2369,6 +2424,30 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, = long nr_pages, int cpu) if (cpu_buffer->ring_meta->head_buffer) rb_meta_buffer_update(cpu_buffer, bpage); bpage->range =3D 1; + } else if (buffer->remote) { + struct ring_buffer_desc *desc =3D ring_buffer_desc(buffer->remote->desc,= cpu); + + if (!desc) + goto fail_free_reader; + + cpu_buffer->remote =3D buffer->remote; + cpu_buffer->meta_page =3D (struct trace_buffer_meta *)(void *)desc->meta= _va; + cpu_buffer->nr_pages =3D nr_pages; + cpu_buffer->subbuf_ids =3D kcalloc(cpu_buffer->nr_pages + 1, + sizeof(*cpu_buffer->subbuf_ids), GFP_KERNEL); + if (!cpu_buffer->subbuf_ids) + goto fail_free_reader; + + /* Remote buffers are read-only and immutable */ + atomic_inc(&cpu_buffer->record_disabled); + atomic_inc(&cpu_buffer->resize_disabled); + + bpage->page =3D ring_buffer_desc_page(desc, cpu_buffer->meta_page->reade= r.id); + if (!bpage->page) + goto fail_free_reader; + + bpage->range =3D 1; + cpu_buffer->subbuf_ids[0] =3D bpage; } else { page =3D alloc_pages_node(cpu_to_node(cpu), GFP_KERNEL | __GFP_COMP | __GFP_ZERO, @@ -2431,6 +2510,9 @@ static void rb_free_cpu_buffer(struct ring_buffer_per= _cpu *cpu_buffer) =20 irq_work_sync(&cpu_buffer->irq_work.work); =20 + if (cpu_buffer->remote) + kfree(cpu_buffer->subbuf_ids); + free_buffer_page(cpu_buffer->reader_page); =20 if (head) { @@ -2453,7 +2535,8 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, int order, unsigned long start, unsigned long end, unsigned long scratch_size, - struct lock_class_key *key) + struct lock_class_key *key, + struct ring_buffer_remote *remote) { struct trace_buffer *buffer __free(kfree) =3D NULL; long nr_pages; @@ -2493,6 +2576,8 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, if (!buffer->buffers) goto fail_free_cpumask; =20 + cpu =3D raw_smp_processor_id(); + /* If start/end are specified, then that overrides size */ if (start && end) { unsigned long buffers_start; @@ -2548,6 +2633,15 @@ static struct trace_buffer *alloc_buffer(unsigned lo= ng size, unsigned flags, buffer->range_addr_end =3D end; =20 rb_range_meta_init(buffer, nr_pages, scratch_size); + } else if (remote) { + struct ring_buffer_desc *desc =3D ring_buffer_desc(remote->desc, cpu); + + buffer->remote =3D remote; + /* The writer is remote. This ring-buffer is read-only */ + atomic_inc(&buffer->record_disabled); + nr_pages =3D desc->nr_page_va - 1; + if (nr_pages < 2) + goto fail_free_buffers; } else { =20 /* need at least two pages */ @@ -2556,7 +2650,6 @@ static struct trace_buffer *alloc_buffer(unsigned lon= g size, unsigned flags, nr_pages =3D 2; } =20 - cpu =3D raw_smp_processor_id(); cpumask_set_cpu(cpu, buffer->cpumask); buffer->buffers[cpu] =3D rb_allocate_cpu_buffer(buffer, nr_pages, cpu); if (!buffer->buffers[cpu]) @@ -2598,7 +2691,7 @@ struct trace_buffer *__ring_buffer_alloc(unsigned lon= g size, unsigned flags, struct lock_class_key *key) { /* Default buffer page size - one system page */ - return alloc_buffer(size, flags, 0, 0, 0, 0, key); + return alloc_buffer(size, flags, 0, 0, 0, 0, key, NULL); =20 } EXPORT_SYMBOL_GPL(__ring_buffer_alloc); @@ -2625,7 +2718,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) @@ -5233,6 +5337,16 @@ unsigned long ring_buffer_overruns(struct trace_buff= er *buffer) } EXPORT_SYMBOL_GPL(ring_buffer_overruns); =20 +static bool rb_read_remote_meta_page(struct ring_buffer_per_cpu *cpu_buffe= r) +{ + local_set(&cpu_buffer->entries, READ_ONCE(cpu_buffer->meta_page->entries)= ); + local_set(&cpu_buffer->overrun, READ_ONCE(cpu_buffer->meta_page->overrun)= ); + local_set(&cpu_buffer->pages_touched, READ_ONCE(cpu_buffer->meta_page->pa= ges_touched)); + local_set(&cpu_buffer->pages_lost, READ_ONCE(cpu_buffer->meta_page->pages= _lost)); + + return rb_num_of_entries(cpu_buffer); +} + static void rb_iter_reset(struct ring_buffer_iter *iter) { struct ring_buffer_per_cpu *cpu_buffer =3D iter->cpu_buffer; @@ -5387,7 +5501,43 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *i= ter, } =20 static struct buffer_page * -rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +__rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer) +{ + struct buffer_page *new_reader, *prev_reader; + + if (!rb_read_remote_meta_page(cpu_buffer)) + return NULL; + + /* More to read on the reader page */ + if (cpu_buffer->reader_page->read < rb_page_size(cpu_buffer->reader_page)= ) { + if (!cpu_buffer->reader_page->read) + cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + return cpu_buffer->reader_page; + } + + prev_reader =3D cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id]; + + WARN_ON_ONCE(cpu_buffer->remote->swap_reader_page(cpu_buffer->cpu, + cpu_buffer->remote->priv)); + /* nr_pages doesn't include the reader page */ + if (WARN_ON_ONCE(cpu_buffer->meta_page->reader.id > cpu_buffer->nr_pages)) + return NULL; + + new_reader =3D cpu_buffer->subbuf_ids[cpu_buffer->meta_page->reader.id]; + + WARN_ON_ONCE(prev_reader =3D=3D new_reader); + + cpu_buffer->reader_page->page =3D new_reader->page; + cpu_buffer->reader_page->id =3D new_reader->id; + cpu_buffer->reader_page->read =3D 0; + cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + cpu_buffer->lost_events =3D cpu_buffer->meta_page->reader.lost_events; + + return rb_page_size(cpu_buffer->reader_page) ? cpu_buffer->reader_page : = NULL; +} + +static struct buffer_page * +__rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) { struct buffer_page *reader =3D NULL; unsigned long bsize =3D READ_ONCE(cpu_buffer->buffer->subbuf_size); @@ -5557,6 +5707,13 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_b= uffer) return reader; } =20 +static struct buffer_page * +rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer) +{ + return cpu_buffer->remote ? __rb_get_reader_page_from_remote(cpu_buffer) : + __rb_get_reader_page(cpu_buffer); +} + static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer) { struct ring_buffer_event *event; @@ -5957,7 +6114,7 @@ ring_buffer_read_start(struct trace_buffer *buffer, i= nt cpu, gfp_t flags) struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_iter *iter; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask)) + if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) return NULL; =20 iter =3D kzalloc(sizeof(*iter), flags); @@ -6125,6 +6282,23 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) { struct buffer_page *page; =20 + if (cpu_buffer->remote) { + if (!cpu_buffer->remote->reset) + return; + + cpu_buffer->remote->reset(cpu_buffer->cpu, cpu_buffer->remote->priv); + rb_read_remote_meta_page(cpu_buffer); + + /* Read related values, not covered by the meta-page */ + local_set(&cpu_buffer->pages_read, 0); + cpu_buffer->read =3D 0; + cpu_buffer->read_bytes =3D 0; + cpu_buffer->last_overrun =3D 0; + cpu_buffer->reader_page->read =3D 0; + + return; + } + rb_head_page_deactivate(cpu_buffer); =20 cpu_buffer->head_page @@ -6355,6 +6529,48 @@ bool ring_buffer_empty_cpu(struct trace_buffer *buff= er, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu); =20 +int ring_buffer_poll_remote(struct trace_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return -EINVAL; + + cpu_buffer =3D buffer->buffers[cpu]; + + guard(raw_spinlock)(&cpu_buffer->reader_lock); + if (rb_read_remote_meta_page(cpu_buffer)) + rb_wakeups(buffer, cpu_buffer); + + return 0; + } + + cpus_read_lock(); + + /* + * Make sure all the ring buffers are up to date before we start reading + * them. + */ + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer =3D buffer->buffers[cpu]; + + guard(raw_spinlock)(&cpu_buffer->reader_lock); + rb_read_remote_meta_page(cpu_buffer); + } + + for_each_buffer_cpu(buffer, cpu) { + cpu_buffer =3D buffer->buffers[cpu]; + + if (rb_num_of_entries(cpu_buffer)) + rb_wakeups(buffer, cpu_buffer); + } + + cpus_read_unlock(); + + return 0; +} + #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP /** * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers @@ -6600,6 +6816,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer, unsigned int commit; unsigned int read; u64 save_timestamp; + bool force_memcpy; =20 if (!cpumask_test_cpu(cpu, buffer->cpumask)) return -1; @@ -6637,6 +6854,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer, /* Check if any events were dropped */ missed_events =3D cpu_buffer->lost_events; =20 + force_memcpy =3D cpu_buffer->mapped || cpu_buffer->remote; + /* * If this page has been partially read or * if len is not big enough to read the rest of the page or @@ -6646,7 +6865,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; @@ -7225,7 +7444,7 @@ int ring_buffer_map(struct trace_buffer *buffer, int = cpu, unsigned long flags; int err; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask)) + if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) return -EINVAL; =20 cpu_buffer =3D buffer->buffers[cpu]; --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 576871F1302 for ; Fri, 3 Oct 2025 13:39:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498744; cv=none; b=nfGQjNC70gRXE021RroVBIy4ERxKS/Sm0VuXMFfc4xqDUkpN2LimNCVOGRD5lbSfqXXzYT40WcWJ/xJ4MsusJtnjHR6nus2tKFX9GScPkpD6RNNaNPVmg8iHSKeNQoEOo2AvCRKtdvGedQO8iTtYJkSsOiIre4qnneiobAOQ3t8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498744; c=relaxed/simple; bh=XRylxRegtzNDYd9BgfEEjeSNPLRLZezIsWEeEyVhZYg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=p66+ZvsebQOs3b0PS6B02fIuU5zzYNKeHinPh6ioseCBvjq8gKQU+IjAe8/TdGjiYvxUjTW9xcdp9PBjvFNl8GMwBPdSlpcye/YZ6EVIgLMsQaL/pnK9RgD5R0FBZPz2Wq22okq2HBCK6AWEBuNo9XE1k8BhWdjb/IST1a89HRk= 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=OzRVq+fH; 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="OzRVq+fH" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-46e4cc8ed76so8146825e9.1 for ; Fri, 03 Oct 2025 06:39:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498741; x=1760103541; 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=OeES3oT5PyEYk0S7oFEzISO9wFmxktxYre//FfeIR3c=; b=OzRVq+fHgEuV84avK3GDEKiIiSubtogaHErZzR6PiQKHGw+fa7LyMG+Cm42i/o8M0A Ak6FDMm2Zq58RXvzHdLceLhuxbsMsqYf/44lhrumuDKDU/GMQV5TuF2z87y6XwulQ7at siRBv0DZr0Zi7zouHyoYCjZfGGVO0F0bzJ7kW3SvDYmJupZ6JIwomrUkkkwtVtmIREqb ON69Axq3ydq9fp7CodK+FIX+3Aq50nqVwVo4yPifbRHnWstMvxB2urc5jZNQ/COq+EMl INSiuDBdnB7NECyd6SeZMYc+kFLgHSF6/cgUH9sgsLYvgmmp5ZympnT6zs0SFMeNVnj3 RG9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498741; x=1760103541; 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=OeES3oT5PyEYk0S7oFEzISO9wFmxktxYre//FfeIR3c=; b=VzM76oHjw0CmOdkedm8QbuCf9u9Gzj7rlvVdnTcby7zbFpean6UpWh6yz2KI6E9zN8 UiuxdWbnoaeWOJI5auu2PN1yqubhb8NBTG8QTgdGzhbFJMgUlivGjedSqt6WFCAwwuVl nqKalXhRW1Stb0jz+wH1cZIzq9VQwBH5Hj/03skPzsoUJMeglSMZxqxzd3KAV4fqfEVy dMI0ZqTLKssgk1JsXUwN6d8EsYFFbpIro2RGV6vauiMWigImnblvBE+VgjuZnVVeJT6Y t69c3WHBBdveXtw+7o/2faiTz28PtWQgoPMaxxB1twfGymjtaxZs7CLmgHn7jXnff2// EZOQ== X-Forwarded-Encrypted: i=1; AJvYcCVfJWyybHy3hTE2wh43ZvrQ2NOAhLAhla3OhqbuyXcXLwJT9dBowuU0+USQ8+Nb1E9YU8l+N/AgbyVeszg=@vger.kernel.org X-Gm-Message-State: AOJu0Yzjtm6IBBwHD99Wv8EJkeJi0d4SjW9jdDiLRvYLbqbZ79UGc9Hu aJUndF+jL0o4QCgZ1OaRikLzi+enLPfMf1XKO3eSANwHb4/izENNsYQjZniBAPFeoK7X3dX8BMi ARFE/6OhPyEKNFcK76fwZeg== X-Google-Smtp-Source: AGHT+IGobet5rQpznC+XIhmKIJiRNYXHbeaHBHQTmrC1zAJ4pbkMbv8NZ8mLtntgHPeO+O/7sVs17qI0/PPoX2Bh X-Received: from wmoo17.prod.google.com ([2002:a05:600d:111:b0:46e:1bcf:3f8]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8185:b0:468:7a5a:1494 with SMTP id 5b1f17b1804b1-46e710f6c7amr19128115e9.1.1759498740786; Fri, 03 Oct 2025 06:39:00 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:01 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-5-vdonnefort@google.com> Subject: [PATCH v7 04/28] ring-buffer: Add non-consuming read for ring-buffer remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hopefully, the remote will only swap pages on the kernel instruction (via the swap_reader_page() callback). This means we know at what point the ring-buffer geometry has changed. It is therefore possible to rearrange the kernel view of that ring-buffer to allow non-consuming read. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 54f3f47b392b..eb556e691b5e 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5347,10 +5347,51 @@ static bool rb_read_remote_meta_page(struct ring_bu= ffer_per_cpu *cpu_buffer) return rb_num_of_entries(cpu_buffer); } =20 +static void rb_update_remote_head(struct ring_buffer_per_cpu *cpu_buffer) +{ + struct buffer_page *next, *orig; + int retry =3D 3; + + orig =3D next =3D cpu_buffer->head_page; + rb_inc_page(&next); + + /* Run after the writer */ + while (cpu_buffer->head_page->page->time_stamp > next->page->time_stamp) { + rb_inc_page(&next); + + rb_list_head_clear(cpu_buffer->head_page->list.prev); + rb_inc_page(&cpu_buffer->head_page); + rb_set_list_to_head(cpu_buffer->head_page->list.prev); + + if (cpu_buffer->head_page =3D=3D orig) { + if (WARN_ON_ONCE(!(--retry))) + return; + } + } + + orig =3D cpu_buffer->commit_page =3D cpu_buffer->head_page; + retry =3D 3; + + while (cpu_buffer->commit_page->page->time_stamp < next->page->time_stamp= ) { + rb_inc_page(&next); + rb_inc_page(&cpu_buffer->commit_page); + + if (cpu_buffer->commit_page =3D=3D orig) { + if (WARN_ON_ONCE(!(--retry))) + return; + } + } +} + static void rb_iter_reset(struct ring_buffer_iter *iter) { struct ring_buffer_per_cpu *cpu_buffer =3D iter->cpu_buffer; =20 + if (cpu_buffer->remote) { + rb_read_remote_meta_page(cpu_buffer); + rb_update_remote_head(cpu_buffer); + } + /* Iterator usage is expected to have record disabled */ iter->head_page =3D cpu_buffer->reader_page; iter->head =3D cpu_buffer->reader_page->read; @@ -5503,7 +5544,7 @@ rb_update_iter_read_stamp(struct ring_buffer_iter *it= er, static struct buffer_page * __rb_get_reader_page_from_remote(struct ring_buffer_per_cpu *cpu_buffer) { - struct buffer_page *new_reader, *prev_reader; + struct buffer_page *new_reader, *prev_reader, *prev_head, *new_head, *las= t; =20 if (!rb_read_remote_meta_page(cpu_buffer)) return NULL; @@ -5527,10 +5568,32 @@ __rb_get_reader_page_from_remote(struct ring_buffer= _per_cpu *cpu_buffer) =20 WARN_ON_ONCE(prev_reader =3D=3D new_reader); =20 - cpu_buffer->reader_page->page =3D new_reader->page; - cpu_buffer->reader_page->id =3D new_reader->id; - cpu_buffer->reader_page->read =3D 0; - cpu_buffer->read_stamp =3D cpu_buffer->reader_page->page->time_stamp; + prev_head =3D new_reader; /* New reader was also the previous head */ + new_head =3D prev_head; + rb_inc_page(&new_head); + last =3D prev_head; + rb_dec_page(&last); + + /* Clear the old HEAD flag */ + rb_list_head_clear(cpu_buffer->head_page->list.prev); + + prev_reader->list.next =3D prev_head->list.next; + prev_reader->list.prev =3D prev_head->list.prev; + + /* Swap prev_reader with new_reader */ + last->list.next =3D &prev_reader->list; + new_head->list.prev =3D &prev_reader->list; + + new_reader->list.prev =3D &new_reader->list; + new_reader->list.next =3D &new_head->list; + + /* Reactivate the HEAD flag */ + rb_set_list_to_head(&last->list); + + cpu_buffer->head_page =3D new_head; + cpu_buffer->reader_page =3D new_reader; + cpu_buffer->pages =3D &new_head->list; + cpu_buffer->read_stamp =3D new_reader->page->time_stamp; cpu_buffer->lost_events =3D cpu_buffer->meta_page->reader.lost_events; =20 return rb_page_size(cpu_buffer->reader_page) ? cpu_buffer->reader_page : = NULL; @@ -6114,7 +6177,7 @@ ring_buffer_read_start(struct trace_buffer *buffer, i= nt cpu, gfp_t flags) struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_iter *iter; =20 - if (!cpumask_test_cpu(cpu, buffer->cpumask) || buffer->remote) + if (!cpumask_test_cpu(cpu, buffer->cpumask)) return NULL; =20 iter =3D kzalloc(sizeof(*iter), flags); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A00FE1F91E3 for ; Fri, 3 Oct 2025 13:39:03 +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=1759498746; cv=none; b=E2WevXjw7Q0dlHl/Uq8hM89VoXObjmL63ehKKJv9gRQZkX1tQUc54oKxdqbca4XS7IRuk4dZClMauIG9yk8ue3AP2VOpReHLPJINwojaif0Ped7F0LcqAS/GvzDupuDMlEoBA1MdcfnWp10Zs+ooA5PmbAgOA/udFzkK/W+PPxw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498746; c=relaxed/simple; bh=xsk0Fr9A+w1DewJI/K8RaUFYlIl3bjuDw5oMWYqdzvs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=scvnJM6omTjXIlWE5LcPZB/iCRgTcQlKTS6OeXLG5VFx0+IC0syWYqxde00XOTv+2nisN7H1Odxhk6cHcDIxCZ4ksTtcRkdIHeXx6TdmKt1AFJ3cPGUfC/0TvwkClcZ9Sv/WH2flqnb73Lai5/Kp+IcpizNV2/4bawzROwALsbQ= 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=Wq+sVe6y; 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="Wq+sVe6y" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e3d43bbc7so9561465e9.2 for ; Fri, 03 Oct 2025 06:39:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498742; x=1760103542; 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=kVzZAsanqUx6NEVMWn1d673EGvV8PVmejN0FaUdBRuM=; b=Wq+sVe6y3xS04z05hXInJlIQF8thUVX/8w5jHuh38I1ZKfwyK5WMtxXYNktvSuk9mw YNYQVcd3zXCF9PyMqiMGDPtOsjBdLjYG0LQm1Nky1XtRrxyLqjRT4odGpYkWOCLuil0x fCIOVpCtNNmh7B5u58cO5SuNzJfNjLsvurvdAfdE6skMOA1cu+G8mHYdvg5yW+Xy71vh /BNewnOCmcTViL7SHLPQ3TCFC0fNUeraubaa23OsRBZXWd1nnmsdSxVDux/w0haFAS1G e5NEhPc756zlm7lUPhPBQo0bJNBFtv7jKHF4BofDZGdtIs7Lnoo90E5P6u2GCIq7NTd5 cvuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498742; x=1760103542; 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=kVzZAsanqUx6NEVMWn1d673EGvV8PVmejN0FaUdBRuM=; b=lWqWMdauQ9eUXTGR5FrVfUL+Z5WS48xSonZAd8ij1Ok/8V64sJVWTBBpFv7kS7qOnD shlY9EA5XALSR4NpJgV++D3Ez+5053p1kOJBIFXQl5LtEHWRQKEbB6ihd9iybsUIZN9p 9VMzZ6LKMOhkLy4XaXItq86NbC8aAsIiBO45AzHGfI5+w9uRch/EB5SEGhli+seMyuRk ThEuJTJvtjuxPmBkM0uw4jk9PRqtAQL4EMD/8AbttAGuBl2SixS6sF0USUSBf+bz54ej m/Op3va9RjEF5SJSQvOsGSvMxABHN+w8+tByNb37KqB3gf1I7No9XO2UycFnvOy+ZlTT 58Cg== X-Forwarded-Encrypted: i=1; AJvYcCWUX91eT0uNEE4O9YpAY2wVpxiLUydcFMuqJyJWuZMkSA4iy5QOJqyDNWB59gYWO6mXWY4i0yaiyM+1tU4=@vger.kernel.org X-Gm-Message-State: AOJu0YwSC/yyVLZBRJs6NNLCZ7EnSzMNuZn/d+IwJRteNGXAtfXGQhjX tZ7cOoUgTYErTgFLBOgnZCqX/Yh+RKG751uh+FN9kxfDIhOybXmrrgRR0Yy4kJ4UyZcP3xbq+Zk IwoD7hYfiLdxNl1cqFmTBuA== X-Google-Smtp-Source: AGHT+IGtoiMOJbbUGluKcrrf2jpd/NA0bAXHTN5z3JSiX93+rkt/dUPjaiqGSvXO5tGCjwTSEh0V65pmrBuPuVG1 X-Received: from wmht22.prod.google.com ([2002:a05:600c:41d6:b0:46e:3190:9ce]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:a11:b0:46e:33a6:46b2 with SMTP id 5b1f17b1804b1-46e71109edfmr23711595e9.12.1759498741833; Fri, 03 Oct 2025 06:39:01 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:02 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-6-vdonnefort@google.com> Subject: [PATCH v7 05/28] tracing: Introduce trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A trace remote relies on ring-buffer remotes to read and control compatible tracing buffers, written by entity such as firmware or hypervisor. Add a Tracefs directory remotes/ that contains all instances of trace remotes. Each instance follows the same hierarchy as any other to ease the support by existing user-space tools. This currently does not provide any event support, which will come later. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h new file mode 100644 index 000000000000..feb3433c2128 --- /dev/null +++ b/include/linux/trace_remote.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_TRACE_REMOTE_H +#define _LINUX_TRACE_REMOTE_H + +#include + +/** + * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote + * + * @load_trace_buffer: Called before Tracefs accesses the trace buffer fo= r the first + * time. Must return a &trace_buffer_desc + * (most likely filled with trace_remote_alloc_buffer()) + * @unload_trace_buffer: + * Called once Tracefs has no use for the trace buffer + * (most likely call trace_remote_free_buffer()) + * @enable_tracing: Called on Tracefs tracing_on. It is expected from the + * remote to allow writing. + * @swap_reader_page: Called when Tracefs consumes a new page from a + * ring-buffer. It is expected from the remote to isolate a + * new reader-page from the @cpu ring-buffer. + */ +struct trace_remote_callbacks { + struct trace_buffer_desc *(*load_trace_buffer)(unsigned long size, void *= priv); + void (*unload_trace_buffer)(struct trace_buffer_desc *desc, void *priv); + int (*enable_tracing)(bool enable, void *priv); + int (*swap_reader_page)(unsigned int cpu, void *priv); +}; + +/** + * trace_remote_register() - Register a Tracefs remote + * + * A trace remote is an entity, outside of the kernel (most likely firmwar= e or + * hypervisor) capable of writing events into a Tracefs compatible ring-bu= ffer. + * The kernel would then act as a reader. + * + * The registered remote will be found under the Tracefs directory + * remotes/. + * + * @name: Name of the remote, used for the Tracefs remotes/ directory. + * @cbs: Set of callbacks used to control the remote. + * @priv: Private data, passed to each callback from @cbs. + * @events: Array of events. &remote_event.name and &remote_event.id must = be + * filled by the caller. + * @nr_events: Number of events in the @events array. + * + * Return: 0 on success, negative error code on failure. + */ +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv); + +/** + * trace_remote_alloc_buffer() - Dynamically allocate a trace buffer + * + * Helper to dynamically allocate a set of pages (enough to cover @buffer_= size) + * for each CPU from @cpumask and fill @desc. Most likely called from + * &trace_remote_callbacks.load_trace_buffer. + * + * @desc: Uninitialized trace_buffer_desc + * @desc_size: Size of the trace_buffer_desc. Must be at least equal to + * trace_buffer_desc_size() + * @buffer_size: Size in bytes of each per-CPU ring-buffer + * @cpumask: CPUs to allocate a ring-buffer for + * + * Return: 0 on success, negative error code on failure. + */ +int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_= size, size_t buffer_size, + const struct cpumask *cpumask); + +/** + * trace_remote_free_buffer() - Free trace buffer allocated with + * trace_remote_alloc_buffer() + * + * Most likely called from &trace_remote_callbacks.unload_trace_buffer. + * + * @desc: Descriptor of the per-CPU ring-buffers, originally filled by + * trace_remote_alloc_buffer() + */ +void trace_remote_free_buffer(struct trace_buffer_desc *desc); + +#endif diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index d2c79da81e4f..99af56d39eaf 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1238,4 +1238,7 @@ config HIST_TRIGGERS_DEBUG =20 source "kernel/trace/rv/Kconfig" =20 +config TRACE_REMOTE + bool + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index dcb4e02afc5f..6dab341acc46 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -110,4 +110,5 @@ obj-$(CONFIG_FPROBE_EVENTS) +=3D trace_fprobe.o obj-$(CONFIG_TRACEPOINT_BENCHMARK) +=3D trace_benchmark.o obj-$(CONFIG_RV) +=3D rv/ =20 +obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o libftrace-y :=3D ftrace.o diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b3c94fbaf002..ec0cdbe96766 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -8949,7 +8949,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 5f4bed5842f9..a3386cf0c760 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -672,6 +672,12 @@ struct dentry *trace_create_file(const char *name, struct dentry *parent, void *data, const struct file_operations *fops); +struct dentry *trace_create_cpu_file(const char *name, + umode_t mode, + struct dentry *parent, + void *data, + long cpu, + const struct file_operations *fops); =20 =20 /** diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c new file mode 100644 index 000000000000..3d76a4d7d5f5 --- /dev/null +++ b/kernel/trace/trace_remote.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "trace.h" + +#define TRACEFS_DIR "remotes" +#define TRACEFS_MODE_WRITE 0640 +#define TRACEFS_MODE_READ 0440 + +struct trace_remote_iterator { + struct trace_remote *remote; + struct trace_seq seq; + struct delayed_work poll_work; + unsigned long lost_events; + u64 ts; + int cpu; + int evt_cpu; +}; + +struct trace_remote { + struct trace_remote_callbacks *cbs; + void *priv; + struct trace_buffer *trace_buffer; + struct trace_buffer_desc *trace_buffer_desc; + unsigned long trace_buffer_size; + struct ring_buffer_remote rb_remote; + struct mutex lock; + unsigned int nr_readers; + unsigned int poll_ms; + bool tracing_on; +}; + +static bool trace_remote_loaded(struct trace_remote *remote) +{ + return remote->trace_buffer; +} + +static int trace_remote_load(struct trace_remote *remote) +{ + struct ring_buffer_remote *rb_remote =3D &remote->rb_remote; + + lockdep_assert_held(&remote->lock); + + if (trace_remote_loaded(remote)) + return 0; + + remote->trace_buffer_desc =3D remote->cbs->load_trace_buffer(remote->trac= e_buffer_size, + remote->priv); + if (IS_ERR(remote->trace_buffer_desc)) + return PTR_ERR(remote->trace_buffer_desc); + + rb_remote->desc =3D remote->trace_buffer_desc; + rb_remote->swap_reader_page =3D remote->cbs->swap_reader_page; + rb_remote->priv =3D remote->priv; + remote->trace_buffer =3D ring_buffer_alloc_remote(rb_remote); + if (!remote->trace_buffer) { + remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv= ); + return -ENOMEM; + } + + return 0; +} + +static void trace_remote_try_unload(struct trace_remote *remote) +{ + lockdep_assert_held(&remote->lock); + + if (!trace_remote_loaded(remote)) + return; + + /* The buffer is being read or writable */ + if (remote->nr_readers || remote->tracing_on) + return; + + /* The buffer has readable data */ + if (!ring_buffer_empty(remote->trace_buffer)) + return; + + ring_buffer_free(remote->trace_buffer); + remote->trace_buffer =3D NULL; + remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv); +} + +static int trace_remote_enable_tracing(struct trace_remote *remote) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (remote->tracing_on) + return 0; + + ret =3D trace_remote_load(remote); + if (ret) + return ret; + + ret =3D remote->cbs->enable_tracing(true, remote->priv); + if (ret) { + trace_remote_try_unload(remote); + return ret; + } + + remote->tracing_on =3D true; + + return 0; +} + +static int trace_remote_disable_tracing(struct trace_remote *remote) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (!remote->tracing_on) + return 0; + + ret =3D remote->cbs->enable_tracing(false, remote->priv); + if (ret) + return ret; + + ring_buffer_poll_remote(remote->trace_buffer, RING_BUFFER_ALL_CPUS); + remote->tracing_on =3D false; + trace_remote_try_unload(remote); + + return 0; +} + +static ssize_t +tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) +{ + struct trace_remote *remote =3D filp->private_data; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + ret =3D val ? trace_remote_enable_tracing(remote) : trace_remote_disable_= tracing(remote); + if (ret) + return ret; + + return cnt; +} +static int tracing_on_show(struct seq_file *s, void *unused) +{ + struct trace_remote *remote =3D s->private; + + seq_printf(s, "%d\n", remote->tracing_on); + + return 0; +} +DEFINE_SHOW_STORE_ATTRIBUTE(tracing_on); + +static ssize_t buffer_size_kb_write(struct file *filp, const char __user *= ubuf, size_t cnt, + loff_t *ppos) +{ + struct trace_remote *remote =3D filp->private_data; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + /* KiB to Bytes */ + if (!val || check_shl_overflow(val, 10, &val)) + return -EINVAL; + + guard(mutex)(&remote->lock); + + remote->trace_buffer_size =3D val; + + return cnt; +} + +static int buffer_size_kb_show(struct seq_file *s, void *unused) +{ + struct trace_remote *remote =3D s->private; + + seq_printf(s, "%lu (%s)\n", remote->trace_buffer_size >> 10, + trace_remote_loaded(remote) ? "loaded" : "unloaded"); + + return 0; +} +DEFINE_SHOW_STORE_ATTRIBUTE(buffer_size_kb); + +static int trace_remote_get(struct trace_remote *remote, int cpu) +{ + int ret; + + if (remote->nr_readers =3D=3D UINT_MAX) + return -EBUSY; + + ret =3D trace_remote_load(remote); + if (ret) + return ret; + + remote->nr_readers++; + + return 0; +} + +static void trace_remote_put(struct trace_remote *remote) +{ + if (WARN_ON(!remote->nr_readers)) + return; + + remote->nr_readers--; + if (remote->nr_readers) + return; + + trace_remote_try_unload(remote); +} + +static void __poll_remote(struct work_struct *work) +{ + struct delayed_work *dwork =3D to_delayed_work(work); + struct trace_remote_iterator *iter; + + iter =3D container_of(dwork, struct trace_remote_iterator, poll_work); + ring_buffer_poll_remote(iter->remote->trace_buffer, iter->cpu); + schedule_delayed_work((struct delayed_work *)work, + msecs_to_jiffies(iter->remote->poll_ms)); +} + +static struct trace_remote_iterator +*trace_remote_iter(struct trace_remote *remote, int cpu, enum tri_type typ= e) +{ + struct trace_remote_iterator *iter =3D NULL; + int ret; + + lockdep_assert_held(&remote->lock); + + + ret =3D trace_remote_get(remote, cpu); + if (ret) + return ERR_PTR(ret); + + /* Test the CPU */ + ret =3D ring_buffer_poll_remote(remote->trace_buffer, cpu); + if (ret) + goto err; + + iter =3D kzalloc(sizeof(*iter), GFP_KERNEL); + if (iter) { + iter->remote =3D remote; + iter->cpu =3D cpu; + trace_seq_init(&iter->seq); + INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); + schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_ms= )); + + return iter; + } + ret =3D -ENOMEM; + +err: + kfree(iter); + trace_remote_put(remote); + + return ERR_PTR(ret); +} + +static void trace_remote_iter_free(struct trace_remote_iterator *iter) +{ + struct trace_remote *remote; + + if (!iter) + return; + + remote =3D iter->remote; + + lockdep_assert_held(&remote->lock); + + kfree(iter); + trace_remote_put(remote); +} + +static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) +{ + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + int cpu =3D iter->cpu; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + if (ring_buffer_empty_cpu(trace_buffer, cpu)) + return false; + + if (!ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_events)) + return false; + + iter->evt_cpu =3D cpu; + return true; + } + + iter->ts =3D U64_MAX; + for_each_possible_cpu(cpu) { + unsigned long lost_events; + u64 ts; + + if (ring_buffer_empty_cpu(trace_buffer, cpu)) + continue; + + if (!ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events)) + continue; + + if (ts >=3D iter->ts) + continue; + + iter->ts =3D ts; + iter->evt_cpu =3D cpu; + iter->lost_events =3D lost_events; + } + + return iter->ts !=3D U64_MAX; +} + +static int trace_remote_iter_print(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); + + trace_remote_iter_free(iter); + + return 0; +} + +static ssize_t trace_pipe_read(struct file *filp, char __user *ubuf, size_= t cnt, loff_t *ppos) +{ + struct trace_remote_iterator *iter =3D filp->private_data; + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + int ret; + +copy_to_user: + ret =3D trace_seq_to_user(&iter->seq, ubuf, cnt); + if (ret !=3D -EBUSY) + return ret; + + trace_seq_init(&iter->seq); + + ret =3D ring_buffer_wait(trace_buffer, iter->cpu, 0, NULL, NULL); + if (ret < 0) + return ret; + + while (trace_remote_iter_next(iter)) { + while (trace_remote_iter_read_event(iter)) { + int prev_len =3D iter->seq.seq.len; + + if (trace_remote_iter_print_event(iter)) { + iter->seq.seq.len =3D prev_len; + break; + } + + ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + } + + goto copy_to_user; +} + +static const struct file_operations trace_pipe_fops =3D { + .open =3D trace_pipe_open, + .read =3D trace_pipe_read, + .release =3D trace_pipe_release, +}; + +static int trace_remote_init_tracefs(const char *name, struct trace_remote= *remote) +{ + struct dentry *remote_d, *percpu_d; + static struct dentry *root; + static DEFINE_MUTEX(lock); + bool root_inited =3D false; + int cpu; + + guard(mutex)(&lock); + + if (!root) { + root =3D tracefs_create_dir(TRACEFS_DIR, NULL); + if (!root) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"\n"); + return -ENOMEM; + } + root_inited =3D true; + } + + remote_d =3D tracefs_create_dir(name, root); + if (!remote_d) { + pr_err("Failed to create tracefs dir "TRACEFS_DIR"%s/\n", name); + goto err; + } + + 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 desc_= size, size_t buffer_size, + const struct cpumask *cpumask) +{ + unsigned int nr_pages =3D max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) = + 1; + void *desc_end =3D desc + desc_size; + struct ring_buffer_desc *rb_desc; + int cpu, ret =3D -ENOMEM; + + if (desc_size < struct_size(desc, __data, 0)) + return -EINVAL; + + desc->nr_cpus =3D 0; + desc->struct_len =3D struct_size(desc, __data, 0); + + rb_desc =3D (struct ring_buffer_desc *)&desc->__data[0]; + + for_each_cpu(cpu, cpumask) { + unsigned int id; + + if ((void *)rb_desc + struct_size(rb_desc, page_va, nr_pages) > desc_end= ) { + ret =3D -EINVAL; + goto err; + } + + rb_desc->cpu =3D cpu; + rb_desc->nr_page_va =3D 0; + rb_desc->meta_va =3D (unsigned long)__get_free_page(GFP_KERNEL); + if (!rb_desc->meta_va) + goto err; + + for (id =3D 0; id < nr_pages; id++) { + rb_desc->page_va[id] =3D (unsigned long)__get_free_page(GFP_KERNEL); + if (!rb_desc->page_va[id]) + goto err; + + rb_desc->nr_page_va++; + } + desc->nr_cpus++; + desc->struct_len +=3D offsetof(struct ring_buffer_desc, page_va); + desc->struct_len +=3D struct_size(rb_desc, page_va, rb_desc->nr_page_va); + rb_desc =3D __next_ring_buffer_desc(rb_desc); + } + + return 0; + +err: + trace_remote_free_buffer(desc); + return ret; +} --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E33661B6D06 for ; Fri, 3 Oct 2025 13:39:04 +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=1759498747; cv=none; b=Ec4dq6bL1CP4bpYX6MP9iCZ0L1errQ3cdiNE97aVtVLLLtfxFTGdCyk3hrG7/TVTW4SW+Ou0NfYOdbqHyoDhVcgDUxyDH43wFWl9BXhlob/njcw7iY9KQIuIcpVjF+fqM5Bos8lXImV2nAO20SreGKvmon+O2BjTxjoAt/fN5J0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498747; c=relaxed/simple; bh=zT74DeXMaKIG/3fbrwAf0icnHo/7anzc8q2SBfDJcnY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jiS0rZ2oACUTQyl1bihYATMfp5dOZ+I0osnQGVB+ZfGou2KqJ0hETbNqxOdFFIv/eCCCqPrYTmWtueW9W/4bRnBj86AKTwFK+ZqytNb0DvhPOTbXgJs3iho5YilTKFv4I7Tq3siH0QeIl3YterSySKvXAiVNGA1EJKk0yih3XqY= 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=232FwJFj; 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="232FwJFj" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-4255d025f41so1511951f8f.1 for ; Fri, 03 Oct 2025 06:39:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498743; x=1760103543; 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=d5ChM7xYZbIcJhJhkgKHyrsGnApdkThlCNMDyu2wV38=; b=232FwJFjEvhUbHrAWt2593KmQDUhtg1IAhHRJBrhAGoC9pcyuE5s2vZrVWkRS/owwn 6auLscGPF9mhFkF6LHISHei3rBJMQnCJ3+VR7TnmTHxqIrxxQsqSEm6pctEEjKB0unIL H18imi6tTIwqwtPt6bsTLtLaNk3mhd5kR7PbfVyFnHE7pIO65dAzbSHUkYB6RtG0oBl9 SHTV/KbRdV8c99L++UIqONrLgeBNa7FUmMGPs+JNKtqd23ezH1U5Ni9Q1RSR4gUJO6tO hoZeU1r4U8WdpCZbwFXaKxlXWUvJpU/tJZc3vWl+2pF8IU5JEc5lFQ675+feDtvYPqNu ACDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498743; x=1760103543; 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=d5ChM7xYZbIcJhJhkgKHyrsGnApdkThlCNMDyu2wV38=; b=iBjTrSuxWUXaAPX0t9OQW8q12evRnDOT2QvuxQhSpvzBWISx0DS2XJ44laHG1eP3f/ s6l1toE5az3rf/lO4moEK5Mlvj8BanIO5bvfbWeoYhMFPiUdNBFQ7+koBQhFecmhYODB W2oqHt1JWcc7ZtG31lrAJH/vZfrBYCQL2EF4ZGpMWZsve8jAvm1goRgSG3rh/W4+ZUL8 bxRV4OXQ1K+YxfsROgbmiP4W1yVlyCwg9syP//DT2v7GtrqNJ8k+01R045pwY5ig7Gqw n1w0QOZ/km+ljtFc7S35NyU6VXApXaMPaV/Jqdns+W+D9nxzVFaAx/U+nBg0YAYAbixP B2xQ== X-Forwarded-Encrypted: i=1; AJvYcCXE1tjgOE0njVSNKblOMjAcocmT303EMvY1GqD7xuBatcwLMYNIYz/SZOxT2QmjxX/p69SUwKbNTHpD/TY=@vger.kernel.org X-Gm-Message-State: AOJu0Yy4UqtJrONqKB+RymLA7RApKUwEQ+aA9F39Dp34ALNhamWKV7rA Fspe8+h8jzL8GuVHRcG4HSdsUWUa8tqz177tRIMpuXpSFj1Vq6TckPrTHhIad9BCT5x0VwjsPNS H0uh8YDJw1Bcdqd/OUZgj8w== X-Google-Smtp-Source: AGHT+IGEKVUnoX9TtZqLBT0f/tik6zhh9b91Brx6pOn/31k484u2FIJbEyDbYJWN7r7k8vY/aCKrmMghs8AZJmNC X-Received: from wmcn6.prod.google.com ([2002:a05:600c:c0c6:b0:45d:d522:48a9]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3d90:b0:46e:3d5a:d15d with SMTP id 5b1f17b1804b1-46e7114dea1mr21903175e9.26.1759498743037; Fri, 03 Oct 2025 06:39:03 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:03 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-7-vdonnefort@google.com> Subject: [PATCH v7 06/28] tracing: Add reset to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow to reset the trace remote buffer by writing to the Tracefs "trace" file. This is similar to the regular Tracefs interface. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index feb3433c2128..55754ef78104 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -18,6 +18,8 @@ * remote to allow writing. * @swap_reader_page: Called when Tracefs consumes a new page from a * ring-buffer. It is expected from the remote to isolate a + * @reset: Called on `echo 0 > trace`. It is expected from the + * remote to reset all ring-buffer pages. * new reader-page from the @cpu ring-buffer. */ struct trace_remote_callbacks { @@ -25,6 +27,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 /** diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 3d76a4d7d5f5..abf83ff75df5 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -63,6 +63,7 @@ static int trace_remote_load(struct trace_remote *remote) rb_remote->desc =3D remote->trace_buffer_desc; rb_remote->swap_reader_page =3D remote->cbs->swap_reader_page; rb_remote->priv =3D remote->priv; + rb_remote->reset =3D remote->cbs->reset; remote->trace_buffer =3D ring_buffer_alloc_remote(rb_remote); if (!remote->trace_buffer) { remote->cbs->unload_trace_buffer(remote->trace_buffer_desc, remote->priv= ); @@ -136,6 +137,21 @@ static int trace_remote_disable_tracing(struct trace_r= emote *remote) return 0; } =20 +static void trace_remote_reset(struct trace_remote *remote, int cpu) +{ + lockdep_assert_held(&remote->lock); + + if (!trace_remote_loaded(remote)) + return; + + if (cpu =3D=3D RING_BUFFER_ALL_CPUS) + ring_buffer_reset(remote->trace_buffer); + else + ring_buffer_reset_cpu(remote->trace_buffer, cpu); + + trace_remote_try_unload(remote); +} + static ssize_t tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) { @@ -411,6 +427,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; @@ -441,7 +477,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", TRACEFS_MODE_WRITE, remote_d, remote, + &trace_fops)) goto err; =20 percpu_d =3D tracefs_create_dir("per_cpu", remote_d); @@ -463,7 +501,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", TRACEFS_MODE_WRITE, cpu_d, remote, c= pu, + &trace_fops)) goto err; } =20 --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B129E215F42 for ; Fri, 3 Oct 2025 13:39:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498749; cv=none; b=LdcLxxRiGyZZEQ6KkteuA3D8lekjXfsj2zfOzK/Bko1/611L111OScxgzHFilIpqCd1u//YJsNc1nbTljquf4QgWLIqKWy2Ttg/g8O0B7TztKGYidsmeAnSgVxHH7AuuqeAcqk10vS5/3rAM77tjZURljkMsa84i5inNIobn2sU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498749; c=relaxed/simple; bh=t75ayGxCMrO/NuaBi1lq2ZZ8I5KlQamlv7LOF2C6wXE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QcpJ4SILaNMlYrVkVzz+jp2wIT4biLsmI46TOiP3Mi+IjeN+zk/v9OLbxt+fBMBiOznpMfSWD23jvltsc1BnopSPfcAPfqssEBKoSz9Sq/vbyffke0b94owKXJERTD2e92dPSgB3cS/PVBFNUDdru2KLOhM61qZdWl9C+0hhRlk= 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=x8DESbVx; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="x8DESbVx" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-634bff4ccc6so2485120a12.1 for ; Fri, 03 Oct 2025 06:39:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498744; x=1760103544; 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=sRrzwoqtDq69fzY2uAOlys9sUNZV01DsfbfPbHPHmEY=; b=x8DESbVxlUbJ6J1xbFuhW/W8Iqeq5ZcUmqg5ttElIEC/FxxWeYQXsPEYkar2bn1NY6 ipbc40sShX+nJqohLewdkWaPwqULnavamTtBgmDgrQmHJyRDwPZJeSPrek6zY9FLhwbM 0RYPvfxtoUbTjG8Zx2jxZ3he/PztKBYang4PmVvvQxhfHJv1yIGhynvoiLR7MOCgBBPb E+bMoNgJs46qjJQqQ3RyEIaQ1xIcrjW2VHkZgLdQV2cRdYfpCwPC0dWT8vthDXee9x7d SLOKdKTvf5TL/tpkTHwu1EO8r0+mpyS/7lg/5XmwgofyBWf50bjpZ9H2XWUqDHXFY5f/ BKyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498744; x=1760103544; 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=sRrzwoqtDq69fzY2uAOlys9sUNZV01DsfbfPbHPHmEY=; b=JWipUFMgG0LKOr0VZANrPPt1L7AxidWtwtibiHSZzEfLlWTHcNoiHxzy6motDBApaR T79VZnC+zMq4l0Hz1rpydzt6pTf5ArjHqSjvQxJKT2feQ12NcJhNKdexffSIOu/sFczg uSHRMyoUZ2wjZEUSfEHjl33pvHJ76pLo8629sFBUF1aVxMAl+kq7lfgLn5K9zzpiY3+L AhwP27bPm14WHuUmC/NPKZPHpeIwsNmSU5CyyTB77GuVzjs+zQmyGtzc/T/YwtL37KUM H0MK0vPi1aZd6jUmY/sWMBomACNrBrF545D2qCQPuK2sN7tFez9AJ7fZMS09H6KqwYA+ tFkQ== X-Forwarded-Encrypted: i=1; AJvYcCU/D0fnFaKQSJej1ufXElAMyJtH4wY6+y7JTvxP6YT57mRSkbE3CGgNyRo+iDxPfjQizbgWYFG7i/jHhb8=@vger.kernel.org X-Gm-Message-State: AOJu0Yw1scfx1a50cYYiDurZZFgP5F4ZbPBWtALHBDt7ydmUyYooXSAG yyb4vTqUrPuLnYm7tW0ziGqXfl7fyUC4a7may6ik+FpGRFaFs+P+MTeqwyA7h3HiVbJMfoTC3fR AOIBqRbUw0k38Qw0cpFxoSA== X-Google-Smtp-Source: AGHT+IGUXWWds2ewsHTgFFn05kr5zfhEYrWur6uTyVy86MnDd3O3kJhjbZCZxqlXxu52/kXMpwtMGcq/0xgmj2Uu X-Received: from ejcd15.prod.google.com ([2002:a17:906:370f:b0:b3d:f163:3222]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:9727:b0:b3b:d772:719b with SMTP id a640c23a62f3a-b49c3932abemr367080566b.41.1759498744135; Fri, 03 Oct 2025 06:39:04 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:04 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-8-vdonnefort@google.com> Subject: [PATCH v7 07/28] tracing: Add non-consuming read to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow reading the trace file for trace remotes. This performs a non-consuming read of the trace buffer. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index abf83ff75df5..c011df20df95 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -18,14 +18,25 @@ #define TRACEFS_MODE_WRITE 0640 #define TRACEFS_MODE_READ 0440 =20 +enum tri_type { + TRI_CONSUMING, + TRI_NONCONSUMING, +}; + struct trace_remote_iterator { struct trace_remote *remote; struct trace_seq seq; struct delayed_work poll_work; unsigned long lost_events; u64 ts; + union { + struct ring_buffer_iter **rb_iters; + struct ring_buffer_iter *rb_iter; + }; int cpu; int evt_cpu; + loff_t pos; + enum tri_type type; }; =20 struct trace_remote { @@ -36,6 +47,8 @@ struct trace_remote { unsigned long trace_buffer_size; struct ring_buffer_remote rb_remote; struct mutex lock; + struct rw_semaphore reader_lock; + struct rw_semaphore *pcpu_reader_locks; unsigned int nr_readers; unsigned int poll_ms; bool tracing_on; @@ -225,6 +238,20 @@ static int trace_remote_get(struct trace_remote *remot= e, int cpu) if (ret) return ret; =20 + if (cpu !=3D RING_BUFFER_ALL_CPUS && !remote->pcpu_reader_locks) { + int lock_cpu; + + remote->pcpu_reader_locks =3D kcalloc(nr_cpu_ids, sizeof(*remote->pcpu_r= eader_locks), + GFP_KERNEL); + if (!remote->pcpu_reader_locks) { + trace_remote_try_unload(remote); + return -ENOMEM; + } + + for_each_possible_cpu(lock_cpu) + init_rwsem(&remote->pcpu_reader_locks[lock_cpu]); + } + remote->nr_readers++; =20 return 0; @@ -239,6 +266,9 @@ static void trace_remote_put(struct trace_remote *remot= e) if (remote->nr_readers) return; =20 + kfree(remote->pcpu_reader_locks); + remote->pcpu_reader_locks =3D NULL; + trace_remote_try_unload(remote); } =20 @@ -253,6 +283,48 @@ static void __poll_remote(struct work_struct *work) msecs_to_jiffies(iter->remote->poll_ms)); } =20 +static int __alloc_ring_buffer_iter(struct trace_remote_iterator *iter, in= t cpu) +{ + bool once =3D false; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + iter->rb_iter =3D ring_buffer_read_start(iter->remote->trace_buffer, cpu= , GFP_KERNEL); + + return iter->rb_iter ? 0 : -ENOMEM; + } + + iter->rb_iters =3D kcalloc(nr_cpu_ids, sizeof(*iter->rb_iters), GFP_KERNE= L); + if (!iter->rb_iters) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + iter->rb_iters[cpu] =3D ring_buffer_read_start(iter->remote->trace_buffe= r, cpu, + GFP_KERNEL); + if (iter->rb_iters[cpu]) + once =3D true; + } + + return once ? 0 : -ENOMEM; +} + +static void __free_ring_buffer_iter(struct trace_remote_iterator *iter, in= t cpu) +{ + if (!iter->rb_iter) + return; + + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + ring_buffer_read_finish(iter->rb_iter); + return; + } + + for_each_possible_cpu(cpu) { + if (iter->rb_iters[cpu]) + ring_buffer_read_finish(iter->rb_iters[cpu]); + } + + kfree(iter->rb_iters); +} + static struct trace_remote_iterator *trace_remote_iter(struct trace_remote *remote, int cpu, enum tri_type typ= e) { @@ -261,6 +333,8 @@ static struct trace_remote_iterator =20 lockdep_assert_held(&remote->lock); =20 + if (type =3D=3D TRI_NONCONSUMING && !trace_remote_loaded(remote)) + return NULL; =20 ret =3D trace_remote_get(remote, cpu); if (ret) @@ -275,9 +349,21 @@ static struct trace_remote_iterator if (iter) { iter->remote =3D remote; iter->cpu =3D cpu; + iter->type =3D type; trace_seq_init(&iter->seq); - INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); - schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_ms= )); + + switch (type) { + case TRI_CONSUMING: + INIT_DELAYED_WORK(&iter->poll_work, __poll_remote); + schedule_delayed_work(&iter->poll_work, msecs_to_jiffies(remote->poll_m= s)); + break; + case TRI_NONCONSUMING: + ret =3D __alloc_ring_buffer_iter(iter, cpu); + break; + } + + if (ret) + goto err; =20 return iter; } @@ -301,10 +387,100 @@ static void trace_remote_iter_free(struct trace_remo= te_iterator *iter) =20 lockdep_assert_held(&remote->lock); =20 + switch (iter->type) { + case TRI_CONSUMING: + cancel_delayed_work_sync(&iter->poll_work); + break; + case TRI_NONCONSUMING: + __free_ring_buffer_iter(iter, iter->cpu); + break; + } + kfree(iter); trace_remote_put(remote); } =20 +static void trace_remote_iter_read_start(struct trace_remote_iterator *ite= r) +{ + struct trace_remote *remote =3D iter->remote; + int cpu =3D iter->cpu; + + /* Acquire global reader lock */ + if (cpu =3D=3D RING_BUFFER_ALL_CPUS && iter->type =3D=3D TRI_CONSUMING) + down_write(&remote->reader_lock); + else + down_read(&remote->reader_lock); + + if (cpu =3D=3D RING_BUFFER_ALL_CPUS) + return; + + /* + * No need for the remote lock here, iter holds a reference on + * remote->nr_readers + */ + + /* Get the per-CPU one */ + if (WARN_ON_ONCE(!remote->pcpu_reader_locks)) + return; + + if (iter->type =3D=3D TRI_CONSUMING) + down_write(&remote->pcpu_reader_locks[cpu]); + else + down_read(&remote->pcpu_reader_locks[cpu]); +} + +static void trace_remote_iter_read_finished(struct trace_remote_iterator *= iter) +{ + struct trace_remote *remote =3D iter->remote; + int cpu =3D iter->cpu; + + /* Release per-CPU reader lock */ + if (cpu !=3D RING_BUFFER_ALL_CPUS) { + /* + * No need for the remote lock here, iter holds a reference on + * remote->nr_readers + */ + if (iter->type =3D=3D TRI_CONSUMING) + up_write(&remote->pcpu_reader_locks[cpu]); + else + up_read(&remote->pcpu_reader_locks[cpu]); + } + + /* Release global reader lock */ + if (cpu =3D=3D RING_BUFFER_ALL_CPUS && iter->type =3D=3D TRI_CONSUMING) + up_write(&remote->reader_lock); + else + up_read(&remote->reader_lock); +} + +static struct ring_buffer_iter *__get_rb_iter(struct trace_remote_iterator= *iter, int cpu) +{ + return iter->cpu !=3D RING_BUFFER_ALL_CPUS ? iter->rb_iter : iter->rb_ite= rs[cpu]; +} + +static struct ring_buffer_event * +__peek_event(struct trace_remote_iterator *iter, int cpu, u64 *ts, unsigne= d long *lost_events) +{ + struct ring_buffer_event *rb_evt; + struct ring_buffer_iter *rb_iter; + + switch (iter->type) { + case TRI_CONSUMING: + return ring_buffer_peek(iter->remote->trace_buffer, cpu, ts, lost_events= ); + case TRI_NONCONSUMING: + rb_iter =3D __get_rb_iter(iter, cpu); + rb_evt =3D ring_buffer_iter_peek(rb_iter, ts); + if (!rb_evt) + return NULL; + + *lost_events =3D ring_buffer_iter_dropped(rb_iter); + + return rb_evt; + } + + return NULL; +} + static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) { struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; @@ -314,7 +490,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) return false; =20 - if (!ring_buffer_peek(trace_buffer, cpu, &iter->ts, &iter->lost_events)) + if (!__peek_event(iter, cpu, &iter->ts, &iter->lost_events)) return false; =20 iter->evt_cpu =3D cpu; @@ -329,7 +505,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) continue; =20 - if (!ring_buffer_peek(trace_buffer, cpu, &ts, &lost_events)) + if (!__peek_event(iter, cpu, &ts, &lost_events)) continue; =20 if (ts >=3D iter->ts) @@ -343,7 +519,21 @@ static bool trace_remote_iter_read_event(struct trace_= remote_iterator *iter) return iter->ts !=3D U64_MAX; } =20 -static int trace_remote_iter_print(struct trace_remote_iterator *iter) +static void trace_remote_iter_move(struct trace_remote_iterator *iter) +{ + struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + + switch (iter->type) { + case TRI_CONSUMING: + ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + break; + case TRI_NONCONSUMING: + ring_buffer_iter_advance(__get_rb_iter(iter, iter->evt_cpu)); + break; + } +} + +static int trace_remote_iter_print_event(struct trace_remote_iterator *ite= r) { unsigned long usecs_rem; u64 ts =3D iter->ts; @@ -371,7 +561,11 @@ static int trace_pipe_open(struct inode *inode, struct= file *filp) cpu =3D (long)inode->i_cdev - 1; =20 guard(mutex)(&remote->lock); - iter =3D trace_remote_iter(remote, cpu); + + iter =3D trace_remote_iter(remote, cpu, TRI_CONSUMING); + if (IS_ERR(iter)) + return PTR_ERR(iter); + filp->private_data =3D iter; =20 return IS_ERR(iter) ? PTR_ERR(iter) : 0; @@ -406,7 +600,8 @@ static ssize_t trace_pipe_read(struct file *filp, char = __user *ubuf, size_t cnt, if (ret < 0) return ret; =20 - while (trace_remote_iter_next(iter)) { + trace_remote_iter_read_start(iter); + while (trace_remote_iter_read_event(iter)) { int prev_len =3D iter->seq.seq.len; =20 @@ -415,9 +610,11 @@ static ssize_t trace_pipe_read(struct file *filp, char= __user *ubuf, size_t cnt, break; } =20 - ring_buffer_consume(trace_buffer, iter->evt_cpu, NULL, NULL); + trace_remote_iter_move(iter); } =20 + trace_remote_iter_read_finished(iter); + goto copy_to_user; } =20 @@ -427,6 +624,119 @@ static const struct file_operations trace_pipe_fops = =3D { .release =3D trace_pipe_release, }; =20 +static void *trace_seq_start(struct seq_file *m, loff_t *pos) +{ + struct trace_remote_iterator *iter =3D m->private; + loff_t i =3D *pos; + + if (!iter) + return NULL; + + if (iter->pos <=3D *pos) { + do { + if (!trace_remote_iter_read_event(iter)) + return NULL; + + trace_remote_iter_move(iter); + iter->pos++; + } while (i--); + } + + return iter; +} + +static void *trace_seq_next(struct seq_file *m, void *v, loff_t *pos) +{ + struct trace_remote_iterator *iter =3D m->private; + + ++*pos; + + if (!iter || !trace_remote_iter_read_event(iter)) + return NULL; + + trace_remote_iter_move(iter); + iter->pos++; + + return iter; +} + +static int trace_seq_show(struct seq_file *m, void *v) +{ + struct trace_remote_iterator *iter =3D v; + + trace_seq_init(&iter->seq); + + if (trace_remote_iter_print_event(iter)) { + seq_printf(m, "[EVENT %d PRINT TOO BIG]\n", iter->evt->id); + return 0; + } + + return trace_print_seq(m, &iter->seq); +} + +static void trace_seq_stop(struct seq_file *s, void *v) { } + +static const struct seq_operations trace_seq_ops =3D { + .start =3D trace_seq_start, + .next =3D trace_seq_next, + .show =3D trace_seq_show, + .stop =3D trace_seq_stop, +}; + +static int trace_open(struct inode *inode, struct file *filp) +{ + struct trace_remote *remote =3D inode->i_private; + struct trace_remote_iterator *iter =3D NULL; + int cpu =3D RING_BUFFER_ALL_CPUS; + int ret; + + if (!(filp->f_mode & FMODE_READ)) + return 0; + + if (inode->i_cdev) + cpu =3D (long)inode->i_cdev - 1; + + guard(mutex)(&remote->lock); + + iter =3D trace_remote_iter(remote, cpu, TRI_NONCONSUMING); + if (IS_ERR(iter)) + return PTR_ERR(iter); + + ret =3D seq_open(filp, &trace_seq_ops); + if (ret) { + trace_remote_iter_free(iter); + return ret; + } + + if (iter) + trace_remote_iter_read_start(iter); + + ((struct seq_file *)filp->private_data)->private =3D (void *)iter; + + return 0; +} + +static int trace_release(struct inode *inode, struct file *filp) +{ + struct trace_remote_iterator *iter; + + if (!(filp->f_mode & FMODE_READ)) + return 0; + + iter =3D ((struct seq_file *)filp->private_data)->private; + seq_release(inode, filp); + + if (!iter) + return 0; + + guard(mutex)(&iter->remote->lock); + + trace_remote_iter_read_finished(iter); + trace_remote_iter_free(iter); + + return 0; +} + static ssize_t trace_write(struct file *filp, const char __user *ubuf, siz= e_t cnt, loff_t *ppos) { struct inode *inode =3D file_inode(filp); @@ -444,7 +754,11 @@ static ssize_t trace_write(struct file *filp, const ch= ar __user *ubuf, size_t cn } =20 static const struct file_operations trace_fops =3D { + .open =3D trace_open, .write =3D trace_write, + .read =3D seq_read, + .read_iter =3D seq_read_iter, + .release =3D trace_release, }; =20 static int trace_remote_init_tracefs(const char *name, struct trace_remote= *remote) @@ -533,6 +847,7 @@ int trace_remote_register(const char *name, struct trac= e_remote_callbacks *cbs, remote->trace_buffer_size =3D 7 << 10; remote->poll_ms =3D 100; mutex_init(&remote->lock); + init_rwsem(&remote->reader_lock); =20 if (trace_remote_init_tracefs(name, remote)) { kfree(remote); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BEE9C218EA2 for ; Fri, 3 Oct 2025 13:39:06 +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=1759498750; cv=none; b=Cmn9tXxKI4LQKBatV4UpXSH2GcJrHiGJnk8pLTDvLxyXnT75ExfV4+gEUsUSDrjtwhGXI2BQsez9nDOQaxvXXpvvTcnW0juavf4AEANR+qrufHwuvxU0KZ1Nsb7X5feoNE4uBzQQX6zvi2pANfCCBT6peMaIH+eR3pgK8kP46+0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498750; c=relaxed/simple; bh=LuttUe5CO5VAn3hELI/7s6eCl7Ml9SPGqKByWNdQ0S8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=giScCpgTyiMEEuRuRiGrrUY4sOnB6sb5gI5nbbO/++kR7FvyhpRLbZzWKH7PKjSUiohTHTAH3Kurt+Oc5Y5Ayw3ouo5icEN0W1R4ZF1tRcT3McetMCFkBGnoIoEcjEjLNuEjJXtj7OKppZA/JlS/oLqR1JgC/gXwSEf1IOjd87o= 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=1YYage+7; 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="1YYage+7" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e46486972so8021655e9.0 for ; Fri, 03 Oct 2025 06:39:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498745; x=1760103545; 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=fs/M7Fqoy0zdu3rq0sxtnZW6IS3TOjHhsegHTeIPLQM=; b=1YYage+71pG6+WfPFQUKbh5EJGtoPch4oVzuP4zljmjVNqw61f33TndpEupmm5oFxh g2ObI2QJ1DrDuSwWn1004h8hRwkeOnHS1TYRUmjacjKquvtQuL0JStnUGudxtnQKTRHv D1lrHxG/gGcl9tiEv3DupRgfqxi5xfuaj+n8gd96mqx7iHWUcmqi8ftR2ta/jVhcpeek 6zW7LG/vUAxm6YKRYE1nVPQnFYCJ9oAFUx3pZpMnylYzcBlLidNeUgSpndERWii9Ylem 0kbvTe9BGa+3GbIkR5NlsgdHILOJHQcgkdoPWGC16buC5GGSggvr2uG0SYlf+pvtKI9G dEqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498745; x=1760103545; 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=fs/M7Fqoy0zdu3rq0sxtnZW6IS3TOjHhsegHTeIPLQM=; b=JruY2X3vmbFagKS7f6BJTTNqlfZcsHLPtCR3M0NO6mnclF7pgXds6+gLhZ3p+u+9XS LIP1tqwyataZPkkoY4xo2idxCKiaY/50h4HaBWjPmkK/6rNgQSJi96raezAww199O8Wx mHyePZNJCqv3Vywotvd/7lswq0Sb6WBmMXTWwxfXK0LLh/Ff5I4xtuYg5f0yUGUAbDhc fJzrMAc25a7u0Pbm2Y/vReH9r70Hd303Kyn15otQ4gfbYYENnBS6wJOXz/nzap9kkjFu vC3jtfmusyARWCHfgm/HYqmTM2KRitKWzYGmI8zRqIUcY5+omo4wfePxbXHabaFKaeUP T6Jw== X-Forwarded-Encrypted: i=1; AJvYcCXGZrJDUarNYVofCotT4NpWfW75woY4XAMT87vaeEJCCzGabNG6rL0dVeb3vV2JgQ0oQ5cy0UGakJzcmg4=@vger.kernel.org X-Gm-Message-State: AOJu0YwA0EZhs30ennBeulZ0zUsR/kLdQt6oLQibY7M8hIXeqZqqvBHb qg5RXAwrrf3RQvLJMnRSjIeThrQIuXtMvKJYUAsrqgyoh5x88tB5nTJP+j77799q5nuj6j16/Ri WyZNMrWOxFwqlA2mc0TlmuQ== X-Google-Smtp-Source: AGHT+IGhMHN0dJUUicPDV7IwYD5dxjTKJb2FY9Dk+V7sxgd83geumTaXQTdlEwmEdvOKbgxCexNOxhanuhI6Kor0 X-Received: from wmbz10.prod.google.com ([2002:a05:600c:c08a:b0:46e:38cf:fbd6]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:34ce:b0:45c:4470:271c with SMTP id 5b1f17b1804b1-46e711408b5mr20342175e9.18.1759498745183; Fri, 03 Oct 2025 06:39:05 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:05 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-9-vdonnefort@google.com> Subject: [PATCH v7 08/28] tracing: Add init callback to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a .init call back so the trace remote callers can add entries to the tracefs directory. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 55754ef78104..15a579633123 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -3,11 +3,14 @@ #ifndef _LINUX_TRACE_REMOTE_H #define _LINUX_TRACE_REMOTE_H =20 +#include #include =20 /** * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote * + * @init: Called once the remote has been registered. Allows the + * caller to extend the Tracefs remote directory * @load_trace_buffer: Called before Tracefs accesses the trace buffer fo= r the first * time. Must return a &trace_buffer_desc * (most likely filled with trace_remote_alloc_buffer()) @@ -23,6 +26,7 @@ * new reader-page from the @cpu ring-buffer. */ struct trace_remote_callbacks { + int (*init)(struct dentry *d, void *priv); struct trace_buffer_desc *(*load_trace_buffer)(unsigned long size, void *= priv); void (*unload_trace_buffer)(struct trace_buffer_desc *desc, void *priv); int (*enable_tracing)(bool enable, void *priv); diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index c011df20df95..55ba3fd9e002 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -837,6 +837,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) @@ -854,7 +855,11 @@ int trace_remote_register(const char *name, struct tra= ce_remote_callbacks *cbs, return -ENOMEM; } =20 - return 0; + ret =3D cbs->init ? cbs->init(remote->dentry, priv) : 0; + if (ret) + pr_err("Init failed for trace remote '%s' (%d)\n", name, ret); + + return ret; } =20 void trace_remote_free_buffer(struct trace_buffer_desc *desc) --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D1BD721ABB1 for ; Fri, 3 Oct 2025 13:39:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498750; cv=none; b=l4YUYrNxdBjTEkZfyj6vHzIcOvZ34GpDMXnRmfaKNZmAwd0ufS5+kZhRzgJkHiwxVC6U45z7hxV/t8Z9Icvxv/QHnBZWrStAxraaGIOOpXb4RURpumlUNB+zVVW0u9bj88n/3gBaBgMaGTo2e2SuEgGvmW8O767Zw/kvSUOLoiY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498750; c=relaxed/simple; bh=UlV2P8HE6UloPyjMWwbeS4xK7drRiIoRCBgpbZbrDM4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hc2N2iP94y11PuNfXX2JVNU/t5J8gt2pmeXTEbz4i1aeB6O+n3238T3npoG80e/iglnyrXebyc09O3HSMZWjRmJyvTRl3pHuLytEATmSLJn2Nc/Im30TQr9ZA9jk3Pq6PL7nGpb3oG6kSNjd40o1nyCIMbi+5ye9NyjTwvhRTYw= 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=Cy0Txtut; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Cy0Txtut" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-b07c2924d53so198665466b.3 for ; Fri, 03 Oct 2025 06:39:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498746; x=1760103546; 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=FnIs6mkC8461WxAdM06cuKij/sR9Wa7LFhPzklSO9gg=; b=Cy0TxtutQ29hb38mR24bS3cHmjyhTJaB88640kY/+ghe6e0MrmsdmOxGqxczqOs6i9 6jaxAW/MnjYWXK0JqKij0DWPLXmXHlmXMUBRiOUKonJHW2GzWJYX1LKsr9P6vP5pO/bH xLtGcxv1H04tI3NKgYmCmqSIOyTruifbK0x6oiQY8YIaEKtv3Hb/k+HYeAymzYW4HyqT acDThz5LR93yMz6qtagYoZG89DwR+yQP2SDQUmmS38vXnY4Law1737Afhv/JvsUQDWTB z0YHkVUjYT3SPO5KzJWzJO8VicB1pn8IMJHZlSb0sHRLVTidTZ/TxXQllN4LzspkwbD2 EiAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498746; x=1760103546; 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=FnIs6mkC8461WxAdM06cuKij/sR9Wa7LFhPzklSO9gg=; b=ThC98ckRpOOhT7lHLXivGfA7VyYh7XMFmNHG7Jjmd9eIiZHJj4PYQlvwsI3pw9JYDe /Et+3VC+squhzPUHl2hTi3VACaQ0jVYQ/iMi6mszL3htNr8WPINhFxsCORLc0KILJJHg BRvuldbszweUitl4i4q2lcCEW5pI+DKXYvIb3R+LXdm7oHg1JAp/zkfKuxQYVQqZQj1J fHVYtIvcKEZiYB06wyJrn1lnclYRuO7roavrqx75v2/j5iCmdcBOIib0tGVU5VjpiwIC y8zHu8qYG7DEqu0PVxsNSvwk0wLpjwpPhGNuDA6D7PUUAPQsPnG+JmlAXvAcvK+TRAVt 1wZw== X-Forwarded-Encrypted: i=1; AJvYcCXBaww43zbYPjs3aERkYCp440Cr6BFtcTKQZVwKMFOqxz7qq3SEJBclX4EpcPMyiz6oYzSgJIp+j4frFdE=@vger.kernel.org X-Gm-Message-State: AOJu0YwR/fnCmy74zHzcNpgEGc8pW5i/WA3vtrKckBYRmyK5puPclQ9I aeeCTkETv7R2NsgQgla9zZlbzUVEqb5MNXGDSmsOrQOgjFumnfszZEuoecrqtWfaI5BL/JTdOtT +ZryEDrs3OSHZjuEyCndl7Q== X-Google-Smtp-Source: AGHT+IFD3HeWIoToYX0mtY54yQekjj5b06NSm6nMjymXtmA/dEJabOncQXjfK7kXo3lD7+6n6IxKIVzX9L5JzG25 X-Received: from ejbdx26.prod.google.com ([2002:a17:906:a85a:b0:b45:b254:8e03]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:d90:b0:b43:2a3c:c74a with SMTP id a640c23a62f3a-b49c48a8de0mr380223366b.60.1759498745977; Fri, 03 Oct 2025 06:39:05 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:06 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-10-vdonnefort@google.com> Subject: [PATCH v7 09/28] tracing: Add events to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An event is predefined point in the writer code that allows to log data. Following the same scheme as kernel events, add remote events, described to user-space within the events/ tracefs directory found in the corresponding trace remote. Remote events are expected to be described during the trace remote registration. Add also a .enable_event callback for trace_remote to toggle the event logging, if supported. Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote.h b/include/linux/trace_remote.h index 15a579633123..456df837fc6b 100644 --- a/include/linux/trace_remote.h +++ b/include/linux/trace_remote.h @@ -5,6 +5,7 @@ =20 #include #include +#include =20 /** * struct trace_remote_callbacks - Callbacks used by Tracefs to control th= e remote @@ -24,6 +25,8 @@ * @reset: Called on `echo 0 > trace`. It is expected from the * remote to reset all ring-buffer pages. * new reader-page from the @cpu ring-buffer. + * @enable_event: Called on events/event_name/enable. It is expected from + * the remote to allow the writing event @id. */ struct trace_remote_callbacks { int (*init)(struct dentry *d, void *priv); @@ -32,6 +35,7 @@ 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 /** @@ -53,7 +57,8 @@ struct trace_remote_callbacks { * * Return: 0 on success, negative error code on failure. */ -int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv); +int trace_remote_register(const char *name, struct trace_remote_callbacks = *cbs, void *priv, + struct remote_event *events, size_t nr_events); =20 /** * trace_remote_alloc_buffer() - Dynamically allocate a trace buffer diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remot= e_event.h new file mode 100644 index 000000000000..a4449008a075 --- /dev/null +++ b/include/linux/trace_remote_event.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_TRACE_REMOTE_EVENTS_H +#define _LINUX_TRACE_REMOTE_EVENTS_H + +struct trace_remote; +struct trace_event_fields; + +struct remote_event_hdr { + unsigned short id; +}; + +#define REMOTE_EVENT_NAME_MAX 30 +struct remote_event { + char name[REMOTE_EVENT_NAME_MAX]; + unsigned short id; + bool enabled; + struct trace_remote *remote; + struct trace_event_fields *fields; + char *print_fmt; + void (*print)(void *evt, struct trace_seq *seq); +}; +#endif diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 55ba3fd9e002..9504d9c04bef 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -33,6 +33,7 @@ struct trace_remote_iterator { struct ring_buffer_iter **rb_iters; struct ring_buffer_iter *rb_iter; }; + struct remote_event_hdr *evt; int cpu; int evt_cpu; loff_t pos; @@ -44,6 +45,10 @@ struct trace_remote { void *priv; struct trace_buffer *trace_buffer; struct trace_buffer_desc *trace_buffer_desc; + struct dentry *dentry; + struct eventfs_inode *eventfs; + struct remote_event *events; + unsigned long nr_events; unsigned long trace_buffer_size; struct ring_buffer_remote rb_remote; struct mutex lock; @@ -168,7 +173,8 @@ static void trace_remote_reset(struct trace_remote *rem= ote, int cpu) static ssize_t tracing_on_write(struct file *filp, const char __user *ubuf, size_t cnt, l= off_t *ppos) { - struct trace_remote *remote =3D filp->private_data; + struct seq_file *seq =3D filp->private_data; + struct trace_remote *remote =3D seq->private; unsigned long val; int ret; =20 @@ -197,7 +203,8 @@ DEFINE_SHOW_STORE_ATTRIBUTE(tracing_on); static ssize_t buffer_size_kb_write(struct file *filp, const char __user *= ubuf, size_t cnt, loff_t *ppos) { - struct trace_remote *remote =3D filp->private_data; + struct seq_file *seq =3D filp->private_data; + struct trace_remote *remote =3D seq->private; unsigned long val; int ret; =20 @@ -484,16 +491,19 @@ __peek_event(struct trace_remote_iterator *iter, int = cpu, u64 *ts, unsigned long static bool trace_remote_iter_read_event(struct trace_remote_iterator *ite= r) { struct trace_buffer *trace_buffer =3D iter->remote->trace_buffer; + struct ring_buffer_event *rb_evt; int cpu =3D iter->cpu; =20 if (cpu !=3D RING_BUFFER_ALL_CPUS) { if (ring_buffer_empty_cpu(trace_buffer, cpu)) return false; =20 - if (!__peek_event(iter, cpu, &iter->ts, &iter->lost_events)) + rb_evt =3D __peek_event(iter, cpu, &iter->ts, &iter->lost_events); + if (!rb_evt) return false; =20 iter->evt_cpu =3D cpu; + iter->evt =3D (struct remote_event_hdr *)ring_buffer_event_data(rb_evt); return true; } =20 @@ -505,7 +515,8 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) if (ring_buffer_empty_cpu(trace_buffer, cpu)) continue; =20 - if (!__peek_event(iter, cpu, &ts, &lost_events)) + rb_evt =3D __peek_event(iter, cpu, &ts, &lost_events); + if (!rb_evt) continue; =20 if (ts >=3D iter->ts) @@ -513,6 +524,7 @@ static bool trace_remote_iter_read_event(struct trace_r= emote_iterator *iter) =20 iter->ts =3D ts; iter->evt_cpu =3D cpu; + iter->evt =3D (struct remote_event_hdr *)ring_buffer_event_data(rb_evt); iter->lost_events =3D lost_events; } =20 @@ -533,8 +545,11 @@ static void trace_remote_iter_move(struct trace_remote= _iterator *iter) } } =20 +static struct remote_event *trace_remote_find_event(struct trace_remote *r= emote, unsigned short id); + static int trace_remote_iter_print_event(struct trace_remote_iterator *ite= r) { + struct remote_event *evt; unsigned long usecs_rem; u64 ts =3D iter->ts; =20 @@ -548,6 +563,12 @@ static int trace_remote_iter_print_event(struct trace_= remote_iterator *iter) trace_seq_printf(&iter->seq, "[%03d]\t%5llu.%06lu: ", iter->evt_cpu, ts, usecs_rem); =20 + evt =3D trace_remote_find_event(iter->remote, iter->evt->id); + if (!evt) + trace_seq_printf(&iter->seq, "UNKNOWN id=3D%d\n", iter->evt->id); + else + evt->print(iter->evt, &iter->seq); + return trace_seq_has_overflowed(&iter->seq) ? -EOVERFLOW : 0; } =20 @@ -821,6 +842,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: @@ -834,7 +857,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; @@ -855,6 +882,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); @@ -926,3 +960,220 @@ int trace_remote_alloc_buffer(struct trace_buffer_des= c *desc, size_t desc_size, trace_remote_free_buffer(desc); return ret; } + +static int +trace_remote_enable_event(struct trace_remote *remote, struct remote_event= *evt, bool enable) +{ + int ret; + + lockdep_assert_held(&remote->lock); + + if (evt->enabled =3D=3D enable) + return 0; + + ret =3D remote->cbs->enable_event(evt->id, enable, remote->priv); + if (ret) + return ret; + + evt->enabled =3D enable; + + return 0; +} + +static int remote_event_enable_show(struct seq_file *s, void *unused) +{ + struct remote_event *evt =3D s->private; + + seq_printf(s, "%d\n", evt->enabled); + + return 0; +} + +static ssize_t remote_event_enable_write(struct file *filp, const char __u= ser *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *seq =3D filp->private_data; + struct remote_event *evt =3D seq->private; + struct trace_remote *remote =3D evt->remote; + u8 enable; + int ret; + + ret =3D kstrtou8_from_user(ubuf, count, 10, &enable); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + ret =3D trace_remote_enable_event(remote, evt, enable); + if (ret) + return ret; + + return count; +} +DEFINE_SHOW_STORE_ATTRIBUTE(remote_event_enable); + +static int remote_event_id_show(struct seq_file *s, void *unused) +{ + struct remote_event *evt =3D s->private; + + seq_printf(s, "%d\n", evt->id); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(remote_event_id); + +static int remote_event_format_show(struct seq_file *s, void *unused) +{ + size_t offset =3D sizeof(struct remote_event_hdr); + struct remote_event *evt =3D s->private; + struct trace_event_fields *field; + + seq_printf(s, "name: %s\n", evt->name); + seq_printf(s, "ID: %d\n", evt->id); + seq_puts(s, + "format:\n\tfield:unsigned short common_type;\toffset:0;\tsize:2;\tsign= ed:0;\n\n"); + + field =3D &evt->fields[0]; + while (field->name) { + seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%u;\tsigned:%d;\n", + field->type, field->name, offset, field->size, + !field->is_signed); + offset +=3D field->size; + field++; + } + + if (field !=3D &evt->fields[0]) + seq_puts(s, "\n"); + + seq_printf(s, "print fmt: %s\n", evt->print_fmt); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(remote_event_format); + +static int remote_event_callback(const char *name, umode_t *mode, void **d= ata, + const struct file_operations **fops) +{ + if (!strcmp(name, "enable")) { + *mode =3D TRACEFS_MODE_WRITE; + *fops =3D &remote_event_enable_fops; + return 1; + } + + if (!strcmp(name, "id")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_event_id_fops; + return 1; + } + + if (!strcmp(name, "format")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_event_id_fops; + return 1; + } + + return 0; +} + +static int trace_remote_init_eventfs(const char *remote_name, struct trace= _remote *remote, + struct remote_event *evt) +{ + struct eventfs_inode *eventfs =3D remote->eventfs; + static struct eventfs_entry entries[] =3D { + { + .name =3D "enable", + .callback =3D remote_event_callback, + }, { + .name =3D "id", + .callback =3D remote_event_callback, + }, { + .name =3D "format", + .callback =3D remote_event_callback, + } + }; + bool eventfs_create =3D false; + + if (!eventfs) { + eventfs =3D eventfs_create_events_dir("events", remote->dentry, NULL, 0,= NULL); + if (IS_ERR(eventfs)) + return PTR_ERR(eventfs); + + /* + * Create similar hierarchy as local events even if a single system is s= upported at + * the moment + */ + eventfs =3D eventfs_create_dir(remote_name, eventfs, NULL, 0, NULL); + if (IS_ERR(eventfs)) + return PTR_ERR(eventfs); + + remote->eventfs =3D eventfs; + eventfs_create =3D true; + } + + eventfs =3D eventfs_create_dir(evt->name, eventfs, entries, ARRAY_SIZE(en= tries), evt); + if (IS_ERR(eventfs)) { + if (eventfs_create) { + eventfs_remove_events_dir(remote->eventfs); + remote->eventfs =3D NULL; + } + return PTR_ERR(eventfs); + } + + return 0; +} + +static int trace_remote_attach_events(struct trace_remote *remote, struct = remote_event *events, + size_t nr_events) +{ + int i; + + for (i =3D 0; i < nr_events; i++) { + struct remote_event *evt =3D &events[i]; + + if (evt->remote) + return -EEXIST; + + evt->remote =3D remote; + + /* We need events to be sorted for efficient lookup */ + if (i && evt->id <=3D events[i - 1].id) + return -EINVAL; + } + + remote->events =3D events; + remote->nr_events =3D nr_events; + + return 0; +} + +static int trace_remote_register_events(const char *remote_name, struct tr= ace_remote *remote, + struct remote_event *events, size_t nr_events) +{ + int i, ret; + + ret =3D trace_remote_attach_events(remote, events, nr_events); + if (ret) + return ret; + + for (i =3D 0; i < nr_events; i++) { + struct remote_event *evt =3D &events[i]; + + ret =3D trace_remote_init_eventfs(remote_name, remote, evt); + if (ret) + pr_warn("Failed to init eventfs for event '%s' (%d)", + evt->name, ret); + } + + return 0; +} + +static int __cmp_events(const void *id, const void *evt) +{ + return (long)id - ((struct remote_event *)evt)->id; +} + +static struct remote_event *trace_remote_find_event(struct trace_remote *r= emote, unsigned short id) +{ + return bsearch((const void *)(unsigned long)id, remote->events, remote->n= r_events, + sizeof(*remote->events), __cmp_events); +} --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6EBF421C9F9 for ; Fri, 3 Oct 2025 13:39:08 +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=1759498751; cv=none; b=iXcKYH3lb4u7LQWUhgcGQNz95i3HqlBvtTGXis/zBFL/Rg3am4KAZgCTk6s85KG2WiLEVddeHNLbZZAHyf+1+IE/61DAtX+tDL3ZC19WmUyfH9Qr0MB4rNgnutl/KqA90keFZKNZCU4MObZyffrYFQpwf23kbipk9hQtxHkRcGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498751; c=relaxed/simple; bh=QUPYfbDskoW1V0zL8PrtXLcVNc0Rj9seLNH5bvzhzHg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=oT1TNFsVxf2gXTw7b7yx+BVOm3zQv9tUqFNMQbBJU7jBW7rfAjMiV7NqBgGYez6uSi76VE07KPnw937L6FloT37bYuJnfT/Il5aS0FfJgiHtqEG3jFDJocQheqptOMAH4eVG557jOZnq+OlSj+T42SPKa2AZzSUdpZdEOiPIMHc= 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=Ow8jIPZM; 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="Ow8jIPZM" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-40cfb98eddbso1592997f8f.0 for ; Fri, 03 Oct 2025 06:39:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498746; x=1760103546; 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=wNuzwqo0SryxPVWfT4A633RiduwyoKQb5duSwc7WjqM=; b=Ow8jIPZMndKD2jXZCBjb6ZJEOq0N7+1sXOb/slAocdVBB/HctRqXLhYoZRxid4bC4p E3BuqcAcqnR16L+CyEc3ouUhykqVddsOTNB5ct+iK2PcV90hcaEz+huDuGHaI3mhsXi8 BQZAPN+PBDUHrvtQ2iFNHK1n8vrt2PcIQstu0mBgsiKyp/iqyNrWq8i/VAIV/+TLtsnP 5XY36OgnOP/iwfU5UYNMefNEbHHshrrdqEV9b4i526bSCKT73KKSWeTh09fZt2GEf04j Uep8EU9MQ9vi/FbLXpMsS7bQoBwGXz5RYo7sp3mBxm9xv3xbQIwfxKKVbczWTYzY8iR7 r+2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498746; x=1760103546; 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=wNuzwqo0SryxPVWfT4A633RiduwyoKQb5duSwc7WjqM=; b=kihg52EXYCI2TqGB6fPeoRFrI+DbOndISj/qabY3tr6JfBWCjpoTu+nL4cZuwONd6C I9mcJeixIm51mCEQikqXaeTmRIFeQm0VaPFJMpHZ3dBu/yVYj8ZXzl7HRjtHFlhN5K/D OFkOnt4pyQxQxBhajZ6fTOVEi15rKeR8QDRAMRvyXfkm7N5eynSHjVgyXRdNGlXd/SwW QRiAbQWc71ZweBpTAjkOjeaTdIm7Xw31oUk8Dx+mkJslT5w3uEJVJoOBO6+CYTRFxmYj kGb7SLsOb/uKWH9mce/g7xvUua1PUosXJrp9XT7m3Puq4SVHZbhfLhu/gK84MmFd6Y8Y cGnA== X-Forwarded-Encrypted: i=1; AJvYcCUnH+tFP6aFzdrsJATJ/UWbFfP9j5jECw5Qty6kD0VQLI1sufVG4RHQKt2Th7I5i1f6QbHUtu8SlIP2lt8=@vger.kernel.org X-Gm-Message-State: AOJu0YxLARwznHPs106pKKURjob/j0tTQiWGCkLXbeQBoKZEUkc03aJA zcaGzBfNgj7Fm5ziwu5f/Y2T9UPc/vhFxglBb/akT88UdftNCT6R3YgsDUSj9Nc6+vz90tUtxva zArSbtFSCMLZuJH9aN9NcOg== X-Google-Smtp-Source: AGHT+IHdLlzmFSd/8uLT/n+RQpFrBV4OeFRePRaDs9j8FRUA3U3c+FD2rubzZ09J18jdk0ft6f5Qd0MP++kgD1NG X-Received: from wmrk19.prod.google.com ([2002:a05:600c:b53:b0:46e:5ad6:9013]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600d:11:b0:46e:6d12:ee2a with SMTP id 5b1f17b1804b1-46e6d12f14dmr30146875e9.16.1759498746709; Fri, 03 Oct 2025 06:39:06 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:07 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-11-vdonnefort@google.com> Subject: [PATCH v7 10/28] tracing: Add events/ root files to trace remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Just like for the kernel events directory, add 'enable', 'header_page' and 'header_event' at the root of the trace remote events/ directory. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index eb556e691b5e..a26a6f537f87 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 9504d9c04bef..1bc9c9a5197f 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -1075,10 +1075,145 @@ static int remote_event_callback(const char *name,= umode_t *mode, void **data, return 0; } =20 +static ssize_t remote_events_dir_enable_write(struct file *filp, const cha= r __user *ubuf, + size_t count, loff_t *ppos) +{ + struct trace_remote *remote =3D file_inode(filp)->i_private; + int i, ret; + u8 enable; + + ret =3D kstrtou8_from_user(ubuf, count, 10, &enable); + if (ret) + return ret; + + guard(mutex)(&remote->lock); + + for (i =3D 0; i < remote->nr_events; i++) { + struct remote_event *evt =3D &remote->events[i]; + + trace_remote_enable_event(remote, evt, enable); + } + + return count; +} + +static ssize_t remote_events_dir_enable_read(struct file *filp, char __use= r *ubuf, size_t cnt, + loff_t *ppos) +{ + struct trace_remote *remote =3D file_inode(filp)->i_private; + const char enabled_char[] =3D {'0', '1', 'X'}; + char enabled_str[] =3D " \n"; + int i, enabled =3D -1; + + guard(mutex)(&remote->lock); + + for (i =3D 0; i < remote->nr_events; i++) { + struct remote_event *evt =3D &remote->events[i]; + + if (enabled =3D=3D -1) { + enabled =3D evt->enabled; + } else if (enabled !=3D evt->enabled) { + enabled =3D 2; + break; + } + } + + enabled_str[0] =3D enabled_char[enabled =3D=3D -1 ? 0 : enabled]; + + return simple_read_from_buffer(ubuf, cnt, ppos, enabled_str, 2); +} + +static const struct file_operations remote_events_dir_enable_fops =3D { + .write =3D remote_events_dir_enable_write, + .read =3D remote_events_dir_enable_read, +}; + +static ssize_t +remote_events_dir_header_page_read(struct file *filp, char __user *ubuf, s= ize_t cnt, loff_t *ppos) +{ + struct trace_seq *s; + int ret; + + s =3D kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + trace_seq_init(s); + + ring_buffer_print_page_header(NULL, s); + ret =3D simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_use= d(s)); + kfree(s); + + return ret; +} + +static const struct file_operations remote_events_dir_header_page_fops =3D= { + .read =3D remote_events_dir_header_page_read, +}; + +static ssize_t +remote_events_dir_header_event_read(struct file *filp, char __user *ubuf, = size_t cnt, loff_t *ppos) +{ + struct trace_seq *s; + int ret; + + s =3D kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + trace_seq_init(s); + + ring_buffer_print_entry_header(s); + ret =3D simple_read_from_buffer(ubuf, cnt, ppos, s->buffer, trace_seq_use= d(s)); + kfree(s); + + return ret; +} + +static const struct file_operations remote_events_dir_header_event_fops = =3D { + .read =3D remote_events_dir_header_event_read, +}; + +static int remote_events_dir_callback(const char *name, umode_t *mode, voi= d **data, + const struct file_operations **fops) +{ + if (!strcmp(name, "enable")) { + *mode =3D TRACEFS_MODE_WRITE; + *fops =3D &remote_events_dir_enable_fops; + return 1; + } + + if (!strcmp(name, "header_page")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_events_dir_header_page_fops; + return 1; + } + + if (!strcmp(name, "header_event")) { + *mode =3D TRACEFS_MODE_READ; + *fops =3D &remote_events_dir_header_event_fops; + return 1; + } + + return 0; +} + static int trace_remote_init_eventfs(const char *remote_name, struct trace= _remote *remote, struct remote_event *evt) { struct eventfs_inode *eventfs =3D remote->eventfs; + static struct eventfs_entry dir_entries[] =3D { + { + .name =3D "enable", + .callback =3D remote_events_dir_callback, + }, { + .name =3D "header_page", + .callback =3D remote_events_dir_callback, + }, { + .name =3D "header_event", + .callback =3D remote_events_dir_callback, + } + }; static struct eventfs_entry entries[] =3D { { .name =3D "enable", @@ -1094,7 +1229,8 @@ static int trace_remote_init_eventfs(const char *remo= te_name, struct trace_remot bool eventfs_create =3D false; =20 if (!eventfs) { - eventfs =3D eventfs_create_events_dir("events", remote->dentry, NULL, 0,= NULL); + eventfs =3D eventfs_create_events_dir("events", remote->dentry, dir_entr= ies, + ARRAY_SIZE(dir_entries), remote); if (IS_ERR(eventfs)) return PTR_ERR(eventfs); =20 --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5465D221290 for ; Fri, 3 Oct 2025 13:39:09 +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=1759498753; cv=none; b=n2zgDbCSPvJP5Z2e4aC69YFawYgnxjMmVDSgdQTs7wJFE/MWoM9tFw+A9pAycc2mCsq+780olhDIXXx30O97wDUpGQrVcfrVgYBaG83Oc4388D46wj+m7zgg38lh8madgdRoBpaQLyVk/uUSwkIZ1UokCKwiUlar96GFfa7XFFE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498753; c=relaxed/simple; bh=9/4IUKboS3yeSww6Pu1BgVsJcgcL3OjiuC5fyLEdPSs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FoGNHgAjtBw4uUKvYl7/xeJfw5MMLfhyEEW+DOn2ImL1dQv33YuZ5pRZvapeXm0TflL6ucsydfIdNndAjzs49wSJqcj4gIETQSBnhfmiFl43/iTJczyS3J0bAgT8Q4vf1RAjngNYCo5360+SUPWbhTM0pA2uH+pDpko37wdYsF8= 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=Us/XTCa1; 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="Us/XTCa1" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-46e44b9779eso9336865e9.1 for ; Fri, 03 Oct 2025 06:39:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498747; x=1760103547; 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=VlIvMmYTYW9xFXQL0KLrUt7g4tYarY39wioQ68L5ZKE=; b=Us/XTCa1OO5f57OJ9mp7UfVLw97Nu/vrnz76HFt1jghnI76UvVbXhM56/tJg1ARxtV w1VYYoLw7ob+haTi3mFTsQ8HcY9KHggTwRnn11sjfNRU8/xptWqxPlzJJtfxE2x21f0k a0gEQTX3U8hjw28fkAlOCnp2kAHPzDOF/VfAxeKMitvCN33ZEo3GNfUsgI34yMW6T6D0 6L/ZAf44nv22JrdUx1T07MpJttlveMnOzpcYp5GeKJw+OKDS8V3CvzL+Zmd4ZRZtiD6t pFzmqqFo8DI4FIttndWyR2hnAlhXoYb1biMb6YEpZ8s7+/46VnjYpINdGxVpefnNsanI lUkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498747; x=1760103547; 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=VlIvMmYTYW9xFXQL0KLrUt7g4tYarY39wioQ68L5ZKE=; b=gsX+rOOB7Je3H1+hJCVqlOH3fXaAu3fpdm+0pUoWVBmIvu3rxYu7i8TAnfvSAU5Xm7 e31eLYiDnCsnU0XohWLN5poUdSUcgz1VoethdFt5DIc8Bc9gowhqjZDyvghlR9Vym/wo hsYh6TxEHYoiEjUS/n/Ap0eHVocBxFmbAu1kl3YLybVuvXnT2/jDgDxR4yaPE7gyJJ8n R4IHQkU55hkrldZG4xqayXSxGeH4xWtACPi/TYo25mNvfNeWPGjhWx4wonT67G1Jvy45 1PPjzQj9PFBzjGccoyMOj9Z2fmmS06wlROtSDUtXqbhXtNR90rSnvBNs0cEk1iuWhdeD to0Q== X-Forwarded-Encrypted: i=1; AJvYcCXfaP9vFdU0LojSwJAz9YNK6wd5YFQn8Nn7d/hLALZTjUQWHPUDkisYKt12LjQ3QEURNY8Jidrsz7DlFZ8=@vger.kernel.org X-Gm-Message-State: AOJu0YxyB7TaY8OowV/I9p4XX/JeO9JtfW8FTbva3evDdb07c3mELE7D xCIuDNI6p/25jF2pyqSs51EbhTt0qaffgu2d+s9YhWHoYdlc3UpfhrOA9eHWAe2ciPLy9fd3pjT rvZc1EWFOx1mcvzOG4XsOZA== X-Google-Smtp-Source: AGHT+IHsx8P5Vs9M8mnwbrakrOPGXjbApzSto+nkAQM4Qfn3U+7Iz7dieUnzsV71vFzwGuJGfn1Qycvc9bWbG44R X-Received: from wmcq5.prod.google.com ([2002:a05:600c:c105:b0:46e:32e6:eb8f]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b61:b0:45b:79fd:cb3d with SMTP id 5b1f17b1804b1-46e71157894mr21943305e9.36.1759498747404; Fri, 03 Oct 2025 06:39:07 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:08 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-12-vdonnefort@google.com> Subject: [PATCH v7 11/28] tracing: Add helpers to create trace remote events From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Declaring remote events can be cumbersome let's add a set of macros to simplify developers life. The declaration of a remote event is very similar to kernel's events: REMOTE_EVENT(name, id, RE_STRUCT( re_field(u64 foo) ), RE_PRINTK("foo=3D%llu", __entry->foo) ) Signed-off-by: Vincent Donnefort diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remot= e_event.h index a4449008a075..c8ae1e1f5e72 100644 --- a/include/linux/trace_remote_event.h +++ b/include/linux/trace_remote_event.h @@ -5,6 +5,7 @@ =20 struct trace_remote; struct trace_event_fields; +struct trace_seq; =20 struct remote_event_hdr { unsigned short id; @@ -20,4 +21,13 @@ struct remote_event { char *print_fmt; void (*print)(void *evt, struct trace_seq *seq); }; + +#define RE_STRUCT(__args...) __args +#define re_field(__type, __field) __type __field; + +#define REMOTE_EVENT_FORMAT(__name, __struct) \ + struct remote_event_format_##__name { \ + struct remote_event_hdr hdr; \ + __struct \ + } #endif diff --git a/include/trace/define_remote_events.h b/include/trace/define_re= mote_events.h new file mode 100644 index 000000000000..03c9f5515c5a --- /dev/null +++ b/include/trace/define_remote_events.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include +#include + +#define REMOTE_EVENT_INCLUDE(__file) __stringify(../../__file) + +#ifdef REMOTE_EVENT_SECTION +# define __REMOTE_EVENT_SECTION(__name) __used __section(REMOTE_EVENT_SECT= ION"."#__name) +#else +# define __REMOTE_EVENT_SECTION(__name) +#endif + +#define __REMOTE_PRINTK_COUNT_ARGS(_0, _1, _2, _n, __args...) _n +#define REMOTE_PRINTK_COUNT_ARGS(__args...) __REMOTE_PRINTK_COUNT_ARGS(, #= #__args, 2, 1, 0) + +#define __remote_printk0() \ + trace_seq_putc(seq, '\n') + +#define __remote_printk1(__fmt) \ + trace_seq_puts(seq, " " __fmt "\n") \ + +#define __remote_printk2(__fmt, __args...) \ +do { \ + trace_seq_putc(seq, ' '); \ + trace_seq_printf(seq, __fmt, __args); \ + trace_seq_putc(seq, '\n'); \ +} while (0) + +/* Apply the appropriate trace_seq sequence according to the number of arg= uments */ +#define remote_printk(__args...) \ + CONCATENATE(__remote_printk, REMOTE_PRINTK_COUNT_ARGS(__args))(__args) + +#define RE_PRINTK(__args...) __args + +#define REMOTE_EVENT(__name, __id, __struct, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + static void remote_event_print_##__name(void *evt, struct trace_seq *seq)= \ + { \ + struct remote_event_format_##__name __maybe_unused *__entry =3D evt; \ + trace_seq_puts(seq, #__name); \ + remote_printk(__printk); \ + } +#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) + +#undef REMOTE_EVENT +#undef RE_PRINTK +#undef re_field +#define re_field(__type, __field) \ + { \ + .type =3D #__type, .name =3D #__field, \ + .size =3D sizeof(__type), .align =3D __alignof__(__type), \ + .is_signed =3D is_signed_type(__type), \ + }, +#define __entry REC +#define RE_PRINTK(__fmt, __args...) "\"" __fmt "\", " __stringify(__args) +#define REMOTE_EVENT(__name, __id, __struct, __printk) \ + static struct trace_event_fields remote_event_fields_##__name[] =3D { \ + __struct \ + {} \ + }; \ + static char remote_event_print_fmt_##__name[] =3D __printk; \ + static struct remote_event __REMOTE_EVENT_SECTION(__name) \ + remote_event_##__name =3D { \ + .name =3D #__name, \ + .id =3D __id, \ + .fields =3D remote_event_fields_##__name, \ + .print_fmt =3D remote_event_print_fmt_##__name, \ + .print =3D remote_event_print_##__name, \ + } +#include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A93002147F9 for ; Fri, 3 Oct 2025 13:39:10 +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=1759498753; cv=none; b=pFXsUbT2+V2e3fdwn5zpqKpizaN4bFungFOtlJxGlocP+C/deETwzH2EUbL3mfzyr6NMddHJbPdmNmjSliG0eUGQ0BYqrTUul7wPxrSrrZTMZ59bpDiWLkuIcAIQJxAoXlRIVj5GGi/HuZZA3e8GkbyvHKnSMKbpIDRn+U6dbPk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498753; c=relaxed/simple; bh=gsWglG1nPzv9SNVjHtG/HI84T+0OhpOoLwao0n82xTQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KX4Z8Rgf57noH33Of/D5MupFvlLqx6zPJG8FrezGdsxaawWeLiJnhuiQMfkWZ84iMII23wuAYw9nusNQji8OmkjwN8vv1jdnk/QK3AsgTd12v9RmToDAI1yKIUlqaMGYI4r1WnR3jNzqsx/ygOdyTUc+AYIM4Jcup+iiQGd5/AM= 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=F/QwLBvx; 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="F/QwLBvx" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e38bd6680so9482545e9.1 for ; Fri, 03 Oct 2025 06:39:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498748; x=1760103548; 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=ykRZt4psK54fzec+OCYqwqliJC1dewmuT/merLHMNBI=; b=F/QwLBvxSekEOiUSGiyoG9xxrhU3Sf1htjKtbTBL9bFhjpTyr4QFGkdJGIjQUhF41W m1gayDj0Y3noAhHxjs4qqiKcEfw+SB4UJgpvSeNRleYmhZrubo7mmybKXZ/ovjyDqSoy e4ka+xtWNJX0F5VVaSus4JtkzrqGuoawnTB99d2xTgT0eHrRSVqYD8cxqOk4TxnyvoUJ CyDwbYCJtdJZ3LU6slutrx+cT4S+5X5VQkADfcbtXYJWy9V9SNi+hpMXm7gzV6/vDhAo 4K3CFQqqsn2723yYwQkXiU6q0Iu2opZ8Ul/sRMi3sz1jWj8L6xZotYc13hKbCrUMIDvw CAww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498748; x=1760103548; 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=ykRZt4psK54fzec+OCYqwqliJC1dewmuT/merLHMNBI=; b=AxyfQ3ywwIXtyROmg+srB2vglWlfnZwV7S+mhjzBEZ3j6PiAJiEvyZ9VH/TiqUdRF5 o1G8OxOkY1/Om97piH/kIjrOloSNv30DQ/2DGKht2aks9bVn/ks8iyDxVfHQJknkAFyd l2TVa2tW8ejuGDQYBg1GEQf0v9+XrZheZ9Vl5UbuomDbWi8cE2zYfHbWCm7hGw0DN8iu Uqn+w1tByyRLNfz/tNqSlb1LNd8s5OctfezrBalOxeEWoS2tbw6LdlqgWXepNZPGKWuQ LlD4YEPxEW4l+ciHL2n3d46XP/OU+DdSHbrRBZUQWq9WQPNlvESbT3+12WOxsoXqeRdr 6oiA== X-Forwarded-Encrypted: i=1; AJvYcCUasPsBnALz1GZO/Vtk1wUPIozuOFfMwXH46AW64x6Y6hv+iw1NMDs95lGShq4HG74QAoDsvP2wojqsGNw=@vger.kernel.org X-Gm-Message-State: AOJu0YyHJ1Pk+OoGAIs5X8WaJGRRynF4yuDvGxx750uwmNt/M9LFIf9q i8dCX+G3+E6wnpmIdLCANfeU94PcNFSgRqBdRYoLxl+yC+0UCLZrQh2Tn33KyXEwTI9QCr/sRaa i7Zq+QuNdKA5xXlqBClAiwA== X-Google-Smtp-Source: AGHT+IHeEJIiFICQ+unjZAp8uVzxbLqoVsWl8IqXt+7TMHnizGTo35OB5M9RkcuE2jC1IdoxNGX9ssBAd8G8PduC X-Received: from wmaw22.prod.google.com ([2002:a05:600c:6d56:b0:45d:e232:8a3d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:348b:b0:46e:37fc:def0 with SMTP id 5b1f17b1804b1-46e71109e9bmr21805095e9.9.1759498748266; Fri, 03 Oct 2025 06:39:08 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:09 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-13-vdonnefort@google.com> Subject: [PATCH v7 12/28] ring-buffer: Export buffer_data_page and macros From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for allowing the writing of ring-buffer compliant pages outside of ring_buffer.c, move buffer_data_page and timestamps encoding macros into the publicly available ring_buffer_types.h. Signed-off-by: Vincent Donnefort diff --git a/include/linux/ring_buffer_types.h b/include/linux/ring_buffer_= types.h new file mode 100644 index 000000000000..54577021a49d --- /dev/null +++ b/include/linux/ring_buffer_types.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_RING_BUFFER_TYPES_H +#define _LINUX_RING_BUFFER_TYPES_H + +#include + +#define TS_SHIFT 27 +#define TS_MASK ((1ULL << TS_SHIFT) - 1) +#define TS_DELTA_TEST (~TS_MASK) + +/* + * We need to fit the time_stamp delta into 27 bits. + */ +static inline bool test_time_stamp(u64 delta) +{ + return !!(delta & TS_DELTA_TEST); +} + +#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) + +#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) +#define RB_ALIGNMENT 4U +#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) +#define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ + +#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS +# define RB_FORCE_8BYTE_ALIGNMENT 0 +# define RB_ARCH_ALIGNMENT RB_ALIGNMENT +#else +# define RB_FORCE_8BYTE_ALIGNMENT 1 +# define RB_ARCH_ALIGNMENT 8U +#endif + +#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) + +struct buffer_data_page { + u64 time_stamp; /* page time stamp */ + local_t commit; /* write committed index */ + unsigned char data[] RB_ALIGN_DATA; /* data of buffer page */ +}; +#endif diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index a26a6f537f87..06aae6a2a308 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4,6 +4,7 @@ * * Copyright (C) 2008 Steven Rostedt */ +#include #include #include #include @@ -156,23 +157,6 @@ int ring_buffer_print_entry_header(struct trace_seq *s) /* Used for individual buffers (after the counter) */ #define RB_BUFFER_OFF (1 << 20) =20 -#define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) - -#define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) -#define RB_ALIGNMENT 4U -#define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) -#define RB_EVNT_MIN_SIZE 8U /* two 32bit words */ - -#ifndef CONFIG_HAVE_64BIT_ALIGNED_ACCESS -# define RB_FORCE_8BYTE_ALIGNMENT 0 -# define RB_ARCH_ALIGNMENT RB_ALIGNMENT -#else -# define RB_FORCE_8BYTE_ALIGNMENT 1 -# define RB_ARCH_ALIGNMENT 8U -#endif - -#define RB_ALIGN_DATA __aligned(RB_ARCH_ALIGNMENT) - /* define RINGBUF_TYPE_DATA for 'case RINGBUF_TYPE_DATA:' */ #define RINGBUF_TYPE_DATA 0 ... RINGBUF_TYPE_DATA_TYPE_LEN_MAX =20 @@ -315,10 +299,6 @@ EXPORT_SYMBOL_GPL(ring_buffer_event_data); #define for_each_online_buffer_cpu(buffer, cpu) \ for_each_cpu_and(cpu, buffer->cpumask, cpu_online_mask) =20 -#define TS_SHIFT 27 -#define TS_MASK ((1ULL << TS_SHIFT) - 1) -#define TS_DELTA_TEST (~TS_MASK) - static u64 rb_event_time_stamp(struct ring_buffer_event *event) { u64 ts; @@ -337,12 +317,6 @@ static u64 rb_event_time_stamp(struct ring_buffer_even= t *event) =20 #define RB_MISSED_MASK (3 << 30) =20 -struct buffer_data_page { - u64 time_stamp; /* page time stamp */ - local_t commit; /* write committed index */ - unsigned char data[] RB_ALIGN_DATA; /* data of buffer page */ -}; - struct buffer_data_read_page { unsigned order; /* order of the page */ struct buffer_data_page *data; /* actual data, stored in this page */ @@ -401,14 +375,6 @@ static void free_buffer_page(struct buffer_page *bpage) kfree(bpage); } =20 -/* - * We need to fit the time_stamp delta into 27 bits. - */ -static inline bool test_time_stamp(u64 delta) -{ - return !!(delta & TS_DELTA_TEST); -} - struct rb_irq_work { struct irq_work work; wait_queue_head_t waiters; --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6996F224B14 for ; Fri, 3 Oct 2025 13:39:11 +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=1759498755; cv=none; b=Ee5nuFs1KxsgF18SqXSmYPDUHGEDvEa9Iu9kaVneUWg90KD8af//+B0MrEASjqPu6XbzK+u3KXT7NSOuxAPmqljrrXADC8pLJ/dyTeE/xKVGyGMVIeea1ZRhSuxkQpPXZoQVnRjaZ1M92LxgHCIxmfBtLATjdJtRhQPHEePlGBs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498755; c=relaxed/simple; bh=X49FmshLX8HOy0FR+aT3rMqYFXahnrAXs21bSMdcCVI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=uH5w85iPt/0So0nAT+Y1q0p2F0r5UpzBO4RvY6JRuJgFS3DRfB08s2qXVwU4GjIkGxdvF9k8Y+lckdDVt9nNAtIXgc0jEoAqvjYBTUGy8mUsAqSDjlTsImMeC+6cOGqUvD2CayDpbxNcc1Q6EHMDisS6W9V9cc7syORo5KtADrw= 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=3cd5KS1N; 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="3cd5KS1N" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3f93db57449so1179270f8f.2 for ; Fri, 03 Oct 2025 06:39:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498749; x=1760103549; 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=kYaxTGFgJHBLxqvN9L5dqvTFN43LH6gYWiDy8aNjrDk=; b=3cd5KS1NNwKLXSm5Xc8yjRTck5sctGoiXgL++yGmSFR+io2hGSqrQEMPFZd9MlHM0W VBK+6T6t0I7ER5S3takw0pw6xMSP9Ao7ZosxBMAIJPTYhBHrrb9K+HRh55lDGADhTYK5 hZFWohbiwF9varwFc/QTrN5rosSgEUV94vo3BYRRbIUmVGi7e476XzHObLLwTuiBQXbY MdkBzAfAp6rFPPPQE8hUbVhFGuD5z4dzmewdWVBeKh4LmAkM3ZWEyQpIJZP5pyXSMy0G pTX8QtTqROCXXAZ8hjQN532G9ZMLMrcwN5nsJotLVvxMLDfCIyCE9uuiljQN4ClNIr1J rpWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498749; x=1760103549; 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=kYaxTGFgJHBLxqvN9L5dqvTFN43LH6gYWiDy8aNjrDk=; b=DqALhXj/3LlTK2qH4K3rMfYYsJlzcBtUq/N211pIoQf2yb2GdjSyNqxDDAbYZERbeT 8+ZdwNhVIU3yjyv+2A+qNnr2/K5tEu5rE9cfOZDi9uHjeJ/CTj8C99iQgaaQ34A3tMKv 7C1B3CkixxNi5Im6ADaxUZcHztInY3/xFVtxY0TDkWXJAaW/X5OJya7F+FgqINk+VPa2 bG0DQHZuQ9AcM76hL5WZDraeR+Hlg5R3nHdtOpMK+W1tItq/wFYU+7bgjHudr6GsHkY2 ZLntBmRkuJeY0+jfNyCz2n1Bg4laJ2Pq+kWte4UHKekBxAHMaBLChkMG8hi1H9whnwbO 6K6A== X-Forwarded-Encrypted: i=1; AJvYcCVMd6CCG7sTPKLwQFbEMd9IC9j4WYS3TYQl1PP4gOZ3r7TNt/jqUAXVtQa4Hs1wmQQHrfmxIZUfIq9eVNc=@vger.kernel.org X-Gm-Message-State: AOJu0YwjOubW9T9zxUZX2FPcXGrNvmxmjvOeUemnYt/AmrTH/YEpBOj8 LTYtvM6IKxZvrgdq0gTLUf3V7NN6VR6C15COVvadEWMi4g1cV5gxECuFu5yoE5iBqs7Nljo9ltT x2rpLktI1J0R75jhgLDtpLQ== X-Google-Smtp-Source: AGHT+IEKzB1TeH2GCUCk3DeRZGRRtVVnvZ1dqQmSZ4O8ut99dI6xppsR6ptaX947LdRRickHWtLizPeRbkZDs6ao X-Received: from wmbjv25.prod.google.com ([2002:a05:600c:5719:b0:46e:2640:aa83]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5f84:0:b0:3d9:7021:fff0 with SMTP id ffacd0b85a97d-4256719e3aemr1841373f8f.37.1759498749351; Fri, 03 Oct 2025 06:39:09 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:10 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-14-vdonnefort@google.com> Subject: [PATCH v7 13/28] tracing: Introduce simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a simple implementation of the kernel ring-buffer. This intends to be used later by ring-buffer remotes such as the pKVM hypervisor, hence the need for a cut down version (write only) without any dependency. Signed-off-by: Vincent Donnefort diff --git a/include/linux/simple_ring_buffer.h b/include/linux/simple_ring= _buffer.h new file mode 100644 index 000000000000..f324df2f875b --- /dev/null +++ b/include/linux/simple_ring_buffer.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_SIMPLE_RING_BUFFER_H +#define _LINUX_SIMPLE_RING_BUFFER_H + +#include +#include +#include +#include + +/* + * Ideally those struct would stay private but the caller needs to know + * the allocation size for simple_ring_buffer_init(). + */ +struct simple_buffer_page { + struct list_head link; + struct buffer_data_page *page; + u64 entries; + u32 write; + u32 id; +}; + +struct simple_rb_per_cpu { + struct simple_buffer_page *tail_page; + struct simple_buffer_page *reader_page; + struct simple_buffer_page *head_page; + struct simple_buffer_page *bpages; + struct trace_buffer_meta *meta; + u32 nr_pages; + +#define SIMPLE_RB_UNAVAILABLE 0 +#define SIMPLE_RB_READY 1 +#define SIMPLE_RB_WRITING 2 + u32 status; + + u64 last_overrun; + u64 write_stamp; + + struct simple_rb_cbs *cbs; +}; + +/** + * simple_ring_buffer_init - Init @cpu_buffer based on @desc + * + * @cpu_buffer: A simple_rb_per_cpu buffer to init, allocated by the calle= r. + * @bpages: Array of simple_buffer_pages, with as many elements as @desc->= nr_page_va + * @desc: A ring_buffer_desc + * + * Returns: 0 on success or -EINVAL if the content of @desc is invalid + */ +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc); + +/** + * simple_ring_buffer_unload - Prepare @cpu_buffer for deletion + * + * @cpu_buffer: A simple_rb_per_cpu that will be deleted. + */ +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer); + +/** + * simple_ring_buffer_reserve - Reserve an entry in @cpu_buffer + * + * @cpu_buffer: A simple_rb_per_cpu + * @length: Size of the entry in bytes + * @timestamp: Timestamp of the entry + * + * Returns the address of the entry where to write data or NULL + */ +void *simple_ring_buffer_reserve(struct simple_rb_per_cpu *cpu_buffer, uns= igned long length, + u64 timestamp); + +/** + * simple_ring_buffer_commit - Commit the entry reserved with simple_ring_= buffer_reserve() + * + * @cpu_buffer: The simple_rb_per_cpu where the entry has been reserved + */ +void simple_ring_buffer_commit(struct simple_rb_per_cpu *cpu_buffer); + +/** + * simple_ring_buffer_enable_tracing - Enable or disable writing to @cpu_b= uffer + * + * @cpu_buffer: A simple_rb_per_cpu + * @enable: True to enable tracing, False to disable it + * + * Returns 0 on success or -ENODEV if @cpu_buffer was unloaded + */ +int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable); + +/** + * simple_ring_buffer_reset - Reset @cpu_buffer + * + * @cpu_buffer: A simple_rb_per_cpu + * + * This will not clear the content of the data, only reset counters and po= inters + * + * Returns 0 on success or -ENODEV if @cpu_buffer was unloaded. + */ +int simple_ring_buffer_reset(struct simple_rb_per_cpu *cpu_buffer); + +/** + * simple_ring_buffer_swap_reader_page - Swap ring-buffer head with the re= ader + * + * This function enables consuming reading. It ensures the current head pa= ge will not be overwritten + * and can be safely read. + * + * @cpu_buffer: A simple_rb_per_cpu + * + * Returns 0 on success, -ENODEV if @cpu_buffer was unloaded or -EBUSY if = we failed to catch the + * head page. + */ +int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); + +#endif diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 99af56d39eaf..918afcc1fcaf 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1241,4 +1241,7 @@ source "kernel/trace/rv/Kconfig" config TRACE_REMOTE bool =20 +config SIMPLE_RING_BUFFER + bool + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 6dab341acc46..03d7d80a9436 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -111,4 +111,5 @@ obj-$(CONFIG_TRACEPOINT_BENCHMARK) +=3D trace_benchmark= .o obj-$(CONFIG_RV) +=3D rv/ =20 obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o +obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o libftrace-y :=3D ftrace.o diff --git a/kernel/trace/simple_ring_buffer.c b/kernel/trace/simple_ring_b= uffer.c new file mode 100644 index 000000000000..20e3cd6071a2 --- /dev/null +++ b/kernel/trace/simple_ring_buffer.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 - Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include +#include + +enum simple_rb_link_type { + SIMPLE_RB_LINK_NORMAL =3D 0, + SIMPLE_RB_LINK_HEAD =3D 1, + SIMPLE_RB_LINK_HEAD_MOVING +}; + +#define SIMPLE_RB_LINK_MASK ~(SIMPLE_RB_LINK_HEAD | SIMPLE_RB_LINK_HEAD_MO= VING) + +static void simple_bpage_set_head_link(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)bpage->link.next; + + link &=3D SIMPLE_RB_LINK_MASK; + link |=3D SIMPLE_RB_LINK_HEAD; + + /* + * Paired with simple_rb_find_head() to order access between the head + * link and overrun. It ensures we always report an up-to-date value + * after swapping the reader page. + */ + smp_store_release(&bpage->link.next, (struct list_head *)link); +} + +static bool simple_bpage_unset_head_link(struct simple_buffer_page *bpage, + struct simple_buffer_page *dst, + enum simple_rb_link_type new_type) +{ + unsigned long *link =3D (unsigned long *)(&bpage->link.next); + unsigned long old =3D (*link & SIMPLE_RB_LINK_MASK) | SIMPLE_RB_LINK_HEAD; + unsigned long new =3D (unsigned long)(&dst->link) | new_type; + + return try_cmpxchg(link, &old, new); +} + +static void simple_bpage_set_normal_link(struct simple_buffer_page *bpage) +{ + unsigned long link =3D (unsigned long)bpage->link.next; + + WRITE_ONCE(bpage->link.next, (struct list_head *)(link & SIMPLE_RB_LINK_M= ASK)); +} + +static struct simple_buffer_page *simple_bpage_from_link(struct list_head = *link) +{ + unsigned long ptr =3D (unsigned long)link & SIMPLE_RB_LINK_MASK; + + return container_of((struct list_head *)ptr, struct simple_buffer_page, l= ink); +} + +static struct simple_buffer_page *simple_bpage_next_page(struct simple_buf= fer_page *bpage) +{ + return simple_bpage_from_link(bpage->link.next); +} + +static void simple_bpage_reset(struct simple_buffer_page *bpage) +{ + bpage->write =3D 0; + bpage->entries =3D 0; + + local_set(&bpage->page->commit, 0); +} + +static void simple_bpage_init(struct simple_buffer_page *bpage, unsigned l= ong page) +{ + INIT_LIST_HEAD(&bpage->link); + bpage->page =3D (struct buffer_data_page *)page; + + simple_bpage_reset(bpage); +} + +#define simple_rb_meta_inc(__meta, __inc) \ + WRITE_ONCE((__meta), (__meta + __inc)) + +static bool simple_rb_loaded(struct simple_rb_per_cpu *cpu_buffer) +{ + return !!cpu_buffer->bpages; +} + +static int simple_rb_find_head(struct simple_rb_per_cpu *cpu_buffer) +{ + int retry =3D cpu_buffer->nr_pages * 2; + struct simple_buffer_page *head; + + head =3D cpu_buffer->head_page; + + while (retry--) { + unsigned long link; + +spin: + /* See smp_store_release in simple_bpage_set_head_link() */ + link =3D (unsigned long)smp_load_acquire(&head->link.prev->next); + + switch (link & ~SIMPLE_RB_LINK_MASK) { + /* Found the head */ + case SIMPLE_RB_LINK_HEAD: + cpu_buffer->head_page =3D head; + return 0; + /* The writer caught the head, we can spin, that won't be long */ + case SIMPLE_RB_LINK_HEAD_MOVING: + goto spin; + } + + head =3D simple_bpage_next_page(head); + } + + return -EBUSY; +} + +int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er) +{ + struct simple_buffer_page *last, *head, *reader; + unsigned long overrun; + int retry =3D 8; + int ret; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + reader =3D cpu_buffer->reader_page; + + do { + /* Run after the writer to find the head */ + ret =3D simple_rb_find_head(cpu_buffer); + if (ret) + return ret; + + head =3D cpu_buffer->head_page; + + /* Connect the reader page around the header page */ + reader->link.next =3D head->link.next; + reader->link.prev =3D head->link.prev; + + /* The last page before the head */ + last =3D simple_bpage_from_link(head->link.prev); + + /* The reader page points to the new header page */ + simple_bpage_set_head_link(reader); + + overrun =3D cpu_buffer->meta->overrun; + } while (!simple_bpage_unset_head_link(last, reader, SIMPLE_RB_LINK_NORMA= L) && retry--); + + if (!retry) + return -EINVAL; + + cpu_buffer->head_page =3D simple_bpage_from_link(reader->link.next); + cpu_buffer->head_page->link.prev =3D &reader->link; + cpu_buffer->reader_page =3D head; + cpu_buffer->meta->reader.lost_events =3D overrun - cpu_buffer->last_overr= un; + cpu_buffer->meta->reader.id =3D cpu_buffer->reader_page->id; + cpu_buffer->last_overrun =3D overrun; + + return 0; +} + +static struct simple_buffer_page *simple_rb_move_tail(struct simple_rb_per= _cpu *cpu_buffer) +{ + struct simple_buffer_page *tail, *new_tail; + + tail =3D cpu_buffer->tail_page; + new_tail =3D simple_bpage_next_page(tail); + + if (simple_bpage_unset_head_link(tail, new_tail, SIMPLE_RB_LINK_HEAD_MOVI= NG)) { + /* + * Oh no! we've caught the head. There is none anymore and + * swap_reader will spin until we set the new one. Overrun must + * be written first, to make sure we report the correct number + * of lost events. + */ + simple_rb_meta_inc(cpu_buffer->meta->overrun, new_tail->entries); + simple_rb_meta_inc(cpu_buffer->meta->pages_lost, 1); + + simple_bpage_set_head_link(new_tail); + simple_bpage_set_normal_link(tail); + } + + simple_bpage_reset(new_tail); + cpu_buffer->tail_page =3D new_tail; + + simple_rb_meta_inc(cpu_buffer->meta->pages_touched, 1); + + return new_tail; +} + +static unsigned long rb_event_size(unsigned long length) +{ + struct ring_buffer_event *event; + + return length + RB_EVNT_HDR_SIZE + sizeof(event->array[0]); +} + +static struct ring_buffer_event * +rb_event_add_ts_extend(struct ring_buffer_event *event, u64 delta) +{ + event->type_len =3D RINGBUF_TYPE_TIME_EXTEND; + event->time_delta =3D delta & TS_MASK; + event->array[0] =3D delta >> TS_SHIFT; + + return (struct ring_buffer_event *)((unsigned long)event + 8); +} + +static struct ring_buffer_event * +simple_rb_reserve_next(struct simple_rb_per_cpu *cpu_buffer, unsigned long= length, u64 timestamp) +{ + unsigned long ts_ext_size =3D 0, event_size =3D rb_event_size(length); + struct simple_buffer_page *tail =3D cpu_buffer->tail_page; + struct ring_buffer_event *event; + u32 write, prev_write; + u64 time_delta; + + time_delta =3D timestamp - cpu_buffer->write_stamp; + + if (test_time_stamp(time_delta)) + ts_ext_size =3D 8; + + prev_write =3D tail->write; + write =3D prev_write + event_size + ts_ext_size; + + if (unlikely(write > (PAGE_SIZE - BUF_PAGE_HDR_SIZE))) + tail =3D simple_rb_move_tail(cpu_buffer); + + if (!tail->entries) { + tail->page->time_stamp =3D timestamp; + time_delta =3D 0; + ts_ext_size =3D 0; + write =3D event_size; + prev_write =3D 0; + } + + tail->write =3D write; + tail->entries++; + + cpu_buffer->write_stamp =3D timestamp; + + event =3D (struct ring_buffer_event *)(tail->page->data + prev_write); + if (ts_ext_size) { + event =3D rb_event_add_ts_extend(event, time_delta); + time_delta =3D 0; + } + + event->type_len =3D 0; + event->time_delta =3D time_delta; + event->array[0] =3D event_size - RB_EVNT_HDR_SIZE; + + return event; +} + +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; + int ret; + + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + prev_status =3D simple_rb_enable_tracing(cpu_buffer, false); + + ret =3D simple_rb_find_head(cpu_buffer); + if (ret) + return ret; + + bpage =3D cpu_buffer->tail_page =3D cpu_buffer->head_page; + do { + simple_bpage_reset(bpage); + bpage =3D simple_bpage_next_page(bpage); + } while (bpage !=3D cpu_buffer->head_page); + + simple_bpage_reset(cpu_buffer->reader_page); + + cpu_buffer->last_overrun =3D 0; + cpu_buffer->write_stamp =3D 0; + + cpu_buffer->meta->reader.read =3D 0; + cpu_buffer->meta->reader.lost_events =3D 0; + cpu_buffer->meta->entries =3D 0; + cpu_buffer->meta->overrun =3D 0; + cpu_buffer->meta->read =3D 0; + cpu_buffer->meta->pages_lost =3D 0; + cpu_buffer->meta->pages_touched =3D 0; + + if (prev_status =3D=3D SIMPLE_RB_READY) + simple_rb_enable_tracing(cpu_buffer, true); + + return 0; +} + +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc) +{ + struct simple_buffer_page *bpage =3D bpages; + int i; + + /* At least 1 reader page and two pages in the ring-buffer */ + if (desc->nr_page_va < 3) + return -EINVAL; + + memset(cpu_buffer, 0, sizeof(*cpu_buffer)); + + cpu_buffer->bpages =3D bpages; + + cpu_buffer->meta =3D (void *)desc->meta_va; + memset(cpu_buffer->meta, 0, sizeof(*cpu_buffer->meta)); + cpu_buffer->meta->meta_page_size =3D PAGE_SIZE; + cpu_buffer->meta->nr_subbufs =3D cpu_buffer->nr_pages; + + /* The reader page is not part of the ring initially */ + simple_bpage_init(bpage, desc->page_va[0]); + bpage->id =3D 0; + + cpu_buffer->nr_pages =3D 1; + + cpu_buffer->reader_page =3D bpage; + cpu_buffer->tail_page =3D bpage + 1; + cpu_buffer->head_page =3D bpage + 1; + + for (i =3D 1; i < desc->nr_page_va; i++) { + simple_bpage_init(++bpage, desc->page_va[i]); + + bpage->link.next =3D &(bpage + 1)->link; + bpage->link.prev =3D &(bpage - 1)->link; + bpage->id =3D i; + + cpu_buffer->nr_pages =3D i + 1; + } + + /* Close the ring */ + bpage->link.next =3D &cpu_buffer->tail_page->link; + cpu_buffer->tail_page->link.prev =3D &bpage->link; + + /* The last init'ed page points to the head page */ + simple_bpage_set_head_link(bpage); + + return 0; +} + +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +{ + if (!simple_rb_loaded(cpu_buffer)) + return; + + simple_rb_enable_tracing(cpu_buffer, false); + + cpu_buffer->bpages =3D NULL; +} + +int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable) +{ + if (!simple_rb_loaded(cpu_buffer)) + return -ENODEV; + + simple_rb_enable_tracing(cpu_buffer, enable); + + return 0; +} --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7356322B8CB for ; Fri, 3 Oct 2025 13:39: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=1759498755; cv=none; b=HbQbSI1XHVuFHHiK0KDlrRZOouVw7w/BH6EPpuKjxvpf3pGyhqxdcCdCOvY+KGjH1jeG1ckW+LTgB9Rkv8kNOxKtdVSc2ZOrsjbYrYMTIX1i/plk2PxZw99Np3SVUu9hEkkVW+j0evyRo1HFePdU5N07HK0EBgVI6Zmq2aQxgPI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498755; c=relaxed/simple; bh=xrVBm+FT0XzhRMZkLbkQ3uI8HKhD3I9Ry3Ce2Kr4lCw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=AAiFEKo/9PCeOj+YDpXnoM2vpbcE9k7zzr4l9hOXNsmv6WouDXivgsCu5mJ9Fl3Qtrf1ts9jY37s8ZscxATPMN42In9Hq1AV1jHe/A6zL1opbAmZmi1h/yMfCecSfV74fk6/cFSzTcZxggCCIB29xXH4W7R6uPsuFTUvXaVZIZk= 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=y6yv0w31; 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="y6yv0w31" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-46e41c32209so9805545e9.0 for ; Fri, 03 Oct 2025 06:39:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498750; x=1760103550; 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=WBvCjNgRhVQi+n8pjF4GEugOWJdtcq46oEjmHUcdEEI=; b=y6yv0w31/2IYJYwbbIZWRD1M2NT5Haqj0A1Ufir5/adi9a3g0KSv+u1zzZKBQysYNK HjcOYEogp2srDxTbHlZ+gQyozDRlbMl53h4uKSQVt9CGi7umNjsFAt1x5nsOi6qB9yTE +2IoPgsPMwHM2VeK+MTlo4lCjplBCx3IiruDcOzTossZs1tE28//1NLX+zBlutqR4Jza E9AvZz8Ha80JpJEtyh8ZG0me5KpeR3opYGj9MbvQf14HnmkdUXcXI6MR+tEDgg+n3u/K xWJRgwOYiHmGAJ4LpNxDKXK/vFo0gadTaIKMxpj3/YTSgZWccxsfv/8dK9UyrhjDzf8Z VfYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498750; x=1760103550; 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=WBvCjNgRhVQi+n8pjF4GEugOWJdtcq46oEjmHUcdEEI=; b=kHRfAqk1kFUP0aUdk9/qqcgLqSFfiDdrTS4XjHZTmLjeWdmU2yDJ/EltobYV5KKc6s joKCfoOjC2FVikITlWJZ2mxxkSvxAxl23Z8AEeyt2d/JSboRJtHJeSOD8K8fggoMDF9l 5mbieA8WtSCrXWnAD+jJbNchRLKQCaehSMLd2ZBy5WngGv+ZNuodsdfGrt1hiUChcnP8 zAGPJzqyUyQnGtk8ODQ40liySwIiGPvcruHtaqgPrDAjQ29z9pmB0yT7z9AiJm5bTOnt 0fpy63x6MQm2wdfns7sHk+/jbFia5qrK6dLnwFP6GiSleoLgA3DJUZjAXu7ofzqj//rb nXaA== X-Forwarded-Encrypted: i=1; AJvYcCWoL7c4d8rCMRZrDx5UopnzNtr7a0BCCh3xz7+ksHyxz5pObdMZf/ocZOrp70XeBlxPaj4NxUzijx7vDXg=@vger.kernel.org X-Gm-Message-State: AOJu0YygK8i4lQEqSPLbOZuX1/w6ZBPTPahio7wzV4NiT7IE7418gaT7 6fxRUafamzsvc+G1DVNyOzDiGIq9gi7ojVzK6lY6cKm94QwbqHVNq5g+D1lZIAdKX7r4Df093Vg LpZ533qe9U47R9enboC9lsw== X-Google-Smtp-Source: AGHT+IEZXqk0h/U8X3T5FaPQjU1b3XgoSS4qKq+zLH3tKMaLXszAm0LYuyPG5fUfKH9oUZtB+8PRN2jt9Kkja4Ej X-Received: from wmby13.prod.google.com ([2002:a05:600c:c04d:b0:46e:3771:b9c9]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1993:b0:46e:3d41:5fed with SMTP id 5b1f17b1804b1-46e711026cfmr21469115e9.11.1759498750172; Fri, 03 Oct 2025 06:39:10 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:11 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-15-vdonnefort@google.com> Subject: [PATCH v7 14/28] tracing: Add a trace remote module for testing From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a module to help testing the tracefs support for trace remotes. This module: * Use simple_ring_buffer to write into a ring-buffer. * Declare a single "selftest" event that can be triggered from user-space. * Register a "test" trace remote. This is intended to be used by trace remote selftests. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 918afcc1fcaf..52131d89993c 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1244,4 +1244,12 @@ config TRACE_REMOTE config SIMPLE_RING_BUFFER bool =20 +config TRACE_REMOTE_TEST + tristate "Test module for remote tracing" + select TRACE_REMOTE + select SIMPLE_RING_BUFFER + help + This trace remote includes a ring-buffer writer implementation using + "simple_ring_buffer". This is solely intending for testing. + endif # FTRACE diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 03d7d80a9436..53534447e70b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -112,4 +112,6 @@ obj-$(CONFIG_RV) +=3D rv/ =20 obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o +obj-$(CONFIG_TRACE_REMOTE_TEST) +=3D remote_test.o + libftrace-y :=3D ftrace.o diff --git a/kernel/trace/remote_test.c b/kernel/trace/remote_test.c new file mode 100644 index 000000000000..059127489c99 --- /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 kmalloc(sizeof(*cpu_buffer), GFP_KERNEL); + if (!cpu_buffer) + return ret; + + bpages =3D kmalloc_array(rb_desc->nr_page_va, sizeof(*bpages), GFP_KERNEL= ); + if (!bpages) + goto err_free_cpu_buffer; + + ret =3D simple_ring_buffer_init(cpu_buffer, bpages, rb_desc); + if (ret) + goto err_free_bpages; + + scoped_guard(mutex, &simple_rbs_lock) + *per_cpu_ptr(&simple_rbs, cpu) =3D cpu_buffer; + + return 0; + +err_free_bpages: + kfree(bpages); + +err_free_cpu_buffer: + kfree(cpu_buffer); + + return ret; +} + +static void remote_test_unload_simple_rb(int cpu) +{ + struct simple_rb_per_cpu *cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + struct simple_buffer_page *bpages; + + if (!cpu_buffer) + return; + + guard(mutex)(&simple_rbs_lock); + + bpages =3D cpu_buffer->bpages; + simple_ring_buffer_unload(cpu_buffer); + kfree(bpages); + kfree(cpu_buffer); + *per_cpu_ptr(&simple_rbs, cpu) =3D NULL; +} + +static struct trace_buffer_desc *remote_test_load(unsigned long size, void= *unused) +{ + struct ring_buffer_desc *rb_desc; + struct trace_buffer_desc *desc; + size_t desc_size; + int cpu, ret; + + if (WARN_ON(remote_test_buffer_desc)) + return ERR_PTR(-EINVAL); + + desc_size =3D trace_buffer_desc_size(size, num_possible_cpus()); + if (desc_size =3D=3D SIZE_MAX) { + ret =3D -E2BIG; + goto err_unlock_cpus; + } + + desc =3D kmalloc(desc_size, GFP_KERNEL); + if (!desc) { + ret =3D -ENOMEM; + goto err_unlock_cpus; + } + + ret =3D trace_remote_alloc_buffer(desc, desc_size, size, cpu_possible_mas= k); + if (ret) + goto err_free_desc; + + for_each_ring_buffer_desc(rb_desc, cpu, desc) { + ret =3D remote_test_load_simple_rb(rb_desc->cpu, rb_desc); + if (ret) + goto err; + } + + remote_test_buffer_desc =3D desc; + + return remote_test_buffer_desc; + +err: + for_each_ring_buffer_desc(rb_desc, cpu, remote_test_buffer_desc) + remote_test_unload_simple_rb(rb_desc->cpu); + trace_remote_free_buffer(remote_test_buffer_desc); + +err_free_desc: + kfree(desc); + +err_unlock_cpus: + cpus_read_unlock(); + + return ERR_PTR(ret); +} + +static void remote_test_unload(struct trace_buffer_desc *desc, void *unuse= d) +{ + struct ring_buffer_desc *rb_desc; + int cpu; + + if (WARN_ON(desc !=3D remote_test_buffer_desc)) + return; + + for_each_ring_buffer_desc(rb_desc, cpu, desc) + remote_test_unload_simple_rb(rb_desc->cpu); + + remote_test_buffer_desc =3D NULL; + trace_remote_free_buffer(desc); + kfree(desc); +} + +static int remote_test_enable_tracing(bool enable, void *unused) +{ + struct ring_buffer_desc *rb_desc; + int cpu; + + if (!remote_test_buffer_desc) + return -ENODEV; + + for_each_ring_buffer_desc(rb_desc, cpu, remote_test_buffer_desc) + WARN_ON(simple_ring_buffer_enable_tracing(*per_cpu_ptr(&simple_rbs, rb_d= esc->cpu), + enable)); + return 0; +} + +static int remote_test_swap_reader_page(unsigned int cpu, void *unused) +{ + struct simple_rb_per_cpu *cpu_buffer; + + if (cpu >=3D NR_CPUS) + return -EINVAL; + + cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + if (!cpu_buffer) + return -EINVAL; + + return simple_ring_buffer_swap_reader_page(cpu_buffer); +} + +static int remote_test_reset(unsigned int cpu, void *unused) +{ + struct simple_rb_per_cpu *cpu_buffer; + + if (cpu >=3D NR_CPUS) + return -EINVAL; + + cpu_buffer =3D *per_cpu_ptr(&simple_rbs, cpu); + if (!cpu_buffer) + return -EINVAL; + + return simple_ring_buffer_reset(cpu_buffer); +} + +static int remote_test_enable_event(unsigned short id, bool enable, void *= unused) +{ + if (id !=3D REMOTE_TEST_EVENT_ID) + return -EINVAL; + + /* + * Let's just use the struct remote_event enabled field that is turned on= and off by + * trace_remote. This is a bit racy but good enough for a simple test mod= ule. + */ + return 0; +} + +static ssize_t +write_event_write(struct file *filp, const char __user *ubuf, size_t cnt, = loff_t *pos) +{ + struct remote_event_format_selftest *evt_test; + struct simple_rb_per_cpu *cpu_buffer; + unsigned long val; + int ret; + + ret =3D kstrtoul_from_user(ubuf, cnt, 10, &val); + if (ret) + return ret; + + guard(mutex)(&simple_rbs_lock); + + if (!remote_event_selftest.enabled) + return -ENODEV; + + cpu_buffer =3D *this_cpu_ptr(&simple_rbs); + if (!cpu_buffer) + return -ENODEV; + + evt_test =3D simple_ring_buffer_reserve(cpu_buffer, + sizeof(struct remote_event_format_selftest), + trace_clock_global()); + if (!evt_test) + return -ENODEV; + + evt_test->hdr.id =3D REMOTE_TEST_EVENT_ID; + evt_test->id =3D val; + + simple_ring_buffer_commit(cpu_buffer); + + return cnt; +} + +static const struct file_operations write_event_fops =3D { + .write =3D write_event_write, +}; + +static int remote_test_init_tracefs(struct dentry *d, void *unused) +{ + return tracefs_create_file("write_event", 0200, d, NULL, &write_event_fop= s) ? + 0 : -ENOMEM; +} + +static struct trace_remote_callbacks trace_remote_callbacks =3D { + .init =3D remote_test_init_tracefs, + .load_trace_buffer =3D remote_test_load, + .unload_trace_buffer =3D remote_test_unload, + .enable_tracing =3D remote_test_enable_tracing, + .swap_reader_page =3D remote_test_swap_reader_page, + .reset =3D remote_test_reset, + .enable_event =3D remote_test_enable_event, +}; + +static int __init remote_test_init(void) +{ + return trace_remote_register("test", &trace_remote_callbacks, NULL, + &remote_event_selftest, 1); +} + +module_init(remote_test_init); + +MODULE_DESCRIPTION("Test module for the trace remote interface"); +MODULE_AUTHOR("Vincent Donnefort"); +MODULE_LICENSE("GPL"); diff --git a/kernel/trace/remote_test_events.h b/kernel/trace/remote_test_e= vents.h new file mode 100644 index 000000000000..bb68aac4a25c --- /dev/null +++ b/kernel/trace/remote_test_events.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#define REMOTE_TEST_EVENT_ID 1 + +REMOTE_EVENT(selftest, REMOTE_TEST_EVENT_ID, + RE_STRUCT( + re_field(u64, id) + ), + RE_PRINTK("id=3D%lld", __entry->id) +); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A59C2356C7 for ; Fri, 3 Oct 2025 13:39:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498757; cv=none; b=Pk7MeqXxq16ZubQ2si3OGvF3O8Bq/FbJmgBZ2AA1kTxH3MremYti/Hz/WkbKN6Y65hLw0oBER/Ml7BwuWoh08JpBNtB0RDri8M3QFtwGaE4iRzWAgHT/6S3P/AitvzVp4ErDwDSHQqu75w5NX88aeWzNjn3IraKmmeyXssFYbLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498757; c=relaxed/simple; bh=Mv8pNFZbmTJ+XqCXqwF8C2MKN8hWnv5dSuMf6TGUsdw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=GAYfVWCwiTNwvULDkNfN2eBwrtkncZDgg7EBSlsh5NgGueT6JcozSNqVyn2EthwhvMQpCF7jrymIe7d/1Dnn6CV8rnPZ11hGlDli/xTRE7r4Ioks08pm0r39enEXV0dOJReXRLwD2+SQEHBL91bl5tG8efAOXTOV9BqjRk1ZYyU= 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=dSf7WroO; 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="dSf7WroO" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-46e41c32209so9805815e9.0 for ; Fri, 03 Oct 2025 06:39:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498751; x=1760103551; 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=BQk5nA0tQd154qzWEjnbplL7mTznFCQQR/uRSMMS69k=; b=dSf7WroOGZKJXTtAP5vVTmAAkd/PnAktUU4lYcFCbu/IbEegZDFGg3iLZwS8yqdkA7 22CMl67x4I4VNo4b0A2RtfBCv+LCZDysqYcG+Fog9AkWEWaFcEgoU/U6cE9/wPp6FOIy L8bf8qCrNUNGF0Lk4HcvEclymiRtesr6Ydw82uED2UAV2FsAzCldBSaBS6G2ghWTTkuB 1SmldNdhVWDpbGDpqSACWdKJf7RhGiiwPnvmoj7iZNJj+7G9PO5xAX5rxahTod+lsgRx D4wJvPSMvVTk8yEJ9fFQ8w3PgC3pggbilfg1Reyf37CPyI8HinjHw+rTc8YhLFUmwasA 6cyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498751; x=1760103551; 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=BQk5nA0tQd154qzWEjnbplL7mTznFCQQR/uRSMMS69k=; b=hcYKWP6bHlu6qPeNbeqq10C2RLoOIWh8aRckoGZNWDplnlMdBYrDsbF0gWuT+smHcR 4hvTGvyMYs15bXcbyeWNa9bYSYn3gD7IMxmxz2+oTQyQb3XbJAUjlIwkH3h51pysaNaF 3dbvOeedmFRKgD0zM4+4m5SSxMPSBDVHY7vZZ61pCw2nTwKGiyEccEvfgVCYzW51y1As fvZ9rlpyGy6jcqsw0boXharWDMg5JKri0sWj2kCWVkQXZQuMjGc3QiqPHPNNr07CUiXb CRTLZPaq55hiDHUwmIZa1P7tR0xB0Qfh9eD1tvCmHaGMTdKxBhvstsQXkdFRyTPTHzSj zuAA== X-Forwarded-Encrypted: i=1; AJvYcCVQPxKqXXOSlRA0Y6GTaT8z0pEFbEPKL61UaVen5qKLV91bV09WvDrwv5NvSPTZMU5sYUoCHVL42JRvkdU=@vger.kernel.org X-Gm-Message-State: AOJu0YwbWf3a0qq0IEFSkdVW/7Iun8jEWVoVnOADsbZ8Nwr4boNtZkqz i6KeBeb8jjhR4V47+IYHOA6Jm0rijEIz5H1E4D2CpptfFzw5a4O/gBDtiAk1BKnP9pkg60FMP2i IySEGQzdBa9jvaKYzHeTL/Q== X-Google-Smtp-Source: AGHT+IFbyRWMA3BQMJh/ltu37kawh82G+PgXPvTV4O9v7JYI/uDNrbN03KnfrS6cuP8BGsoXvoNmAqO+5gPxFyLn X-Received: from wmkz19.prod.google.com ([2002:a7b:c7d3:0:b0:46e:25c3:8f69]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:8b71:b0:46e:36fa:6b40 with SMTP id 5b1f17b1804b1-46e7113d33fmr21789585e9.24.1759498751147; Fri, 03 Oct 2025 06:39:11 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:12 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-16-vdonnefort@google.com> Subject: [PATCH v7 15/28] tracing: selftests: Add trace remote tests From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Shuah Khan , linux-kselftest@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Exercise the tracefs interface for trace remote with a set of tests to check: * loading/unloading (unloading.tc) * reset (reset.tc) * size changes (buffer_size.tc) * consuming read (trace_pipe.tc) * non-consuming read (trace.tc) Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Vincent Donnefort diff --git a/tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc b= /tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc new file mode 100644 index 000000000000..1a43280ffa97 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/buffer_size.tc @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote buffer size +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_buffer_size() +{ + echo 0 > tracing_on + assert_unloaded + + echo 4096 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + echo 0 > tracing_on + echo 7 > buffer_size_kb +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + setup_remote_test + test_buffer_size +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/functions b/tool= s/testing/selftests/ftrace/test.d/remotes/functions new file mode 100644 index 000000000000..97a09d564a34 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/functions @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: GPL-2.0 + +setup_remote() +{ + local name=3D$1 + + [ -e $TRACING_DIR/remotes/$name/write_event ] || exit_unresolved + + cd remotes/$name/ + echo 0 > tracing_on + clear_trace + echo 7 > buffer_size_kb + echo 0 > events/enable + echo 1 > events/$name/selftest/enable + echo 1 > tracing_on +} + +setup_remote_test() +{ + [ -d $TRACING_DIR/remotes/test/ ] || modprobe remote_test || exit_unresol= ved + + setup_remote "test" +} + +assert_loaded() +{ + grep -q "(loaded)" buffer_size_kb +} + +assert_unloaded() +{ + grep -q "(unloaded)" buffer_size_kb +} + +dump_trace_pipe() +{ + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + cat trace_pipe > $output & + pid=3D$! + sleep 1 + kill -1 $pid + + echo $output +} + +check_trace() +{ + start_id=3D"$1" + end_id=3D"$2" + file=3D"$3" + + # Ensure the file is not empty + test -n "$(head $file)" + + prev_ts=3D0 + id=3D0 + + # Only keep + tmp=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + sed -e 's/\[[0-9]*\]\s*\([0-9]*.[0-9]*\): [a-z]* id=3D\([0-9]*\)/\1 \2/' = $file > $tmp + + while IFS=3D read -r line; do + ts=3D$(echo $line | cut -d ' ' -f 1) + id=3D$(echo $line | cut -d ' ' -f 2) + + test $(echo "$ts>$prev_ts" | bc) -eq 1 + test $id -eq $start_id + + prev_ts=3D$ts + start_id=3D$((start_id + 1)) + done < $tmp + + test $id -eq $end_id + rm $tmp +} + +get_cpu_ids() +{ + sed -n 's/^processor\s*:\s*\([0-9]\+\).*/\1/p' /proc/cpuinfo +} + +get_page_size() { + sed -ne 's/^.*data.*size:\([0-9][0-9]*\).*/\1/p' events/header_page +} + +get_selftest_event_size() { + sed -ne 's/^.*field:.*;.*size:\([0-9][0-9]*\);.*/\1/p' events/*/selfte= st/format | awk '{s+=3D$1} END {print s}' +} diff --git a/tools/testing/selftests/ftrace/test.d/remotes/reset.tc b/tools= /testing/selftests/ftrace/test.d/remotes/reset.tc new file mode 100644 index 000000000000..4d176349b2bc --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/reset.tc @@ -0,0 +1,90 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote reset +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +check_reset() +{ + write_event_path=3D"write_event" + taskset=3D"" + + clear_trace + + # Is the buffer empty? + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 0 + + if $(echo $(pwd) | grep -q "per_cpu/cpu"); then + write_event_path=3D"../../write_event" + cpu_id=3D$(echo $(pwd) | sed -e 's/.*per_cpu\/cpu//') + taskset=3D"taskset -c $cpu_id" + fi + rm $output + + # Can we properly write a new event? + $taskset echo 7890 > $write_event_path + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 1 + grep -q "id=3D7890" $output + rm $output +} + +test_global_interface() +{ + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + + # Confidence check + echo 123456 > write_event + output=3D$(dump_trace_pipe) + grep -q "id=3D123456" $output + rm $output + + # Reset single event + echo 1 > write_event + check_reset + + # Reset lost events + for i in $(seq 1 10000); do + echo 1 > write_event + done + check_reset +} + +test_percpu_interface() +{ + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + for cpu in $(get_cpu_ids); do + taskset -c $cpu echo 1 > write_event + done + + check_non_empty=3D0 + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + + if [ $check_non_empty -eq 0 ]; then + check_reset + check_non_empty=3D1 + else + # Check we have only reset 1 CPU + output=3D$(dump_trace_pipe) + test $(wc -l $output | cut -d ' ' -f1) -eq 1 + rm $output + fi + cd - + done +} + +test_reset() +{ + test_global_interface + test_percpu_interface +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + setup_remote_test + test_reset +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace.tc b/tools= /testing/selftests/ftrace/test.d/remotes/trace.tc new file mode 100644 index 000000000000..081133ec45ff --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace.tc @@ -0,0 +1,127 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote non-consuming read +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_trace() +{ + echo 0 > tracing_on + assert_unloaded + + echo 7 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + # Simple test: Emit few events and try to read them + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + # + # Test interaction with consuming read + # + + cat trace_pipe > /dev/null & + pid=3D$! + + sleep 1 + kill $pid + + test $(wc -l < trace) -eq 0 + + for i in $(seq 16 32); do + echo $i > write_event + done + + check_trace 16 32 trace + + # + # Test interaction with reset + # + + echo 0 > trace + + test $(wc -l < trace) -eq 0 + + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + # + # Test interaction with lost events + # + + # Ensure the writer is not on the reader page by reloading the buffer + echo 0 > tracing_on + echo 0 > trace + assert_unloaded + echo 1 > tracing_on + assert_loaded + + # Ensure ring-buffer overflow by emitting events from the same CPU + for cpu in $(get_cpu_ids); do + break + done + + events_per_page=3D$(($(get_page_size) / $(get_selftest_event_size))) #= Approx: does not take TS into account + nr_events=3D$(($events_per_page * 2)) + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + id=3D$(sed -n -e '1s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=3D\([0-9]*\= )/\1/p' trace) + test $id -ne 1 + + check_trace $id $nr_events trace + + # + # Test per-CPU interface + # + echo 0 > trace + + for cpu in $(get_cpu_ids) ; do + taskset -c $cpu echo $cpu > write_event + done + + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + + check_trace $cpu $cpu trace + + cd - > /dev/null + done + + # + # Test with hotplug + # + + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + echo 0 > trace + + for cpu in $(get_cpu_ids); do + echo 0 > /sys/devices/system/cpu/cpu$cpu/online + break + done + + for i in $(seq 1 8); do + echo $i > write_event + done + + check_trace 1 8 trace + + echo 1 > /sys/devices/system/cpu/cpu$cpu/online +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_trace +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc b/= tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc new file mode 100644 index 000000000000..d28eaee10c7c --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/trace_pipe.tc @@ -0,0 +1,127 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote consuming read +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_trace_pipe() +{ + echo 0 > tracing_on + assert_unloaded + + # Emit events from the same CPU + for cpu in $(get_cpu_ids); do + break + done + + # + # Simple test: Emit enough events to fill few pages + # + + echo 1024 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + events_per_page=3D$(($(get_page_size) / $(get_selftest_event_size))) + nr_events=3D$(($events_per_page * 4)) + + output=3D$(mktemp $TMPDIR/remote_test.XXXXXX) + + cat trace_pipe > $output & + pid=3D$! + + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + echo 0 > tracing_on + sleep 1 + kill $pid + + check_trace 1 $nr_events $output + + rm $output + + # + # Test interaction with lost events + # + + assert_unloaded + echo 7 > buffer_size_kb + echo 1 > tracing_on + assert_loaded + + nr_events=3D$((events_per_page * 2)) + for i in $(seq 1 $nr_events); do + taskset -c $cpu echo $i > write_event + done + + output=3D$(dump_trace_pipe) + + lost_events=3D$(sed -n -e '1s/CPU:.*\[LOST \([0-9]*\) EVENTS\]/\1/p' $= output) + test -n "$lost_events" + + id=3D$(sed -n -e '2s/\[[0-9]*\]\s*[0-9]*.[0-9]*: [a-z]* id=3D\([0-9]*\= )/\1/p' $output) + test "$id" -eq $(($lost_events + 1)) + + # Drop [LOST EVENTS] line + sed -i '1d' $output + + check_trace $id $nr_events $output + + rm $output + + # + # Test per-CPU interface + # + + echo 0 > trace + echo 1 > tracing_on + + for cpu in $(get_cpu_ids); do + taskset -c $cpu echo $cpu > write_event + done + + for cpu in $(get_cpu_ids); do + cd per_cpu/cpu$cpu/ + output=3D$(dump_trace_pipe) + + check_trace $cpu $cpu $output + + rm $output + cd - > /dev/null + done + + # + # Test interaction with hotplug + # + + [ "$(get_cpu_ids | wc -l)" -ge 2 ] || return 0 + + echo 0 > trace + + for cpu in $(get_cpu_ids); do + echo 0 > /sys/devices/system/cpu/cpu$cpu/online + break + done + + for i in $(seq 1 8); do + echo $i > write_event + done + + output=3D$(dump_trace_pipe) + + check_trace 1 8 $output + + rm $output + + echo 1 > /sys/devices/system/cpu/cpu$cpu/online +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_trace_pipe +fi diff --git a/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc b/t= ools/testing/selftests/ftrace/test.d/remotes/unloading.tc new file mode 100644 index 000000000000..cac2190183f6 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/unloading.tc @@ -0,0 +1,41 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test trace remote unloading +# requires: remotes/test + +. $TEST_DIR/remotes/functions + +test_unloading() +{ + # No reader, writing + assert_loaded + + # No reader, no writing + echo 0 > tracing_on + assert_unloaded + + # 1 reader, no writing + cat trace_pipe & + pid=3D$! + sleep 1 + assert_loaded + kill $pid + assert_unloaded + + # No reader, no writing, events + echo 1 > tracing_on + echo 1 > write_event + echo 0 > tracing_on + assert_loaded + + # Test reset + clear_trace + assert_unloaded +} + +if [ -z "$SOURCE_REMOTE_TEST" ]; then + set -e + + setup_remote_test + test_unloading +fi --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65C6023B616 for ; Fri, 3 Oct 2025 13:39:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498757; cv=none; b=OxaxnYN/wXDYkMyETyAycxJc8p4TMH+mefEmb3zRK+q7wKSTSEuk00lF5idsDHfuuRHomA0Qalazl5a7agBpCodJbXyCpjvPq+nbZ5xFUcaIpXIF2M75zlrF9qhc4+2Ay2qN9Tp40b5d4Ztb8v8QPGLiZmynxuwqFa4m9QHgp8w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498757; c=relaxed/simple; bh=8Cw2K0IyrMbYYLIH+BNRbrAbypKpGcwbo42Tv7az5a8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DpxwyW+MKebCUbWCAVi4hMtJB7lRUlYbSs6gCV9FDN2oOxpxAlkKULrRRcHsVRaI1t4vv0lnX4UeGt9BGsKSkTgeBYI7fPjSk9YMDjkYXyNE7NmKTiZGwUgILu4icDPOKWoj9IqTQzDLvWxb9jQo15YTNhT3tImUz9W3EPwfu3w= 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=ju3Si6Hu; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ju3Si6Hu" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-634ad8328fdso2602387a12.0 for ; Fri, 03 Oct 2025 06:39:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498752; x=1760103552; 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=3ptOXAsK02KET+nuGM2NvZr5tn+Cruj7KUoPt2v9bC4=; b=ju3Si6Hub/YGk4CJyg/z+pCJuu89YaAfXRbf3VdC+TkuwMNIR++OOu4jHwIgQeaZG/ JCC5yE7CpPD+oMPCvRo09TAHFSlbyCREDe10Qq/ORaTJqp3KqfG9Fbbxa3c1jGvmToEC XP8s2QMICsw+i8XWuHSLoGKS01lkbv2WWAqUgDwuYT9H+WLkymnlHT3A3oY+IrQV0/ri jd3JG/mm+iz+3D7C6OZJ6zsk+J4H+Hog7GVJ6DgUxElnEtJk5/6Ro8nA0pJJ0jivMg23 aB+3PGpOwJ83c2xB2XbNB+cJ8z5a7u07bEQX4wrr5/TJhSW24BDGlRU/wvIyxaWDKQyU excA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498752; x=1760103552; 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=3ptOXAsK02KET+nuGM2NvZr5tn+Cruj7KUoPt2v9bC4=; b=f5FtIBSFO0Uhe4on9XlvwivbGNmLc4kO0EXeb6TmzA3TrdrV2EQawHNCRw/n1VlsIH 6Tf0n0kzSwUVBVf3fyC54hbQjFRyycjHhgeFs0t/Zm2EcklZQVkYDnfFLHeBMRTc8CmJ ALe6pDyw8wyK257xWEV565+cTPi6hlXHS0MSPkbTEUNSg6mgitd8MkgwO1k7P2xyAZ6i Il+Yk7bx8R8A4FWzItc9XYwOIQuibxc/EdkgdTxRA93YnDIiUI70noCGZG8ZOc9Z4r51 /hTWUZzQk3TFISevR2Bh8kvjhCi6EDOWelNlVsSKWTUFaATcZbcYRhREShTbYyb3ikWU Kd9A== X-Forwarded-Encrypted: i=1; AJvYcCXKQwGgnxxmBo0hlaqHdIDJfbDR9p043xUdreGxtoF7zfljYjA8Oo3/uNSeNebK8UbiARLgnC2IJPJAAG8=@vger.kernel.org X-Gm-Message-State: AOJu0YyCH35+2cR+krC+hY5XDZZloYuoYmryMlXVG6Yo+KiDEoIO6brT kl7FZ99iWxgwxlzV916Hdskp5Z201WJrHhtOKVXVVvDLHNShwyVRl21t/D5LytBOGiT/ZoWVrjX cI8U16F7xoTNpn7Z6UsF/BQ== X-Google-Smtp-Source: AGHT+IH1xhwr98a1KjzKNYHcZRC7sH0MEyc8VNAbl5gX0uevl9b95kinJk1XW3eUNT+SGJ+58Lgd/woZKqcy9o+d X-Received: from edwr6.prod.google.com ([2002:a05:6402:346:b0:636:640b:3c66]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:50c7:b0:637:e17e:1a9a with SMTP id 4fb4d7f45d1cf-63939c2df6dmr3356826a12.26.1759498752381; Fri, 03 Oct 2025 06:39:12 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:13 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-17-vdonnefort@google.com> Subject: [PATCH v7 16/28] Documentation: tracing: Add tracing remotes From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add documentation about the newly introduced tracing remotes framework. Signed-off-by: Vincent Donnefort diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst index b4a429dc4f7a..d77ffb7e2d08 100644 --- a/Documentation/trace/index.rst +++ b/Documentation/trace/index.rst @@ -90,6 +90,17 @@ interactions. user_events uprobetracer =20 +Remote Tracing +-------------- + +This section covers the framework to read compatible ring-buffers, written= by +entities outside of the kernel (most likely firmware or hypervisor) + +.. toctree:: + :maxdepth: 1 + + remotes + Additional Resources -------------------- =20 diff --git a/Documentation/trace/remotes.rst b/Documentation/trace/remotes.= rst new file mode 100644 index 000000000000..e7fb3ee96c30 --- /dev/null +++ b/Documentation/trace/remotes.rst @@ -0,0 +1,59 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Tracing Remotes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +:Author: Vincent Donnefort + +Overview +=3D=3D=3D=3D=3D=3D=3D=3D +A trace remote relies on ring-buffer remotes to read and control compatible +tracing buffers, written by entity such as firmware or hypervisor. + +Once registered, a tracefs instance will appear for this remote in the Tra= cefs +directory **remotes/**. This remote can be read and controlled using the s= ame +files as regular Tracefs instances such as **trace_pipe**, **tracing_on** = or +**trace**. + +Register a remote +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +A remote must provide a set of callbacks `struct trace_remote_callbacks` w= hom +description can be found below. Those callbacks allows Tracefs to enable a= nd +disable tracing and events, to load and unload a tracing buffer (a set of +ring-buffers) and to swap a reader page with the head page, which enables +consuming reading. + +.. kernel-doc:: include/linux/trace_remote.h + +Declare a remote event +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Macros are provided to ease the declaration of remote events, in a similar +fashion to in-kernel events. A declaration must provide an ID, a descripti= on of +the event arguments and how to print the event: + +.. code-block:: c + + REMOTE_EVENT(foo, EVENT_FOO_ID, + RE_STRUCT( + re_field(u64, bar) + ), + RE_PRINTK("bar=3D%lld", __entry->bar) + ); + +Then those events must be declared in a C file with the following: + +.. code-block:: c + + #define REMOTE_EVENT_INCLUDE_FILE foo_events.h + #include + +This will provide a `struct remote_event remote_event_foo` that can be giv= en to +`trace_remote_register`. + +Simple ring-buffer +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +A simple implementation for a ring-buffer writer can be found in +kernel/trace/simple_ring_buffer.c. + +.. kernel-doc:: include/linux/simple_ring_buffer.h --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F4CD242D7B for ; Fri, 3 Oct 2025 13:39:15 +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=1759498759; cv=none; b=a7jW74AhK77ijr4D7F1jV6/7aXBo7s4LVkFFZLza+MFPB8pWOEkvh1ty+Jd5R7qSD+smub487RTgEll7CGyuhmD16dmsrTpg+ojARiIbOWys1aeGrxeaeP1gQJLaFozFfWRsU/IJL+pgyzulc9E1Ne71p8N8j+tVvjVOGhz2IfA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498759; c=relaxed/simple; bh=3Gyq8aA8JN0nK+7FXBMD7LVv1KmJh45YjAAyxT/uPCw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WYuDjFtEwhz+xrBNBRmfVSvwglpvwvzQPn7hn0q8AZzSrK/Obj1bKXDe7uRwRCezEVphe2JN7SWRaVRjupAdNH95Vl3QK2DryZZlQ0QKsimOMkhsPy1YVFXbHEk9wQRN7qY828sFpS18Fz5i7OjPVysnyZZdrKfccmCTe8Ivq5w= 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=Lao6h/qg; 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="Lao6h/qg" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3ee1365964cso1750605f8f.2 for ; Fri, 03 Oct 2025 06:39:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498753; x=1760103553; 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=cusWrm7Pe7Vzh2zNqiDKt7LKbdzyFf6LREbhhod2FBw=; b=Lao6h/qgwbSPXuxKRlQhRIR+tILvaqUoMprgAexnGedblVpa3CqYF8Fllpf4YNE0ne zxeC2+EtY+F7UKlzUXri18vu/fc5k4dTJ4RXC8zq6vfYV0L5UzWiF7NTC8aQNIdI1RSF yteLmgrsQ66+wrypH27mbdiLTy2x7uTjxFUsMSMM+Um/O4VXZwElcxVRRcmbzLMnypAx fiefd5DAgpTQv4UY8MJ/vbnxq79Vty4PwWgruSVx5BagU8qoQ2/3fS1rDBA9K47qFLrQ L/XJYLpdmLLFALw5A3ANZuNSa883W9ABoK3TJw0Jdjniu9Pwo/jrfNPf5xMenJeg7wDc UkAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498753; x=1760103553; 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=cusWrm7Pe7Vzh2zNqiDKt7LKbdzyFf6LREbhhod2FBw=; b=lgTSN/XdvKb6EDkupa74gLnd3onH46AnCZEBUC2Txbfmm28DfFhlsa/wOp/jnouKJe sA1CP5RbYi6JNUDx/w9MW5G8tzQFegeydDd+EY5MYHn9BGe0PdFo/xWyfQ5IYM3PhqwZ uXc6U4bXM2Wyix0cKWPVZT+/yqw3hpMbFdtVic0zyyHHGwPIYz4ykB4JpJUOj1erUqbk hLBCCW+NiiyIHA7tkVtPIA6Jo7ItEe5dJ/HDCy717qiRfWID52A9k8u18vnSfnrcFS2B EFBqoZQZBVVCPdUWMVGbzvV3TEfM5+IbpNTx7p72h2rvACFnvf1AK97vxsEy9syesiuG EFwA== X-Forwarded-Encrypted: i=1; AJvYcCWsEOxNoICvWK9PsyrivK4dDuoreTrlYXV7VwJkaXE4NtojmA3Z8RJSxn7zYgQPZ/I34m3IeU1I6H2a+Pc=@vger.kernel.org X-Gm-Message-State: AOJu0YyuPWD/NpNFHDACd2vtdJv/RPpEsEdaKCaMg6AaoPFG0kFPjNBb jApcPXxioziB3nP+oQMXYiroJbpsVdDyoGF0ejVuuMZPg7M6M40/lFsiT/sx1nw4opkHC9VVvHr 9RdImKygRyQyuhpN6pVJ0JA== X-Google-Smtp-Source: AGHT+IF6GiKCqwKfjKEeuxZgNsXAZSGVRxvCwcB1YwHTIPjTMo5AijDWEtVQrQi9EZhBvqgSIyLZKQ4QheeyH+xU X-Received: from wmby13.prod.google.com ([2002:a05:600c:c04d:b0:46e:3771:b9c9]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:18a9:b0:404:ac77:6598 with SMTP id ffacd0b85a97d-4256713ac9dmr2185339f8f.11.1759498753278; Fri, 03 Oct 2025 06:39:13 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:14 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-18-vdonnefort@google.com> Subject: [PATCH v7 17/28] tracing: load/unload page callbacks for simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add load/unload callback used for each admitted page in the ring-buffer. This will be later useful for the pKVM hypervisor which uses a different VA space and need to dynamically map/unmap the ring-buffer pages. Signed-off-by: Vincent Donnefort diff --git a/include/linux/simple_ring_buffer.h b/include/linux/simple_ring= _buffer.h index f324df2f875b..ecd0e988c699 100644 --- a/include/linux/simple_ring_buffer.h +++ b/include/linux/simple_ring_buffer.h @@ -110,4 +110,11 @@ int simple_ring_buffer_reset(struct simple_rb_per_cpu = *cpu_buffer); */ int simple_ring_buffer_swap_reader_page(struct simple_rb_per_cpu *cpu_buff= er); =20 +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 20e3cd6071a2..c2ec6017c37c 100644 --- a/kernel/trace/simple_ring_buffer.c +++ b/kernel/trace/simple_ring_buffer.c @@ -71,7 +71,7 @@ static void simple_bpage_reset(struct simple_buffer_page = *bpage) local_set(&bpage->page->commit, 0); } =20 -static void simple_bpage_init(struct simple_buffer_page *bpage, unsigned l= ong page) +static void simple_bpage_init(struct simple_buffer_page *bpage, void *page) { INIT_LIST_HEAD(&bpage->link); bpage->page =3D (struct buffer_data_page *)page; @@ -338,10 +338,15 @@ int simple_ring_buffer_reset(struct simple_rb_per_cpu= *cpu_buffer) return 0; } =20 -int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, - const struct ring_buffer_desc *desc) +int __simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, + struct simple_buffer_page *bpages, + const struct ring_buffer_desc *desc, + void *(*load_page)(unsigned long va), + void (*unload_page)(void *va)) { struct simple_buffer_page *bpage =3D bpages; + int ret =3D 0; + void *page; int i; =20 /* At least 1 reader page and two pages in the ring-buffer */ @@ -350,15 +355,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; @@ -368,7 +380,13 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu *= cpu_buffer, struct simple_ cpu_buffer->head_page =3D bpage + 1; =20 for (i =3D 1; i < desc->nr_page_va; i++) { - simple_bpage_init(++bpage, desc->page_va[i]); + page =3D load_page(desc->page_va[i]); + if (!page) { + ret =3D -EINVAL; + break; + } + + simple_bpage_init(++bpage, page); =20 bpage->link.next =3D &(bpage + 1)->link; bpage->link.prev =3D &(bpage - 1)->link; @@ -377,6 +395,14 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu *= cpu_buffer, struct simple_ cpu_buffer->nr_pages =3D i + 1; } =20 + if (ret) { + for (i--; i >=3D 0; i--) + unload_page((void *)desc->page_va[i]); + unload_page(cpu_buffer->meta); + + return ret; + } + /* Close the ring */ bpage->link.next =3D &cpu_buffer->tail_page->link; cpu_buffer->tail_page->link.prev =3D &bpage->link; @@ -384,19 +410,46 @@ int simple_ring_buffer_init(struct simple_rb_per_cpu = *cpu_buffer, struct simple_ /* The last init'ed page points to the head page */ simple_bpage_set_head_link(bpage); =20 + cpu_buffer->bpages =3D bpages; + return 0; } =20 -void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +static void *__load_page(unsigned long page) { + return (void *)page; +} + +static void __unload_page(void *page) { } + +int simple_ring_buffer_init(struct simple_rb_per_cpu *cpu_buffer, struct s= imple_buffer_page *bpages, + const struct ring_buffer_desc *desc) +{ + return __simple_ring_buffer_init(cpu_buffer, bpages, desc, __load_page, _= _unload_page); +} + +void __simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer, + void (*unload_page)(void *)) +{ + int p; + if (!simple_rb_loaded(cpu_buffer)) return; =20 simple_rb_enable_tracing(cpu_buffer, false); =20 + unload_page(cpu_buffer->meta); + for (p =3D 0; p < cpu_buffer->nr_pages; p++) + unload_page(cpu_buffer->bpages[p].page); + cpu_buffer->bpages =3D NULL; } =20 +void simple_ring_buffer_unload(struct simple_rb_per_cpu *cpu_buffer) +{ + return __simple_ring_buffer_unload(cpu_buffer, __unload_page); +} + int simple_ring_buffer_enable_tracing(struct simple_rb_per_cpu *cpu_buffer= , bool enable) { if (!simple_rb_loaded(cpu_buffer)) --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5893C1B6D06 for ; Fri, 3 Oct 2025 13:39:15 +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=1759498759; cv=none; b=kwDMUxYmjs1NBAo+DD9L8q2nf00k4n3txN/iVzNGmLdMcbe7vPeZZCWV2DAdOMGxPbv9NDSlrpJuNNHymV3RuWVkeEzeRcmiGcFrZoEUSn7xa8QSHKle155z+ROQgWTBseq4pL59K7VvJHHuhLa0cla83ZQ3Zv22r1hteleen6g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498759; c=relaxed/simple; bh=0GoKLpSdS6ldxQXPbUu3GD19jDi+5YDA57nA2CXdDXI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=d4pDtpSjMdx+bt6pEr0i31DjzGvn88uPrfBD/D/9pD/87pTiNrv+nWmjtlvxeBeyAVc41I3JVgdpUjB1Mdr4XeV4rIsOam0yFvgYDWIwb+IaHjPb4kzKYfRGxLeRWnEptY9dr1kpizpC/xAoU9mD+MsOMGCPSwlgKRIiD2kvKcw= 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=NhCXOlXR; 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="NhCXOlXR" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3ecdc9dbc5fso1041319f8f.1 for ; Fri, 03 Oct 2025 06:39:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498754; x=1760103554; 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=QCcr65sPLORj627Lp0bpZGMol0uaDnoIgHQtYd2TdNg=; b=NhCXOlXRiizWQiOP5srFfv0kvtMw2WiUZcvdnDrlX+zi7Za1RHuu9ONcv7XWfuucVp oEdHWjb+Dew3pyuFRuDu5BD/7ZnwcKuUvBSO/qYJWQL01f3DIh3/WLEGVA690Tkvx1xG YvhHyNBI3EdRCU2k6YuORbgii30NcwshUHlLaTntF2mx454qY4pfYDbrAH/w8z1lz0hh zNA5a/VLfBaN5Pv/OkFEHzEu8IYCTwirQ/c5H8TR9afHK9bicQlZLbyU+ZYjcb0lPey+ h1xaGcm/dpwkwvz4YhRKOsz6QzCBU7KwiCv7Y7+uNhZRoL1wwgx7uRtSoQ7im6xuTZHL +8hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498754; x=1760103554; 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=QCcr65sPLORj627Lp0bpZGMol0uaDnoIgHQtYd2TdNg=; b=BMwo8FeC9zgEjr/HEHk7uKrKEHJdJh2vcJeSl2UN5Pw8mb30mlbQHXw2WfquDLJBA7 DpZIW/G3vL8Z4Aw18GqNZlmUTELsqXboRPhEkc/8bmq9uwWNBLDHV7WYUX96kXMNYS6N 4wkJW7quJRYm6DXMBl1bHt1RnRjq3JfxJoeVLqEEl+vgAGmWSWLH/mk+QYIYAnrwqUb2 7tFbQkA74qKS4FSyDgxX/DAd9M3wYBGr+RNnQ+S7PQeG8IzVEME/GusPKNKWoICRVHAM /pS3oV+fVHlK8OEZS4BLQ+BJqnXZ/jmdOdlTPRIYx6LS7brYlpAZ45qNWEu2oOsLdUIO 6iNA== X-Forwarded-Encrypted: i=1; AJvYcCVIduL1UV6wF2K9GWVVjEpZ502XY0EDhu0KKyYHCv695NS1HDeL1aSat+LFYMbaHt39ANInx+3CGIhvjIE=@vger.kernel.org X-Gm-Message-State: AOJu0YzA+Hi7col26Bu+ZTvs7Z6TwRXKKThLLEH5tLDuNoGmvfg+tNjA V6Epz7eXjfL+cbjCxOIMZcgaJFz7YClGUUn1ueTf4yecXbxVCFg6VtEpZ3M+gG2jV4EdpDEn6aC kONJk9D/z/giaSEEpRYPK2Q== X-Google-Smtp-Source: AGHT+IHQ12IlCfmMAydiKBsHPD9Q4iJr8SeYEXmAn4PmVdl5+Rxkjar+IUCHmSelDg/tdXKzfnSMs19tRFdbpfxM X-Received: from wmdd3.prod.google.com ([2002:a05:600c:a203:b0:45c:b62f:ca0d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:18a9:b0:411:3c14:3aa1 with SMTP id ffacd0b85a97d-42567139debmr2038918f8f.3.1759498754083; Fri, 03 Oct 2025 06:39:14 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:15 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-19-vdonnefort@google.com> Subject: [PATCH v7 18/28] tracing: Check for undefined symbols in simple_ring_buffer From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The simple_ring_buffer implementation must remain simple enough to be used by the pKVM hypervisor. Prevent the object build if unresolved symbols are found. Signed-off-by: Vincent Donnefort diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 53534447e70b..38523ea2e19b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -114,4 +114,20 @@ obj-$(CONFIG_TRACE_REMOTE) +=3D trace_remote.o obj-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o obj-$(CONFIG_TRACE_REMOTE_TEST) +=3D remote_test.o =20 +# +# simple_ring_buffer is used by the pKVM hypervisor which does not have ac= cess +# to all kernel symbols. Fail the build if forbidden symbols are found. +# +UNDEFINED_ALLOWLIST :=3D memset alt_cb_patch_nops __x86 __ubsan __asan __k= asan __gcov __aeabi_unwind +UNDEFINED_ALLOWLIST +=3D __stack_chk_fail stackleak_track_stack __ref_stac= k __sanitizer +UNDEFINED_ALLOWLIST :=3D $(addprefix -e , $(UNDEFINED_ALLOWLIST)) + +quiet_cmd_check_undefined =3D NM $< + cmd_check_undefined =3D test -z "`$(NM) -u $< | grep -v $(UNDEFINED_= ALLOWLIST)`" + +$(obj)/%.o.checked: $(obj)/%.o FORCE + $(call if_changed,check_undefined) + +always-$(CONFIG_SIMPLE_RING_BUFFER) +=3D simple_ring_buffer.o.checked + libftrace-y :=3D ftrace.o --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B280256C6C for ; Fri, 3 Oct 2025 13:39:16 +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=1759498760; cv=none; b=t1Mt8tqpbPud1CLghPORMT7Z6UaQUTAKKZ5jHoghHOM9bBvRvG6t1iLlHbncA4MiFTw8YzlPtfOvO4dPixiP0t/Ghzhv1eh79ABWLBX5HC7swwSUDjczGiDx/xeYTh7RaSG39Q1asMEgdc8LVTMNONa+APkeTdXVZK7DfGDUIdM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498760; c=relaxed/simple; bh=jCbG47nIr2/y0UdsIaiKkxyaIjKy+gc2r3vZExVABsk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=unB/cAubGpj4oEcsYoUSqGOh8qTY3Yi6/X45tW+TrrgKjhfzSousakUvmyD7XSk7us3OPtqtaaKU8F326lAgSK0B9zhZzTJ/r3cdWO3zW2LltXAixd/t2vdLI9ieCS35z0QtmgzM8eWvXCz+ZT/CF9+eEbYvRNTcs+2+AjvttNw= 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=OBGthic/; 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="OBGthic/" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e5bcf38dfso22013925e9.0 for ; Fri, 03 Oct 2025 06:39:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498755; x=1760103555; 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=1VsntBoZ2UX1thgOJTBqIcQGNGyw+Zp/ZR+M9plVUyY=; b=OBGthic/M3iI4fYRo9IiGexA+QyMqTa3fbFj77yNp5ZQV8l4XCBTj170Qx2MNlXglv EBVSXsZDRrUNYIyGRfIgw8kki99WfUxQWSPoJJby7IiGRsjjQnQCazgeDZ6HF62yIApF T1hN8jD+yJhX/JxCAP3B1jTxZ0RTwgekfg1yiBX0ZOBVDC5dETPgpOm0mArh//NwwTBR ipUgsCpFBzamthzhjSp8bbvR2Har4wR5Z6e4vfDShbv9LrrgVHqCVGlNFmjuPPA1HsqF vQ+z8FMtbTDEG+uLj+hnNLWTZpRVpNVnaoOAYARFv1LC4fo7UFqjzun619Sn23lMLe0m ApVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498755; x=1760103555; 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=1VsntBoZ2UX1thgOJTBqIcQGNGyw+Zp/ZR+M9plVUyY=; b=ZUWKj4HDS1s0f0vDeFxEYVMKagNgO1MzCCaADuHqmibng5W/R9Yp0Qs6quJGbVPggn CgKob67up1ljm1zN7t2wDHyJN/fesFGVbOxCMv0b0wClXxuYkXQnParISJdXCj9aWD8x lIRk06Bnv6GMdgwUjpO+9U4VDUk0uq6ur7doK2UchqCUsC6uKybE2YY81I0EtFT7VWRY gcMXjZAGcwJOVJwlRkAurLpwH7nnmKnovs5lOppYDBg93hc1PkvnJfDH4Rt1NxZxZySW XR7oEjRTaZ3WWvTZZpWLyVWELQBapmn2emHYmw/YJmSYdOb7hcUMLmACHOY1dviz8X5Y aj1w== X-Forwarded-Encrypted: i=1; AJvYcCXqM0Nbctp4nR3bFNNc+iIcb3usNTXy8/UNppDkNWVVaQiI11kvCh2zWFGL9mKJU5PDfHVRxed53B0xNAQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzAHOzMWksmq8vS3dsYycl+65qbGmhTwjmikQHu2/OzC0SChHXz gmxUF7QWyWiV0WqX+3QC26V4w+tZJUNzetgRDNzSjxL/GonUj042jyKc1YdrbH8tDy76hd/gFap Xvr3AKgB8cOOKpAq92Ro14Q== X-Google-Smtp-Source: AGHT+IFsYzxWE1q+iyfd/CPcAE+BH9Qt6DCpr8RRj96mk+HtmlAuCb4ka3fjLLxAs1Crrs+qBq6aGz3zEY320EBD X-Received: from wmbdn6.prod.google.com ([2002:a05:600c:6546:b0:46e:6605:3ac2]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:83ca:b0:45d:5c71:769d with SMTP id 5b1f17b1804b1-46e70c5cef4mr26594895e9.8.1759498754928; Fri, 03 Oct 2025 06:39:14 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:16 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-20-vdonnefort@google.com> Subject: [PATCH v7 19/28] KVM: arm64: Support unaligned fixmap in the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Return the fixmap VA with the page offset, instead of the page base address. This allows to use hyp_fixmap_map() seamlessly regardless of the address alignment. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index ae8391baebc3..75014dc7d82e 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -239,7 +239,7 @@ static void *fixmap_map_slot(struct hyp_fixmap_slot *sl= ot, phys_addr_t phys) WRITE_ONCE(*ptep, pte); dsb(ishst); =20 - return (void *)slot->addr; + return (void *)slot->addr + offset_in_page(phys); } =20 void *hyp_fixmap_map(phys_addr_t phys) --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDDD41EE7DC for ; Fri, 3 Oct 2025 13:39: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=1759498760; cv=none; b=LZPeX460aV2qkV+K6sCHFzdJhccKJnO2vOOUkGLtACvTw82IP36iq64k6xRmfNC2gLKpar4U7AvDXnjXHdivOqDKnzVJoX/07Mvl4UtPH+p+8ulWm5k/k8xdC4qc2nIATeR+KUy4mgMwHaAB6koib197LzTnzz9XKuZRZg3Io8o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498760; c=relaxed/simple; bh=g+NA4zSfwGxqsI4IC/ZtvkJUw3mWlopfHq/pqvBkNBQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DmGsUgPG9IY+2qJ6NURe9fYot7jUFece3iEwwmaNiTvoabGTUhQdFzPkjFXMRPuTqeRfn//tCwwTllVo35HQ5JCyp0syqfL4LlMnTnTwsbGvGp566n1rQEZsTJwzZsfjnVgQFxkdOQPY//Vn3obY3vxKKwtMu+twjr/Nqri1Jgg= 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=P4Go2lEm; 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="P4Go2lEm" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e41c32209so9806175e9.0 for ; Fri, 03 Oct 2025 06:39:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498756; x=1760103556; 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=ylDyk9s+5460dWO0uwqzLTOwTHPUFfBCKGnbJPl3EJ0=; b=P4Go2lEmbcp1oiL+k1DbeT+rub247fAJHHsHvPMwW9EEMx/Vhy8s9SjmB8WCK06uKU ChTmilKOndJcgZvPUCFW+hUvzdFLBP8zHIRHHR67p1KJXGv33Ek2XwycjWdlDFLBc0yQ E8IlZGVO7Dg5wRWUH5Q/6kNNLfjimqJ2YsGhYemoyVbu7X1vSh0bGoMPGRbVffVc8ZHH cxEKpNigY5+8b75au2OO1k8bEVIlXfIh29ZYOkMibyBEkqkTyxjZxb5xzA+Lz3foWQT8 M7ZFEj8FVf1RL3hFqVHuorcWxiVSktkoEPJcIltzJo+LSi0+iWqAd/rF7jmYTTqIuse0 lxtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498756; x=1760103556; 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=ylDyk9s+5460dWO0uwqzLTOwTHPUFfBCKGnbJPl3EJ0=; b=ZxRLxUKuI7kZprECVLmuJnSeaY2T2YrT+H9Q58bgYPLPFwagDeIUotmC6BGwEoWyjQ 0xxBAQjtxnpFfFHuHrngiuuLnKspBeD2cjMWEjvbS1RnmIsAMGiNq+jU8v7emmG+QFyA Od1G33DkhuGcV/hZwrBOdbhFgXkS6xWxjSDGrRdamEqZwI/whFi8imxXqEh8kMVKoUZC xeo4sD45xTxHHVzaEGyXrweS4JgfZcLJfhyCKvj6AI57GzFzZOJsE+Z46up8Lt2MB0oR v2bhHAOGkVw2k317zkc7P6vUTRBdswQBCYRtdiueK72yN1zjcME4ZO9RXkcCeH/b3QMf LZNA== X-Forwarded-Encrypted: i=1; AJvYcCUTFyink8MzPcik5xJGm3jLeBTHa3OWzQvx5fzojLAAznek6tw2Typ6D4msGkuEJe/cz+SaKUfiQXrfoH4=@vger.kernel.org X-Gm-Message-State: AOJu0YxYQ618liAG0pV1sJStICdl4msvAMMrpvDqiGPPrpBXrSJIWVCZ l6dy2kv8ZjisJP4wgFdHsTcpIDNcdoepEvXt5zyfVmp+j+THk9Fap9RfJyuDtW8wS3uHh3s1Bbq GDsG0Mvq70wQEil62Ae1CjA== X-Google-Smtp-Source: AGHT+IFhcfElMZQqoCh3Cq6hmENi8kEnMvrnlOccnmd1TZhS72DJCQ0YPYUh2/TUKvb4CJDArB7pSvRYLVze8uJU X-Received: from wmjf9.prod.google.com ([2002:a7b:cd09:0:b0:46b:7c6d:220]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:468e:b0:43c:ec4c:25b4 with SMTP id 5b1f17b1804b1-46e71102467mr22982065e9.10.1759498755769; Fri, 03 Oct 2025 06:39:15 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:17 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-21-vdonnefort@google.com> Subject: [PATCH v7 20/28] KVM: arm64: Add clock support for the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" By default, the arm64 host kernel is using the arch timer as a source for sched_clock. Conveniently, EL2 has access to that same counter, allowing to generate clock values that are synchronized. The clock needs nonetheless to be setup with the same slope values as the kernel. Introducing at the same time trace_clock() which is expected to be later configured by the hypervisor tracing. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_= hyp.h index e6be1f5d0967..d46621d936e3 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -146,5 +146,4 @@ extern u64 kvm_nvhe_sym(id_aa64smfr0_el1_sys_val); extern unsigned long kvm_nvhe_sym(__icache_flags); extern unsigned int kvm_nvhe_sym(kvm_arm_vmid_bits); extern unsigned int kvm_nvhe_sym(kvm_host_sve_max_vl); - #endif /* __ARM64_KVM_HYP_H__ */ diff --git a/arch/arm64/kvm/hyp/include/nvhe/clock.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/clock.h new file mode 100644 index 000000000000..9e152521f345 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/clock.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ARM64_KVM_HYP_NVHE_CLOCK_H +#define __ARM64_KVM_HYP_NVHE_CLOCK_H +#include + +#include + +#ifdef CONFIG_PKVM_TRACING +void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc); +u64 trace_clock(void); +#else +static inline void +trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc) { } +static inline u64 trace_clock(void) { return 0; } +#endif +#endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index 0b0a68b663d4..607357e36026 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -17,7 +17,7 @@ ccflags-y +=3D -fno-stack-protector \ hostprogs :=3D gen-hyprel HOST_EXTRACFLAGS +=3D -I$(objtree)/include =20 -lib-objs :=3D clear_page.o copy_page.o memcpy.o memset.o +lib-objs :=3D clear_page.o copy_page.o memcpy.o memset.o tishift.o lib-objs :=3D $(addprefix ../../../lib/, $(lib-objs)) =20 CFLAGS_switch.nvhe.o +=3D -Wno-override-init @@ -28,6 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o +hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o hyp-obj-y +=3D $(lib-objs) =20 ## diff --git a/arch/arm64/kvm/hyp/nvhe/clock.c b/arch/arm64/kvm/hyp/nvhe/cloc= k.c new file mode 100644 index 000000000000..600a300bece7 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/clock.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include + +#include +#include + +static struct clock_data { + struct { + u32 mult; + u32 shift; + u64 epoch_ns; + u64 epoch_cyc; + u64 cyc_overflow64; + } data[2]; + u64 cur; +} trace_clock_data; + +static u64 __clock_mult_uint128(u64 cyc, u32 mult, u32 shift) +{ + __uint128_t ns =3D (__uint128_t)cyc * mult; + + ns >>=3D shift; + + return (u64)ns; +} + +/* Does not guarantee no reader on the modified bank. */ +void trace_clock_update(u32 mult, u32 shift, u64 epoch_ns, u64 epoch_cyc) +{ + struct clock_data *clock =3D &trace_clock_data; + u64 bank =3D clock->cur ^ 1; + + clock->data[bank].mult =3D mult; + clock->data[bank].shift =3D shift; + clock->data[bank].epoch_ns =3D epoch_ns; + clock->data[bank].epoch_cyc =3D epoch_cyc; + clock->data[bank].cyc_overflow64 =3D ULONG_MAX / mult; + + smp_store_release(&clock->cur, bank); +} + +/* Using host provided data. Do not use for anything else than debugging. = */ +u64 trace_clock(void) +{ + struct clock_data *clock =3D &trace_clock_data; + u64 bank =3D smp_load_acquire(&clock->cur); + u64 cyc, ns; + + cyc =3D __arch_counter_get_cntpct() - clock->data[bank].epoch_cyc; + + if (likely(cyc < clock->data[bank].cyc_overflow64)) { + ns =3D cyc * clock->data[bank].mult; + ns >>=3D clock->data[bank].shift; + } else { + ns =3D __clock_mult_uint128(cyc, clock->data[bank].mult, + clock->data[bank].shift); + } + + return (u64)ns + clock->data[bank].epoch_ns; +} --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA2C0248F66 for ; Fri, 3 Oct 2025 13:39:18 +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=1759498763; cv=none; b=DbfQTZkl38RIFxcMQFlCellKecwm+aNAwjAJQ1jKoSDVGqPcSaDowxxrsQXMu/LUodc0DJ82F2g/6SBxURcS/iHEuspAmtEfI4snjpmsC+1SYU7IPz9gSv8BXgHShMKcCdgvLnKvU7QC7J8F0hpAJuYmS7xIM8TLgJquKNJmUdI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498763; c=relaxed/simple; bh=F+0cjrxWFdeA+UrB7NDtHsNVvvqpAO1Aix0Nfp1dlfU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SzUW8s3itlshtFtFFO2xmTJ2BVO2hBqk2rDvBAPRWmcq+FEhaAk2BQuE7UTUwbE7/eLzNxkunKmjNcvPYw9q4DKob+OHHM3sHYZgSyuHGsAVJRVbt3hV1fQ9vcAxU9xGzfzwQfx98GPo1Cxsd5dSy550fGKIiOtZxUh9J/QLfAc= 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=OL+GYEo+; 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="OL+GYEo+" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e25f5ed85so17181365e9.3 for ; Fri, 03 Oct 2025 06:39:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498757; x=1760103557; 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=RQ6Qb9wj3BQ6hl/5CAj5rOPQ6CxI9L5MDgZi8E/svdg=; b=OL+GYEo+ZFqdZpyY2RWOvdiu3mt+UWRzOIzDk7Wj/RUtpnGHMIdoH0u6JxQ+41ymto 2UWHROtZvt6LcMyS+mwuKovUVgCWwa1QKLXUzths3oWS0vc/gjI7QqBEiwR3uU1ROq7J 41wilnDTV2vwj3Qa78ppFwVxTVMl6kmJsZtBMjSwaneq6RbsWSHmVijT5QNh9xqRMfqT U7/0tMj0aQdl+qcI25jBZaCM0x+GuwzLqBZ7lRcKyFkE03k7zRy4bJzilRtvDX/tUT7J IRAzOOBulRSk+DhWIRj6HBbqfrwUVGLy2dW1gHb9BatrnKNNnbk5e7kVytHmL3UZgI6i 4ztQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498757; x=1760103557; 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=RQ6Qb9wj3BQ6hl/5CAj5rOPQ6CxI9L5MDgZi8E/svdg=; b=nglrqPiFbLuRzD5+hLgVI/E9q3NBD5WiCuwpxNCRSrn06qPYwksJmcZ9O+5OZWXUqt H9oNDlh0/kk0ewlq+W5ryiNyzR9Y8ZkLdaGgKNlQC69hBz01sANZHhpkOmKz/od0JXPE nSu+eUOVUzzEDspKLEgC7x6IZnP2+xSXyM7pMxU7UOadwastAIok2FykrH4spO7pVTGy TyYgvF1el8fg0nTz+xIz4vrA3UN3zT93V5NV/fTJw/9gxRCOMcQzZRAcPZBA1gzZUF3/ jlicJc0+7LTXIJJ1lBOi45D0lt904QKrjmLCz0zKdTLr8hcP6vt9K5jmcooNEcdH+Kg7 AbNQ== X-Forwarded-Encrypted: i=1; AJvYcCWHFHnmkgKPMPdbkm3pm2MUG8umk4y8ja1rdlBHX56SIDHhhdbzg8Mu4uttmV8K2D3pyI+EiGOwpbmKR98=@vger.kernel.org X-Gm-Message-State: AOJu0YyYunCvZ7k7y0OZ1uEjY6Z07SloWM/XawBAL4+MDzOj6LX5la/e 03ggvLWIjdP+1vjD4cVw0B1MnAMxLvp79q6ZkCs7FE6TWgllXyUbitXjdIIQuIi0P+K4EgOXVos WOQszGfrNc5zVEyvi/bIroA== X-Google-Smtp-Source: AGHT+IGsl5FnF7HkLitsp8rwH907TghuzS3HhWu90DM6qRMXoLyGeXaVam0onlElR+MiPphNI6wwWN6X+pllVfED X-Received: from wmht10.prod.google.com ([2002:a05:600c:41ca:b0:46e:34af:fbab]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3551:b0:46d:27b7:e7ff with SMTP id 5b1f17b1804b1-46e7115c811mr23866335e9.36.1759498756792; Fri, 03 Oct 2025 06:39:16 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:18 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-22-vdonnefort@google.com> Subject: [PATCH v7 21/28] KVM: arm64: Add tracing capability for the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running with protected mode, the host has very little knowledge about what is happening in the hypervisor. Of course this is an essential feature for security but nonetheless, that piece of code growing with more responsibilities, we need now a way to debug and profile it. Tracefs by its reliability, versatility and support for user-space is the perfect tool. There's no way the hypervisor could log events directly into the host tracefs ring-buffers. So instead let's use our own, where the hypervisor is the writer and the host the reader. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index bec227f9500a..437ac948d136 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -87,6 +87,10 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load, __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put, __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid, + __KVM_HOST_SMCCC_FUNC___pkvm_load_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm= /kvm_hyptrace.h new file mode 100644 index 000000000000..9c30a479bc36 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hyptrace.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_HYPTRACE_H_ +#define __ARM64_KVM_HYPTRACE_H_ + +#include + +struct hyp_trace_desc { + unsigned long bpages_backing_start; + size_t bpages_backing_size; + struct trace_buffer_desc trace_buffer_desc; + +}; +#endif diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 713248f240e0..06e948d066ac 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -82,4 +82,11 @@ config PTDUMP_STAGE2_DEBUGFS =20 If in doubt, say N. =20 +config PKVM_TRACING + bool + depends on KVM + depends on TRACING + select SIMPLE_RING_BUFFER + default y + endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h new file mode 100644 index 000000000000..996e90c0974f --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __ARM64_KVM_HYP_NVHE_TRACE_H +#define __ARM64_KVM_HYP_NVHE_TRACE_H +#include + +#ifdef CONFIG_PKVM_TRACING +void *tracing_reserve_entry(unsigned long length); +void tracing_commit_entry(void); + +int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); +void __pkvm_unload_tracing(void); +int __pkvm_enable_tracing(bool enable); +int __pkvm_swap_reader_tracing(unsigned int cpu); +#else +static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } +static inline void tracing_commit_entry(void) { } + +static inline int __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } +static inline void __pkvm_unload_tracing(void) { } +static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } +static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } +#endif +#endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index 607357e36026..e640f12808f7 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -28,7 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o +hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o hyp-obj-y +=3D $(lib-objs) =20 ## diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 3206b2c07f82..02b2fdd9a8e4 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -18,6 +18,7 @@ #include #include #include +#include #include =20 DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); @@ -573,6 +574,35 @@ static void handle___pkvm_teardown_vm(struct kvm_cpu_c= ontext *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_teardown_vm(handle); } =20 +static void handle___pkvm_load_tracing(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); + DECLARE_REG(size_t, desc_size, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) =3D __pkvm_load_tracing(desc_hva, desc_size); +} + +static void handle___pkvm_unload_tracing(struct kvm_cpu_context *host_ctxt) +{ + __pkvm_unload_tracing(); + + cpu_reg(host_ctxt, 1) =3D 0; +} + +static void handle___pkvm_enable_tracing(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(bool, enable, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_enable_tracing(enable); +} + +static void handle___pkvm_swap_reader_tracing(struct kvm_cpu_context *host= _ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_swap_reader_tracing(cpu); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -612,6 +642,10 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_vcpu_load), HANDLE_FUNC(__pkvm_vcpu_put), HANDLE_FUNC(__pkvm_tlb_flush_vmid), + HANDLE_FUNC(__pkvm_load_tracing), + HANDLE_FUNC(__pkvm_unload_tracing), + HANDLE_FUNC(__pkvm_enable_tracing), + HANDLE_FUNC(__pkvm_swap_reader_tracing), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c new file mode 100644 index 000000000000..def5cbc75722 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -0,0 +1,257 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +static DEFINE_PER_CPU(struct simple_rb_per_cpu, __simple_rbs); + +static struct hyp_trace_buffer { + struct simple_rb_per_cpu __percpu *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; + unsigned int cpu; + + desc_end =3D (void *)desc + desc_size; /* __pkvm_host_donate_hyp validate= s desc_size */ + + bpages_end =3D (void *)desc->bpages_backing_start + desc->bpages_backing_= size; + if (bpages_end < (void *)desc->bpages_backing_start) + return false; + + for_each_ring_buffer_desc(rb_desc, cpu, &desc->trace_buffer_desc) { + /* Can we read nr_page_va? */ + if ((void *)rb_desc + struct_size(rb_desc, page_va, 0) > desc_end) + return false; + + /* Overflow desc? */ + if ((void *)rb_desc + struct_size(rb_desc, page_va, rb_desc->nr_page_va)= > desc_end) + return false; + + /* Overflow bpages backing memory? */ + if ((void *)(bpages + rb_desc->nr_page_va) > bpages_end) + return false; + + if (cpu >=3D hyp_nr_cpus) + return false; + + if (cpu !=3D rb_desc->cpu) + return false; + + bpages +=3D rb_desc->nr_page_va; + } + + return true; +} + +int __pkvm_load_tracing(unsigned long desc_hva, size_t desc_size) +{ + struct hyp_trace_desc *desc =3D (struct hyp_trace_desc *)kern_hyp_va(desc= _hva); + int ret; + + if (!desc_size || !PAGE_ALIGNED(desc_hva) || !PAGE_ALIGNED(desc_size)) + return -EINVAL; + + ret =3D __pkvm_host_donate_hyp(hyp_virt_to_pfn((void *)desc), + desc_size >> PAGE_SHIFT); + if (ret) + return ret; + + if (!hyp_trace_desc_validate(desc, desc_size)) + goto err_donate_desc; + + hyp_spin_lock(&trace_buffer.lock); + + ret =3D hyp_trace_buffer_load(&trace_buffer, desc); + + hyp_spin_unlock(&trace_buffer.lock); + +err_donate_desc: + WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn((void *)desc), + desc_size >> PAGE_SHIFT)); + return ret; +} + +void __pkvm_unload_tracing(void) +{ + hyp_spin_lock(&trace_buffer.lock); + hyp_trace_buffer_unload(&trace_buffer); + hyp_spin_unlock(&trace_buffer.lock); +} + +int __pkvm_enable_tracing(bool enable) +{ + int cpu, ret =3D enable ? -EINVAL : 0; + + hyp_spin_lock(&trace_buffer.lock); + + if (!hyp_trace_buffer_loaded(&trace_buffer)) + goto unlock; + + for (cpu =3D 0; cpu < hyp_nr_cpus; cpu++) + simple_ring_buffer_enable_tracing(per_cpu_ptr(trace_buffer.simple_rbs, c= pu), + enable); + + ret =3D 0; + +unlock: + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} + +int __pkvm_swap_reader_tracing(unsigned int cpu) +{ + int ret; + + if (cpu >=3D hyp_nr_cpus) + return -EINVAL; + + hyp_spin_lock(&trace_buffer.lock); + + if (hyp_trace_buffer_loaded(&trace_buffer)) + ret =3D simple_ring_buffer_swap_reader_page( + per_cpu_ptr(trace_buffer.simple_rbs, cpu)); + else + ret =3D -ENODEV; + + hyp_spin_unlock(&trace_buffer.lock); + + return ret; +} --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D737D262D0B for ; Fri, 3 Oct 2025 13:39:19 +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=1759498763; cv=none; b=dWNvpgYZdt7NRT4JSg6nR1q/WpA6LweeF4oszlLO//E7jqgXtHEySfriILRcA/Sp06/P1gcSoQiT/UCw9NTue2XSYCa9A8BQI+WLy3+XdNzC8CzNE7uLsPZGyfI6vRfBO71FiNCCMO5tSrA7g1WnslLsFMLY4rKeL1N9TBjNgsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498763; c=relaxed/simple; bh=lkXzBnOUkrdXIFOR6kM3+TKkbc/NIZVvnmgUub2mmmo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=E4qY1tdwKj4khPO35JPPJVITjlRmjlC7egxznFJhErHGdwhDAPNH1w2mY7v3dbEBbhkf2/ISbmWCyKiccKfstTgKMbp2XNzb8DpUEFF8D+CWdBgAIF8QGRgidcMJUKYfCBQhek/XKf3/WC29P6LWttwo4Ir6O99rz0AduVdny24= 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=V0g1oAEi; 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="V0g1oAEi" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3f44000639fso1382810f8f.0 for ; Fri, 03 Oct 2025 06:39:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498758; x=1760103558; 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=VEPCpb8Giw3QEglYCiqJrzwrdbMptmLdZZNuUdhqXc8=; b=V0g1oAEip3cwIRVdo812qQArs4N3lQ+zHylOnVYZjZHHWnCxw26cwECdeoM81qtOsp 8Ha8XhxxF2fYyB1530lOoFTA5v4o92pjxE5grsh/GjTvdWNFCmdHS5X5vx6qrvKRFnBE DTxng2S0+wOT+eP47qhap+DlwKnjZqDxnWA+C1CQ3KzyHfHs7aKqBxfmHWZ5zLmGLeUo e7FNz1+yBd0ODWyppR/sg0I97i7Dy5PVw3Dh3ZKocJC3K0TQMfIx7YXAtDMWDv6RrpiS lWpU54fxNK3PzjSEzojTwzAy+Jo5BD6FWgympulsYy9Ali0ZwshuK+zYhNqKeukv3fai QN7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498758; x=1760103558; 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=VEPCpb8Giw3QEglYCiqJrzwrdbMptmLdZZNuUdhqXc8=; b=GuUG5C43I8Q3xXe3HGleb2uCfkvSF4TPF/qZk9lntdUJ5rIounJSGzu7Nvid5iIjzq gOLSjjqt0AIfA9zMAZGJBpz2Va8eGYzXTaCniFxjQEW/sQyWLV4H6HIBVYCD3GPBTG2G xLduawBFIpGThVGUha+l83blIXuorvgf1WGEA1UsbMoJhqfKSwcSt1ZVu/n5ts+RsIT9 vmN71GbNaBd7iBPjFLTxoRcFuNfpWQWrJoSy4SvZBHjrBMTN9ewTxrjeT2CHe+mfslrW naiNFJ3rqLZ8uQFRcmS8rP8wDktQxAfMq6Lb31Os/s08FeWi+BobRhh3iggR19RjlXyN QDUQ== X-Forwarded-Encrypted: i=1; AJvYcCWwBHpcuLzY94XdBK22/C8r3fMlpS3BSVGeANU77waOJJvle+v7rQzS8n4xrzYt7RV2tdeIXJVgCKig9/A=@vger.kernel.org X-Gm-Message-State: AOJu0Yzr9PyEfcfkOxiVAR3jN3QkNG9HbE4gklhmhmlpWZ/g6SiflpEf lbrAJNIIyiE+gsaw8WNKBI1OOPixVpXi6PwCV8zLc90OafYoKc3xr53JKyQ3QpkBhxDCFHlJSDf uTqwLh9Z9n8lpM++shFjWkg== X-Google-Smtp-Source: AGHT+IH2ZUVDed8aIvlGUAf3SXC9zH0qA3IVeZ37S9l0gnG6K29TPAI6jFJ6sbS7IkwNs6IVpWEVC3ah6nrrqV/u X-Received: from wmwm24.prod.google.com ([2002:a05:600d:6358:b0:45f:2437:5546]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:348a:b0:46e:432f:32ab with SMTP id 5b1f17b1804b1-46e7115cbc4mr19708035e9.33.1759498757632; Fri, 03 Oct 2025 06:39:17 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:19 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-23-vdonnefort@google.com> Subject: [PATCH v7 22/28] KVM: arm64: Add trace remote for the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When running with KVM protected mode, the hypervisor is able to generate events into tracefs compatible ring-buffers. Create a trace remote so the kernel can read those buffers. This currently doesn't provide any event support which will come later. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 06e948d066ac..e06358aaf1af 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -86,6 +86,7 @@ config PKVM_TRACING bool depends on KVM depends on TRACING + select TRACE_REMOTE select SIMPLE_RING_BUFFER default y =20 diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 3ebc0570345c..2c184e3abd8e 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -30,6 +30,8 @@ kvm-$(CONFIG_HW_PERF_EVENTS) +=3D pmu-emul.o pmu.o kvm-$(CONFIG_ARM64_PTR_AUTH) +=3D pauth.o kvm-$(CONFIG_PTDUMP_STAGE2_DEBUGFS) +=3D ptdump.o =20 +kvm-$(CONFIG_PKVM_TRACING) +=3D hyp_trace.o + always-y :=3D hyp_constants.h hyp-constants.s =20 define rule_gen_hyp_constants diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index bd6b6a620a09..6ae3c822b199 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 @@ -2332,6 +2333,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..98051c3fb0c2 --- /dev/null +++ b/arch/arm64/kvm/hyp_trace.c @@ -0,0 +1,210 @@ +// 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 */ +static struct hyp_trace_buffer { + struct hyp_trace_desc *desc; + size_t desc_size; +} trace_buffer; + +static int hyp_trace_buffer_alloc_bpages_backing(struct hyp_trace_buffer *= trace_buffer, size_t size) +{ + int nr_bpages =3D (PAGE_ALIGN(size) / PAGE_SIZE) + 1; + size_t backing_size; + void *start; + + backing_size =3D PAGE_ALIGN(sizeof(struct simple_buffer_page) * nr_bpages= * + num_possible_cpus()); + + start =3D alloc_pages_exact(backing_size, GFP_KERNEL_ACCOUNT); + if (!start) + return -ENOMEM; + + trace_buffer->desc->bpages_backing_start =3D (unsigned long)start; + trace_buffer->desc->bpages_backing_size =3D backing_size; + + return 0; +} + +static void hyp_trace_buffer_free_bpages_backing(struct hyp_trace_buffer *= trace_buffer) +{ + free_pages_exact((void *)trace_buffer->desc->bpages_backing_start, + trace_buffer->desc->bpages_backing_size); +} + +static int __load_page(unsigned long va) +{ + return kvm_call_hyp_nvhe(__pkvm_host_share_hyp, virt_to_pfn((void *)va), = 1); +} + +static void __unload_page(unsigned long va) +{ + WARN_ON(kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, virt_to_pfn((void *)va= ), 1)); +} + +static void hyp_trace_buffer_unload_pages(struct hyp_trace_buffer *trace_b= uffer, int last_cpu) +{ + struct ring_buffer_desc *rb_desc; + int cpu, p; + + for_each_ring_buffer_desc(rb_desc, cpu, &trace_buffer->desc->trace_buffer= _desc) { + if (cpu > last_cpu) + break; + + __unload_page(rb_desc->meta_va); + for (p =3D 0; p < rb_desc->nr_page_va; p++) + __unload_page(rb_desc->page_va[p]); + } +} + +static int hyp_trace_buffer_load_pages(struct hyp_trace_buffer *trace_buff= er) +{ + struct ring_buffer_desc *rb_desc; + int cpu, p, ret =3D 0; + + for_each_ring_buffer_desc(rb_desc, cpu, &trace_buffer->desc->trace_buffer= _desc) { + ret =3D __load_page(rb_desc->meta_va); + if (ret) + break; + + for (p =3D 0; p < rb_desc->nr_page_va; p++) { + ret =3D __load_page(rb_desc->page_va[p]); + if (ret) + break; + } + + if (ret) { + for (p--; p >=3D 0; p--) + __unload_page(rb_desc->page_va[p]); + break; + } + } + + if (ret) + hyp_trace_buffer_unload_pages(trace_buffer, cpu--); + + return ret; +} + +static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *= priv) +{ + struct hyp_trace_buffer *trace_buffer =3D priv; + struct hyp_trace_desc *desc; + size_t desc_size; + int ret; + + if (WARN_ON(trace_buffer->desc)) + return ERR_PTR(-EINVAL); + + desc_size =3D trace_buffer_desc_size(size, num_possible_cpus()); + if (desc_size =3D=3D SIZE_MAX) + return ERR_PTR(-E2BIG); + + /* + * The hypervisor will unmap the descriptor from the host to protect the = reading. Page + * granularity for the allocation ensures no other useful data will be un= mapped. + */ + desc_size =3D PAGE_ALIGN(desc_size); + desc =3D (struct hyp_trace_desc *)alloc_pages_exact(desc_size, GFP_KERNEL= ); + if (!desc) + return ERR_PTR(-ENOMEM); + + trace_buffer->desc =3D desc; + + ret =3D hyp_trace_buffer_alloc_bpages_backing(trace_buffer, size); + if (ret) + goto err_free_desc; + + ret =3D trace_remote_alloc_buffer(&desc->trace_buffer_desc, desc_size, si= ze, + cpu_possible_mask); + if (ret) + goto err_free_backing; + + ret =3D hyp_trace_buffer_load_pages(trace_buffer); + if (ret) + goto err_free_buffer; + + ret =3D kvm_call_hyp_nvhe(__pkvm_load_tracing, (unsigned long)desc, desc_= size); + if (ret) + goto err_unload_pages; + + return &desc->trace_buffer_desc; + +err_unload_pages: + hyp_trace_buffer_unload_pages(trace_buffer, INT_MAX); + +err_free_buffer: + trace_remote_free_buffer(&desc->trace_buffer_desc); + +err_free_backing: + hyp_trace_buffer_free_bpages_backing(trace_buffer); + +err_free_desc: + free_pages_exact(desc, desc_size); + trace_buffer->desc =3D NULL; + + return ERR_PTR(ret); +} + +static void hyp_trace_unload(struct trace_buffer_desc *desc, void *priv) +{ + struct hyp_trace_buffer *trace_buffer =3D priv; + + if (WARN_ON(desc !=3D &trace_buffer->desc->trace_buffer_desc)) + return; + + kvm_call_hyp_nvhe(__pkvm_unload_tracing); + hyp_trace_buffer_unload_pages(trace_buffer, INT_MAX); + trace_remote_free_buffer(desc); + hyp_trace_buffer_free_bpages_backing(trace_buffer); + free_pages_exact(trace_buffer->desc, trace_buffer->desc_size); + trace_buffer->desc =3D NULL; +} + +static int hyp_trace_enable_tracing(bool enable, void *priv) +{ + return kvm_call_hyp_nvhe(__pkvm_enable_tracing, enable); +} + +static int hyp_trace_swap_reader_page(unsigned int cpu, void *priv) +{ + return kvm_call_hyp_nvhe(__pkvm_swap_reader_tracing, cpu); +} + +static int hyp_trace_reset(unsigned int cpu, void *priv) +{ + return 0; +} + +static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) +{ + return 0; +} + +static struct trace_remote_callbacks trace_remote_callbacks =3D { + .load_trace_buffer =3D hyp_trace_load, + .unload_trace_buffer =3D hyp_trace_unload, + .enable_tracing =3D hyp_trace_enable_tracing, + .swap_reader_page =3D hyp_trace_swap_reader_page, + .reset =3D hyp_trace_reset, + .enable_event =3D hyp_trace_enable_event, +}; + +int hyp_trace_init(void) +{ + if (!is_protected_kvm_enabled()) + return 0; + + return trace_remote_register("hypervisor", &trace_remote_callbacks, &trac= e_buffer, NULL, 0); +} diff --git a/arch/arm64/kvm/hyp_trace.h b/arch/arm64/kvm/hyp_trace.h new file mode 100644 index 000000000000..54d8b1f44ca5 --- /dev/null +++ b/arch/arm64/kvm/hyp_trace.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ARM64_KVM_HYP_TRACE_H__ +#define __ARM64_KVM_HYP_TRACE_H__ + +#ifdef CONFIG_PKVM_TRACING +int hyp_trace_init(void); +#else +static inline int hyp_trace_init(void) { return 0; } +#endif +#endif --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E2C2C218EA2 for ; Fri, 3 Oct 2025 13:39:20 +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=1759498764; cv=none; b=IuDOIiWnK+LBCLmTsde7nsitAJlk57sBnUOnUtDUYyZosFBFok0OpnQKnbjGD3DDAyzyDskU8p0vR71joOE4+7Oo1DHlQwnITjz+G7jDxyB3bbLC+o74+Qxkw1zWWE4lS4tw2UdZH9k1iNYcOBMKfhlpOcfwKHHSN5wjdap2TC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498764; c=relaxed/simple; bh=Vhxl/qaQpNnNzbGrf2Yfx58y04M5WXFsxMJnUxdT/pk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=B6AiRc1WBYA8ymM0eR65iECaN7wnWUHOZIF08q8XGa3W5XXKdjq+Z+hte0ppqEfFYI2YSRMVsE4w7b/nOzD9m11iYJQVmRI0h9Yv1IbLDlhLDzOLknWj33VZE0oiBO64tU9njauRi9NB4kT0gAaxuvIJ65JotqGmmFjWlCsbv2Y= 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=WFU28BR/; 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="WFU28BR/" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-401dbafbcfaso1446461f8f.1 for ; Fri, 03 Oct 2025 06:39:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498759; x=1760103559; 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=EvbcZ/9JwQ50AQRxhxf/g+ZmyyJKqJ3DWwQCljO0JC0=; b=WFU28BR/9eF1eWVt4frXviBUmm37JZhvST8d+Q7Gh6iwtuzsa4YuGqwo3Kf2b6Pcbl 7m04Nq/6+fBS95b0F2ZklweO+3jr/H9aQuOabMYzBn1VonKgV3PyF9x3MqXZ6UoGjMPH ZUxCDxafgyQpewMCZ708wwao7IJ0vTqc/hr5MI6aoQZ6lvfRoLms+RVJLNCdGUFeMbK/ FFJCgamWSJFLsDiaSIZu2GffLkUkTZwxSArO+JTQzE7JM98FoSlXXhNKJieUGEXZP18a wWY9KfqXCfwgQrjHg1XBE5INeJM/r2nBEh6Tmv+kahgsIleHXoBVviHSqQu/nd7pc881 YbPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498759; x=1760103559; 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=EvbcZ/9JwQ50AQRxhxf/g+ZmyyJKqJ3DWwQCljO0JC0=; b=FHLGo3mTEyhQrP7vs/PzBNwPkHkwMoPro6z9cirEcywEusakyrEc9xlDtGP2f6rdaV n9r+mFV1/WFhdoKjCnSvJwCwnNiG0T8lyRvBiXNisVeFbhxAMBz7ihh40R1ghw+k59mH Wq//KIdmyLa8xRI5YUp5AnVNPUpfKtsU09b4esYtDyeZElU5NDZQJuek+qFCYdvkl8dz BPmJ+/WKbmZgzMhbtexXuRQA4l8JySV8muoTzblI1p/ZG8RNB2cZeazEVZH2p5lzpR+F gao61Gd8oKO/dmIBfK99Uv7HmpIk8ztGSa4wfCFpm9IJ+Ibsjatxuov4NRUYRHPyvKzh 2BvA== X-Forwarded-Encrypted: i=1; AJvYcCWdv8r1t5cRmJ+E2sSNE9apvyfEbAHZpYC3zHgXURVb/mA+SFWNS36jEq+f4JVryiAr43OlkwmG+ZjiqFU=@vger.kernel.org X-Gm-Message-State: AOJu0YwaI3AF4U3Yefl2LeOC56fsm0M+cCG2NVviiGm8HKvXZp4Q6PMA xzPW41zMlMa+BaKBVzkeHx9uVZ+FqldCWAXEf5dmEaRLvr7ufSjNCcDo4Lq/WxSmvCqj1Vm10VR Opn/TmU4oSGbbhIs837v3JA== X-Google-Smtp-Source: AGHT+IHRFBl6xcKM3euFKM3qcCjqstVQ5iqgGtD/Yu1lJW5dw3vQ2ZJ2GnzE/ICAKttrTohsi5EQeP4aP9wcvJMD X-Received: from wroh18.prod.google.com ([2002:adf:f192:0:b0:3ee:12ad:455e]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2909:b0:3ee:109a:3a6f with SMTP id ffacd0b85a97d-425671c0fbamr2158648f8f.51.1759498758849; Fri, 03 Oct 2025 06:39:18 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:20 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-24-vdonnefort@google.com> Subject: [PATCH v7 23/28] KVM: arm64: Sync boot clock with the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Thomas Gleixner , Stephen Boyd , "Christopher S. Hall" , Richard Cochran Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Configure the pKVM hypervisor tracing clock with the kernel boot clock. For tracing purpose, the boot clock is interesting as it doesn't stop on suspend. However, it is corrected on a regular basis, which implies we need to re-evaluate it every once in a while. Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: Christopher S. Hall Cc: Richard Cochran Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index 437ac948d136..d122d79718a0 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -87,6 +87,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load, __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put, __KVM_HOST_SMCCC_FUNC___pkvm_tlb_flush_vmid, + __KVM_HOST_SMCCC_FUNC___pkvm_update_clock_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_load_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 996e90c0974f..4e11dcdf049b 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -7,6 +7,7 @@ void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 +void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc); int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); @@ -15,6 +16,8 @@ int __pkvm_swap_reader_tracing(unsigned int cpu); static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } =20 +static inline +void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc) { } static inline int __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 02b2fdd9a8e4..36a263422e4e 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -574,6 +574,18 @@ static void handle___pkvm_teardown_vm(struct kvm_cpu_c= ontext *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_teardown_vm(handle); } =20 +static void handle___pkvm_update_clock_tracing(struct kvm_cpu_context *hos= t_ctxt) +{ + DECLARE_REG(u32, mult, host_ctxt, 1); + DECLARE_REG(u32, shift, host_ctxt, 2); + DECLARE_REG(u64, epoch_ns, host_ctxt, 3); + DECLARE_REG(u64, epoch_cyc, host_ctxt, 4); + + __pkvm_update_clock_tracing(mult, shift, epoch_ns, epoch_cyc); + + cpu_reg(host_ctxt, 1) =3D 0; +} + static void handle___pkvm_load_tracing(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); @@ -642,6 +654,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_vcpu_load), HANDLE_FUNC(__pkvm_vcpu_put), HANDLE_FUNC(__pkvm_tlb_flush_vmid), + HANDLE_FUNC(__pkvm_update_clock_tracing), HANDLE_FUNC(__pkvm_load_tracing), HANDLE_FUNC(__pkvm_unload_tracing), HANDLE_FUNC(__pkvm_enable_tracing), diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index def5cbc75722..d146ac3046de 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -255,3 +255,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 98051c3fb0c2..4f154ec743f3 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 */ static struct hyp_trace_buffer { struct hyp_trace_desc *desc; @@ -174,6 +290,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 @@ -192,7 +310,22 @@ static int hyp_trace_enable_event(unsigned short id, b= ool enable, void *priv) return 0; } =20 +static int hyp_trace_clock_show(struct seq_file *m, void *v) +{ + seq_puts(m, "[boot]\n"); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(hyp_trace_clock); + +static int hyp_trace_init_tracefs(struct dentry *d, void *priv) +{ + return tracefs_create_file("trace_clock", 0440, d, NULL, &hyp_trace_clock= _fops) ? + 0 : -ENOMEM; +} + static struct trace_remote_callbacks trace_remote_callbacks =3D { + .init =3D hyp_trace_init_tracefs, .load_trace_buffer =3D hyp_trace_load, .unload_trace_buffer =3D hyp_trace_unload, .enable_tracing =3D hyp_trace_enable_tracing, --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9D09275860 for ; Fri, 3 Oct 2025 13:39: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=1759498766; cv=none; b=XJV0eieHdoKUi9Hz+Fh7zJl0wklgtxWPcesMPVLU4qbB+7HiPXkyDW1buzExKQ01FQELXPI+Cz7JKoQDwxXDcy8LsA3xByPPpi3P7yLtyUHOh2kablVNdvf8i1aoU9SJd5u8XMjEe232hyQpYStnl3WA9fcish+1evPoUinNdsk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498766; c=relaxed/simple; bh=YYPtZx7KhRfp3aC5CCHm1JhakHuUybZFtGRIGxxWxOM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fWSp8QZiLRKhAAw+Xgf91K2VvzoD44JpuCejBS6tPKooEgkfV9h1+74XM8e3tDRdtfHg7Sl8sVdecVOajw1XUpbC+O7ewAAD2zKKzMoPcllNCXc+7NpOFOh/FGRcHIORQcnDI3Bb3FhmFI0L4Id3Dws7Xo7byd0OLhm4/ZxH6cA= 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=lCZtq87f; 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="lCZtq87f" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e25f5ed85so17181525e9.3 for ; Fri, 03 Oct 2025 06:39:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498759; x=1760103559; 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=CKoVOt7SfjBg9tHla8UyfyracQ+ttFmAkYCdQchY/Cw=; b=lCZtq87fp7XIeA07taExq7f6LF2XAmOYipitqXFlZcKUle5n1oflrXgmbuUHd/fRi0 THf739/V1IEuKLAoBhXzDeKXRIenqw2DJm/WeirljNZySWrofzMoRms+gCebqYEvFkfU 1kbsOR2fGeohZc9cbZCnO/ryEwcpFgys7VunPaq0jnr/DFwANRmZV1Ie61NTE0r/ghgP tgZ+3TQHC489eMFFNqFNAkPmsf0vDU6Cdv3MVOqSfs8ARzTBTF7RBS5kFKCFcm1dzD5Y kjBP5NvBvOR4IM3Bhg5FiPXGdzaQB3YLzNEB6EI4mSLLYfCUtASbTW84jbjZpUuEjaKW 2/7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498759; x=1760103559; 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=CKoVOt7SfjBg9tHla8UyfyracQ+ttFmAkYCdQchY/Cw=; b=AtXdjWCzHnpUbDcV1bhtEZXpRMQ7535W+isTzjqFE+momXVQVodb7KSX+/T4OLjHLQ Z1u9u7glmV3ywHEuL1HIjIKk93bkQJ2lIDBJTR7m131vqhEvmKZCYKTXyI5Drr9kuQGO UT8KLnM/5RetXXDBhwRH3xZTt58vhjOdEc0a6HFjlr78EHpJPoipzEwkFUEdb9FHKnCV hAcg+RUyY6zpHerFCjCcvuN97NV9B4/Hahv+f5Ra2g9LxpOsmdPOvZGiMr7qLg6qpplr 2rFBDMY5exw7b8Q7x5DKL8uYz12vcQA+0t07Sen/5Pvg5Jat1W/cEkXBqPNm04V1lmFk YH5g== X-Forwarded-Encrypted: i=1; AJvYcCVRwznx/TSmUJS1Icz+mFc5BqPIs7QHZd97w84DtGtbbX8Lgz9t2DtitsufGiPlh12v576tXTMzeDmtEW8=@vger.kernel.org X-Gm-Message-State: AOJu0YyFjdgjPMe3c2rCEmAkT2LksVnbSwr60IgzNPKq8UvH/FmDXN/s DwpKN6o14h9D8d6jffJsjmuViUUUVjjCyTwqo7DIs2ly8dKFfJzuj/Y0KmqstUq8pqiTje/xxqq KOJvWVhYXRp0s7H2WLtdBqA== X-Google-Smtp-Source: AGHT+IF3XrIOuZLzr95zLbd7FnCvuwGAUE/NKipTgwAL9Vm4NhQ+xCaEbNPY72ptqM5YQLLSLemYx+UklOwNUX8Q X-Received: from wmoe6.prod.google.com ([2002:a05:600c:4486:b0:46e:67c8:72a6]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3551:b0:46d:27b7:e7ff with SMTP id 5b1f17b1804b1-46e7115c811mr23867565e9.36.1759498759672; Fri, 03 Oct 2025 06:39:19 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:21 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-25-vdonnefort@google.com> Subject: [PATCH v7 24/28] KVM: arm64: Add trace reset to the pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Let the hypervisor reset the trace buffer when triggered from the tracefs file remotes/hypervisor/trace. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index d122d79718a0..c40820a4b049 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -91,6 +91,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_load_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_unload_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, }; =20 diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 4e11dcdf049b..0d2732f0d406 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -11,6 +11,7 @@ void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64= epoch_ns, u64 epoch_cy int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); +int __pkvm_reset_tracing(unsigned int cpu); int __pkvm_swap_reader_tracing(unsigned int cpu); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } @@ -21,6 +22,7 @@ void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64= epoch_ns, u64 epoch_cy static inline int __pkvm_load_tracing(unsigned long desc_va, size_t desc_s= ize) { return -ENODEV; } static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } +static inline int __pkvm_reset_tracing(unsigned int cpu) { return -ENODEV;= } static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 36a263422e4e..a7c5e9fc27a0 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -608,6 +608,13 @@ static void handle___pkvm_enable_tracing(struct kvm_cp= u_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_enable_tracing(enable); } =20 +static void handle___pkvm_reset_tracing(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned int, cpu, host_ctxt, 1); + + cpu_reg(host_ctxt, 1) =3D __pkvm_reset_tracing(cpu); +} + static void handle___pkvm_swap_reader_tracing(struct kvm_cpu_context *host= _ctxt) { DECLARE_REG(unsigned int, cpu, host_ctxt, 1); @@ -658,6 +665,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_load_tracing), HANDLE_FUNC(__pkvm_unload_tracing), HANDLE_FUNC(__pkvm_enable_tracing), + HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), }; =20 diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index d146ac3046de..1fd9b32950fe 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -236,6 +236,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 4f154ec743f3..1062b4310f8c 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -302,7 +302,7 @@ static int hyp_trace_swap_reader_page(unsigned int cpu,= void *priv) =20 static int hyp_trace_reset(unsigned int cpu, void *priv) { - return 0; + return kvm_call_hyp_nvhe(__pkvm_reset_tracing, cpu); } =20 static int hyp_trace_enable_event(unsigned short id, bool enable, void *pr= iv) --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F3E09202961 for ; Fri, 3 Oct 2025 13:39:21 +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=1759498766; cv=none; b=P4GMUSCDvI8Jhxe7trs/yd7Ofzt1CvML/55UWW1VpWHL/6uewe7GLCYPoQ1VyJXtH6rBd5p4kuZJjc0HOfvG4Q+LbyOXH8tJPbpyU+6A62ibDQbQJDJHzv8Er/gMtsaU2QyT8PuxnlA40Q16MQ7ptMDbo2QU7g2Y/tvYwrd3HcI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498766; c=relaxed/simple; bh=l6PMwVLOHepg5l9uIxnW/ICyzU/c1ZpmTcLy250cgHA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LhyBF58dN7jCz4ygH5WCsENT0wVejbC7hNu3Nk9l/DGoJT+Xyrq6qzBM7HfeuknEZmmEatcpLAsQLu1QjaO+DBBUMsDgV94mTjfIx4unpABc12UYwxiMOkz56vAN0QmKo2Cbp+DM/cKuaamG28UmqnjTQf4cdnA++lu3zbLqZ5o= 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=lDAdtod8; 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="lDAdtod8" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3efa77de998so1575262f8f.0 for ; Fri, 03 Oct 2025 06:39:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498760; x=1760103560; 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=NBH7mX8hqUWuMd8ft0BAB55Akh3ZIkAjzkYag/eDdtI=; b=lDAdtod8aXitS5bkGCZImqP8pUH2q/0wQsGTSVGVOXVewXFbIrAohjMSmU/DQpZguv TrdoOQGDJAVqFECn4bFUfclZGtWYu1gygeyUViMe1rWo+QXD3ONo7m+3KHmkBBsyvExe pidV//SZ20JMLDc0MIcyGNfSwli1WV+pBUTHaZLOMWxMjZisiyMGg+Y0+eC/TXk2WzZX nH4A4rZtL+LZ4XiIf5ubn3k+RodlWC+Au+A62IbqQ9RD96kIv88gT9CQ0Pxz41CjDV9o g47KDoNBhAbj2EEA/dBGrUNLIe4gwsfP/asIdlzmSFUknJbhlHvrukDTK12IYmDTuBqH QSkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498760; x=1760103560; 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=NBH7mX8hqUWuMd8ft0BAB55Akh3ZIkAjzkYag/eDdtI=; b=VdjYYdPQYINJywNGG16zoX51XFCifvg5lA4QxyXoa84Xemd/dD1BQEUcgt2qhpSPak AinGTFq1R+HOdoDupeoAJM+jnq+3yCeCIdNNMwD4G/o4k0bWK724CQvfaZ/ZCuf95wR1 PLRNje4ysXMbKWno62OJ0MNSN3dJngv4+5X/zNXcFWAODHyn4dzTIPFTZn6HhTqbLAym c70UKTMFgMHmt3KLT+JomHYdR4SyZI1M2GzZlpOZaM3jqaVo59pf5AoxrIWw3VUoU3s1 xu5hSIIKX7mv+5SqPI7K2pFbDqmcakz3WEfB1p6MypgW+3zJXMA2/vGC+17eu1Dd2S0g 5ncw== X-Forwarded-Encrypted: i=1; AJvYcCVDP+ucxkFRUh9irfVpCojVexuxiwIqkZi9l7ZGA9A+q9SnWPg4hhaa95N8X2oRq4HdoldEihshfTMuhBs=@vger.kernel.org X-Gm-Message-State: AOJu0YxW4p6LX9Prp+lE+Ca1Neuz9PbhSAK4UwkVqaGFOJvZ9VLhgsEg pr1GCatNcRLksDri9ZRcsdhXTclrpmOok+EWxntAXqVyFD78QE/V7YDsydkrvfvPResQo7v4b25 lfv8MKL8YBj8BPwi2NPquJg== X-Google-Smtp-Source: AGHT+IH/PJgRLPULsUjcfYURSxxv3/VeyYFrYwGc8MO8Sqvzd3hkzkzqfAS/t0Jovus1S0w8fOfR71dCwBB56+qE X-Received: from wmoo17.prod.google.com ([2002:a05:600d:111:b0:46e:54f3:6f51]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:25ef:b0:3ee:1563:a78b with SMTP id ffacd0b85a97d-4256714be13mr2090567f8f.20.1759498760357; Fri, 03 Oct 2025 06:39:20 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:22 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-26-vdonnefort@google.com> Subject: [PATCH v7 25/28] KVM: arm64: Add event support to the pKVM hyp and trace remote From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the creation of hypervisor and trace remote events with a single macro HYP_EVENT(). That macro expands in the kernel side to add all the required declarations (based on REMOTE_EVENT()) as well as in the hypervisor side to create the trace_() function. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index c40820a4b049..79019e11f529 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -93,6 +93,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_enable_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, + __KVM_HOST_SMCCC_FUNC___pkvm_enable_event, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_define_hypevents.h b/arch/arm64/inc= lude/asm/kvm_define_hypevents.h new file mode 100644 index 000000000000..0ef5a9eefcbe --- /dev/null +++ b/arch/arm64/include/asm/kvm_define_hypevents.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef HYP_EVENT_FILE +# undef __ARM64_KVM_HYPEVENTS_H_ +# define REMOTE_EVENT_INCLUDE_FILE arch/arm64/include/asm/kvm_hypevents.h +#else +# define REMOTE_EVENT_INCLUDE_FILE HYP_EVENT_FILE +#endif + +#define REMOTE_EVENT_SECTION "_hyp_events" + +#define HE_STRUCT(__args) __args +#define HE_PRINTK(__args...) __args +#define he_field re_field + +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + REMOTE_EVENT(__name, 0, RE_STRUCT(__struct), RE_PRINTK(__printk)) + +#define HYP_EVENT_MULTI_READ + +#include diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h new file mode 100644 index 000000000000..d6e033c96c52 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if !defined(__ARM64_KVM_HYPEVENTS_H_) || defined(HYP_EVENT_MULTI_READ) +#define __ARM64_KVM_HYPEVENTS_H_ + +#ifdef __KVM_NVHE_HYPERVISOR__ +#include +#endif + +#endif diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm= /kvm_hyptrace.h index 9c30a479bc36..d6e0953a07d6 100644 --- a/arch/arm64/include/asm/kvm_hyptrace.h +++ b/arch/arm64/include/asm/kvm_hyptrace.h @@ -10,4 +10,17 @@ struct hyp_trace_desc { struct trace_buffer_desc trace_buffer_desc; =20 }; + +struct hyp_event_id { + unsigned short id; + void *data; +}; + +extern struct remote_event __hyp_events_start[]; +extern struct remote_event __hyp_events_end[]; + +/* hyp_event section used by the hypervisor */ +extern struct hyp_event_id __hyp_event_ids_start[]; +extern struct hyp_event_id __hyp_event_ids_end[]; + #endif diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 714b0b5ec5ac..c1dbf0d317db 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -134,6 +134,10 @@ KVM_NVHE_ALIAS(__hyp_data_start); KVM_NVHE_ALIAS(__hyp_data_end); KVM_NVHE_ALIAS(__hyp_rodata_start); KVM_NVHE_ALIAS(__hyp_rodata_end); +#ifdef CONFIG_PKVM_TRACING +KVM_NVHE_ALIAS(__hyp_event_ids_start); +KVM_NVHE_ALIAS(__hyp_event_ids_end); +#endif =20 /* pKVM static key */ KVM_NVHE_ALIAS(kvm_protected_mode_initialized); diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.ld= s.S index ad6133b89e7a..0e201a3c8de5 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -13,12 +13,23 @@ *(__kvm_ex_table) \ __stop___kvm_ex_table =3D .; =20 +#ifdef CONFIG_PKVM_TRACING +#define HYPERVISOR_EVENT_IDS \ + . =3D ALIGN(PAGE_SIZE); \ + __hyp_event_ids_start =3D .; \ + *(HYP_SECTION_NAME(.event_ids)) \ + __hyp_event_ids_end =3D .; +#else +#define HYPERVISOR_EVENT_IDS +#endif + #define HYPERVISOR_RODATA_SECTIONS \ HYP_SECTION_NAME(.rodata) : { \ . =3D ALIGN(PAGE_SIZE); \ __hyp_rodata_start =3D .; \ *(HYP_SECTION_NAME(.data..ro_after_init)) \ *(HYP_SECTION_NAME(.rodata)) \ + HYPERVISOR_EVENT_IDS \ . =3D ALIGN(PAGE_SIZE); \ __hyp_rodata_end =3D .; \ } @@ -307,6 +318,13 @@ SECTIONS =20 HYPERVISOR_DATA_SECTION =20 +#ifdef CONFIG_PKVM_TRACING + .data.hyp_events : { + __hyp_events_start =3D .; + *(SORT(_hyp_events.*)) + __hyp_events_end =3D .; + } +#endif /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback diff --git a/arch/arm64/kvm/hyp/include/nvhe/define_events.h b/arch/arm64/k= vm/hyp/include/nvhe/define_events.h new file mode 100644 index 000000000000..2298b49cb355 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef HYP_EVENT_FILE +# define __HYP_EVENT_FILE +#else +# define __HYP_EVENT_FILE __stringify(HYP_EVENT_FILE) +#endif + +#undef HYP_EVENT +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + atomic_t __ro_after_init __name##_enabled =3D ATOMIC_INIT(0); \ + struct hyp_event_id hyp_event_id_##__name \ + __section(".hyp.event_ids."#__name) =3D { \ + .data =3D (void *)&__name##_enabled, \ + } + +#define HYP_EVENT_MULTI_READ +#include __HYP_EVENT_FILE +#undef HYP_EVENT_MULTI_READ + +#undef HYP_EVENT diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 0d2732f0d406..f7b286e92853 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -1,21 +1,52 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #ifndef __ARM64_KVM_HYP_NVHE_TRACE_H #define __ARM64_KVM_HYP_NVHE_TRACE_H + +#include + #include =20 +#define HE_PROTO(__args...) __args + #ifdef CONFIG_PKVM_TRACING void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 +#define HE_ASSIGN(__args...) __args +#define HE_STRUCT RE_STRUCT +#define he_field re_field + +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + extern atomic_t __name##_enabled; \ + extern struct hyp_event_id hyp_event_id_##__name; \ + static __always_inline void trace_##__name(__proto) \ + { \ + struct remote_event_format_##__name *__entry; \ + size_t length =3D sizeof(*__entry); \ + \ + if (!atomic_read(&__name##_enabled)) \ + return; \ + __entry =3D tracing_reserve_entry(length); \ + if (!__entry) \ + return; \ + __entry->hdr.id =3D hyp_event_id_##__name.id; \ + __assign \ + tracing_commit_entry(); \ + } + void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc); int __pkvm_load_tracing(unsigned long desc_va, size_t desc_size); void __pkvm_unload_tracing(void); int __pkvm_enable_tracing(bool enable); int __pkvm_reset_tracing(unsigned int cpu); int __pkvm_swap_reader_tracing(unsigned int cpu); +int __pkvm_enable_event(unsigned short id, bool enable); #else static inline void *tracing_reserve_entry(unsigned long length) { return N= ULL; } static inline void tracing_commit_entry(void) { } +#define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ + static inline void trace_##__name(__proto) {} =20 static inline void __pkvm_update_clock_tracing(u32 mult, u32 shift, u64 epoch_ns, u64 ep= och_cyc) { } @@ -24,5 +55,6 @@ static inline void __pkvm_unload_tracing(void) { } static inline int __pkvm_enable_tracing(bool enable) { return -ENODEV; } static inline int __pkvm_reset_tracing(unsigned int cpu) { return -ENODEV;= } static inline int __pkvm_swap_reader_tracing(unsigned int cpu) { return -E= NODEV; } +static inline int __pkvm_enable_event(unsigned short id, bool enable) { r= eturn -ENODEV; } #endif #endif diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index e640f12808f7..09bb8dfa7ca2 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -28,7 +28,7 @@ hyp-obj-y :=3D timer-sr.o sysreg-sr.o debug-sr.o switch.o= tlb.o hyp-init.o host.o hyp-obj-y +=3D ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../en= try.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o hyp-obj-$(CONFIG_LIST_HARDENED) +=3D list_debug.o -hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o +hyp-obj-$(CONFIG_PKVM_TRACING) +=3D clock.o trace.o ../../../../../kernel/= trace/simple_ring_buffer.o events.o hyp-obj-y +=3D $(lib-objs) =20 ## diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/eve= nts.c new file mode 100644 index 000000000000..5905b42cb0d0 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/events.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Google LLC + * Author: Vincent Donnefort + */ + +#include +#include + +#include + +extern struct hyp_event_id __hyp_event_ids_start[]; +extern struct hyp_event_id __hyp_event_ids_end[]; + +int __pkvm_enable_event(unsigned short id, bool enable) +{ + struct hyp_event_id *event_id =3D __hyp_event_ids_start; + atomic_t *enable_key; + + for (; (unsigned long)event_id < (unsigned long)__hyp_event_ids_end; + event_id++) { + if (event_id->id !=3D id) + continue; + + enable_key =3D (atomic_t *)event_id->data; + enable_key =3D hyp_fixmap_map(__hyp_pa(enable_key)); + + atomic_set(enable_key, enable); + + hyp_fixmap_unmap(); + + return 0; + } + + return -EINVAL; +} diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index a7c5e9fc27a0..aebed41f7de7 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -622,6 +622,14 @@ static void handle___pkvm_swap_reader_tracing(struct k= vm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_swap_reader_tracing(cpu); } =20 +static void handle___pkvm_enable_event(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(unsigned short, id, host_ctxt, 1); + DECLARE_REG(bool, enable, host_ctxt, 2); + + cpu_reg(host_ctxt, 1) =3D __pkvm_enable_event(id, enable); +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -667,6 +675,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_enable_tracing), HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), + HANDLE_FUNC(__pkvm_enable_event), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S b/arch/arm64/kvm/hyp/nvhe/hy= p.lds.S index d724f6d69302..a68411bf4bef 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp.lds.S +++ b/arch/arm64/kvm/hyp/nvhe/hyp.lds.S @@ -16,6 +16,12 @@ SECTIONS { HYP_SECTION(.text) HYP_SECTION(.data..ro_after_init) HYP_SECTION(.rodata) +#ifdef CONFIG_PKVM_TRACING + . =3D ALIGN(PAGE_SIZE); + BEGIN_HYP_SECTION(.event_ids) + *(SORT(.hyp.event_ids.*)) + END_HYP_SECTION +#endif =20 /* * .hyp..data..percpu needs to be page aligned to maintain the same diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 1062b4310f8c..73539f5b5e42 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -307,7 +307,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) @@ -334,10 +334,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); } diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c index 1bc9c9a5197f..dc6bc387ebca 100644 --- a/kernel/trace/trace_remote.c +++ b/kernel/trace/trace_remote.c @@ -1037,7 +1037,7 @@ static int remote_event_format_show(struct seq_file *= s, void *unused) while (field->name) { seq_printf(s, "\tfield:%s %s;\toffset:%zu;\tsize:%u;\tsigned:%d;\n", field->type, field->name, offset, field->size, - !field->is_signed); + field->is_signed); offset +=3D field->size; field++; } @@ -1068,7 +1068,7 @@ static int remote_event_callback(const char *name, um= ode_t *mode, void **data, =20 if (!strcmp(name, "format")) { *mode =3D TRACEFS_MODE_READ; - *fops =3D &remote_event_id_fops; + *fops =3D &remote_event_format_fops; return 1; } =20 --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 324BA1F1306 for ; Fri, 3 Oct 2025 13:39:23 +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=1759498766; cv=none; b=UUhPHaCMPYRlNVTD/AdpRuH1y5PkJDFEMUJyekQCC4KBh7h8HGuMcGDtrbYAqdol/XUiRyUVXmBYrNOXNwPH3RJ5LK7MCVew12pPueUj5fEjU/lpBjv0kiYVK3+GXhOcudW/MESqMFRT60CfidPZhIKLfkj5juz492658A15FBQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498766; c=relaxed/simple; bh=jTAlnSa7AOMdWm9cZwFdWCnXMdLuV1ot4YyzNmol8bI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=AfnK/jWGBMRKg8c4CSEKB8nnkDBUfjifT/RPSwzA9IxiV0fkVYwMYLmDrMUkft8wbh7hXdOSvCVovX6Qf1BY9k2OUeBZQ73I8z07HzDukAIe1n47K+eLWx25VCOMFm/lAqbvZGZoFSIIAuej3AFsiic0c3oGpm/z5UDTglQgUEU= 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=vj/oMjSH; 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="vj/oMjSH" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3ed9557f976so1554702f8f.3 for ; Fri, 03 Oct 2025 06:39:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498761; x=1760103561; 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=zQpWFI+mvDhlS6QzvPWKy0HH/MqUOwvvkoBBWzfvzIQ=; b=vj/oMjSHEelftMKmuq0sPB+nNpqCf88zkI02QbW01tdGtsU+4N+53kyWlXL/0rGOKS C/CUeB5gjIHBg+RFN1lfUd1znFXet3dCr+MexcKcP6xEWGKn7qi+AyVtLF9Qg5JUzita R15tA+6e4qMBvhxu0/z3L2wdOxNN88IQ0hsVR4EgSxpZWDWV01fi+0U1PGtH0v+YwOU3 Oa+a9QbxcXqdVn0N8sCp5lfi1+VkZGahQic3HQdbqgoqn115Kd+AwQjoGpHEjlW7lRm+ 6SzL5QxmtrPOtmW52D3VG1aXRCPpEB2K+x6bYqa6zdIq/dhFUXH5Sill16oHQVuNZiiX lVlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498761; x=1760103561; 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=zQpWFI+mvDhlS6QzvPWKy0HH/MqUOwvvkoBBWzfvzIQ=; b=YQTJ1DHylCWoeNTBcIxVD62TUfhucm2ghUCEIgKhHopvQq6hccWPMR7FHgN4xc/l8x vthHhK6kAqkJ/zAAPWR0aDORAWFoxGmSHHK9/R6KS/NktLH3ppBCiq6CigAMQArI6vsB h/xh11hIA3DTD2nzhRZxxXHHQdbpdtO/P6m0YeJB+CuX6fUBEQWcTEMoo2P3uAVEJdPT QSGQENva7vNyEpAxJL4qV3XtVlEG7QOCNxj6f+NdUn5Fkuqmbqby22vkQEqUKh32uNgd eC+9p+KZ3okUZBh4c8yvLuBM+zEXxUvocElACmdbuBRC8u8xq39B+EE5HgBmQ66nsK2w Gmgw== X-Forwarded-Encrypted: i=1; AJvYcCXTYyw/D8O9HDmzglAZTf1e9sBCkqcw23Tf7bbYiImsXMNs+zthidoPn04m2cwpGNdyvOZb6obxbr/AxUE=@vger.kernel.org X-Gm-Message-State: AOJu0YxKiTOUfxdH82IElqWFI/QvoBc/Q2DhMmptohlHZ3Se08zH1tMK 3l2tUZuYkIClFBGIMNIx5BFpqx6FONUFF0rCpqcCDpPNEfpQrsCdhAcviVl5foUsBYUmfnj5oPk KK2FUAJrhi3u6vbZnmJar/A== X-Google-Smtp-Source: AGHT+IG52bRYhXeAJFDgF8uvfHA2+/FCR+eKvs+CIPgd7e1dd8btx3CvmT6Gt+2L3xnnRQYWHWkcwf2OxLo8X/Rp X-Received: from wmpj2.prod.google.com ([2002:a05:600c:4882:b0:46e:684e:1977]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5885:0:b0:3ee:13b1:d70e with SMTP id ffacd0b85a97d-425671aa0b6mr2309114f8f.40.1759498761198; Fri, 03 Oct 2025 06:39:21 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:23 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-27-vdonnefort@google.com> Subject: [PATCH v7 26/28] KVM: arm64: Add hyp_enter/hyp_exit events to pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The hyp_enter and hyp_exit events are logged by the hypervisor any time it is entered and exited. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h index d6e033c96c52..ce3953bc884a 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -7,4 +7,21 @@ #include #endif =20 +HYP_EVENT(hyp_enter, + HE_PROTO(void), + HE_STRUCT( + ), + HE_ASSIGN( + ), + HE_PRINTK() +); + +HYP_EVENT(hyp_exit, + HE_PROTO(void), + HE_STRUCT( + ), + HE_ASSIGN( + ), + HE_PRINTK() +); #endif diff --git a/arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h b/arch/arm64/kvm/h= yp/include/nvhe/arm-smccc.h new file mode 100644 index 000000000000..4b69d33e4f2d --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/arm-smccc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include + +#undef arm_smccc_1_1_smc +#define arm_smccc_1_1_smc(...) \ + do { \ + trace_hyp_exit(); \ + __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__); \ + trace_hyp_enter(); \ + } while (0) diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 3369dd0c4009..e00931fd194f 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -26,10 +26,10 @@ * the duration and are therefore serialised. */ =20 -#include #include #include =20 +#include #include #include #include diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index aebed41f7de7..f8361520967b 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -12,6 +12,7 @@ #include #include #include +#include #include =20 #include @@ -716,7 +717,9 @@ static void handle_host_hcall(struct kvm_cpu_context *h= ost_ctxt) =20 static void default_host_smc_handler(struct kvm_cpu_context *host_ctxt) { + trace_hyp_exit(); __kvm_hyp_host_forward_smc(host_ctxt); + trace_hyp_enter(); } =20 static void handle_host_smc(struct kvm_cpu_context *host_ctxt) @@ -740,6 +743,8 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) { u64 esr =3D read_sysreg_el2(SYS_ESR); =20 + trace_hyp_enter(); + switch (ESR_ELx_EC(esr)) { case ESR_ELx_EC_HVC64: handle_host_hcall(host_ctxt); @@ -754,4 +759,6 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) default: BUG(); } + + trace_hyp_exit(); } diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe= /psci-relay.c index c3e196fb8b18..64d1d418df1d 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -6,11 +6,12 @@ =20 #include #include +#include #include -#include #include #include =20 +#include #include #include =20 @@ -205,6 +206,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bo= ol is_cpu_on) struct psci_boot_args *boot_args; struct kvm_cpu_context *host_ctxt; =20 + trace_hyp_enter(); host_ctxt =3D host_data_ptr(host_ctxt); =20 if (is_cpu_on) @@ -221,6 +223,7 @@ asmlinkage void __noreturn __kvm_host_psci_cpu_entry(bo= ol is_cpu_on) write_sysreg_el1(INIT_SCTLR_EL1_MMU_OFF, SYS_SCTLR); write_sysreg(INIT_PSTATE_EL1, SPSR_EL2); =20 + trace_hyp_exit(); __host_enter(host_ctxt); } =20 diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/swi= tch.c index d3b9ec8a7c28..66ed30135815 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -7,7 +7,6 @@ #include #include =20 -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -308,10 +308,13 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __debug_switch_to_guest(vcpu); =20 do { + trace_hyp_exit(); + /* Jump in the fire! */ exit_code =3D __guest_enter(vcpu); =20 /* And we're baaack! */ + trace_hyp_enter(); } while (fixup_guest_exit(vcpu, &exit_code)); =20 __sysreg_save_state_nvhe(guest_ctxt); --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-ed1-f73.google.com (mail-ed1-f73.google.com [209.85.208.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 548C5201004 for ; Fri, 3 Oct 2025 13:39:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498768; cv=none; b=N/B8UnJVvuJ3zA0LQkY/7FNgj2yrGc///4W/w7Jm9ZOACbE+Ad8L4M+4LeosUkpmyVmrq84Geo9MljDlVEr755g0VpN5bHMrZx5/iI09sI0wL42BNX+ZuViPbTtITvwXUIOzxU3Flydd9dVgKmEUqLdaXLJU8W2j63M0e11TjIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498768; c=relaxed/simple; bh=YOcY/2t1xn7bzDzdjSoq/pxkXWDBu/K2LcwDSpcHWtU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QOlutm3tdG/pi+qMNBIwSxJtEOMAWyhPgYmq3tjLfM1wUouRvs/0DcWxzutCTeqhB/m5Yo+zKa2BeUHFznZ861pqKD3EGWB98XJnGp05NJgvWcg1ANyKfd4+xufMNyf09Czye/B+GZFVemyUPkamL/VsHloMFpobCAZzHJcKH7c= 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=kDqMQDym; arc=none smtp.client-ip=209.85.208.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--vdonnefort.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="kDqMQDym" Received: by mail-ed1-f73.google.com with SMTP id 4fb4d7f45d1cf-6344e493258so3028823a12.2 for ; Fri, 03 Oct 2025 06:39:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498762; x=1760103562; 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=HybwN5usXimaW4enq6meCBW9SZH/kRyin9xx36GATCg=; b=kDqMQDymkgjhQn8Wy0HmE0/CgihHx7ZtK+hJZ8gxinp8Y3+G3pqHH7oEPUaAvcQQYO WAwLitLOxADeYePmfUJsGae5J8+2X7PTWht9Gg3ZqmaaxtkD9Rm7bSETYwZ/CHRe5iON gQZvu6LErRQ6D+caABV4+YvrmSiwHfXi+SekW7fxD+1S5oGGeeIP/DYmnrlf7ldW/g3k frMvV2juJvoHPr/+RdE0bjg1yImWkcfv7t9jvhXgwwvfS5kWLUTLvsah5PKy4qtSvFV4 eqVXNV7YqWoGWU8hCNEt3KAVX6lZKTVle7JWbliEoXrWmDutX2/UDN2OB+GToVCboPf+ a4UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498762; x=1760103562; 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=HybwN5usXimaW4enq6meCBW9SZH/kRyin9xx36GATCg=; b=vUKp/dWSBVjwEsccZsUcqsaXy9MmRmMSIDIxARZuL+jXKBDTE7Iby3h3xounRCth+K UeQmfQarO92Mk0zUX2gvc4hZHT29d6KrEi0x9DVr5iNeQd7yKtpjSIvm2s4Ajmv3LLpS LAjxWZs4AqUap5jVBjWhbLXONyBHwft7m0NgB3i9/dxzUt6/Ea+xz+kUtG3rCvpFmQTd j+tMIgf5as+/qCnX1Wyof3wXpy4QZgEM7U5+CBFfWxqOUqcShPH6b/jPW1/X3s/WcEY6 lJv7vSicgsWZdo+SpO5r4v7kXfqgSHPGNjoQ48my0CibqyNH5sp9jR78GYqy2gtpwacE xA7Q== X-Forwarded-Encrypted: i=1; AJvYcCXVRm35TRqTZpgvaZHylmPYKuk38fFGHdHP9BuHMitELrncMo28G/ne/3XlZLs6aZtJtphbi7PlKeUt21A=@vger.kernel.org X-Gm-Message-State: AOJu0YwggUlXyEmJ0t72giWt9q6fxgMTfX7XVXsG5B3Xfp+r0fw+s7my gaDxrNAM5MsNl4kAZSB5TVNetc7oLPbcgrGj++eTdPw6s9Nr//2SVIIH/LVFRbeCf2XD7X/5JZM Wa2fOcj0hviloNQ6y8m7o5w== X-Google-Smtp-Source: AGHT+IELwj3gBuJyF3leF3G8LaRkBWs2P6oRG/az18DDC/e2gYixHQvg3JdF7vBDcun0KzShSZpMuULh4WsxehBQ X-Received: from edpd15.prod.google.com ([2002:aa7:c1cf:0:b0:631:f056:e88b]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6402:1d53:b0:637:ec59:3169 with SMTP id 4fb4d7f45d1cf-639348e62c2mr3027788a12.14.1759498762216; Fri, 03 Oct 2025 06:39:22 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:24 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-28-vdonnefort@google.com> Subject: [PATCH v7 27/28] KVM: arm64: Add selftest event support to pKVM hyp From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a selftest event that can be triggered from a `write_event` tracefs file. This intends to be used by trace remote selftests. Signed-off-by: Vincent Donnefort diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_= asm.h index 79019e11f529..522cccef32b7 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -94,6 +94,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_reset_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_swap_reader_tracing, __KVM_HOST_SMCCC_FUNC___pkvm_enable_event, + __KVM_HOST_SMCCC_FUNC___pkvm_write_event, }; =20 #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/as= m/kvm_hypevents.h index ce3953bc884a..3d1244972869 100644 --- a/arch/arm64/include/asm/kvm_hypevents.h +++ b/arch/arm64/include/asm/kvm_hypevents.h @@ -24,4 +24,18 @@ HYP_EVENT(hyp_exit, ), HE_PRINTK() ); + +#ifdef CONFIG_PKVM_SELFTESTS +HYP_EVENT(selftest, + HE_PROTO(u64 id), + HE_STRUCT( + he_field(u64, id) + ), + HE_ASSIGN( + __entry->id =3D id; + ), + RE_PRINTK("id=3D%lld", __entry->id) +); #endif + +#endif /* __ARM64_KVM_HYPEVENTS_H_ */ diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index e06358aaf1af..dc2ac3049428 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -45,6 +45,7 @@ menuconfig KVM config NVHE_EL2_DEBUG bool "Debug mode for non-VHE EL2 object" depends on KVM + select PKVM_SELFTESTS help Say Y here to enable the debug mode for the non-VHE KVM EL2 object. Failure reports will BUG() in the hypervisor. This is intended for @@ -82,6 +83,15 @@ config PTDUMP_STAGE2_DEBUGFS =20 If in doubt, say N. =20 +config PKVM_SELFTESTS + bool "Protected KVM hypervisor selftests" + depends on KVM + default n + help + Say Y here to enable pKVM hypervisor testing infrastructure. + + If unsure, say N. + config PKVM_TRACING bool depends on KVM diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index f8361520967b..81d8628a9047 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -631,6 +631,20 @@ static void handle___pkvm_enable_event(struct kvm_cpu_= context *host_ctxt) cpu_reg(host_ctxt, 1) =3D __pkvm_enable_event(id, enable); } =20 +static void handle___pkvm_write_event(struct kvm_cpu_context *host_ctxt) +{ + int smc_ret =3D SMCCC_RET_NOT_SUPPORTED, ret =3D -EOPNOTSUPP; +#ifdef CONFIG_PKVM_SELFTESTS + DECLARE_REG(u64, id, host_ctxt, 1); + + trace_selftest(id); + smc_ret =3D SMCCC_RET_SUCCESS; + ret =3D 0; +#endif + cpu_reg(host_ctxt, 0) =3D smc_ret; + cpu_reg(host_ctxt, 1) =3D ret; +} + typedef void (*hcall_t)(struct kvm_cpu_context *); =20 #define HANDLE_FUNC(x) [__KVM_HOST_SMCCC_FUNC_##x] =3D (hcall_t)handle_##x @@ -677,6 +691,7 @@ static const hcall_t host_hcall[] =3D { HANDLE_FUNC(__pkvm_reset_tracing), HANDLE_FUNC(__pkvm_swap_reader_tracing), HANDLE_FUNC(__pkvm_enable_event), + HANDLE_FUNC(__pkvm_write_event), }; =20 static void handle_host_hcall(struct kvm_cpu_context *host_ctxt) diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 73539f5b5e42..7d078f87f86d 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -318,8 +318,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; } diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc b/= tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc new file mode 100644 index 000000000000..49dca7c3861a --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.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 --=20 2.51.0.618.g983fd99d29-goog From nobody Sat Oct 4 01:39:24 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC3F42F1FC1 for ; Fri, 3 Oct 2025 13:39:25 +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=1759498768; cv=none; b=nDdRhcaXiT4eQxvDhmXrviBKRyuRV0HEP17ooHdhlDC/RsJPApMUj3+bZynbS+lhrb6QhaO84qnm0MUEkUpfm+H+yufTqZxJwlvJgoxguVBpuE5qQl2jlpN51U5MGLq5KkZukrkpEphvTWGC3d7PZKol7K0OCADbarWkwhARu+M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1759498768; c=relaxed/simple; bh=EhJlCtUGcSeWQktaiM83P9YNtXVSdRR4pDoNVCpu5bk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DPnP6ny7XNMYWWDvPnnBUubQOo3fmZOUdhaLiYgMrM8x08r5EkMEvFZ7VSo1RFGqMuOy4WKmVK83XJIRqSoD2zG5wg97+oh2W0jgEuospJU3ZuMpjWZ9PZwiS4b8P81ISbHh2L7rF6rs8XdY1gDBZDiECBDf6vhFD+6BIrQwPzY= 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=wgeU7H9s; 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="wgeU7H9s" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-46e2c11b94cso11959725e9.3 for ; Fri, 03 Oct 2025 06:39:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1759498763; x=1760103563; 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=9UM3bjOGfRXsiIqNoVQZ3XTLMtvfmMCHhcAES2xrn08=; b=wgeU7H9sSbsrjdJ3kHLO/aKVcmAegzUy/xfLFaWHfe+rLIfmkIkDxnh3nar4ajBVA9 AjjZgt+gIq+P18hFGbDKF4YchbyAShj5kMOBTQESUQRrjI410WQp9Osdm7tnUniCFruL /CtpA97GZHe5EBtY89CaJKEH0s9dm3gdunWjQQmRg2lvtqCwClkT6LSSOAsR9upS5+yW EecikaBye/FAYxcB8CcYPpVwBv7NNOKfXQqlqBDzxsXSo+Nwta4gfSy1JHV1O8D3EL5e KEb6NtBsTDKpc+4A5egb8wWIofq126Qn54RHpWa3FhngkZt4vlxJeG+vocDTX9VFb3da miAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759498763; x=1760103563; 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=9UM3bjOGfRXsiIqNoVQZ3XTLMtvfmMCHhcAES2xrn08=; b=I8Y5ke4J2cHFW5OhdhTBRYqR5YCFEhZAYdBTRtWR3+5Q8hS1TYGyYnWiwMbdkMDDEA nZdwSS6Zz+UDoRNT6Z4piYK9jn3ZLnz2aAzlHWNZuxlpVto5R7Kx1NnC/+gfjphzI8zO LsQw6oPf+q5BZP75ZLDxSU045QCBS59JhBGtkHA5tkbVgd78ADLMy2j+i8IxoD9shXz/ DbYOnhuB/ddweIYn/ZF4PBkmo8mPhdUjTTK+VX6OMCRI7Q05pTAr1sVX4gkLfoYJoLJt teNwc7VgNm6DFzhGf9xID/t2wzQfRTw9e/7mOjOQgzIR8x76TD4WIcpmzjMurBDHUJ55 hSuw== X-Forwarded-Encrypted: i=1; AJvYcCU6X1eh2Fu3CKfmki/8IiP+7p6xHa2ccbi+83XMMPkazTPo9oUF4z5bxrPGrFklGIn2lDaunywqhbpQp0U=@vger.kernel.org X-Gm-Message-State: AOJu0YzK8/UGHEoRs7KnwhTfKDjmWeWHR9KAs+Myb+NtO/sxGesFTrgU rHsozQsrpiYs1ZS39R3SqKmwguNxN4zLu3S4771e/KzjQTFCxq5vjh4x7qIAGLXuWzfampm7uGy o2B+J/iuqVWZEyR6KrhylEQ== X-Google-Smtp-Source: AGHT+IH69tFTi6ZXKv+400BRPyLOvUgxD9vIa5eZfePSc6PtEn5y2PQMqER0DyOBvI5qOTvfVEhXP1sn9nPiGRc7 X-Received: from wmco6.prod.google.com ([2002:a05:600c:a306:b0:45d:cfa4:ce0d]) (user=vdonnefort job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:4447:b0:46e:3dad:31ea with SMTP id 5b1f17b1804b1-46e7113ceddmr26045525e9.17.1759498763415; Fri, 03 Oct 2025 06:39:23 -0700 (PDT) Date: Fri, 3 Oct 2025 14:38:25 +0100 In-Reply-To: <20251003133825.2068970-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: <20251003133825.2068970-1-vdonnefort@google.com> X-Mailer: git-send-email 2.51.0.618.g983fd99d29-goog Message-ID: <20251003133825.2068970-29-vdonnefort@google.com> Subject: [PATCH v7 28/28] tracing: selftests: Add pKVM trace remote tests From: Vincent Donnefort To: rostedt@goodmis.org, mhiramat@kernel.org, mathieu.desnoyers@efficios.com, linux-trace-kernel@vger.kernel.org, maz@kernel.org, oliver.upton@linux.dev, joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org, jstultz@google.com, qperret@google.com, will@kernel.org, aneesh.kumar@kernel.org, kernel-team@android.com, linux-kernel@vger.kernel.org, Vincent Donnefort , Shuah Khan , linux-kselftest@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Run the trace remote selftests with the pKVM trace remote "hypervisor". Cc: Shuah Khan Cc: linux-kselftest@vger.kernel.org Signed-off-by: Vincent Donnefort diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size= .tc b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size.tc new file mode 100644 index 000000000000..2de07e4d72fe --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/buffer_size.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor trace buffer size +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/buffer_size.tc + +set -e +setup_remote "hypervisor" +test_buffer_size diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/reset.tc b/= tools/testing/selftests/ftrace/test.d/remotes/pkvm/reset.tc new file mode 100644 index 000000000000..48afc51627e8 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/reset.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor trace buffer reset +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/reset.tc + +set -e +setup_remote "hypervisor" +test_reset diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc b/= tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc index 49dca7c3861a..00aed1c2e650 100644 --- a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace.tc @@ -1,9 +1,10 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 -# description: Test pkvm hypervisor tracing pipe +# description: Test pkvm hypervisor non-consuming trace read +# requires: remotes/hypervisor/write_event =20 SOURCE_REMOTE_TEST=3D1 -. $TEST_DIR/remotes/trace_pipe.tc +. $TEST_DIR/remotes/trace.tc =20 set -e setup_remote "hypervisor" 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..b63339aca380 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/trace_pipe.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor consuming trace read +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/trace_pipe.tc + +set -e +setup_remote "hypervisor" +test_trace_pipe diff --git a/tools/testing/selftests/ftrace/test.d/remotes/pkvm/unloading.t= c b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/unloading.tc new file mode 100644 index 000000000000..eb1640a927cc --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/remotes/pkvm/unloading.tc @@ -0,0 +1,11 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Test pkvm hypervisor trace buffer unloading +# requires: remotes/hypervisor/write_event + +SOURCE_REMOTE_TEST=3D1 +. $TEST_DIR/remotes/unloading.tc + +set -e +setup_remote "hypervisor" +test_unloading --=20 2.51.0.618.g983fd99d29-goog