From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 472E53EA949 for ; Thu, 21 May 2026 14:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779373572; cv=none; b=IpmX/Q2HNyjFUPTKz0YjHUjsqBTE1p/aGLElfZofATGmOJwgyXkseCbGVPye23cH/LJ++4b3oUDOPoo0pFPkTtQhRxALmkmoaLjKagrlIU4pbSx7zWERjsKprcME+aPb0lU1uH/rpSi36ae53RF177e7stCXE/RuzeTZc7+HlaE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779373572; c=relaxed/simple; bh=crZFG5EEQ/XpebF5oR/q/KAWJip2MvYpvjgZ/M671mI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FYfKZWXCYYOXayP86uCZr/yoKv5wk7QuOkAPXiZyqhjyaGNWYIc7kjmn7F5O/wYFuVk+4wRZOfbldakbI/BqoP61j523iy7wlE9qqfFLBZt7ZBCPFSyVLY5CF8dKTsFfjzAHEMi3KYHcB3bQwVAjWjQGoaMDKub1NC7heH9ii0o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=jfLoyjdr; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=fRhTFnia; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="jfLoyjdr"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="fRhTFnia" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 64L99saA3451575 for ; Thu, 21 May 2026 14:26:10 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= GcR7ReLeAOcf7bVj6RK9HechYfK2p6RdYNeXOdB466A=; b=jfLoyjdrIwGRCyQa wYvUu31g0uE7lprdX5K8EP7XGMGm+DqMLsYIVeMoWqt2/9zBBpFNPInxl9hq4hmh cOfjVXwhXDmsdfvsoxR33nmNYOjyoTJx3s1+dzGCrIHSt9OJz4kJAB9dF0UoKT2f basls60gjyZtZiz5jGDwc0BOUhQPdUWwVIepoSe87lEQ+9lMnao8BfIo6SL6Lgde XBthy7BF0rLfbM+7kiCMeZo2I+UjiNfvRrN5WLpuHZ8QSmglA0g0PFu0gGx0N2pj zSVOH1Q/GTSO+SZAN6fHUx4b7qSnEV9aemvEcGWEoAaddUOb7ufUdkW09RHfgtzH Klbr9Q== Received: from mail-vs1-f71.google.com (mail-vs1-f71.google.com [209.85.217.71]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4e9y1h99g6-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Thu, 21 May 2026 14:26:10 +0000 (GMT) Received: by mail-vs1-f71.google.com with SMTP id ada2fe7eead31-6343bea7909so2535896137.0 for ; Thu, 21 May 2026 07:26:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1779373569; x=1779978369; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=GcR7ReLeAOcf7bVj6RK9HechYfK2p6RdYNeXOdB466A=; b=fRhTFniagP+oI+WBRPSsdNW7iwGpLrz7Dp94tj310cOUglDmNQbZV/BBt74GRe2pnP gUN7TN59F7YxpNCt8PACagzAPItIuBkX8EKt8wYXF4nfDEsctZNfVp0+ZZBB/nW5HdgC z/G0u6tTw6so/XIZLpP6mQhDGMCPxgptdB+J3pRKBMyNDFl8vZQhCsEu2c+5gZDwLjN9 iLmCkwzf82e38kZ1D4zkKr+SHaLID15gDlp5pz4IUQhNyriQXigknZm41ZI/N55yaG1R ewdi894RON+ljF7zS7JqRPTNmVkNiRVOCOgt6tafcTOkP+j/NiaKEOo+3khurXBZVGx2 quvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779373569; x=1779978369; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=GcR7ReLeAOcf7bVj6RK9HechYfK2p6RdYNeXOdB466A=; b=jN4+DEdlU1WfCDWQ0iJfBR/N0ortxOlQy5QuA8M7vMoMIUnSLkknd2kpayxV2Q9BFR c4zFMbljjeSrT1ZmRIHsG6GPV1ZAf6mcfzw9it36C+SxKID3wXyvZ9/tZaBF8EXZe6EU xO3BnXTlc8rfnFmz4ICVtg4JAiZmr3etmKgWLlgPKtYaScrV8rYD8dJIsK7AeqxsxhH0 3kIp9YxW+pUgmDdsduB6kT2brJCI7X4YBeiSBL3q+iQp7hy2/d2qN7Dx5ZpKNdXrDAUG //jpAB7rQ1HGSzN2Hmu3UmZQ7zA5tu0OqPntGmG8D+62VXzlldl+mYkZ0iKttzki+xRZ rROw== X-Gm-Message-State: AOJu0Yx9en1XuEhrqzCpPXXw5YbThyuLZXq3KWpNgVcgpwazYNHFheZB S4g8+vQu5kBMJ1DXOIJ6ApahRALx89r8Yl0xFGcRdX+vwmOh2lPim7eATFGln829d8KCmnuuIUK yOPNNU15FoKBBRYhqL1MFkGt/JKstZ+p3a5boVhcchk4NO95ex53KMUKjaONPozOhpGI= X-Gm-Gg: Acq92OGfBIwMs4Fo0sgj640NklzHLpLEbReBkSkqNKJf9IXsiCTQjzR9cwMBRDP7ZHR AHawd+6LsRoXtsqOX0e6RtAHedGdp0u1O1VFk0hminLA/qZ2waBHaIguBN+f6GBJ6QISzQbuQLP fk7rHxFkP9PN2bSU1W6XsYMb+VyvbFiRo6meGQjOS4grmvbobjZvf3fTiZN3HwbLTO6eHFLGv68 GsmvX3CCscI2fXzWEK1O+E5X0TRy0S8d//SVR6/D1WiHvUKx8xnjbFd5VaeDcSpZZw2I19hUoCc DI0woa3EPTwPUjVgGIbRov3WA4F3t1Gd6bj8Tvi4dvTiDw+dYkGj/T0fR90/lkscNOLRCAk9JQ5 Msu/a9jGijARVMjuAZywmRYFcPAx8MhxP+MB/rTjKGVZtlHDReJ0= X-Received: by 2002:a05:6102:1591:b0:62e:c54:fccb with SMTP id ada2fe7eead31-6739d5d98f8mr1555410137.28.1779373569368; Thu, 21 May 2026 07:26:09 -0700 (PDT) X-Received: by 2002:a05:6102:1591:b0:62e:c54:fccb with SMTP id ada2fe7eead31-6739d5d98f8mr1555350137.28.1779373568830; Thu, 21 May 2026 07:26:08 -0700 (PDT) Received: from brgl-qcom.local ([2a01:cb1d:dc:7e00:bb10:ae82:b7c3:d15a]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4903c9abbadsm30441925e9.8.2026.05.21.07.26.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2026 07:26:07 -0700 (PDT) From: Bartosz Golaszewski Date: Thu, 21 May 2026 16:25:43 +0200 Subject: [PATCH v4 10/10] nvmem: protect nvmem_device::ops with SRCU Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260521-nvmem-unbind-v4-10-7fa136759491@oss.qualcomm.com> References: <20260521-nvmem-unbind-v4-0-7fa136759491@oss.qualcomm.com> In-Reply-To: <20260521-nvmem-unbind-v4-0-7fa136759491@oss.qualcomm.com> To: Srinivas Kandagatla , Bartosz Golaszewski , Johan Hovold , Loic Poulain Cc: linux-kernel@vger.kernel.org, brgl@kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=5454; i=bartosz.golaszewski@oss.qualcomm.com; h=from:subject:message-id; bh=crZFG5EEQ/XpebF5oR/q/KAWJip2MvYpvjgZ/M671mI=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBqDxXtcmDVxEWpP0cV9/rKa0InNP9L5HAVPpYS9 aP+ys5klamJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCag8V7QAKCRAFnS7L/zaE w4EtD/4patwRqDURTdftzfi5d2F5oGFg8mYkK5RSDZcX4bGYUSsCAMAGDb592SH1ZVTdVljxJhs xH7EFNdlvn/k0UCb3EftflZnazXYcMaudCpRGhS5ggv+uNwhNtxM2c/eOfzIa76WNUjuABbGfuY ImG43Mir23FYSA3LKXNKTW3BMbj4P6yUFpyHxzKdXN471Xd/+WWtJ02zi+oMZ6dPDTk66vhI4f8 zQobKg2xX7S//suSAyFRreX+712GKxWzbGXyJqcxk7MTC1OqG4iCaL4G6gBbfl43iiK1Dw+jAL0 GrrFse/NgaMGFthcxinPnggtetZ4++mCPF9iABFT8vZY8VxmlzEmGGWiTsYni/IWM35ilNT2Xte 0y2Hcuzeaugi27yE1YFfdegRYQfq4I0NAWK4CyrULAgdZS/c+8/tzN5eUh10SZMX+tOu6frDB6F J2mRjG4VMaOPhHFwrjOrrQqHfSc0oBl0GqRn8vjIkBUB4HSh0abGzpbyoBmJ4Q/XbChMQyKwx2F tLKyGuKGuDWwLveb1XhZcNTvEGRnLGs5QnmXmcQzZa3Cdb8FCzVNpzHjV1RJHpOzR6SpmfhdcZp 0WaTdgAZsyzx58q6aR9K4H5Dt5Eyule0aHlwRy6KbBacuFa/eiHZuH9awlI4DvvTU1FBwG6aJKC xwUg12hZONdcncw== X-Developer-Key: i=bartosz.golaszewski@oss.qualcomm.com; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 X-Proofpoint-ORIG-GUID: dJmKm5iAgE-XFQFvEfBry8_LnhSC-P3r X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNTIxMDE0NCBTYWx0ZWRfXznLTU/3wvjFB uTgvC7PPwlHQTOQ82VarVEQJRE8dWZssVJkDYt0VJUd/M8aW7CMzPK2OcYQmZkZKXQpDpPMecda RFVYRsu4daJlEqKDZMNAViAN8fDJj8ZiXkWgsCs3tmXNSsvls18rb+8p/OVqjd+p9i+tTfjlRbT CVIJqvasIWBlbL7RD25O9zcag/tvgodyFeliwvs08SCu6f5EppCv1R/fyZmw14BI7JSwUFoJL9L R7i635OtfmCl/8ddiysuClkZRR8SHfAljPBcBVJKlUsXleOn6PmlAfevaH0tWryT8GbJPj6HmLy SAoHiAs/JuZHCkppHulBbQa6Hlqw8QiejN5aCdSxsrMWzl0/MkGu8pNDj5/m9ZfID5NWDd0bg6u 2h+Bvf3Shli/H19Z7Tju5VlNma9NazZwK0v42tVjWlNl+qQ7KVlNztx8seD/fVCrV92ObwUL3f3 gal29tFLoslIrQT/VKQ== X-Authority-Analysis: v=2.4 cv=YfyNIQRf c=1 sm=1 tr=0 ts=6a0f1602 cx=c_pps a=P2rfLEam3zuxRRdjJWA2cw==:117 a=xqWC_Br6kY4A:10 a=IkcTkHD0fZMA:10 a=NGcC8JguVDcA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=ydBWjX_Uc0Q5hLJtmLYA:9 a=QEXdDO2ut3YA:10 a=ODZdjJIeia2B_SHc_B0f:22 X-Proofpoint-GUID: dJmKm5iAgE-XFQFvEfBry8_LnhSC-P3r X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.51,FMLib:17.12.100.49 definitions=2026-05-21_02,2026-05-18_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 priorityscore=1501 impostorscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 suspectscore=0 clxscore=1015 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2605130000 definitions=main-2605210144 With the provider-owned data split out into a separate 'ops' structure, we can now protect it with SRCU. Protect all dereferences of nvmem->ops with an SRCU read lock. Synchronize SRCU in nvmem_unregister() after setting the implementation pointer to NULL. This has the effect of numbing down the device after nvmem_unregister() returns - it will no longer accept any consumer calls and return -ENODEV. The actual device will live on for as long as there are references to it but we will no longer reach into the consumer's memory which may be gone by this time. Nvmem cell entries are destroyed in .release() now as they may be still dereferenced via the nvmem_cell handles after nvmem_release(). The actual calls will still go through SRCU and fail with -ENODEV if the provider is gone. Signed-off-by: Bartosz Golaszewski --- drivers/nvmem/core.c | 44 ++++++++++++++++++++++++++++++++++++++------ drivers/nvmem/internals.h | 4 +++- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 2c6d058a20d97e039f42e45c7b8d4305344c4ba0..2e66d4ae4aedca36662171abacec02fadd5e9039 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -57,7 +57,12 @@ static BLOCKING_NOTIFIER_HEAD(nvmem_notifier); static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, void *val, size_t bytes) { - struct nvmem_operations *ops = nvmem->ops; + struct nvmem_operations *ops; + + guard(srcu)(&nvmem->srcu); + ops = srcu_dereference(nvmem->ops, &nvmem->srcu); + if (!ops) + return -ENODEV; if (!ops->reg_read) return -EOPNOTSUPP; @@ -68,9 +73,14 @@ static int __nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset, static int __nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset, void *val, size_t bytes) { - struct nvmem_operations *ops = nvmem->ops; + struct nvmem_operations *ops; int ret, wr_ok; + guard(srcu)(&nvmem->srcu); + ops = srcu_dereference(nvmem->ops, &nvmem->srcu); + if (!ops) + return -ENODEV; + if (!ops->reg_write) return -EOPNOTSUPP; @@ -289,7 +299,7 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj, static umode_t nvmem_bin_attr_get_umode(struct nvmem_device *nvmem) { - struct nvmem_operations *ops = nvmem->ops; + struct nvmem_operations *ops = rcu_dereference_raw(nvmem->ops); umode_t mode = 0400; @@ -333,7 +343,7 @@ static umode_t nvmem_attr_is_visible(struct kobject *kobj, { struct device *dev = kobj_to_dev(kobj); struct nvmem_device *nvmem = to_nvmem_device(dev); - struct nvmem_operations *ops = nvmem->ops; + struct nvmem_operations *ops = rcu_dereference_raw(nvmem->ops); /* * If the device has no .reg_write operation, do not allow @@ -560,7 +570,7 @@ static void nvmem_release(struct device *dev) gpiod_put(nvmem->wp_gpio); nvmem_device_remove_all_cells(nvmem); ida_free(&nvmem_ida, nvmem->id); - kfree(nvmem->ops); + cleanup_srcu_struct(&nvmem->srcu); kfree(nvmem); } @@ -936,7 +946,20 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) nvmem->dev.bus = &nvmem_bus_type; nvmem->dev.parent = config->dev; INIT_LIST_HEAD(&nvmem->cells); - nvmem->ops = ops; + + /* + * Must happen before we assign the release() callback in + * device_initialize(). + */ + rval = init_srcu_struct(&nvmem->srcu); + if (rval) { + ida_free(&nvmem_ida, nvmem->id); + kfree(ops); + kfree(nvmem); + return ERR_PTR(rval); + } + + rcu_assign_pointer(nvmem->ops, ops); device_initialize(&nvmem->dev); @@ -1051,7 +1074,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) err_remove_compat: nvmem_sysfs_remove_compat(nvmem); err_put_device: + ops = rcu_replace_pointer(nvmem->ops, NULL, true); + synchronize_srcu(&nvmem->srcu); put_device(&nvmem->dev); + kfree(ops); return ERR_PTR(rval); } @@ -1064,13 +1090,19 @@ EXPORT_SYMBOL_GPL(nvmem_register); */ void nvmem_unregister(struct nvmem_device *nvmem) { + struct nvmem_operations *ops; + if (!nvmem) return; blocking_notifier_call_chain(&nvmem_notifier, NVMEM_REMOVE, nvmem); + ops = rcu_replace_pointer(nvmem->ops, NULL, true); + synchronize_srcu(&nvmem->srcu); + nvmem_sysfs_remove_compat(nvmem); nvmem_destroy_layout(nvmem); + kfree(ops); device_unregister(&nvmem->dev); } diff --git a/drivers/nvmem/internals.h b/drivers/nvmem/internals.h index 60daa79c404dc915872481bd3b02de2258d33406..17418fd0dcc92b101b56082fc15d74042386107d 100644 --- a/drivers/nvmem/internals.h +++ b/drivers/nvmem/internals.h @@ -6,6 +6,7 @@ #include #include #include +#include /* Hold pointers to callbacks owned by the nvmem provider module. */ struct nvmem_operations { @@ -16,6 +17,7 @@ struct nvmem_operations { struct nvmem_device { struct module *owner; struct device dev; + struct srcu_struct srcu; int stride; int word_size; int id; @@ -33,7 +35,7 @@ struct nvmem_device { unsigned int nkeepout; struct gpio_desc *wp_gpio; struct nvmem_layout *layout; - struct nvmem_operations *ops; + struct nvmem_operations __rcu *ops; void *priv; bool sysfs_cells_populated; }; -- 2.47.3