Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp604776ybh; Tue, 21 Jul 2020 03:31:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzgguQXhsqlMJ0Lu1mzNYCZCfso0XjEHKnCggThfX3Vpn+osHwBUlLmX1ufaEizZSJYHxRj X-Received: by 2002:aa7:d04e:: with SMTP id n14mr26220884edo.161.1595327492771; Tue, 21 Jul 2020 03:31:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595327492; cv=none; d=google.com; s=arc-20160816; b=a+1sekeCXUvSLzVEMldB33fdDtN69kGPA+zkAs62entvT3N3nOQLuY/npYQGTuJyql 0a5FtRWMnhYCVehOurzecZMZ4WPafZ/FNxR8vmrwYXIwvQKA3hUgKokIKb1nqSal5ut2 llP/kcUkoaDqyrGKm3NUtCxDkuDR+MnkZo8MAbokGy/rtNeBZYHOFI31VU0jEc6sIIbc wzF9G0rm98OpRILa4S5sPVvuki6q7/i6YPl5eQ/48mXRuV79/P1VGnYPOAEqaW+xeF5g UF1wojDrOYrKNBi53o+HOZs/mnk3P6O9akg0ERpkvtruzgyD2+6MP2ty57ho51NA9u87 DpUA== 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=lzumWwjBCjoWvyaVpmfup+Sfq7jvpdMDLzihovn9kHY=; b=JFhOe9vyKRnn79zNgOIHZ/XaESTVcZWbOpvWyruJO7znAFYUJZa05JEzaJymLqqj6c OusJVTu3c6DIPUXbFFpm6zrbhNYBM1tobnxn7vk4s+xuXZ0JNvolxWmNR6INwhE6kP6Y hPag7f+c7N2DV6T4WAyXRdtXJN5lEKJYcGss5A1QQlVSO+6uJWlorVDghH8+1Ntn0RF9 CqputnoezxD9mhgIKhYz4P0yjPnTT+RTE9qZU4shPSWOlSpTCjwHOjmsQ9hcs/gXNUJy KabPixAV7XPwBtgyP1NVAjwPQ/6wO19zeaKodcpq+OL2RdEuFgHLecfHsok1Z++MUDuV +IfA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=XzNICzMl; 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 q22si11754251ejx.87.2020.07.21.03.31.10; Tue, 21 Jul 2020 03:31:32 -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=XzNICzMl; 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 S1729272AbgGUKar (ORCPT + 99 others); Tue, 21 Jul 2020 06:30:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729230AbgGUKao (ORCPT ); Tue, 21 Jul 2020 06:30:44 -0400 Received: from mail-wr1-x449.google.com (mail-wr1-x449.google.com [IPv6:2a00:1450:4864:20::449]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AADFFC061794 for ; Tue, 21 Jul 2020 03:30:43 -0700 (PDT) Received: by mail-wr1-x449.google.com with SMTP id m7so6298493wrb.20 for ; Tue, 21 Jul 2020 03:30:43 -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=lzumWwjBCjoWvyaVpmfup+Sfq7jvpdMDLzihovn9kHY=; b=XzNICzMl96GTqpwyTEKH5WKZeDkOtiAXlCZP7pH5ox0PR5UXpNDwNxPWg0EGzpsMmu pA0+IUug3DbSzs9VGjOzLmSr3vBkQeKlCW9ITE52cMpX7CELsrfKiDprEb6vyeO/i//a EXRVaWM8cgtlHEsKnsJKojvbtRlSct98lnKW3um17+/QFnGZWjLF6FamD28VnpVYBOWv vLkPioi7u19bxDSdsCzD3iiN0ltF+/KoY0jpmm9tn3GglNEajbwwkYqGCjw/skwhz3YH lEMqA9pADOQz3uvTCf6N6bmiD7Yi1So40YbiDDmED7qaHwFjYZxF0J2Y89LQ3VIMCmPt pc6w== 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=lzumWwjBCjoWvyaVpmfup+Sfq7jvpdMDLzihovn9kHY=; b=o0xxabt6kpmZ+TDVqEV7moKRfUIcNmr0K975faB6VZ5/XXdLuKrlWPwHjGUaeKxtNh ENU9WTO2ZqVl9UwwdjSp0dxs78sG3VXv+qEUJbDu+7YnKzDyaEsCck/HLhFmUpJR3iT7 3i7VObCTCicnF4nR6PU6mgxJwa7vsADanmgLgy1lfa8+ghu5HC5nGBajDuCeuKW/5bYK 8TQprq5Cq9INW2hWqTQV5Pv0pcmJ6Cg+E2FPj63EOM2OB2hYDpqEH97Dh6hQzHjN34dw isyXR368uZ5YPQrtLbZQi4/FkqEZeSp7D0oQ5FYp5ZTZGsVxgckiOZd6JaRRvxZ0fwSm Bpkg== X-Gm-Message-State: AOAM5323i/3SsaCs6T+srzlPwOw2mi1oow0GV0P+kt7s8x4E6cLBpsQd eWClZ023jWlgKVb0ebIdoKeBsiXhHA== X-Received: by 2002:a1c:984d:: with SMTP id a74mr3644277wme.140.1595327442395; Tue, 21 Jul 2020 03:30:42 -0700 (PDT) Date: Tue, 21 Jul 2020 12:30:13 +0200 In-Reply-To: <20200721103016.3287832-1-elver@google.com> Message-Id: <20200721103016.3287832-6-elver@google.com> Mime-Version: 1.0 References: <20200721103016.3287832-1-elver@google.com> X-Mailer: git-send-email 2.28.0.rc0.105.gf9edc3c819-goog Subject: [PATCH 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 --- 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..cde5b62b0a01 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.105.gf9edc3c819-goog