Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp1948583ybh; Fri, 24 Jul 2020 00:02:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx7kBojLU/sFuUKEjSPfw3BVIwXVVo95iCcbU2N+SsJ8PdwKubmcMVAdBZVxLRSPt/n+tOm X-Received: by 2002:a50:ef10:: with SMTP id m16mr7552497eds.206.1595574169845; Fri, 24 Jul 2020 00:02:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595574169; cv=none; d=google.com; s=arc-20160816; b=aVZD6RKAEJs3mgBxLdt8HXJG6fueTjovUR6hRF6ogyUazPe74FCyy/SifmhXxhjFXX CvH4cl9ZBx7wgOD8+oC7F8miH6kHNrVa3q7t54CLsttvUxCbTnru/V2xsW2Xzg8aqX23 s/PeJgCaHJrijoN8vZbDHqkHAJCbX4wqAeg/utlMn/z9cIjtJszfruakr6tPbFEz9MAw wCNFJiMWv+MWCPWmu7/BXcUGH2m5Th5mc6z/3mtUrQq3hgXWy0a4+UhbVEdNCUSWXwXc syMPnPQFQz3+z9oiJCkyeIDio++1NbZjAJ/0Ko8X5S1ZhDbHG1KwOjj29ezDTlHzh3Qw gWuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:references :mime-version:message-id:in-reply-to:date:dkim-signature; bh=ZaqDMwLk6PPGhSBflviL3tpxd3/gyTDsl7bIZ5aTHls=; b=0kyCGrrbMq+dQ0WiBT1dVJ1t596s/T8/bvfnzUNTnTdhqZsHTPufBSNGmczAdyK5HO Y8XzZwF6+mS3W0ObglL1Vv5peqONPg+3RKWh7AkRfBKgdovxh6q6skigp0pTRXwWwI7/ YADkmFvVMLQA4A/iSYYWIf5XC8PIcL1ZwtLa9iJYhNHVwWczRxKwVaxFXwCzR8oQawMT PquJu04abfjt2UUlfPL0MfsUXi/oJNf0/HnBnF3aLG4fqmqCcQl+QW+YMDOVlrKt1qhq Xk8dYTosWGlbg5OwJ1V0siRgdM2sgEobuUSt22sJi643MVltkMBFIkUitL2zrILTXHzq actA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=mu+faoc3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t22si14369edy.39.2020.07.24.00.02.27; Fri, 24 Jul 2020 00:02:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=mu+faoc3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726988AbgGXHAj (ORCPT + 99 others); Fri, 24 Jul 2020 03:00:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33500 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726964AbgGXHAg (ORCPT ); Fri, 24 Jul 2020 03:00:36 -0400 Received: from mail-lf1-x14a.google.com (mail-lf1-x14a.google.com [IPv6:2a00:1450:4864:20::14a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E56CAC0619D3 for ; Fri, 24 Jul 2020 00:00:35 -0700 (PDT) Received: by mail-lf1-x14a.google.com with SMTP id u11so1732274lfg.11 for ; Fri, 24 Jul 2020 00:00:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZaqDMwLk6PPGhSBflviL3tpxd3/gyTDsl7bIZ5aTHls=; b=mu+faoc3jNSqK70L4X9nu3dc03seMsHg+pzbym/iGnAuBCPGXzIe66t9iSgBa1AVRs IZmsJ8DrvWoGUdGiWgJyLaNtbsz0Ya5G7ELGErwixQDFpMLA0l2MEqY5ZLF2EOadwDBY K9K78WZF+iKiKbLLdzPil+0Lzt0V0KynyPmP3ensS7SdkpDIBh4JTVPBkVmoZonu39ZS MzQ6HhCnJiBuLYkdzfOfsse+sHXEHwYX5bY94XTrvN7fRmyk7B3PYj+Lfc0R1ce9Tlli SqkkZfvJDODHhtYID+PLSt7RPaRQPqKH1vsnPuQVDeLIztSbmKy6k4KkLwGKrttIfUN/ wfFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZaqDMwLk6PPGhSBflviL3tpxd3/gyTDsl7bIZ5aTHls=; b=iGKzPXpaELX1l49yn71ePhHKApIhqLaVoQgSenTeHpVUWlsl3VlEoDf/jEOi2u/htL GdJK82zgl5M4w0XovM4SVaxy2ehjqdPsXmQaJzFflSx321V1jUHxDQ6/cZLrMmtnrqVR zXEpVJ1zNWP4sKB4VtQJDnK6JWxnEChqCske/wabCs3ZLdH2eP1mVTUHReLYmvno0Erv N7huIXR+mToROPr1XamMrkQPNp4/GYmC+JEsZt+Klg0G3b0jvH+ERbiAaHh9zm2RnDY5 S1mIT1DLYtMRpZ6bVu+5p9xrfsmqBm138wzMvvppzrFS+w7ofwfaJf24BgtxKgBb0PlH 5lsA== X-Gm-Message-State: AOAM531GmBHg3ld7IiV4x7Kel5AUyAr1QsWx5YWCKONacSlEjXX/nJFa 2+CMVDDX9h9bGZpp5mY7S1JcbBBR4g== X-Received: by 2002:a2e:8618:: with SMTP id a24mr3774032lji.302.1595574034152; Fri, 24 Jul 2020 00:00:34 -0700 (PDT) Date: Fri, 24 Jul 2020 09:00:05 +0200 In-Reply-To: <20200724070008.1389205-1-elver@google.com> Message-Id: <20200724070008.1389205-6-elver@google.com> Mime-Version: 1.0 References: <20200724070008.1389205-1-elver@google.com> X-Mailer: git-send-email 2.28.0.rc0.142.g3c755180ce-goog Subject: [PATCH v2 5/8] kcsan: Test support for compound instrumentation From: Marco Elver To: elver@google.com, paulmck@kernel.org Cc: will@kernel.org, peterz@infradead.org, arnd@arndb.de, mark.rutland@arm.com, dvyukov@google.com, glider@google.com, kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Changes kcsan-test module to support checking reports that include compound instrumentation. Since we should not fail the test if this support is unavailable, we have to add a config variable that the test can use to decide what to check for. Signed-off-by: Marco Elver --- v2: * Fix CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE: s/--param -tsan/--param tsan/ --- kernel/kcsan/kcsan-test.c | 65 ++++++++++++++++++++++++++++++--------- lib/Kconfig.kcsan | 5 +++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/kernel/kcsan/kcsan-test.c b/kernel/kcsan/kcsan-test.c index 721180cbbab1..ebe7fd245104 100644 --- a/kernel/kcsan/kcsan-test.c +++ b/kernel/kcsan/kcsan-test.c @@ -27,6 +27,12 @@ #include #include +#ifdef CONFIG_CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE +#define __KCSAN_ACCESS_RW(alt) (KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE) +#else +#define __KCSAN_ACCESS_RW(alt) (alt) +#endif + /* Points to current test-case memory access "kernels". */ static void (*access_kernels[2])(void); @@ -186,20 +192,21 @@ static bool report_matches(const struct expect_report *r) /* Access 1 & 2 */ for (i = 0; i < 2; ++i) { + const int ty = r->access[i].type; const char *const access_type = - (r->access[i].type & KCSAN_ACCESS_ASSERT) ? - ((r->access[i].type & KCSAN_ACCESS_WRITE) ? - "assert no accesses" : - "assert no writes") : - ((r->access[i].type & KCSAN_ACCESS_WRITE) ? - "write" : - "read"); + (ty & KCSAN_ACCESS_ASSERT) ? + ((ty & KCSAN_ACCESS_WRITE) ? + "assert no accesses" : + "assert no writes") : + ((ty & KCSAN_ACCESS_WRITE) ? + ((ty & KCSAN_ACCESS_COMPOUND) ? + "read-write" : + "write") : + "read"); const char *const access_type_aux = - (r->access[i].type & KCSAN_ACCESS_ATOMIC) ? - " (marked)" : - ((r->access[i].type & KCSAN_ACCESS_SCOPED) ? - " (scoped)" : - ""); + (ty & KCSAN_ACCESS_ATOMIC) ? + " (marked)" : + ((ty & KCSAN_ACCESS_SCOPED) ? " (scoped)" : ""); if (i == 1) { /* Access 2 */ @@ -277,6 +284,12 @@ static noinline void test_kernel_write_atomic(void) WRITE_ONCE(test_var, READ_ONCE_NOCHECK(test_sink) + 1); } +static noinline void test_kernel_atomic_rmw(void) +{ + /* Use builtin, so we can set up the "bad" atomic/non-atomic scenario. */ + __atomic_fetch_add(&test_var, 1, __ATOMIC_RELAXED); +} + __no_kcsan static noinline void test_kernel_write_uninstrumented(void) { test_var++; } @@ -439,8 +452,8 @@ static void test_concurrent_races(struct kunit *test) const struct expect_report expect = { .access = { /* NULL will match any address. */ - { test_kernel_rmw_array, NULL, 0, KCSAN_ACCESS_WRITE }, - { test_kernel_rmw_array, NULL, 0, 0 }, + { test_kernel_rmw_array, NULL, 0, __KCSAN_ACCESS_RW(KCSAN_ACCESS_WRITE) }, + { test_kernel_rmw_array, NULL, 0, __KCSAN_ACCESS_RW(0) }, }, }; static const struct expect_report never = { @@ -629,6 +642,29 @@ static void test_read_plain_atomic_write(struct kunit *test) KUNIT_EXPECT_TRUE(test, match_expect); } +/* Test that atomic RMWs generate correct report. */ +__no_kcsan +static void test_read_plain_atomic_rmw(struct kunit *test) +{ + const struct expect_report expect = { + .access = { + { test_kernel_read, &test_var, sizeof(test_var), 0 }, + { test_kernel_atomic_rmw, &test_var, sizeof(test_var), + KCSAN_ACCESS_COMPOUND | KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ATOMIC }, + }, + }; + bool match_expect = false; + + if (IS_ENABLED(CONFIG_KCSAN_IGNORE_ATOMICS)) + return; + + begin_test_checks(test_kernel_read, test_kernel_atomic_rmw); + do { + match_expect = report_matches(&expect); + } while (!end_test_checks(match_expect)); + KUNIT_EXPECT_TRUE(test, match_expect); +} + /* Zero-sized accesses should never cause data race reports. */ __no_kcsan static void test_zero_size_access(struct kunit *test) @@ -942,6 +978,7 @@ static struct kunit_case kcsan_test_cases[] = { KCSAN_KUNIT_CASE(test_write_write_struct_part), KCSAN_KUNIT_CASE(test_read_atomic_write_atomic), KCSAN_KUNIT_CASE(test_read_plain_atomic_write), + KCSAN_KUNIT_CASE(test_read_plain_atomic_rmw), KCSAN_KUNIT_CASE(test_zero_size_access), KCSAN_KUNIT_CASE(test_data_race), KCSAN_KUNIT_CASE(test_assert_exclusive_writer), diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index 3d282d51849b..f271ff5fbb5a 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -40,6 +40,11 @@ menuconfig KCSAN if KCSAN +# Compiler capabilities that should not fail the test if they are unavailable. +config CC_HAS_TSAN_COMPOUND_READ_BEFORE_WRITE + def_bool (CC_IS_CLANG && $(cc-option,-fsanitize=thread -mllvm -tsan-compound-read-before-write=1)) || \ + (CC_IS_GCC && $(cc-option,-fsanitize=thread --param tsan-compound-read-before-write=1)) + config KCSAN_VERBOSE bool "Show verbose reports with more information about system state" depends on PROVE_LOCKING -- 2.28.0.rc0.142.g3c755180ce-goog