From nobody Thu Oct 9 10:02:58 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 4D8092853F6 for ; Wed, 18 Jun 2025 10:09:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241361; cv=none; b=uai3PSkGl3VmJNW6zUzoG9m9yWBrLQJngrHqizkkjRl8trkBeyOGfu9eD573zfr7I5FIMOH29oK7pcFDXygUjwpEBGTwu0T925eX801nZ/cGG546gbN5FfCWfIxtGdRM1E5m9gBupHIzUSaHw3gBoNzBOnz5CcYzCAf5WW4mu60= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241361; c=relaxed/simple; bh=1tJ2d/lN3+UrL4g9qzU73LtY+bAG6q0wkYciipeCLQI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gj3tFgYJfx7Tn2Hcuh72vMiTb2PQSC5K8+C+a3n/m/BS1fp+yZQE6PcYqZP1gVC8/Nk6VbSLVv64uAWvExGwjGavCxKwS7b8HWe8WjrK7IhumW20MrM0hjQsAUn1gTD6NAwz3cU0kUrrYBorlk2VVq/S5FwxZs5nmVpNhCqWKo4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=W94xfTtI; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="W94xfTtI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1750241359; x=1781777359; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1tJ2d/lN3+UrL4g9qzU73LtY+bAG6q0wkYciipeCLQI=; b=W94xfTtIgxdCrJZrjyjtCNCe2rPv/F/zfPKXghKLsBf7LmSnsUzYcQV5 5P6fdaSwGzrcxMVeP+P/i6srMi8GAQzZ6PhA5ICPHvh0C91YqkCW8Uf72 OIA2IglygV/68okFf08GPPSHm7xYvPq9NaX6i1+hzWyY1Rlxi4CaU4cIE oxkOnhGXM7i8HjdmrbzNwqsQqZR/I9Fvoab7PUsvKvPvBk5i5PyNAEYo8 79fL2IVoqRntof1blhK7ANhEWfyx7239IxKIUrdR0+ZUKI6S2synxs9og TCcUL+s3abpNLZJYtxkMy16Oi82n36OE6S1GPB857yNKNJ5P40X1PTCfI w==; X-CSE-ConnectionGUID: +I0N1zQLSj6JnCN6prB+ng== X-CSE-MsgGUID: qDwTbluqTUiyy7weNm6V7w== X-IronPort-AV: E=McAfee;i="6800,10657,11467"; a="52591001" X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="52591001" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:09 -0700 X-CSE-ConnectionGUID: 00G6yquTS+6Z+WF2zuOo3A== X-CSE-MsgGUID: wymknRrNQaGuuhP9cH/cdw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="149461193" Received: from sannilnx-dsk.jer.intel.com ([10.12.231.107]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:07 -0700 From: Alexander Usyskin To: Greg Kroah-Hartman Cc: Reuven Abliyev , Alexander Usyskin , linux-kernel@vger.kernel.org Subject: [char-misc-next 1/3] mei: refcount mei_device Date: Wed, 18 Jun 2025 12:54:31 +0300 Message-ID: <20250618095433.3943546-2-alexander.usyskin@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250618095433.3943546-1-alexander.usyskin@intel.com> References: <20250618095433.3943546-1-alexander.usyskin@intel.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" mei_device lifetime is managed by devm procedure of parent device. But such memory is freed on device_del. Mei_device object is used by client object that may be alive after parent device is removed. It may lead to use-after-free if discrete graphics driver unloads mei_gsc auxiliary device while user-space holds open handle to mei character device. Replace devm lifetime management with reference counting to eliminate the use-after-free. Signed-off-by: Alexander Usyskin --- drivers/misc/mei/bus.c | 10 +++++++--- drivers/misc/mei/gsc-me.c | 6 ++++-- drivers/misc/mei/hw-me.c | 2 +- drivers/misc/mei/hw-txe.c | 2 +- drivers/misc/mei/init.c | 35 +++++++++++++++++++++++++++++++++ drivers/misc/mei/main.c | 6 +++++- drivers/misc/mei/mei_dev.h | 6 ++++++ drivers/misc/mei/pci-me.c | 5 ++++- drivers/misc/mei/pci-txe.c | 5 ++++- drivers/misc/mei/platform-vsc.c | 7 ++++--- 10 files changed, 71 insertions(+), 13 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 67176caf5416..0a6176e72d10 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1286,16 +1286,20 @@ static const struct bus_type mei_cl_bus_type =3D { =20 static struct mei_device *mei_dev_bus_get(struct mei_device *bus) { - if (bus) - get_device(bus->dev); + struct mei_device *rbus; + + rbus =3D mei_device_get(bus); + if (rbus) + get_device(rbus->dev); =20 - return bus; + return rbus; } =20 static void mei_dev_bus_put(struct mei_device *bus) { if (bus) put_device(bus->dev); + mei_device_put(bus); } =20 static void mei_cl_bus_dev_release(struct device *dev) diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c index 5a8c26c3df13..6b34645e4504 100644 --- a/drivers/misc/mei/gsc-me.c +++ b/drivers/misc/mei/gsc-me.c @@ -69,7 +69,7 @@ static int mei_gsc_probe(struct auxiliary_device *aux_dev, hw->mem_addr =3D devm_ioremap_resource(device, &adev->bar); if (IS_ERR(hw->mem_addr)) { ret =3D PTR_ERR(hw->mem_addr); - goto err; + goto free_dev; } =20 hw->irq =3D adev->irq; @@ -131,7 +131,8 @@ static int mei_gsc_probe(struct auxiliary_device *aux_d= ev, mei_stop(dev); if (!mei_me_hw_use_polling(hw)) devm_free_irq(device, hw->irq, dev); - +free_dev: + mei_device_put(dev); err: dev_err(device, "probe failed: %d\n", ret); dev_set_drvdata(device, NULL); @@ -159,6 +160,7 @@ static void mei_gsc_remove(struct auxiliary_device *aux= _dev) mei_disable_interrupts(dev); if (!mei_me_hw_use_polling(hw)) devm_free_irq(&aux_dev->dev, hw->irq, dev); + mei_device_put(dev); } =20 static int __maybe_unused mei_gsc_pm_suspend(struct device *device) diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index d11a0740b47c..7a49c4bd2734 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -1804,7 +1804,7 @@ struct mei_device *mei_me_dev_init(struct device *par= ent, struct mei_me_hw *hw; int i; =20 - dev =3D devm_kzalloc(parent, sizeof(*dev) + sizeof(*hw), GFP_KERNEL); + dev =3D kzalloc(sizeof(*dev) + sizeof(*hw), GFP_KERNEL); if (!dev) return NULL; =20 diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c index e9476f9ae25d..c6e396ad2e9e 100644 --- a/drivers/misc/mei/hw-txe.c +++ b/drivers/misc/mei/hw-txe.c @@ -1197,7 +1197,7 @@ struct mei_device *mei_txe_dev_init(struct pci_dev *p= dev) struct mei_device *dev; struct mei_txe_hw *hw; =20 - dev =3D devm_kzalloc(&pdev->dev, sizeof(*dev) + sizeof(*hw), GFP_KERNEL); + dev =3D kzalloc(sizeof(*dev) + sizeof(*hw), GFP_KERNEL); if (!dev) return NULL; =20 diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 8ef2b1df8ac7..26ae60f26772 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -389,6 +389,7 @@ void mei_device_init(struct mei_device *dev, bool slow_fw, const struct mei_hw_ops *hw_ops) { + kref_init(&dev->refcnt); /* setup our list array */ INIT_LIST_HEAD(&dev->file_list); INIT_LIST_HEAD(&dev->device_list); @@ -445,3 +446,37 @@ void mei_device_init(struct mei_device *dev, } EXPORT_SYMBOL_GPL(mei_device_init); =20 +/** + * mei_device_get - increases mei device refcount + * + * @dev: the mei device + * + * Return: mei device or NULL on failure + */ +struct mei_device *mei_device_get(struct mei_device *dev) +{ + if (dev && kref_get_unless_zero(&dev->refcnt)) + return dev; + + return NULL; +} +EXPORT_SYMBOL_GPL(mei_device_get); + +static void mei_device_release(struct kref *ref) +{ + struct mei_device *dev =3D container_of(ref, struct mei_device, refcnt); + + kfree(dev); +} + +/** + * mei_device_put - decrease mei device refcount and free object if necess= ary + * + * @dev: the mei device + */ +void mei_device_put(struct mei_device *dev) +{ + if (dev) + kref_put(&dev->refcnt, mei_device_release); +} +EXPORT_SYMBOL_GPL(mei_device_put); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 1f5aaf16e300..03898246ab16 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -51,7 +51,9 @@ static int mei_open(struct inode *inode, struct file *fil= e) =20 int err; =20 - dev =3D container_of(inode->i_cdev, struct mei_device, cdev); + dev =3D mei_device_get(container_of(inode->i_cdev, struct mei_device, cde= v)); + if (!dev) + return -ENODEV; =20 mutex_lock(&dev->device_lock); =20 @@ -77,6 +79,7 @@ static int mei_open(struct inode *inode, struct file *fil= e) =20 err_unlock: mutex_unlock(&dev->device_lock); + mei_device_put(dev); return err; } =20 @@ -152,6 +155,7 @@ static int mei_release(struct inode *inode, struct file= *file) file->private_data =3D NULL; =20 mutex_unlock(&dev->device_lock); + mei_device_put(dev); return rets; } =20 diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 37d7fb15cad7..b745cde80662 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -474,6 +474,8 @@ struct mei_dev_timeouts { * @cdev : character device * @minor : minor number allocated for device * + * @refcnt : struct reference count + * * @write_list : write pending list * @write_waiting_list : write completion list * @ctrl_wr_list : pending control write list @@ -560,6 +562,8 @@ struct mei_device { struct cdev cdev; int minor; =20 + struct kref refcnt; + struct list_head write_list; struct list_head write_waiting_list; struct list_head ctrl_wr_list; @@ -706,6 +710,8 @@ void mei_device_init(struct mei_device *dev, struct device *device, bool slow_fw, const struct mei_hw_ops *hw_ops); +struct mei_device *mei_device_get(struct mei_device *dev); +void mei_device_put(struct mei_device *dev); int mei_reset(struct mei_device *dev); int mei_start(struct mei_device *dev); int mei_restart(struct mei_device *dev); diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 3f9c60b579ae..7acfdd04924a 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -235,7 +235,7 @@ static int mei_me_probe(struct pci_dev *pdev, const str= uct pci_device_id *ent) if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq =3D %d\n", pdev->irq); - goto end; + goto free_dev; } =20 if (mei_start(dev)) { @@ -286,6 +286,8 @@ static int mei_me_probe(struct pci_dev *pdev, const str= uct pci_device_id *ent) mei_cancel_work(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); +free_dev: + mei_device_put(dev); end: dev_err(&pdev->dev, "initialization failed.\n"); return err; @@ -338,6 +340,7 @@ static void mei_me_remove(struct pci_dev *pdev) free_irq(pdev->irq, dev); =20 mei_deregister(dev); + mei_device_put(dev); } =20 #ifdef CONFIG_PM_SLEEP diff --git a/drivers/misc/mei/pci-txe.c b/drivers/misc/mei/pci-txe.c index 2a584104ba38..bad1577d283d 100644 --- a/drivers/misc/mei/pci-txe.c +++ b/drivers/misc/mei/pci-txe.c @@ -106,7 +106,7 @@ static int mei_txe_probe(struct pci_dev *pdev, const st= ruct pci_device_id *ent) if (err) { dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq =3D %d\n", pdev->irq); - goto end; + goto free_dev; } =20 if (mei_start(dev)) { @@ -150,6 +150,8 @@ static int mei_txe_probe(struct pci_dev *pdev, const st= ruct pci_device_id *ent) mei_cancel_work(dev); mei_disable_interrupts(dev); free_irq(pdev->irq, dev); +free_dev: + mei_device_put(dev); end: dev_err(&pdev->dev, "initialization failed.\n"); return err; @@ -199,6 +201,7 @@ static void mei_txe_remove(struct pci_dev *pdev) free_irq(pdev->irq, dev); =20 mei_deregister(dev); + mei_device_put(dev); } =20 =20 diff --git a/drivers/misc/mei/platform-vsc.c b/drivers/misc/mei/platform-vs= c.c index 435760b1e86f..e1ec992211c3 100644 --- a/drivers/misc/mei/platform-vsc.c +++ b/drivers/misc/mei/platform-vsc.c @@ -340,8 +340,7 @@ static int mei_vsc_probe(struct platform_device *pdev) if (!tp) return dev_err_probe(dev, -ENODEV, "no platform data\n"); =20 - mei_dev =3D devm_kzalloc(dev, size_add(sizeof(*mei_dev), sizeof(*hw)), - GFP_KERNEL); + mei_dev =3D kzalloc(size_add(sizeof(*mei_dev), sizeof(*hw)), GFP_KERNEL); if (!mei_dev) return -ENOMEM; =20 @@ -373,8 +372,9 @@ static int mei_vsc_probe(struct platform_device *pdev) =20 err_stop: mei_stop(mei_dev); - err_cancel: + mei_device_put(mei_dev); + mei_cancel_work(mei_dev); =20 mei_disable_interrupts(mei_dev); @@ -393,6 +393,7 @@ static void mei_vsc_remove(struct platform_device *pdev) mei_disable_interrupts(mei_dev); =20 mei_deregister(mei_dev); + mei_device_put(mei_dev); } =20 static int mei_vsc_suspend(struct device *dev) --=20 2.43.0 From nobody Thu Oct 9 10:02:58 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 AD8522877D9 for ; Wed, 18 Jun 2025 10:09:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241362; cv=none; b=YbS6xbjTgczqxtAaanx3DwbU+vaIyw0eEwTivJESYk4dg56ZaTttDLdVsB4eBwtvTNnNP5o66Pp858jF81uxkvFtZSxKh/8Kx0hxojujwQd4UoUqBNuHF70gNmed/6V6Pjl9jtC4c1VZ7qTvM8UeGzVk/1W+WvvgA2VUNsdnvJY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241362; c=relaxed/simple; bh=8aJBHTaoDwbPr+X9duP3A0ddPan1c4bJ9DT1hCoqjF8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GR12ttjPvUXzzqPyNWVSSew7NkTZLUBAcPHnFvHwCj7TCjd6rJEcgmkrLEqpZJ6jR6/32ouHpA9zQhWVxOkpzPEYKZ72YypkZEst/X3r2xL+ctioKI7v+XTwJ8cwKFE8gyKvyPz0jcy+kMqdUtU+wNL+Al5UQOfcJaVH36lqAEo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=NKUcom2R; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="NKUcom2R" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1750241361; x=1781777361; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8aJBHTaoDwbPr+X9duP3A0ddPan1c4bJ9DT1hCoqjF8=; b=NKUcom2RFSiJ6FTBMBTDakSkTEsZEs8AWVM7rFX+d5nHUyhBgqlGfImE oIATziK4Cn52bWlEDvs2E6ucxfH2iWsm0EE+H+91VbyoVgDvSHeVSucdv NxGzc/ZY1wm4gPMNe+a7Xvr1yQnL66Mupafcf7oOHoTI1YN7qSqIqe+L3 rUcgZ6gudR3kHRU5yx9nM/gCdSjGWdynIGeeH6Ug8PvHU0uIRM8jAYHkd 8pZqCVjyQuGISc88w1PQCNlSFX/YJKGkHVUHBkO3LqKSqA2sItieGrOFn e+Hr2MIJI07CJtq9rSzdmhvDzkKvkAjnVFlPb5ZVnwpTIz2OyHPLdcuPs g==; X-CSE-ConnectionGUID: yfHYi5QjQyq5FtzTEEtThA== X-CSE-MsgGUID: Y4UM5nUBSeqRfbY5C7Mxzg== X-IronPort-AV: E=McAfee;i="6800,10657,11467"; a="52591011" X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="52591011" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:10 -0700 X-CSE-ConnectionGUID: Lc2DfxmERHWb0PFOl04oeA== X-CSE-MsgGUID: 8CAy3dduRJKbPjJehl/w4A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="149461238" Received: from sannilnx-dsk.jer.intel.com ([10.12.231.107]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:09 -0700 From: Alexander Usyskin To: Greg Kroah-Hartman Cc: Reuven Abliyev , Alexander Usyskin , linux-kernel@vger.kernel.org Subject: [char-misc-next 2/3] mei: set parent for char device Date: Wed, 18 Jun 2025 12:54:32 +0300 Message-ID: <20250618095433.3943546-3-alexander.usyskin@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250618095433.3943546-1-alexander.usyskin@intel.com> References: <20250618095433.3943546-1-alexander.usyskin@intel.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" Connect char device to parent device to avoid parent device unload while char device is still held open by user-space. Signed-off-by: Alexander Usyskin --- drivers/misc/mei/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 03898246ab16..c160703d0782 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1229,6 +1229,7 @@ int mei_register(struct mei_device *dev, struct devic= e *parent) devno =3D MKDEV(MAJOR(mei_devt), dev->minor); cdev_init(&dev->cdev, &mei_fops); dev->cdev.owner =3D parent->driver->owner; + cdev_set_parent(&dev->cdev, &parent->kobj); =20 /* Add the device */ ret =3D cdev_add(&dev->cdev, devno, 1); --=20 2.43.0 From nobody Thu Oct 9 10:02:58 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 752792877E7 for ; Wed, 18 Jun 2025 10:09:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241363; cv=none; b=RX2HStw5T9GkB5gygnW+bXwXCaT2ODvfbsC+NG/wvBA25wcTLXEyFBzuKnQ57gs3yHqTaQuKTd6Z+LoLt3lZ4h6CWn6KAEdxHjmPPRvJ1JMe5Ade3yLazzUqdyDhgAzX9DoUIyitV+bhT7rp2gg1gVFvH7mJNLFvD5Yba0LiUXQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750241363; c=relaxed/simple; bh=xpn/EHIABiAzTJLgy/jCZXbyjPag492xA6bZdLVSFwI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g0dL9LrGRbFcgT5FCHlro54Rp/0udteC6TJ3F8U9SSl2dGkUtU0p9p3KsuunIrFSprV0ty5xGT6EFtzHIykkWXWJffB+Vuuzz72ulQLylMFtIeqBqu5jKIaLtV8XmNCFXeRYncoIfahIgFZeAVBATyJ7M+cDRmirr7gSUqAMDcM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=QewFDs4v; arc=none smtp.client-ip=198.175.65.18 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="QewFDs4v" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1750241362; x=1781777362; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xpn/EHIABiAzTJLgy/jCZXbyjPag492xA6bZdLVSFwI=; b=QewFDs4vcdiXg4YwOfOdxrLP8WeXB/yXsoqqRCD666eK+yZ6ko8oIVWL kpkmLyIVe/TCRmhkMmv1WSgkSGANZOHA2tN6rdEs0Vy1wCbv7OlVL8ruD 6Chz7pJbBbEasR9tYG7veSihuzy0tx8oEoPstOiMRN38ZpvZKkWXY7dLM /r7mxJTDsBUXPOq+dKt7rb/23QJHgB4YpAr6qLdwWKoTBsoyMPz2voble 4VsSpOdCrHRbYogYTOAMDFAkcIMx5aof7I4Zz+A8CJDhSNsBAzrE4Rq1p glDik6tvf35eAkL6VVOD6e7sxW4W5+ugWSKu6m34pQhb6LR8AQbgB6j3g w==; X-CSE-ConnectionGUID: PGIVtt8+TzKcbJGFYkK0TA== X-CSE-MsgGUID: BGlCwLKITDizssDjo1BRaA== X-IronPort-AV: E=McAfee;i="6800,10657,11467"; a="52591024" X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="52591024" Received: from fmviesa006.fm.intel.com ([10.60.135.146]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:12 -0700 X-CSE-ConnectionGUID: dxAJV6kYS1CuINge0wA7hQ== X-CSE-MsgGUID: zrRYSo7sShikWKGAWN8j3A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.16,245,1744095600"; d="scan'208";a="149461269" Received: from sannilnx-dsk.jer.intel.com ([10.12.231.107]) by fmviesa006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Jun 2025 03:08:10 -0700 From: Alexander Usyskin To: Greg Kroah-Hartman Cc: Reuven Abliyev , Alexander Usyskin , linux-kernel@vger.kernel.org Subject: [char-misc-next 3/3] mei: make char device control its own lifetime Date: Wed, 18 Jun 2025 12:54:33 +0300 Message-ID: <20250618095433.3943546-4-alexander.usyskin@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250618095433.3943546-1-alexander.usyskin@intel.com> References: <20250618095433.3943546-1-alexander.usyskin@intel.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" Allocate character device dynamically and allow to control its own lifetime as it may outlive mei_device structure while character device closes after parent device is removed from the system. Signed-off-by: Alexander Usyskin --- drivers/misc/mei/main.c | 34 +++++++++++++++++++++------------- drivers/misc/mei/mei_dev.h | 4 ++-- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c160703d0782..2162a8de9e6a 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -51,7 +51,7 @@ static int mei_open(struct inode *inode, struct file *fil= e) =20 int err; =20 - dev =3D mei_device_get(container_of(inode->i_cdev, struct mei_device, cde= v)); + dev =3D mei_device_get(idr_find(&mei_idr, iminor(inode))); if (!dev) return -ENODEV; =20 @@ -1122,7 +1122,10 @@ void mei_set_devstate(struct mei_device *dev, enum m= ei_dev_state state) =20 dev->dev_state =3D state; =20 - clsdev =3D class_find_device_by_devt(&mei_class, dev->cdev.dev); + if (!dev->cdev) + return; + + clsdev =3D class_find_device_by_devt(&mei_class, dev->cdev->dev); if (clsdev) { sysfs_notify(&clsdev->kobj, NULL, "dev_state"); put_device(clsdev); @@ -1227,16 +1230,21 @@ int mei_register(struct mei_device *dev, struct dev= ice *parent) =20 /* Fill in the data structures */ devno =3D MKDEV(MAJOR(mei_devt), dev->minor); - cdev_init(&dev->cdev, &mei_fops); - dev->cdev.owner =3D parent->driver->owner; - cdev_set_parent(&dev->cdev, &parent->kobj); + dev->cdev =3D cdev_alloc(); + if (!dev->cdev) { + ret =3D -ENOMEM; + goto err; + } + dev->cdev->ops =3D &mei_fops; + dev->cdev->owner =3D parent->driver->owner; + cdev_set_parent(dev->cdev, &parent->kobj); =20 /* Add the device */ - ret =3D cdev_add(&dev->cdev, devno, 1); + ret =3D cdev_add(dev->cdev, devno, 1); if (ret) { dev_err(parent, "unable to add device %d:%d\n", MAJOR(mei_devt), dev->minor); - goto err_dev_add; + goto err_del_cdev; } =20 clsdev =3D device_create_with_groups(&mei_class, parent, devno, @@ -1247,16 +1255,16 @@ int mei_register(struct mei_device *dev, struct dev= ice *parent) dev_err(parent, "unable to create device %d:%d\n", MAJOR(mei_devt), dev->minor); ret =3D PTR_ERR(clsdev); - goto err_dev_create; + goto err_del_cdev; } =20 mei_dbgfs_register(dev, dev_name(clsdev)); =20 return 0; =20 -err_dev_create: - cdev_del(&dev->cdev); -err_dev_add: +err_del_cdev: + cdev_del(dev->cdev); +err: mei_minor_free(dev); return ret; } @@ -1266,8 +1274,8 @@ void mei_deregister(struct mei_device *dev) { int devno; =20 - devno =3D dev->cdev.dev; - cdev_del(&dev->cdev); + devno =3D dev->cdev->dev; + cdev_del(dev->cdev); =20 mei_dbgfs_deregister(dev); =20 diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index b745cde80662..8f081c6735c4 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -471,7 +471,7 @@ struct mei_dev_timeouts { * struct mei_device - MEI private device struct * * @dev : device on a bus - * @cdev : character device + * @cdev : character device pointer * @minor : minor number allocated for device * * @refcnt : struct reference count @@ -559,7 +559,7 @@ struct mei_dev_timeouts { */ struct mei_device { struct device *dev; - struct cdev cdev; + struct cdev *cdev; int minor; =20 struct kref refcnt; --=20 2.43.0