Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp1367864ybg; Thu, 4 Jun 2020 08:02:03 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwxXeS1oCklkhrVlHZOBIJbAfuIYBizgJ38xDxeNrs9o3LlYAiFLpTCtc/vZUwd6zvaLjcU X-Received: by 2002:a17:906:16d3:: with SMTP id t19mr4087312ejd.297.1591282923593; Thu, 04 Jun 2020 08:02:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591282923; cv=none; d=google.com; s=arc-20160816; b=CejQXr3/GDC7e1n2SS4oaU0/Fpt4AVPzTEf+secqr97YDH9I7x6304WoQCai/e+G4H XWrjYuMCY+4B3Oc55c28gEVUbC6sc4f29E6ciNA/UOmd0dKCwSkojKPv10a//mrsgNuk Yd9IbBvJLEMxOb5N+mOjjMU99gZlCWeBWmmbo9uH2XNbjZE3qkLayI6pbQJRIAjmE/of c3n3rW6wzfqXLTtVu4taPal3xI+P96kg+FKRy/omsyVKM7h0j0hGwzJvblWT9MmQiAP7 VK4204ZChlH9hLkKm1WjZa+eyCTHb1gbUJTJiUSh3iY1j3qE5znL5SvGtBUMDAJkKXR4 lvug== 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=I7c54UO+jBDB8Mu0xGlRZFnGkQOtoIXkr80oIo5a6yg=; b=O9rGlhXd5I7uDEUvdS2tsny7BQeZrNvzUyKmy5DkQuNjXNB1mN0KYsFeJ6tQzRLC21 DsWLB7gd6kySaVynInXxVgdMCW1E8btI/9bQ+pic4qKA4o28nw/aFIB5FiejMP7wJMOc LZevN1nCnV514SK+3VUg9Jj5pM+o/QA+E1oX/Vtk6HYrtccsvqwt92Ahr5pbccerbTsm qUYBez2o5V/oDQm1nVJZqd9wbTRnuF+6mZY1njO/jkBvceIxVi+YWc33meKp4KAZjPhS ignLXfKXWwyeMOerCYrqIxw5JnXelyf3Jdi+a/qAwE/w382mVgcCUpqAigI1WAc03Jrk LCtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=WdAR16zY; 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 d17si1563759eje.142.2020.06.04.08.01.36; Thu, 04 Jun 2020 08:02:03 -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=WdAR16zY; 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 S1729171AbgFDO4y (ORCPT + 99 others); Thu, 4 Jun 2020 10:56:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729153AbgFDO4r (ORCPT ); Thu, 4 Jun 2020 10:56:47 -0400 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D764FC08C5C0 for ; Thu, 4 Jun 2020 07:56:46 -0700 (PDT) Received: by mail-qk1-x749.google.com with SMTP id i82so3860860qke.10 for ; Thu, 04 Jun 2020 07:56:46 -0700 (PDT) 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=I7c54UO+jBDB8Mu0xGlRZFnGkQOtoIXkr80oIo5a6yg=; b=WdAR16zYbaIpErpsEUjQUxhf/HVJmWp9W2xV9KUpPSOChHzHXHifTJoWwWOYOgQr66 0tu9vvF0JqyYKkPP+BQVmRzBp26oSZ6f5MBQIGKG9QuJ+2MeZlMY19pWKVIj+DjzY8x+ IFeOAnr488HRfID5IN9RfVX7CdLbjjQrnAA6c6fCFlYMlZ385fOeMUsizNK0tkN+DBK7 M3P20DNhi79d33RVXcTSYH8WcEQjbOohH22CnJjNh7PCoeNx0EGyMUlhMdc59XV2JLn9 1+s2pMv/7JWlvLF+V2r97qS7XXEKlFVPKO7k/2NxgzCW1Gu8GNAKXCbVEp2GmdyG9Ytf hksA== 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=I7c54UO+jBDB8Mu0xGlRZFnGkQOtoIXkr80oIo5a6yg=; b=WJYnH5y9t2LW7o802HIaDiVUdTub/paXHaG+inwWhkL3FWF1NUpRvA7F8v3yC1ntyK nSqINW0JP9DgPM3zvyHKxvJbpUbgln7j4/nzwybkRTllFczQFJhwOvtSSzUqljLBVaJj yNNQTQk2vj+kL9HRO0fjWm2f1tEptRGqR0xWiSM5ZCm+e1JSmiNMLGY05LuWueKqMgJF gQvAHwj5wQllauz6X2Kw9LdLxYqJp52pv2Ti5c8ppf7ymOAhAlazlTTbWWHmc4CHwOgJ A+PAkaJA8zpN7t+Ta6ZjvXyua495LeCQlw0gHInD7Zn2GN49nVXeIM2S07vXdEYlhKHd 1TJg== X-Gm-Message-State: AOAM5302lHlJSLhJFLzGx04a+ttmroY4PFMHOBWwLWq856okVrByaJeY jvMfp/nwjz3iIh0NTKfl0ioq5lY6qA== X-Received: by 2002:ad4:556b:: with SMTP id w11mr5001166qvy.171.1591282605967; Thu, 04 Jun 2020 07:56:45 -0700 (PDT) Date: Thu, 4 Jun 2020 16:56:34 +0200 Message-Id: <20200604145635.21565-1-elver@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.27.0.rc2.251.g90737beb825-goog Subject: [PATCH v2 1/2] kcov, objtool: Make runtime functions noinstr-compatible From: Marco Elver To: elver@google.com Cc: peterz@infradead.org, bp@alien8.de, tglx@linutronix.de, mingo@kernel.org, clang-built-linux@googlegroups.com, paulmck@kernel.org, dvyukov@google.com, glider@google.com, andreyknvl@google.com, kasan-dev@googlegroups.com, linux-kernel@vger.kernel.org, x86@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 While we lack a compiler attribute to add to noinstr that would disable KCOV, make the KCOV runtime functions return if the caller is in a noinstr section. We then whitelist __sanitizer_cov_*() functions in objtool. __sanitizer_cov_*() cannot safely become safe noinstr functions as-is, as they may fault due to accesses to vmalloc's memory. Declare write_comp_data() as __always_inline to ensure it is inlined, and reduce stack usage and remove one extra call from the fast-path. In future, our compilers may provide an attribute to implement __no_sanitize_coverage, which can then be added to noinstr, and the checks added in this patch can be guarded by an #ifdef checking if the compiler has such an attribute or not. Signed-off-by: Marco Elver --- Apply after: https://lkml.kernel.org/r/20200604102241.466509982@infradead.org v2: * Rewrite based on Peter's and Andrey's feedback -- v1 worked because we got lucky. Let's not rely on luck, as it will be difficult to ensure the same conditions remain true in future. v1: https://lkml.kernel.org/r/20200604095057.259452-1-elver@google.com Note: There are a set of KCOV patches from Andrey in -next: https://lkml.kernel.org/r/cover.1585233617.git.andreyknvl@google.com -- Git cleanly merges this patch with those patches, and no merge conflict is expected. --- kernel/kcov.c | 19 +++++++++++++++++-- tools/objtool/check.c | 7 +++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 8accc9722a81..3329a0fdb868 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -24,6 +24,7 @@ #include #include #include +#include #define kcov_debug(fmt, ...) pr_debug("%s: " fmt, __func__, ##__VA_ARGS__) @@ -172,6 +173,12 @@ static notrace unsigned long canonicalize_ip(unsigned long ip) return ip; } +static __always_inline bool in_noinstr_section(unsigned long ip) +{ + return (unsigned long)__noinstr_text_start <= ip && + ip < (unsigned long)__noinstr_text_end; +} + /* * Entry point from instrumented code. * This is called once per basic-block/edge. @@ -180,13 +187,18 @@ void notrace __sanitizer_cov_trace_pc(void) { struct task_struct *t; unsigned long *area; - unsigned long ip = canonicalize_ip(_RET_IP_); + unsigned long ip; unsigned long pos; + if (unlikely(in_noinstr_section(_RET_IP_))) + return; + t = current; if (!check_kcov_mode(KCOV_MODE_TRACE_PC, t)) return; + ip = canonicalize_ip(_RET_IP_); + area = t->kcov_area; /* The first 64-bit word is the number of subsequent PCs. */ pos = READ_ONCE(area[0]) + 1; @@ -198,12 +210,15 @@ void notrace __sanitizer_cov_trace_pc(void) EXPORT_SYMBOL(__sanitizer_cov_trace_pc); #ifdef CONFIG_KCOV_ENABLE_COMPARISONS -static void notrace write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip) +static __always_inline void write_comp_data(u64 type, u64 arg1, u64 arg2, u64 ip) { struct task_struct *t; u64 *area; u64 count, start_index, end_pos, max_pos; + if (unlikely(in_noinstr_section(ip))) + return; + t = current; if (!check_kcov_mode(KCOV_MODE_TRACE_CMP, t)) return; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3e214f879ada..cb208959f560 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2213,6 +2213,13 @@ static inline bool noinstr_call_dest(struct symbol *func) if (!strncmp(func->name, "__ubsan_handle_", 15)) return true; + /* + * The __sanitizer_cov_*() calls include a check if the caller is in the + * noinstr section, and simply return if that is the case. + */ + if (!strncmp(func->name, "__sanitizer_cov_", 16)) + return true; + return false; } -- 2.27.0.rc2.251.g90737beb825-goog