Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp2355161ybv; Fri, 21 Feb 2020 14:03:04 -0800 (PST) X-Google-Smtp-Source: APXvYqz9Q5SPZ6ZnenCKqqQJ6pnCUZGAMAiGdeBw81kZxIFF4KUbqRHTlh7+D/QAbQs1kkBXsX1O X-Received: by 2002:a9d:7410:: with SMTP id n16mr30986210otk.23.1582322584716; Fri, 21 Feb 2020 14:03:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582322584; cv=none; d=google.com; s=arc-20160816; b=DBmQs8N5Bv29B9Q6bQV7TiPNSOi/hmLbXxi76p+QYmDoySfrhI3CPn4s6OkSZOIVIW IiujvwEOi0KBi8XuF+OZfyGU3C1qcHyf1QO3b9DkIYGM6v+2PrisNmfPRqq6IwmKgxyI 0H3Z0Te1JmdX9ii8/pZO/OkaLBDy3zzrQvBaGTFQ2TUNXkfxUauGjDSPuv7/JYBtUs+l 8s9uH+JrcNFexilQl6PGY/LkD9JlRZ8jxxbIaMzOjeyXGTiQvf4hPa+qFLLQtBAEsWUW YcnONUUgNnKO0UVcrUBR9VmaJtQfUWK9rX3TsKRa8X/00t7OhajNZfz4IOFgaaEfzTaC Op1g== 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:mime-version :message-id:date:dkim-signature; bh=qAY3yRNcz+SqxQcajuyksWGgOqqD86eoH5VmlhhevrM=; b=ZUwPhoTnJ9ZAvr44wj/Hf/QmCYByi0PL7fzg1M1shdWUrpgu1cpIZqA0tWOSeSxGfE 6p2FXJGuKiBye9JC/VJiC50wb/BlKZyewDSoAh8SiCOQPrncjDpLvzx87G3BOlCDVBjg Cx3fOWObnZJWk3XrW8prpNaMl4nxIUxv5Xn2HbvvQSKp0eB3L4+1HH3H0ixR4OeUTfWn 940i5Wv9VBQCU8taCgxqUudwz4Hn8z8bs3koSApeKL6DLA9YKeSGLjbN2z0Cqz+/2vPw v0/F3K/sJsVg/O9PqB/+pzFxqVnzToWR4FB7S5rS1t3zBK3qqlfai+2SbfAte2ednDLr IJAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ZoE90Cpv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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. [209.132.180.67]) by mx.google.com with ESMTP id g17si2164087otk.252.2020.02.21.14.02.52; Fri, 21 Feb 2020 14:03:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=ZoE90Cpv; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 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 S1729096AbgBUWCW (ORCPT + 99 others); Fri, 21 Feb 2020 17:02:22 -0500 Received: from mail-qk1-f202.google.com ([209.85.222.202]:54280 "EHLO mail-qk1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728723AbgBUWCV (ORCPT ); Fri, 21 Feb 2020 17:02:21 -0500 Received: by mail-qk1-f202.google.com with SMTP id t185so21582qkc.21 for ; Fri, 21 Feb 2020 14:02:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=qAY3yRNcz+SqxQcajuyksWGgOqqD86eoH5VmlhhevrM=; b=ZoE90CpvzcQpMoi2f2CLd+jqrfa5sOrS1VJu5dS2XFw732ZQylP8j5+KtMp/IzLVHP ca4rFhErNyUrSvdBDxfiBHXcoP1qYPDZn706aDkq/wiWEJNS+r9r7Ums6UQ94rINkZ8M 8n+SbXOKzkkaVChG24ZPMSHB4KwIaygJqfdtGu9ipWPpW83gQLvFyXBTXRfsrDzYlfG2 aLXtNFHmNx3uTUaavNEpS9r7A8pWyWbMdiIPbBPqJGFHSjJWkjClOBD3uZBMJZCnrBxb inKb5+2aMxrsh/0OAzut8iT+gbg7gG9GCtNeqZOH4uYp4Y/Mmj7qJPZSmJBrBasF2kcj 86Ag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=qAY3yRNcz+SqxQcajuyksWGgOqqD86eoH5VmlhhevrM=; b=o9u63eckUXxt5rIvJEwqDuoDjjUBa1/b0TzqJ56v9WZde/RbTCqLxEIghpOfRPUMWV T0XNlGm8nuRzQG1VOWZWs8e3AKSpsCog0lh/0TQmlYfH/CGrsA1nB9dZK163zyflGDEP Lh+m2hR59INDpQg5+fpC/yPqZ9OKW0zQ9YKpStSKjen+ZMSbb7iswXDrrjyXcix2I4CD tmlgTHErk/ZU4h7dj95H89OImN6/u/Li4ZSW4QcKRbvH4+deWaY4jSTtkmSz2Gufe+FL OjRmVnwlsvwmeJMifRLslm4nDmQzHsQe6/qnuMPNkRbLaQaeB6bTYMV54A8m3u9z2MDr h59w== X-Gm-Message-State: APjAAAWDh4gy0wdwoOHHIpOFprqWfZKHjydYP33b3xfiGfbHjNRXuIc5 FVO7miBq6wF5uKbRRolBFlxD4ZTsAA== X-Received: by 2002:ad4:446b:: with SMTP id s11mr32028833qvt.148.1582322539123; Fri, 21 Feb 2020 14:02:19 -0800 (PST) Date: Fri, 21 Feb 2020 23:02:09 +0100 Message-Id: <20200221220209.164772-1-elver@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.25.0.265.gbab2e86ba0-goog Subject: [PATCH v2] kcsan: Add option to allow watcher interruptions From: Marco Elver To: elver@google.com Cc: paulmck@kernel.org, andreyknvl@google.com, glider@google.com, dvyukov@google.com, kasan-dev@googlegroups.com, linux-kernel@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 Add option to allow interrupts while a watchpoint is set up. This can be enabled either via CONFIG_KCSAN_INTERRUPT_WATCHER or via the boot parameter 'kcsan.interrupt_watcher=1'. Note that, currently not all safe per-CPU access primitives and patterns are accounted for, which could result in false positives. For example, asm-generic/percpu.h uses plain operations, which by default are instrumented. On interrupts and subsequent accesses to the same variable, KCSAN would currently report a data race with this option. Therefore, this option should currently remain disabled by default, but may be enabled for specific test scenarios. To avoid new warnings, changes all uses of smp_processor_id() to use the raw version (as already done in kcsan_found_watchpoint()). The exact SMP processor id is for informational purposes in the report, and correctness is not affected. Signed-off-by: Marco Elver --- v2: * Change smp_processor_id() to raw_smp_processor_id() as already used in kcsan_found_watchpoint() to avoid warnings. --- kernel/kcsan/core.c | 34 ++++++++++------------------------ lib/Kconfig.kcsan | 11 +++++++++++ 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 589b1e7f0f253..e7387fec66795 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -21,6 +21,7 @@ static bool kcsan_early_enable = IS_ENABLED(CONFIG_KCSAN_EARLY_ENABLE); static unsigned int kcsan_udelay_task = CONFIG_KCSAN_UDELAY_TASK; static unsigned int kcsan_udelay_interrupt = CONFIG_KCSAN_UDELAY_INTERRUPT; static long kcsan_skip_watch = CONFIG_KCSAN_SKIP_WATCH; +static bool kcsan_interrupt_watcher = IS_ENABLED(CONFIG_KCSAN_INTERRUPT_WATCHER); #ifdef MODULE_PARAM_PREFIX #undef MODULE_PARAM_PREFIX @@ -30,6 +31,7 @@ module_param_named(early_enable, kcsan_early_enable, bool, 0); module_param_named(udelay_task, kcsan_udelay_task, uint, 0644); module_param_named(udelay_interrupt, kcsan_udelay_interrupt, uint, 0644); module_param_named(skip_watch, kcsan_skip_watch, long, 0644); +module_param_named(interrupt_watcher, kcsan_interrupt_watcher, bool, 0444); bool kcsan_enabled; @@ -354,7 +356,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) unsigned long access_mask; enum kcsan_value_change value_change = KCSAN_VALUE_CHANGE_MAYBE; unsigned long ua_flags = user_access_save(); - unsigned long irq_flags; + unsigned long irq_flags = 0; /* * Always reset kcsan_skip counter in slow-path to avoid underflow; see @@ -370,26 +372,9 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) goto out; } - /* - * Disable interrupts & preemptions to avoid another thread on the same - * CPU accessing memory locations for the set up watchpoint; this is to - * avoid reporting races to e.g. CPU-local data. - * - * An alternative would be adding the source CPU to the watchpoint - * encoding, and checking that watchpoint-CPU != this-CPU. There are - * several problems with this: - * 1. we should avoid stealing more bits from the watchpoint encoding - * as it would affect accuracy, as well as increase performance - * overhead in the fast-path; - * 2. if we are preempted, but there *is* a genuine data race, we - * would *not* report it -- since this is the common case (vs. - * CPU-local data accesses), it makes more sense (from a data race - * detection point of view) to simply disable preemptions to ensure - * as many tasks as possible run on other CPUs. - * - * Use raw versions, to avoid lockdep recursion via IRQ flags tracing. - */ - raw_local_irq_save(irq_flags); + if (!kcsan_interrupt_watcher) + /* Use raw to avoid lockdep recursion via IRQ flags tracing. */ + raw_local_irq_save(irq_flags); watchpoint = insert_watchpoint((unsigned long)ptr, size, is_write); if (watchpoint == NULL) { @@ -507,7 +492,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) if (is_assert && value_change == KCSAN_VALUE_CHANGE_TRUE) kcsan_counter_inc(KCSAN_COUNTER_ASSERT_FAILURES); - kcsan_report(ptr, size, type, value_change, smp_processor_id(), + kcsan_report(ptr, size, type, value_change, raw_smp_processor_id(), KCSAN_REPORT_RACE_SIGNAL); } else if (value_change == KCSAN_VALUE_CHANGE_TRUE) { /* Inferring a race, since the value should not have changed. */ @@ -518,13 +503,14 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) if (IS_ENABLED(CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN) || is_assert) kcsan_report(ptr, size, type, KCSAN_VALUE_CHANGE_TRUE, - smp_processor_id(), + raw_smp_processor_id(), KCSAN_REPORT_RACE_UNKNOWN_ORIGIN); } kcsan_counter_dec(KCSAN_COUNTER_USED_WATCHPOINTS); out_unlock: - raw_local_irq_restore(irq_flags); + if (!kcsan_interrupt_watcher) + raw_local_irq_restore(irq_flags); out: user_access_restore(ua_flags); } diff --git a/lib/Kconfig.kcsan b/lib/Kconfig.kcsan index f0b791143c6ab..081ed2e1bf7b1 100644 --- a/lib/Kconfig.kcsan +++ b/lib/Kconfig.kcsan @@ -88,6 +88,17 @@ config KCSAN_SKIP_WATCH_RANDOMIZE KCSAN_WATCH_SKIP. If false, the chosen value is always KCSAN_WATCH_SKIP. +config KCSAN_INTERRUPT_WATCHER + bool "Interruptible watchers" + help + If enabled, a task that set up a watchpoint may be interrupted while + delayed. This option will allow KCSAN to detect races between + interrupted tasks and other threads of execution on the same CPU. + + Currently disabled by default, because not all safe per-CPU access + primitives and patterns may be accounted for, and therefore could + result in false positives. + config KCSAN_REPORT_ONCE_IN_MS int "Duration in milliseconds, in which any given race is only reported once" default 3000 -- 2.25.0.265.gbab2e86ba0-goog