From nobody Sun Oct 5 14:45:20 2025 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2483823645D; Sun, 3 Aug 2025 07:22:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205731; cv=none; b=ATJz/Gajk27f2i769O5sESGv3e58RUre4hOABMcC8RihWW1OLmkeqoyzJb6C8/KZ7boED2hF0StLKWk9lEtUnaK79rTdNawAqvBg8Q0UtJ7ryyiDPVnPVoJvdCV+rVLSJ3O2gSXoegbqNfwUys0v9QNxjDMkOseCLDmv9KlAcZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205731; c=relaxed/simple; bh=fUq2Li45YAs5PecAJwEYKmqj5OXZ+QBFxr7/0K55pqs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uhikyywkPPVuMtl33aTAIFK9ValxNtiK9Cr2CPkKXhxtPOjdj1lI+dNDJ7kS9zo7cGwZMQcIgzbN5RwjNe8xNwfm3o87vkJPaflGt639Y+qrkgsma8F4ks7yZRrArz/KGZ80t1P64WG2ot4ztfcJOhgcHQ7tNDsJcfQsjcc7rYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.216.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-31f5ed172daso537861a91.2; Sun, 03 Aug 2025 00:22:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754205729; x=1754810529; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=v5kjPMrRx3BCdvtMiXfak7wOA3clQMtvTSjhTHkH/fI=; b=M71yEWNYmY+U69p5hMnfKyfCm9M3+45okCcR0sSVIXtXrbowjvQBuNwnruTydGVnN9 aTQoBzMcuTKYRh4dd2IeG5AVGuMqWgx7FGxhxAFvyZZ6egfv0Bhq8k2ItdPQmnYQcxMw KHht/Uuw05vJndm6deqQPN084R45/F7SXNibAWydPiIRqVQ+tYRnyDXJCL4oU0uEKN9e txOswNCZhf53TX0DyzXDlDkFGuIoo7gAqenDsMsO0oViSKnCL8i3RTLv2wxImg3HKj5x AT0gZHVn5vIFLKIJIS2qoZv7C6z18yXHus9L6G/yQnuIPdB4hkRLxtz8tL/JYN1cQVFw cDjw== X-Forwarded-Encrypted: i=1; AJvYcCUXTDx/7lkEIZ7h5Y1jE+NJfhObu+mhqHF9cTIbrY2PJkdlTlV9bcRdsbVPGLLpQoj+ODImHwg+@vger.kernel.org, AJvYcCWpajzvzqcSxSXqmho2abYgRhvFCRu4vEeGKiQ7r2ea07n67gH7TTQO8pVGERG5X4pDr3Ldo/KYaYZF@vger.kernel.org, AJvYcCXP67LkfTa0jV4KBE1HRNOGxz1gDAMv2KO/PEg3wa4le2RJXrY/TuPhWZIiuJapKnvidtI35eH7hAGYImU=@vger.kernel.org X-Gm-Message-State: AOJu0YwQw4sDv21OuYUoZ3/99DMkEAr6dStSVPXx3LR5BL52qHrLB1y3 lnr+DRSQ3v9iJF1xKp+6fGpthdoluP1swu8zrDQ/S7DTFlPwGxP+2O+B X-Gm-Gg: ASbGnctZEsJv5Ck69HHt+DQxSR0LZGKcVb9KndxUn4+FmHKeRgRK7tde0RH7EGSTKek UKz+yd4ZvcYzKYEdB2zWmtwLLNvrXCKQazE+UUGYdVcdiljiYcXTdKOS/O7ehxaN8kC+ze9OwTz xc5s3RQusyqpmA67pzD3CHR1+/avj80SIzZ5ICmQtMkX0xTDzpIoS8FrWeFC5g0cvR7ZA8Rafti UIOeQIIr/cWXk+jmGpIig4Y0rQpX5wSnfpJH4TDxmnPSuOckF9qB+ygWmn+7VeIjzRQgAEkYRNe VJT6bRupSXf3wLSyq+g9R38aj6sJ5NzFIPX6yOd53XlBlYdgqu0nolXQNJcSbAaJmeh0l5ev597 aoaKCCCnT9CZ+ X-Google-Smtp-Source: AGHT+IFzgXBZ0NZjupPHVGqHGMmkqaVS7ylijLqV9m9w7OOaDlsbddfVokWVO7AIwAG6VLW8O6BILQ== X-Received: by 2002:a05:6a20:9f86:b0:1ee:d621:3c3f with SMTP id adf61e73a8af0-23df8d6cec9mr3955467637.0.1754205729321; Sun, 03 Aug 2025 00:22:09 -0700 (PDT) Received: from localhost ([218.152.98.97]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b423d2f4fcesm4517004a12.33.2025.08.03.00.22.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Aug 2025 00:22:08 -0700 (PDT) From: Yunseong Kim To: Dmitry Vyukov , Andrey Konovalov , Greg Kroah-Hartman Cc: Thomas Gleixner , Sebastian Andrzej Siewior , Tetsuo Handa , Byungchul Park , max.byungchul.park@gmail.com, Yeoreum Yun , ppbuk5246@gmail.com, linux-usb@vger.kernel.org, linux-rt-devel@lists.linux.dev, syzkaller@googlegroups.com, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Yunseong Kim Subject: [PATCH 1/4] kcov: Use raw_spinlock_t for kcov->lock and kcov_remote_lock Date: Sun, 3 Aug 2025 07:20:43 +0000 Message-ID: <20250803072044.572733-4-ysk@kzalloc.com> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250803072044.572733-2-ysk@kzalloc.com> References: <20250803072044.572733-2-ysk@kzalloc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The locks kcov->lock and kcov_remote_lock can be acquired from atomic contexts, such as instrumentation hooks invoked from interrupt handlers. On PREEMPT_RT-enabled kernels, spinlock_t is typically implemented as a sleeping lock (e.g., mapped to an rt_mutex). Acquiring such a lock in atomic context, where sleeping is not allowed, can lead to system hangs or crashes. To avoid this, convert both locks to raw_spinlock_t, which always provides non-sleeping spinlock semantics regardless of preemption model. Signed-off-by: Yunseong Kim Reviewed-by: Steven Rostedt (Google) --- kernel/kcov.c | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 187ba1b80bda..7d9b53385d81 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -54,7 +54,7 @@ struct kcov { */ refcount_t refcount; /* The lock protects mode, size, area and t. */ - spinlock_t lock; + raw_spinlock_t lock; enum kcov_mode mode; /* Size of arena (in long's). */ unsigned int size; @@ -84,7 +84,7 @@ struct kcov_remote { struct hlist_node hnode; }; =20 -static DEFINE_SPINLOCK(kcov_remote_lock); +static DEFINE_RAW_SPINLOCK(kcov_remote_lock); static DEFINE_HASHTABLE(kcov_remote_map, 4); static struct list_head kcov_remote_areas =3D LIST_HEAD_INIT(kcov_remote_a= reas); =20 @@ -406,7 +406,7 @@ static void kcov_remote_reset(struct kcov *kcov) struct hlist_node *tmp; unsigned long flags; =20 - spin_lock_irqsave(&kcov_remote_lock, flags); + raw_spin_lock_irqsave(&kcov_remote_lock, flags); hash_for_each_safe(kcov_remote_map, bkt, tmp, remote, hnode) { if (remote->kcov !=3D kcov) continue; @@ -415,7 +415,7 @@ static void kcov_remote_reset(struct kcov *kcov) } /* Do reset before unlock to prevent races with kcov_remote_start(). */ kcov_reset(kcov); - spin_unlock_irqrestore(&kcov_remote_lock, flags); + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); } =20 static void kcov_disable(struct task_struct *t, struct kcov *kcov) @@ -450,7 +450,7 @@ void kcov_task_exit(struct task_struct *t) if (kcov =3D=3D NULL) return; =20 - spin_lock_irqsave(&kcov->lock, flags); + raw_spin_lock_irqsave(&kcov->lock, flags); kcov_debug("t =3D %px, kcov->t =3D %px\n", t, kcov->t); /* * For KCOV_ENABLE devices we want to make sure that t->kcov->t =3D=3D t, @@ -475,12 +475,12 @@ void kcov_task_exit(struct task_struct *t) * By combining all three checks into one we get: */ if (WARN_ON(kcov->t !=3D t)) { - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); return; } /* Just to not leave dangling references behind. */ kcov_disable(t, kcov); - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); kcov_put(kcov); } =20 @@ -492,14 +492,14 @@ static int kcov_mmap(struct file *filep, struct vm_ar= ea_struct *vma) struct page *page; unsigned long flags; =20 - spin_lock_irqsave(&kcov->lock, flags); + raw_spin_lock_irqsave(&kcov->lock, flags); size =3D kcov->size * sizeof(unsigned long); if (kcov->area =3D=3D NULL || vma->vm_pgoff !=3D 0 || vma->vm_end - vma->vm_start !=3D size) { res =3D -EINVAL; goto exit; } - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); vm_flags_set(vma, VM_DONTEXPAND); for (off =3D 0; off < size; off +=3D PAGE_SIZE) { page =3D vmalloc_to_page(kcov->area + off); @@ -511,7 +511,7 @@ static int kcov_mmap(struct file *filep, struct vm_area= _struct *vma) } return 0; exit: - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); return res; } =20 @@ -525,7 +525,7 @@ static int kcov_open(struct inode *inode, struct file *= filep) kcov->mode =3D KCOV_MODE_DISABLED; kcov->sequence =3D 1; refcount_set(&kcov->refcount, 1); - spin_lock_init(&kcov->lock); + raw_spin_lock_init(&kcov->lock); filep->private_data =3D kcov; return nonseekable_open(inode, filep); } @@ -646,18 +646,18 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsig= ned int cmd, kcov->t =3D t; kcov->remote =3D true; kcov->remote_size =3D remote_arg->area_size; - spin_lock_irqsave(&kcov_remote_lock, flags); + raw_spin_lock_irqsave(&kcov_remote_lock, flags); for (i =3D 0; i < remote_arg->num_handles; i++) { if (!kcov_check_handle(remote_arg->handles[i], false, true, false)) { - spin_unlock_irqrestore(&kcov_remote_lock, + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); kcov_disable(t, kcov); return -EINVAL; } remote =3D kcov_remote_add(kcov, remote_arg->handles[i]); if (IS_ERR(remote)) { - spin_unlock_irqrestore(&kcov_remote_lock, + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); kcov_disable(t, kcov); return PTR_ERR(remote); @@ -666,7 +666,7 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigne= d int cmd, if (remote_arg->common_handle) { if (!kcov_check_handle(remote_arg->common_handle, true, false, false)) { - spin_unlock_irqrestore(&kcov_remote_lock, + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); kcov_disable(t, kcov); return -EINVAL; @@ -674,14 +674,14 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsig= ned int cmd, remote =3D kcov_remote_add(kcov, remote_arg->common_handle); if (IS_ERR(remote)) { - spin_unlock_irqrestore(&kcov_remote_lock, + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); kcov_disable(t, kcov); return PTR_ERR(remote); } t->kcov_handle =3D remote_arg->common_handle; } - spin_unlock_irqrestore(&kcov_remote_lock, flags); + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); /* Put either in kcov_task_exit() or in KCOV_DISABLE. */ kcov_get(kcov); return 0; @@ -716,16 +716,16 @@ static long kcov_ioctl(struct file *filep, unsigned i= nt cmd, unsigned long arg) area =3D vmalloc_user(size * sizeof(unsigned long)); if (area =3D=3D NULL) return -ENOMEM; - spin_lock_irqsave(&kcov->lock, flags); + raw_spin_lock_irqsave(&kcov->lock, flags); if (kcov->mode !=3D KCOV_MODE_DISABLED) { - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); vfree(area); return -EBUSY; } kcov->area =3D area; kcov->size =3D size; kcov->mode =3D KCOV_MODE_INIT; - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); return 0; case KCOV_REMOTE_ENABLE: if (get_user(remote_num_handles, (unsigned __user *)(arg + @@ -749,9 +749,9 @@ static long kcov_ioctl(struct file *filep, unsigned int= cmd, unsigned long arg) * All other commands can be normally executed under a spin lock, so we * obtain and release it here in order to simplify kcov_ioctl_locked(). */ - spin_lock_irqsave(&kcov->lock, flags); + raw_spin_lock_irqsave(&kcov->lock, flags); res =3D kcov_ioctl_locked(kcov, cmd, arg); - spin_unlock_irqrestore(&kcov->lock, flags); + raw_spin_unlock_irqrestore(&kcov->lock, flags); kfree(remote_arg); return res; } @@ -883,10 +883,10 @@ void kcov_remote_start(u64 handle) return; } =20 - spin_lock(&kcov_remote_lock); + raw_spin_lock(&kcov_remote_lock); remote =3D kcov_remote_find(handle); if (!remote) { - spin_unlock(&kcov_remote_lock); + raw_spin_unlock(&kcov_remote_lock); local_unlock_irqrestore(&kcov_percpu_data.lock, flags); return; } @@ -908,7 +908,7 @@ void kcov_remote_start(u64 handle) size =3D CONFIG_KCOV_IRQ_AREA_SIZE; area =3D this_cpu_ptr(&kcov_percpu_data)->irq_area; } - spin_unlock(&kcov_remote_lock); + raw_spin_unlock(&kcov_remote_lock); =20 /* Can only happen when in_task(). */ if (!area) { @@ -1037,19 +1037,19 @@ void kcov_remote_stop(void) kcov_remote_softirq_stop(t); } =20 - spin_lock(&kcov->lock); + raw_spin_lock(&kcov->lock); /* * KCOV_DISABLE could have been called between kcov_remote_start() * and kcov_remote_stop(), hence the sequence check. */ if (sequence =3D=3D kcov->sequence && kcov->remote) kcov_move_area(kcov->mode, kcov->area, kcov->size, area); - spin_unlock(&kcov->lock); + raw_spin_unlock(&kcov->lock); =20 if (in_task()) { - spin_lock(&kcov_remote_lock); + raw_spin_lock(&kcov_remote_lock); kcov_remote_area_put(area, size); - spin_unlock(&kcov_remote_lock); + raw_spin_unlock(&kcov_remote_lock); } =20 local_unlock_irqrestore(&kcov_percpu_data.lock, flags); --=20 2.50.0 From nobody Sun Oct 5 14:45:20 2025 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32EB64315C; Sun, 3 Aug 2025 07:22:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205757; cv=none; b=e1P+9SoSPUHUyBtOGchsLsd7QA5jnCFaDM4gKYN7gFzPwqDkeg9kysxYMbAMXlPTBLNdGBJNnZCZuSPwoEEJETwONewwzX8eiVYhlSSPALEGoZc/y7HxwoSwWGyOYCNiqqXmfsMzM1dP/7nxHLYYNZ32EB9do1O3H0f8ovrUoXU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205757; c=relaxed/simple; bh=a1wPu7qWEqbXSE3m92o14aGzkXL9K+CEYt6wZ0QdWlg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=neAlvVSfEF/bRBbcJ1ZmNqK9hW3nsJM1h8QA6FTEuESPcuxT+Dz4Y8fr3Lp4giwofYwUkAUbXVJqO+vy6O0n+zgtomWQ1gHp+TWCiwelMjlDa6XMMd4rbwwVFH6iT6gBgJqkvfM6C7nDCLOugRKPxNkLNnnv0o0ocv5YeH5CloU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2420c9e3445so5047395ad.2; Sun, 03 Aug 2025 00:22:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754205755; x=1754810555; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7jgd1GNOsYadrfuybM239b5t7yZLqoDPXrAoeKpSwNM=; b=IItYMoWkBUpuvrXAVvGV0EYE5mrX6JTBqaPc2+d7LlPXlOKejf/HI9RyXH/VMgQLCL Exj6JklMBMTflv9nmDBRKuhXFUpU79zwqIH3uMjSTrcHHeDwOQOEH2ALlU7M7jAQsPUw asUhY7ae5/+DFI1n1F1zjd8iahs770yqYqXM0toT15xlO9HuynkFuOFXeQYyCobRH8SJ RqVJkpLds0mmzuyyN4+KaGhxltbPybwcuDbqyW64UQ129QAA38bQKjabAEI3Xzg/0U0x xKwL6wlSdLDmKNEWCJ3QuHeNXKDbm8KxfpPNfJcvKGyv911UmrauCuvxb0QflE8fA3SY Z2Ag== X-Forwarded-Encrypted: i=1; AJvYcCUFFB+pq40RViIh9UeQBFBVeW4xWMZyrxumwM+r0l/2nrAh/DVZPb80oFfPzrWEINGruu2HeoIp@vger.kernel.org, AJvYcCWrJsrmXCiqSwIuRZtNyKoq/1O8j2dMi6mK3fZpfYWG7i+XQz8umeyGnbhxz0fSx3MUy36IgRAwMlt0qCw=@vger.kernel.org, AJvYcCWzEzKHkANvoiWTouuWICjTk7qFrJ7mFE8If4RZbTXrNSjexjGeeICkzizAWRrdcgFHZihcTJ1c4yY3@vger.kernel.org X-Gm-Message-State: AOJu0Yw1y4iHbijKznacd7LmF/JammEBj2EUXu+cyO+AUBq5XEjhWnkx fnefwkFTNlBbP+jR8DtFUB3+BjEUbw168umVhHVjwidq/bVaoXNJ9Hav X-Gm-Gg: ASbGnctrFoWV5v0hjYuobeeiCnrXkytEi1plIbJwuqdqoJFKwy51ocLFnfjqiKIKy0K Q4IfNTumgw49IiGgDc9ygdbQOHsU52Dyjv6thE9/mcUI0Log2HDPtGGDluv6F4vQ04WnD0opepY KiKRA8bns8DU0Q6MbRapOSun63SQKHwi+IjgwsThiraN62aZNmoTrZHjNJA2KlH+tvDW30NidTT tGXAjva9tBUL/laWhb1wAOSAOMEECr2Ui3o6MIbLFusav8BYFMJV2JLxhrfFikiepfmDgrAlf+q QyDjKDMs2LiSTfFV6YhPok3j1sRaLLEdBPB/t2DMEML+BSo4bXz0Ke9d3PRsS6ir9EXCt8voVb4 awC93FfOOE0Hu X-Google-Smtp-Source: AGHT+IEExGu5iIl8dO34DlMWk4OmiF1INIjAC/Q4dK9xAmegQ7x38dfO88DNWfygHfkGxkMXswX2Fw== X-Received: by 2002:a05:6a20:748c:b0:230:aa8c:f729 with SMTP id adf61e73a8af0-23df8e3d03emr3551485637.0.1754205755356; Sun, 03 Aug 2025 00:22:35 -0700 (PDT) Received: from localhost ([218.152.98.97]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b423d2f4fcesm4517004a12.33.2025.08.03.00.22.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Aug 2025 00:22:35 -0700 (PDT) From: Yunseong Kim To: Dmitry Vyukov , Andrey Konovalov , Greg Kroah-Hartman Cc: Thomas Gleixner , Sebastian Andrzej Siewior , Tetsuo Handa , Byungchul Park , max.byungchul.park@gmail.com, Yeoreum Yun , ppbuk5246@gmail.com, linux-usb@vger.kernel.org, linux-rt-devel@lists.linux.dev, syzkaller@googlegroups.com, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Yunseong Kim Subject: [PATCH 2/4] kcov: Replace per-CPU local_lock with local_irq_save/restore Date: Sun, 3 Aug 2025 07:20:45 +0000 Message-ID: <20250803072044.572733-6-ysk@kzalloc.com> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250803072044.572733-2-ysk@kzalloc.com> References: <20250803072044.572733-2-ysk@kzalloc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Commit f85d39dd7ed8 ("kcov, usb: disable interrupts in kcov_remote_start_usb_softirq") introduced a local_irq_save() in the kcov_remote_start_usb_softirq() wrapper, placing kcov_remote_start() in atomic context. The previous patch addressed this by converting the global kcov_remote_lock to a non-sleeping raw_spinlock_t. However, per-CPU data in kcov_remote_start() and kcov_remote_stop() remains protected by kcov_percpu_data.lock, which is a local_lock_t. On PREEMPT_RT kernels, local_lock_t is implemented as a sleeping lock. Acquiring it from atomic context triggers warnings or crashes due to invalid sleeping behavior. The original use of local_lock_t assumed that kcov_remote_start() would never be called in atomic context. Now that this assumption no longer holds, replace it with local_irq_save() and local_irq_restore(), which are safe in all contexts and compatible with the use of raw_spinlock_t. With this change, both global and per-CPU synchronization primitives are guaranteed to be non-sleeping, making kcov_remote_start() safe for use in atomic contexts. Signed-off-by: Yunseong Kim --- kernel/kcov.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 7d9b53385d81..faad3b288ca7 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -90,7 +90,6 @@ static struct list_head kcov_remote_areas =3D LIST_HEAD_I= NIT(kcov_remote_areas); =20 struct kcov_percpu_data { void *irq_area; - local_lock_t lock; =20 unsigned int saved_mode; unsigned int saved_size; @@ -99,9 +98,7 @@ struct kcov_percpu_data { int saved_sequence; }; =20 -static DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data) =3D { - .lock =3D INIT_LOCAL_LOCK(lock), -}; +static DEFINE_PER_CPU(struct kcov_percpu_data, kcov_percpu_data); =20 /* Must be called with kcov_remote_lock locked. */ static struct kcov_remote *kcov_remote_find(u64 handle) @@ -862,7 +859,7 @@ void kcov_remote_start(u64 handle) if (!in_task() && !in_softirq_really()) return; =20 - local_lock_irqsave(&kcov_percpu_data.lock, flags); + local_irq_save(flags); =20 /* * Check that kcov_remote_start() is not called twice in background @@ -870,7 +867,7 @@ void kcov_remote_start(u64 handle) */ mode =3D READ_ONCE(t->kcov_mode); if (WARN_ON(in_task() && kcov_mode_enabled(mode))) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } /* @@ -879,7 +876,7 @@ void kcov_remote_start(u64 handle) * happened while collecting coverage from a background thread. */ if (WARN_ON(in_serving_softirq() && t->kcov_softirq)) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } =20 @@ -887,7 +884,7 @@ void kcov_remote_start(u64 handle) remote =3D kcov_remote_find(handle); if (!remote) { raw_spin_unlock(&kcov_remote_lock); - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } kcov_debug("handle =3D %llx, context: %s\n", handle, @@ -912,13 +909,13 @@ void kcov_remote_start(u64 handle) =20 /* Can only happen when in_task(). */ if (!area) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); area =3D vmalloc(size * sizeof(unsigned long)); if (!area) { kcov_put(kcov); return; } - local_lock_irqsave(&kcov_percpu_data.lock, flags); + local_irq_save(flags); } =20 /* Reset coverage size. */ @@ -930,7 +927,7 @@ void kcov_remote_start(u64 handle) } kcov_start(t, kcov, size, area, mode, sequence); =20 - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); =20 } EXPORT_SYMBOL(kcov_remote_start); @@ -1004,12 +1001,12 @@ void kcov_remote_stop(void) if (!in_task() && !in_softirq_really()) return; =20 - local_lock_irqsave(&kcov_percpu_data.lock, flags); + local_irq_save(flags); =20 mode =3D READ_ONCE(t->kcov_mode); barrier(); if (!kcov_mode_enabled(mode)) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } /* @@ -1017,12 +1014,12 @@ void kcov_remote_stop(void) * actually found the remote handle and started collecting coverage. */ if (in_serving_softirq() && !t->kcov_softirq) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } /* Make sure that kcov_softirq is only set when in softirq. */ if (WARN_ON(!in_serving_softirq() && t->kcov_softirq)) { - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); return; } =20 @@ -1052,7 +1049,7 @@ void kcov_remote_stop(void) raw_spin_unlock(&kcov_remote_lock); } =20 - local_unlock_irqrestore(&kcov_percpu_data.lock, flags); + local_irq_restore(flags); =20 /* Get in kcov_remote_start(). */ kcov_put(kcov); --=20 2.50.0 From nobody Sun Oct 5 14:45:20 2025 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFCAC2853F8; Sun, 3 Aug 2025 07:23:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205792; cv=none; b=bljIgEUOsOYaMp8pxiyjO26L9FoLZpdiZO8dtXav7y3CXP7/PnKtpwlQh1QSTR1D4t1tvL2AdlzsBbqdXx7aQBthqq+Lj8oHBZmdqiLFZtyCD8WZ/3BAAyvNmFyn3rABz3RdibulbwESWH/K0eFCuGTxPHZuYKI6IeJqbHHFatY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205792; c=relaxed/simple; bh=VyXyy6e3sil0Ay6ER7lD2FBdbK6i7vMKoMfIwsSxWQI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tGHLZw8udXYwd3dXw+3kq91zC6euV4suV8TK9P9s5MlSZM+d5MHV3Ca1NGpULLhGvdOqKUFazoOO1snt/+AGCd7RNb3AospmeiCNKFOEKN4UUXuqUSS+ttCOhknTc8pYxUTp3hVCVk3gjpzY8i22sH5SUbUFobnNI+fDHeQxZXc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.216.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-31ebeb3882cso371223a91.2; Sun, 03 Aug 2025 00:23:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754205790; x=1754810590; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wUMEPy3NW+Kvt4pCviV3Y3MANBoYuxv/rAODtFlgguI=; b=SPWtd2kjHH0JPL2nWxRagy3mqYLAp/hcLERMgaHwswi/rOf9UdrYPSefo4nfRqnbq6 fpanDjyPR486GZU3J/s2XaFCF/ZsG/hFwWW73aq7+809+e76F814wVOc7s8SBwOX9ATl HHmIr4ftITstZ/79VRrQl6nQkNYDeo2oOGQekNbaQThvI8HQXzmZhwkLIDAPh37BlDF1 VvGlWWFWiQP0x54W+FyjVuCq2nlkxVQCJyYQKNwPfPTS0CdyTLxOCqIwyl57Jr7v6Ahr A+zH/lKuS9GfpsH5DXOtgYlGcUkAgOd+36Lz/KKpdW+oBkfoef0hCh7wcAVtswq9bGbG 1W0w== X-Forwarded-Encrypted: i=1; AJvYcCUHlFN3+KoXwaM6fsTm0z2JSKHQZLVL1uNFMMxRXO5uGD16SLQ9m8KfZnOp9obLAr8PVTLjiZh73eQip0M=@vger.kernel.org, AJvYcCVlM+PkPBByMu1HAGdzHiixkeBVSUI4AvK/qpONATolDAqOXX5y2Pf4Y+JbweYL40JBb9eL68IxuwpG@vger.kernel.org, AJvYcCXf+HntSi9NhbX89jGljmzvVNliR0tGGk5/Dzi5xjqyG6LlaC812IXcm0Jgwt22VwSnotA00PLW@vger.kernel.org X-Gm-Message-State: AOJu0Yw3P0joIlBC7pM6zZP6Qz8xtQfYjlwBPhVLqLfRz4pzLm2sCOFB bFsQYG83eTaL/ECZQ5/vDkbHjtctWPsxfTTKNycMgGr/JxFAI+REApHG X-Gm-Gg: ASbGncsgQE1Tw+/Px5x7GNVEY5pjWQU1D1JrVr2MndeqynbfA1CycrbZG/I44464NW3 iOpuTLy14ojKpYArUq543tzwe77bVaJW7UD+806owOERlvgGI41xNQa/lWYSP2QsysvibIZ7hLa tpBfdkfQ8gPvGaE0wdb9jYZbUWECyI6BeZBW02rAybp0re1FjxBVfufZo9PmHR/mhcS/mw17f7+ 1YYnrTX8apGNWhkPbcpw7unqVvh9Jao2RcueRKHLBnfpbnFxBD7uckHN/OnbgeXAzyQei8IN4TR Fl1MOpkxuzDzuFmd7YiPBLRHX0QcajdpyfB3ahdvNZEKpJf13ZtG1s6W2ChWeGWab15XhQXIQLK kbRMVAciE/MNjpFIOfqWw2fo= X-Google-Smtp-Source: AGHT+IFkiOF2LoZEGkeJ1ZCKCByYFHWEQyRUIxN6P7aax3IOgp/dFnuuDea+zbR2L5+A+YvGsBXbjw== X-Received: by 2002:a17:90b:3ec1:b0:31f:16ee:5ddf with SMTP id 98e67ed59e1d1-321162cd950mr3588228a91.5.1754205790066; Sun, 03 Aug 2025 00:23:10 -0700 (PDT) Received: from localhost ([218.152.98.97]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b423d2f4fcesm4517004a12.33.2025.08.03.00.23.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Aug 2025 00:23:09 -0700 (PDT) From: Yunseong Kim To: Dmitry Vyukov , Andrey Konovalov , Greg Kroah-Hartman Cc: Thomas Gleixner , Sebastian Andrzej Siewior , Tetsuo Handa , Byungchul Park , max.byungchul.park@gmail.com, Yeoreum Yun , ppbuk5246@gmail.com, linux-usb@vger.kernel.org, linux-rt-devel@lists.linux.dev, syzkaller@googlegroups.com, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Yunseong Kim Subject: [PATCH 3/4] kcov: Separate KCOV_REMOTE_ENABLE ioctl helper function Date: Sun, 3 Aug 2025 07:20:47 +0000 Message-ID: <20250803072044.572733-8-ysk@kzalloc.com> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250803072044.572733-2-ysk@kzalloc.com> References: <20250803072044.572733-2-ysk@kzalloc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" kcov_ioctl() entry point is updated to dispatch commands to the appropriate helper function, calling kcov_ioctl_locked_remote_enabled() for the remote enable case and the now-simplified kcov_ioctl_locked() for KCOV_ENABLE and KCOV_DISABLE commands. Signed-off-by: Yunseong Kim --- kernel/kcov.c | 142 +++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 65 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index faad3b288ca7..1e7f08ddf0e8 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -579,15 +579,81 @@ static inline bool kcov_check_handle(u64 handle, bool= common_valid, return false; } =20 -static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, - unsigned long arg) +static int kcov_ioctl_locked_remote_enabled(struct kcov *kcov, + unsigned int cmd, unsigned long arg) { struct task_struct *t; - unsigned long flags, unused; + unsigned long flags; int mode, i; struct kcov_remote_arg *remote_arg; struct kcov_remote *remote; =20 + if (kcov->mode !=3D KCOV_MODE_INIT || !kcov->area) + return -EINVAL; + t =3D current; + if (kcov->t !=3D NULL || t->kcov !=3D NULL) + return -EBUSY; + remote_arg =3D (struct kcov_remote_arg *)arg; + mode =3D kcov_get_mode(remote_arg->trace_mode); + if (mode < 0) + return mode; + if ((unsigned long)remote_arg->area_size > + LONG_MAX / sizeof(unsigned long)) + return -EINVAL; + kcov->mode =3D mode; + t->kcov =3D kcov; + t->kcov_mode =3D KCOV_MODE_REMOTE; + kcov->t =3D t; + kcov->remote =3D true; + kcov->remote_size =3D remote_arg->area_size; + raw_spin_lock_irqsave(&kcov_remote_lock, flags); + for (i =3D 0; i < remote_arg->num_handles; i++) { + if (!kcov_check_handle(remote_arg->handles[i], + false, true, false)) { + raw_spin_unlock_irqrestore(&kcov_remote_lock, + flags); + kcov_disable(t, kcov); + return -EINVAL; + } + remote =3D kcov_remote_add(kcov, remote_arg->handles[i]); + if (IS_ERR(remote)) { + raw_spin_unlock_irqrestore(&kcov_remote_lock, + flags); + kcov_disable(t, kcov); + return PTR_ERR(remote); + } + } + if (remote_arg->common_handle) { + if (!kcov_check_handle(remote_arg->common_handle, + true, false, false)) { + raw_spin_unlock_irqrestore(&kcov_remote_lock, + flags); + kcov_disable(t, kcov); + return -EINVAL; + } + remote =3D kcov_remote_add(kcov, + remote_arg->common_handle); + if (IS_ERR(remote)) { + raw_spin_unlock_irqrestore(&kcov_remote_lock, + flags); + kcov_disable(t, kcov); + return PTR_ERR(remote); + } + t->kcov_handle =3D remote_arg->common_handle; + } + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); + /* Put either in kcov_task_exit() or in KCOV_DISABLE. */ + kcov_get(kcov); + return 0; +} + +static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, + unsigned long arg) +{ + struct task_struct *t; + unsigned long unused; + int mode; + switch (cmd) { case KCOV_ENABLE: /* @@ -624,64 +690,6 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsign= ed int cmd, kcov_disable(t, kcov); kcov_put(kcov); return 0; - case KCOV_REMOTE_ENABLE: - if (kcov->mode !=3D KCOV_MODE_INIT || !kcov->area) - return -EINVAL; - t =3D current; - if (kcov->t !=3D NULL || t->kcov !=3D NULL) - return -EBUSY; - remote_arg =3D (struct kcov_remote_arg *)arg; - mode =3D kcov_get_mode(remote_arg->trace_mode); - if (mode < 0) - return mode; - if ((unsigned long)remote_arg->area_size > - LONG_MAX / sizeof(unsigned long)) - return -EINVAL; - kcov->mode =3D mode; - t->kcov =3D kcov; - t->kcov_mode =3D KCOV_MODE_REMOTE; - kcov->t =3D t; - kcov->remote =3D true; - kcov->remote_size =3D remote_arg->area_size; - raw_spin_lock_irqsave(&kcov_remote_lock, flags); - for (i =3D 0; i < remote_arg->num_handles; i++) { - if (!kcov_check_handle(remote_arg->handles[i], - false, true, false)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return -EINVAL; - } - remote =3D kcov_remote_add(kcov, remote_arg->handles[i]); - if (IS_ERR(remote)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return PTR_ERR(remote); - } - } - if (remote_arg->common_handle) { - if (!kcov_check_handle(remote_arg->common_handle, - true, false, false)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return -EINVAL; - } - remote =3D kcov_remote_add(kcov, - remote_arg->common_handle); - if (IS_ERR(remote)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return PTR_ERR(remote); - } - t->kcov_handle =3D remote_arg->common_handle; - } - raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); - /* Put either in kcov_task_exit() or in KCOV_DISABLE. */ - kcov_get(kcov); - return 0; default: return -ENOTTY; } @@ -740,16 +748,20 @@ static long kcov_ioctl(struct file *filep, unsigned i= nt cmd, unsigned long arg) return -EINVAL; } arg =3D (unsigned long)remote_arg; - fallthrough; + raw_spin_lock_irqsave(&kcov->lock, flags); + res =3D kcov_ioctl_locked_remote_enabled(kcov, cmd, arg); + raw_spin_unlock_irqrestore(&kcov->lock, flags); + kfree(remote_arg); + return res; default: /* - * All other commands can be normally executed under a spin lock, so we - * obtain and release it here in order to simplify kcov_ioctl_locked(). + * KCOV_ENABLE and KCOV_DISABLE commands can be normally executed under + * a raw spin lock, so we obtain and release it here in order to + * simplify kcov_ioctl_locked(). */ raw_spin_lock_irqsave(&kcov->lock, flags); res =3D kcov_ioctl_locked(kcov, cmd, arg); raw_spin_unlock_irqrestore(&kcov->lock, flags); - kfree(remote_arg); return res; } } --=20 2.50.0 From nobody Sun Oct 5 14:45:20 2025 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C32C5283153; Sun, 3 Aug 2025 07:23:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205830; cv=none; b=MYQ3r+FQhdg0AV8FtnnrFFmRztJ2cAs+oQBInLRuaBxjDphK6Ps8hazqoTedOGc1I5URcXVgjwJXYO8C0oPUoNTml4p5vvxf5bFFBYxwv0UAPARMX1NxnS/Z+KXXTpkZH5kbJ0cVDArmtZlir4PaMh4HCCS0P8+3RvjVlrE0mqY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754205830; c=relaxed/simple; bh=o7Sze8vSL1lmHX9XqvuAQ36eR8fWKDTdm/ltFp30Vv8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BM1hj4C9a1B2/2G3KGfQFSjcGzVkwmOKDC0+KMhLYlV6JxoJm+4jlfM7VVfA/3ZQ87HoKUul4fBNm/OKDIC+h0POXr8u/1aUARr/cgB7ahAwFXj+WQ6+a4t2WYhgjz1UbhE4So82eS8eOWEIdyhRc8JXa5LOA168hEwCGxzmgkw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kzalloc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-31ec291f442so583749a91.1; Sun, 03 Aug 2025 00:23:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754205828; x=1754810628; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7gFNaxZHXVjM+wPnIV705hxHarQ4JJ47HvINcfGklyo=; b=nRc8Rh88aRlV5MvFaMk0Q1XFHNbSXiZ4bMTxgtYcEKux8n6C0C0P0+H0HUJ1m3bqAw SOKLx3xn5pCvCgTEGR3VBnZIRc/kC64w+CIa1lBw62HWRApeUEviNjBGFgJtj8RSy2dE qYL9B+3T0F6KaYJifo256DHimtxZL73ob+K+VSjajlT+SJra2s/FQLJeBUqGRqHAJvxt p2e0rmdYwInJenHKvUhGbeFpWqhEwh53bvawEaANB5SIffr5/JYNC+5THNxfQOraiWzC FzB3jVHNYlWTuSxe/D+s9qXXec8hv65T9KHcWHRXhICyJ/OWmuDtL/rZgmpuqJJ7Rgsz 88EA== X-Forwarded-Encrypted: i=1; AJvYcCVwiY9Ya+zsd5+rNls+6Z4CnJFAE1nktb+NxTZj5DpkFTvdBcYlIjJe+VsiY/Xq9VNbOyjuO2or@vger.kernel.org, AJvYcCXksUSXUcovFrcxDN2/BALwd5kLAOyJpklu+Azhu26r0ByaOamTcMBHn+6zLPUkW2KVy1be46jJcg36n2s=@vger.kernel.org, AJvYcCXwgl3GszLkxG6dEDFqiQ1wQzGjOlxFSoynj41fadol8Y5RCqOcYkNbEesW4zVfXSxkYty+ImAE/s3r@vger.kernel.org X-Gm-Message-State: AOJu0YwfbkHL5pANP+SsHGb3jHrkeWykYEokBRXcUpKsvyAh4fZ8VGIJ c/oQ6xhmlR9bNTCGR0GlzLEdSjYkitW+KSnwWUGJ9Ef8jXSowvJkkgpJ X-Gm-Gg: ASbGncvHC2T5LbCIm0K3wzmIR2dn6em17XDgpT4d4AQcE6gtPON5bvj3ZevCndhp80G R9LSEgU8Bu4a4qYF5tc4YlYMWmCdfMpl1bOFM0RUzCC8lKYGod6x5SvB1mHfHGVdaPFke/Im/00 0DkINYBkmBK4xlzmwxOP54VhcWk3UQWAstIjlgedRunux+IIoOgeHhzzuKmn8Zwf1pz+4FqleKW T83R5TELpeHx4Pj7e194QHrrrRn+efTnvr6WrFRiqCUEiKIvYRJIOE7r7bv+HQ+J8cksMVDXjxO iGFs+n2xfZ2aA4UvHBtetDDS078+xgOf1g9C/Mb4lOm8CKrry4oTciaSrbc69klakYuZ2QA4VPS JURO6Rc2zF2uM X-Google-Smtp-Source: AGHT+IHvGJIfC5VXqgphZ7FgmcKBMtlLf0lp9Zp058suCZRx8lnKA8DsXGVlqbqZPFKDrux4mS/HIg== X-Received: by 2002:a05:6a20:7287:b0:240:75c:6f53 with SMTP id adf61e73a8af0-240075c7fdfmr14637.7.1754205828126; Sun, 03 Aug 2025 00:23:48 -0700 (PDT) Received: from localhost ([218.152.98.97]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b423d2f4fcesm4517004a12.33.2025.08.03.00.23.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 Aug 2025 00:23:47 -0700 (PDT) From: Yunseong Kim To: Dmitry Vyukov , Andrey Konovalov , Greg Kroah-Hartman Cc: Thomas Gleixner , Sebastian Andrzej Siewior , Tetsuo Handa , Byungchul Park , max.byungchul.park@gmail.com, Yeoreum Yun , ppbuk5246@gmail.com, linux-usb@vger.kernel.org, linux-rt-devel@lists.linux.dev, syzkaller@googlegroups.com, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Yunseong Kim Subject: [PATCH 4/4] kcov: move remote handle allocation outside raw spinlock Date: Sun, 3 Aug 2025 07:20:49 +0000 Message-ID: <20250803072044.572733-10-ysk@kzalloc.com> X-Mailer: git-send-email 2.50.0 In-Reply-To: <20250803072044.572733-2-ysk@kzalloc.com> References: <20250803072044.572733-2-ysk@kzalloc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" To comply with raw spinlock constraints, move allocation of kcov_remote structs out of the critical section in the KCOV_REMOTE_ENABLE path. Memory is now pre-allocated in kcov_ioctl() before taking any locks, and passed down to the locked section for insertion into the hash table. error handling is updated to release the memory on failure. This aligns with the non-sleeping requirement of raw spinlocks introduced earlier in the series. Signed-off-by: Yunseong Kim --- kernel/kcov.c | 81 +++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/kernel/kcov.c b/kernel/kcov.c index 1e7f08ddf0e8..46d36e0146cc 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -113,15 +113,9 @@ static struct kcov_remote *kcov_remote_find(u64 handle) } =20 /* Must be called with kcov_remote_lock locked. */ -static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle) +static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle, + struct kcov_remote *remote) { - struct kcov_remote *remote; - - if (kcov_remote_find(handle)) - return ERR_PTR(-EEXIST); - remote =3D kmalloc(sizeof(*remote), GFP_ATOMIC); - if (!remote) - return ERR_PTR(-ENOMEM); remote->handle =3D handle; remote->kcov =3D kcov; hash_add(kcov_remote_map, &remote->hnode, handle); @@ -580,13 +574,14 @@ static inline bool kcov_check_handle(u64 handle, bool= common_valid, } =20 static int kcov_ioctl_locked_remote_enabled(struct kcov *kcov, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg, + struct kcov_remote *remote_handles, + struct kcov_remote *remote_common_handle) { struct task_struct *t; unsigned long flags; - int mode, i; + int mode, i, ret; struct kcov_remote_arg *remote_arg; - struct kcov_remote *remote; =20 if (kcov->mode !=3D KCOV_MODE_INIT || !kcov->area) return -EINVAL; @@ -610,41 +605,43 @@ static int kcov_ioctl_locked_remote_enabled(struct kc= ov *kcov, for (i =3D 0; i < remote_arg->num_handles; i++) { if (!kcov_check_handle(remote_arg->handles[i], false, true, false)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return -EINVAL; + ret =3D -EINVAL; + goto err; } - remote =3D kcov_remote_add(kcov, remote_arg->handles[i]); - if (IS_ERR(remote)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return PTR_ERR(remote); + if (kcov_remote_find(remote_arg->handles[i])) { + ret =3D -EEXIST; + goto err; } + kcov_remote_add(kcov, remote_arg->handles[i], + &remote_handles[i]); } if (remote_arg->common_handle) { if (!kcov_check_handle(remote_arg->common_handle, true, false, false)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return -EINVAL; + ret =3D -EINVAL; + goto err; } - remote =3D kcov_remote_add(kcov, - remote_arg->common_handle); - if (IS_ERR(remote)) { - raw_spin_unlock_irqrestore(&kcov_remote_lock, - flags); - kcov_disable(t, kcov); - return PTR_ERR(remote); + if (kcov_remote_find(remote_arg->common_handle)) { + ret =3D -EEXIST; + goto err; } + kcov_remote_add(kcov, + remote_arg->common_handle, remote_common_handle); t->kcov_handle =3D remote_arg->common_handle; } raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); + /* Put either in kcov_task_exit() or in KCOV_DISABLE. */ kcov_get(kcov); return 0; + +err: + raw_spin_unlock_irqrestore(&kcov_remote_lock, flags); + kcov_disable(t, kcov); + kfree(remote_common_handle); + kfree(remote_handles); + + return ret; } =20 static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd, @@ -702,6 +699,7 @@ static long kcov_ioctl(struct file *filep, unsigned int= cmd, unsigned long arg) struct kcov_remote_arg *remote_arg =3D NULL; unsigned int remote_num_handles; unsigned long remote_arg_size; + struct kcov_remote *remote_handles, *remote_common_handle; unsigned long size, flags; void *area; =20 @@ -748,11 +746,22 @@ static long kcov_ioctl(struct file *filep, unsigned i= nt cmd, unsigned long arg) return -EINVAL; } arg =3D (unsigned long)remote_arg; + remote_handles =3D kmalloc_array(remote_arg->num_handles, + sizeof(struct kcov_remote), GFP_KERNEL); + if (!remote_handles) + return -ENOMEM; + remote_common_handle =3D kmalloc(sizeof(struct kcov_remote), GFP_KERNEL); + if (!remote_common_handle) { + kfree(remote_handles); + return -ENOMEM; + } + raw_spin_lock_irqsave(&kcov->lock, flags); - res =3D kcov_ioctl_locked_remote_enabled(kcov, cmd, arg); + res =3D kcov_ioctl_locked_remote_enabled(kcov, cmd, arg, + remote_handles, remote_common_handle); raw_spin_unlock_irqrestore(&kcov->lock, flags); kfree(remote_arg); - return res; + break; default: /* * KCOV_ENABLE and KCOV_DISABLE commands can be normally executed under @@ -762,8 +771,10 @@ static long kcov_ioctl(struct file *filep, unsigned in= t cmd, unsigned long arg) raw_spin_lock_irqsave(&kcov->lock, flags); res =3D kcov_ioctl_locked(kcov, cmd, arg); raw_spin_unlock_irqrestore(&kcov->lock, flags); - return res; + break; } + + return res; } =20 static const struct file_operations kcov_fops =3D { --=20 2.50.0