From nobody Sat Jul 25 04:15:57 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 D647D22A7F0 for ; Sat, 18 Jul 2026 16:09:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784390964; cv=none; b=Czve9zt4dezym0mUbL9PY3htKT9z9xOUpY7nMYtUAHGoddabTaQGXiDBJ32Fj7oAqI/saMWPrD5Yav6YoBPtbjfFyux0m9C/cQgVd+s80YY+1nHVAFBNcfxEugSets0gKhEwr1ml3iFlzkcETd77Nq+taEFk9W2MTFV9Jh5fbMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784390964; c=relaxed/simple; bh=4zI25jP+b6vUs+Ft5P2vSY307wxOFM+jySa6J5N1Sfc=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=j2twSRKqbdthjFQP2kejRl4p63Vbk78PYirh15tcY25TyKbnFEeNSk5+88BBNb8YWEh4nwT9svY8+o5wzLNmJerOwl179ROsM2ZgKDt/5zU6jhoYTLDPta7blzmE3+/73qWASABQFJ5dIYKxgJep3OtaXjrdelsNj1rKI1YFDJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CCCY0qNp; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CCCY0qNp" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4954afac04bso14384475e9.0 for ; Sat, 18 Jul 2026 09:09:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784390955; x=1784995755; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=3Doh9FA1nniC+bls/UOthzLxrZXSrfU96d9z1kczZb4=; b=CCCY0qNplaml6WX7/cA6PZXX39R/nIqBIG7msVnCIEMbt4aOR9VHXopMb6XCkSw6au an78K9HJyDz2wjfaVnw1efsuKmmeCLge6BUrTteyRzvDxuYn/U7jK/78nvmuIyxirvM5 WX+1lng0r5KIPr80jEqitzGMKxlCoJ/Ffv4CVQ17giK1d0lMvunSlQUfTGTnhVmuhl7G s+1Kac+zSDvK+C4EDgxdj7u/ItRWrgulS5B8I9+BIWWuzpGFRUyQo+Q5R52CnS+TfcK3 pLeavCrgYJr2rbJ9KXNHeYnj+xp+FYW3yG5Gep0CM5SbDdOtYKEfDYMHH3WCEd+8w5Mj XVdQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784390955; x=1784995755; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3Doh9FA1nniC+bls/UOthzLxrZXSrfU96d9z1kczZb4=; b=pz6ZfNWsogP2km4D53EI7CWQUFPx+Z4OZB/2pwG9zMvZGThj/mNadnNn3o/QQ7ehXh CqTheQzMMk2Zl6en3kVZJSj9pzbP/SlaS/Q+lG4aMqBDubu861ASoTatA6dEHmU94a6v ytxMt7nB3My4YqddWtsvEOEa41RlqmOuVkwtdeL21IDHDaPHMYwBs0J/1TjUIF1NKaeM 8z8+eVVqEN8s8l0dxMN0GVjEU0ae4YkN6ANfFZ6/eOvb9ND/uEJ75lG+L+kLZ6AVXNyF RaOIl3c21NyeeNg4ZdxzEVEsLkFORIkcpzyfo7gKIR9W5VQxLIGVcunMRbIuchuQBasV a2KA== X-Forwarded-Encrypted: i=1; AHgh+RreU2mKALtTmNpLWAzhC6z0YyHy8FBaz0N2GqAMMK7LKpDczwdnJNBqZcbgO2QprXi+cjJQtaJgL0mc4Rc=@vger.kernel.org X-Gm-Message-State: AOJu0Ywqy2SvyI6T99Ki1mc2AQYO7Fu1pAZ+EF/ZsBangT0ZVzWiyQ2P 5T8bib+dqc4C3dg9vNPPiB8xkIj7xamwoTWTydE32r9v+pigx/Uo94t9 X-Gm-Gg: AfdE7clzmrEsThjlfRh1UVt8T3Knkn8nZaaoyLUsjRLZAL6YODYwg3x47m/vc4oicCt Hms8XV3pbcyYcOF5lIvACD3Cyn5b2EPr2TEI7xMN2LOhjtUpGuVImoL209PT/3mbRkXogwYsrAU uWmcQYzrTVX7dQA3t/lmR03RszL57BX2KJS6UNZt9ufeTT9KyCY6R9Rt3osTeX8gihWhCsKowXZ qBz0hWL/0xG37Su22nDMD5MJJavvNohS5WhWqvW7oX+1wK1GiDH5dIqpz+N/k/PDlhNbDuxYrwP 5UQoJqq7d2v3A4zzvY1HhUdU+GC9LfbuxprDUeYwtzEe3mHlbCCQ2AjXYOPqinytP0Wly3GRe+l WC7ioDKEQNSjST4jAmgskF9tVpdreeNW8B0vArEEyyGbdVvzotgU7XeJfyvJfJCC1RWxujDUhIg CbLaPU06aH9P15xrz2Q9ZSug+on+iiPPsmJzdAbOksW68zpzE4O1Sj2M5nmuAVZ5ia8cLFjnlrM LzNzqfUnZVJ9/VPpUiGxJ4xgSWPbIbW0p6DOHxH0JmpZ68+kDrt6AoAo/PpLviiV8sme/9ZpOuD Ys4MUttJVO808CpuD1QsKoqTpw== X-Received: by 2002:a05:600c:1d15:b0:495:3f26:4f30 with SMTP id 5b1f17b1804b1-4954a3e6e08mr78593255e9.6.1784390954763; Sat, 18 Jul 2026 09:09:14 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a02-3100-9c00-bb01-3966-facf-793f-82a8.310.pool.telefonica.de. [2a02:3100:9c00:bb01:3966:facf:793f:82a8]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49549c96f19sm148137055e9.9.2026.07.18.09.09.13 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sat, 18 Jul 2026 09:09:14 -0700 (PDT) From: Karl Mehltretter To: Andrey Konovalov Cc: Karl Mehltretter , Alexander Potapenko , Dmitry Vyukov , Marco Elver , kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org Subject: [PATCH] kcov: report the first spurious PC in the interrupt selftest Date: Sat, 18 Jul 2026 18:09:05 +0200 Message-Id: <20260718160905.5335-1-kmehltretter@gmail.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The KCOV interrupt selftest enables KCOV_MODE_TRACE_PC without a coverage area so that spurious coverage causes a fault. If the fault path is instrumented, the coverage callback faults recursively. Observed failure modes include a stack overflow on x86_64 and arm32 getting stuck in abort handling, neither of which identifies the original coverage event. The recursive failure is not new, but commit 9a79524d1420 ("kcov: use WRITE_ONCE() for selftest mode stores") made the selftest effective on configurations where the compiler had previously removed the mode store, exposing it more broadly. Use a two-word buffer to record the first spurious PC. Once one is recorded, disable KCOV, report the PC, and panic. This preserves the selftest's hard failure while avoiding the recursive fault path. canonicalize_ip() subtracts kaslr_offset() from recorded PCs. Add it back before printing the PC with %pS. Fixes: 6cd0dd934b03 ("kcov: Add interrupt handling self test") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Karl Mehltretter --- This patch improves the failure diagnostics. With CONFIG_KCOV_SELFTEST, I observed failures under QEMU on arm, arm64, riscv64, s390x, ppc64le, mips64le, loongarch, and x86_64. The reported PCs indicate that this likely needs a global KCOV fix rather than separate exclusions for each architecture. For example, arm64 defconfig with KCOV and KCOV_SELFTEST reports: [ 2.741175] kcov: running self test [ 2.748637] kcov: spurious coverage detected during interrupt selftest= : return_address+0x28/0xa8 [ 2.750623] Kernel panic - not syncing: kcov: interrupt selftest detec= ted spurious coverage [ 2.752147] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0-rc3= -...-dirty #25 PREEMPT(full) kernel/kcov.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 1df373fb562b..5de2d37fc407 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -1102,9 +1102,11 @@ struct kcov_common_handle_id kcov_common_handle(void) EXPORT_SYMBOL(kcov_common_handle); =20 #ifdef CONFIG_KCOV_SELFTEST +static unsigned long selftest_area[2] __initdata; + static void __init selftest(void) { - unsigned long start; + unsigned long start, ip; =20 pr_err("running self test\n"); /* @@ -1114,15 +1116,36 @@ static void __init selftest(void) * leaks out of that section and leads to spurious coverage. * It's hard to call the actual interrupt handler directly, * so we just loop here for a bit waiting for a timer interrupt. - * We set kcov_mode to enable tracing, but don't setup the area, - * so any attempt to trace will crash. Note: we must not call any - * potentially traced functions in this region. + * We set up a two-word coverage area rather than leaving it NULL: + * a leak then records its PC instead of crashing on a NULL + * dereference, and we can report the offending PC. Note: we + * must not call any potentially traced functions in this region. */ - start =3D jiffies; + current->kcov_size =3D ARRAY_SIZE(selftest_area); + current->kcov_area =3D selftest_area; + barrier(); WRITE_ONCE(current->kcov_mode, KCOV_MODE_TRACE_PC); - while ((jiffies - start) * MSEC_PER_SEC / HZ < 300) - ; - WRITE_ONCE(current->kcov_mode, 0); + start =3D jiffies; + while ((jiffies - start) * MSEC_PER_SEC / HZ < 300) { + if (READ_ONCE(selftest_area[0])) + break; + cpu_relax(); + } + WRITE_ONCE(current->kcov_mode, KCOV_MODE_DISABLED); + barrier(); + current->kcov_size =3D 0; + current->kcov_area =3D NULL; + + if (selftest_area[0]) { + /* PCs are recorded with kaslr_offset() subtracted. */ + ip =3D selftest_area[1]; +#ifdef CONFIG_RANDOMIZE_BASE + ip +=3D kaslr_offset(); +#endif + pr_err("spurious coverage detected during interrupt selftest: %pS\n", + (void *)ip); + panic("kcov: interrupt selftest detected spurious coverage"); + } pr_err("done running self test\n"); } #endif --=20 2.53.0