From patchwork Mon Jul 29 02:21:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: andrey.konovalov@linux.dev X-Patchwork-Id: 13744183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7DF52C3DA64 for ; Mon, 29 Jul 2024 02:22:09 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1E8F36B0095; Sun, 28 Jul 2024 22:22:09 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 1BF186B0099; Sun, 28 Jul 2024 22:22:09 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 086B06B009A; Sun, 28 Jul 2024 22:22:09 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id DD4876B0099 for ; Sun, 28 Jul 2024 22:22:08 -0400 (EDT) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 9FC14A02E1 for ; Mon, 29 Jul 2024 02:22:08 +0000 (UTC) X-FDA: 82391190336.07.132E583 Received: from out-176.mta1.migadu.com (out-176.mta1.migadu.com [95.215.58.176]) by imf03.hostedemail.com (Postfix) with ESMTP id DDD242000D for ; Mon, 29 Jul 2024 02:22:05 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b=htsvdPzt; spf=pass (imf03.hostedemail.com: domain of andrey.konovalov@linux.dev designates 95.215.58.176 as permitted sender) smtp.mailfrom=andrey.konovalov@linux.dev; dmarc=pass (policy=none) header.from=linux.dev ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722219674; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=LsRQ18TXosCV7Zr1JLjd4CYqcPz8tKyiBF4C+fLmLDs=; b=z00tpOKP8+q142suDYVycfGwnpRV2BInEptSA9tyqwU49n9tJf31LjpfbByITGdqMFfKQu UdwtyuXUzwxkD6bM8oynmJ5Z7aeqIy3mW4JM232DzQUKfJ13l+MerGZW6Iflg9aENfeI1I lM+6hn2kgeQCkjR/pe9dqZE3yiDJILk= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722219674; a=rsa-sha256; cv=none; b=N3jfJnFZ0CUYIgWn3CYVCzg2UWN7uIQAKWWw8jaTuI8qju2bV6vTTv6kVUyIowSpVgd7k5 mxOSxS4Nx0JLQKJmAJt7fiLCpWlcVwHlkKORw3OvUXp+k+5VmPgaEX7MYIqNWfo4y4NWrI jR0MbfMPIYjSJgEltjMINGfFy3N6VTY= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=linux.dev header.s=key1 header.b=htsvdPzt; spf=pass (imf03.hostedemail.com: domain of andrey.konovalov@linux.dev designates 95.215.58.176 as permitted sender) smtp.mailfrom=andrey.konovalov@linux.dev; dmarc=pass (policy=none) header.from=linux.dev X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1722219723; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=LsRQ18TXosCV7Zr1JLjd4CYqcPz8tKyiBF4C+fLmLDs=; b=htsvdPztIF2VBaEHJS0GKwyJigWRbUzeMGL2rUhSOgsqkALXSnbz73zJesuuqwlWngTseA D3N9M+ptlbThvav7arA5zZ0y7fw3NCh+nmFOexeGT0m75SpxU4zw81qQFJK6GnpUJuZH1t +sZpP0x8gpe4Fp6GHA+TdAm5rwWPlLI= From: andrey.konovalov@linux.dev To: Dmitry Vyukov , Andrew Morton Cc: Andrey Konovalov , Aleksandr Nogikh , Marco Elver , Alexander Potapenko , kasan-dev@googlegroups.com, linux-mm@kvack.org, Alan Stern , Greg Kroah-Hartman , Marcello Sylvester Bauer , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, syzbot+2388cdaeb6b10f0c13ac@syzkaller.appspotmail.com, stable@vger.kernel.org Subject: [PATCH] kcov: properly check for softirq context Date: Mon, 29 Jul 2024 04:21:58 +0200 Message-Id: <20240729022158.92059-1-andrey.konovalov@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: DDD242000D X-Stat-Signature: 83jx5aaqdcnadra4ike7riii9s8zgoww X-HE-Tag: 1722219725-299891 X-HE-Meta: U2FsdGVkX19kSzrFXpLxC810fRsJTrV3ZGDHxpepTWos0JB+iPNORkmeU3gqICyO3xuoV3/JWg6mPN3AqgYPulJE6L7u1yEHcIVZqHWfHfFT9sgAUaNXyqXwz/m774OOUjaUfpbxW9kmJ4qN5tbGDfnlRMEPop0dyqRqUZWawBv5EdT6CK80XR61S6IkQdK/XXhmePC5LiT7azBGpC91q4HJ2vkQcFmB20sjZzF3Ev6qMaNdvuexDcm4Pf/9TJ/TN0UyZ2gtoFEq9vM+2gW3C1drtZZljq/sX25JJixlqCulPoKGmAyMZLznfqSP2x2sS7Id0bxlNUyFmgXr/7aBqRsP6Mq1HwhxKCr6juu0lkVstj9KLerQdGaO7pufycoQFCGq1Mbyy/lnZOwXQnyyKwt90q9cPOPzeLhzuHCPyBpGcIt/8yRh+LDuHyXU5h2r9yO4/eCcYswXdzvdD6SKz9a6wxg/OVuQI6QjBTghRjUhfx+zrBcmTERnuLSaFCyDZNrx8U9BcjPYc97Td5YemAmgxV8+Wy0C/1Zv1vIaqjRUjR/PrmzCqpdf7xI6QOGLqc7HZn2blk/RA8qlO8Is9xQPq7lZd+OqBU5oDB0/r9gqmyVgSslDfDTy7ys9GeeVsXcq8fToULRJ2VGfd72U5DAe89tEdZYUe1hUzFfn+ObyF2ZcigVsEj6XuRHL+fG6EFD455WImxHks+WerxKWSOJTLomcegxVWyRlFidkKhadk2lbG8y26oTocT/EuoSs2ZVj968g3AwMCklAG3TdkCiPcpHmTVwvJgw8C8PEzAw12gloUgsIjxq+G2utycfF0MM7MGHVjytYHFigGdbUpdn6GOiN/J0QVUx00Lsnjq9BrpX99fM89ykWHXY6OYgNfJOsPQ6MDv1v7yjf5Qy3md/RYuLSUNC2B/u+uW7vHmZbUvV1uWy7CmIL9HR4a6mzbfvR9v44iIUJKs7zxk/ vd3jWo34 spy2eMjWYxZ1DXdjVDumRA33M2X6fze2ay6xq0l0V5tbQ5a2+SLXFl/ggn8wDdjc7X67x5bWn5mPVZeBYbChCjWuJzsEt8BPcXDuuXVSJLMJ6+xCXQ7kgqNrnXoAWw41jwFICEiie5U1rZZupVyeQ8c8BQBEAtg+1HVpfWMA032AKevdUa77pQv0J3Dv8+NZx0Z+wfP8skwLkIwEecZyRCFpbnmqoYUBKYTE8xGppzxept+v8UmAPLdLak4MYPgedBCy44mzzgokY9JUT9yAsQDtpSmxesqslaBbBfpoRWQ32MKUlsy6wvMksY459L74wvV6a/a6q1qYJyPXzhybhDeShwz4TgRu/vhJvq7S5SWMeWrtRMxeX3HDDzYUBqaeZGo12GavhuQkPRSAFZV15LOUdbxhavqUVduxx X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Andrey Konovalov When collecting coverage from softirqs, KCOV uses in_serving_softirq() to check whether the code is running in the softirq context. Unfortunately, in_serving_softirq() is > 0 even when the code is running in the hardirq or NMI context for hardirqs and NMIs that happened during a softirq. As a result, if a softirq handler contains a remote coverage collection section and a hardirq with another remote coverage collection section happens during handling the softirq, KCOV incorrectly detects a nested softirq coverate collection section and prints a WARNING, as reported by syzbot. This issue was exposed by commit a7f3813e589f ("usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler"), which switched dummy_hcd to using hrtimer and made the timer's callback be executed in the hardirq context. Change the related checks in KCOV to account for this behavior of in_serving_softirq() and make KCOV ignore remote coverage collection sections in the hardirq and NMI contexts. This prevents the WARNING printed by syzbot but does not fix the inability of KCOV to collect coverage from the __usb_hcd_giveback_urb when dummy_hcd is in use (caused by a7f3813e589f); a separate patch is required for that. Reported-by: syzbot+2388cdaeb6b10f0c13ac@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=2388cdaeb6b10f0c13ac Fixes: 5ff3b30ab57d ("kcov: collect coverage from interrupts") Cc: stable@vger.kernel.org Signed-off-by: Andrey Konovalov Acked-by: Marco Elver --- kernel/kcov.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index f0a69d402066e..274b6b7c718de 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -161,6 +161,15 @@ static void kcov_remote_area_put(struct kcov_remote_area *area, kmsan_unpoison_memory(&area->list, sizeof(area->list)); } +/* + * Unlike in_serving_softirq(), this function returns false when called during + * a hardirq or an NMI that happened in the softirq context. + */ +static inline bool in_softirq_really(void) +{ + return in_serving_softirq() && !in_hardirq() && !in_nmi(); +} + static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_struct *t) { unsigned int mode; @@ -170,7 +179,7 @@ static notrace bool check_kcov_mode(enum kcov_mode needed_mode, struct task_stru * so we ignore code executed in interrupts, unless we are in a remote * coverage collection section in a softirq. */ - if (!in_task() && !(in_serving_softirq() && t->kcov_softirq)) + if (!in_task() && !(in_softirq_really() && t->kcov_softirq)) return false; mode = READ_ONCE(t->kcov_mode); /* @@ -849,7 +858,7 @@ void kcov_remote_start(u64 handle) if (WARN_ON(!kcov_check_handle(handle, true, true, true))) return; - if (!in_task() && !in_serving_softirq()) + if (!in_task() && !in_softirq_really()) return; local_lock_irqsave(&kcov_percpu_data.lock, flags); @@ -991,7 +1000,7 @@ void kcov_remote_stop(void) int sequence; unsigned long flags; - if (!in_task() && !in_serving_softirq()) + if (!in_task() && !in_softirq_really()) return; local_lock_irqsave(&kcov_percpu_data.lock, flags);