Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp247823pxb; Mon, 13 Sep 2021 18:17:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxvfuIMKkOiP6UfPT9U+6Cl6dSnmw8070nIWDLt1dxae6U1Lzu9OGDPGSis2M8WnvMuAIut X-Received: by 2002:a05:6e02:1bc5:: with SMTP id x5mr10045426ilv.83.1631582258595; Mon, 13 Sep 2021 18:17:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631582258; cv=none; d=google.com; s=arc-20160816; b=0QSafJ+neYNGaYIlqR+Hgs8fVcfzO/zUse76VgRYyIqzfg5H77x7Y7wfdQclgIGosI IT43lEvEcCln9N9brortAZO3PScUoLwBQI8lOAMTtEBw2ztigyf6LjtFLX3MRhaldG6X 2TfkuO4F7ZruFPq7VdSFvbLoNxn2iJZ4Qdqpy0H1Q5vR3eJrxcvA++djdH6Z0arkth5a EQVX+nN6S1rg7Bl6CB64i+DMTxP3ufz/W6Y3UprSTc+lCUFTPrZGr7Pp72/fbBzMcEOE N3pZb8p8TvjXy5x9VuC1w8GcLVmIBdvaeU/E+WuFHFWXj2G+7HhDSXtMaB+YgwIr2XHE tjnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wq1m3czHitWeoOUfTJDXFVc73WgkSqZM3eccFzNMRj8=; b=SkQgbyRPGSk1qHORHeOrFzB8NEvlHOXgc/8TXndQENTPTigwcRzukMF9wLz+HSggyP Qk9UgibPtJi6566cHwWSxz/faFSP+jXIetTrplbLdSl7bNvm6zXqvAs+n29pBhp9LZGu nOr0/SvdzmOJi7TIJC4QCOkmxHmnthxD4teBcs8pWslNUiVvBeCHCce7SjsZafnPdse3 i7E8khN7C169yRn+Y5kO7UsdR58ruVKH9GQgNu7bB+8IHglHEXGZZkfmxOfJd2NcY0mU s9gDSBiXRVCk5Uiu7dUI6smSPr0NZXJPVd/Yz+0FIBtjPSpasZ9Yf/9d1100Vf5fMSML rPsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=rTCTgXee; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id e16si8749634ilm.91.2021.09.13.18.17.27; Mon, 13 Sep 2021 18:17:38 -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=@kernel.org header.s=k20201202 header.b=rTCTgXee; 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=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346135AbhIMWfK (ORCPT + 99 others); Mon, 13 Sep 2021 18:35:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:50154 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245581AbhIMWfC (ORCPT ); Mon, 13 Sep 2021 18:35:02 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1F619610FB; Mon, 13 Sep 2021 22:33:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1631572426; bh=Vbu8GoHws7kTSdOjXcFaQxIFUun8efnlHvM7tlmrpf4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rTCTgXeeBM2+kdnSq1STGCHrEC1KGoViqQ/3Gy96KD/g0hyRLp+KvHfYGm397Ka/H VEN9OyWXqi0NHxEGUdRfgdKtQdW3Q+kRhQuu/I4udckLN2by82+dCFinPPfD9uA3Rw lFWtIONMRuqez4EVDjyljhiMBEeOjz9GZ4vz0Rr/jOicMaIQhI90MC0+YRvbX2eHkS sLjMIGO24Tp34v955rseoAu+yPzjBpFMsZv2Cnc0kE1nztzOwfQ2xUEpSx+E6NlUKE laVGYXpK9JSMv01Nm7IHtt2npB6TH5tRfaea65mbixit/MNUS/eTqRwRuRKeI5CjxN btU4mgPAmHbYQ== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Dan Williams , Ben Widawsky , Jonathan Cameron , Sasha Levin , linux-cxl@vger.kernel.org Subject: [PATCH AUTOSEL 5.14 04/25] cxl/pci: Introduce cdevm_file_operations Date: Mon, 13 Sep 2021 18:33:18 -0400 Message-Id: <20210913223339.435347-4-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210913223339.435347-1-sashal@kernel.org> References: <20210913223339.435347-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dan Williams [ Upstream commit 9cc238c7a526dba9ee8c210fa2828886fc65db66 ] In preparation for moving cxl_memdev allocation to the core, introduce cdevm_file_operations to coordinate file operations shutdown relative to driver data release. The motivation for moving cxl_memdev allocation to the core (beyond better file organization of sysfs attributes in core/ and drivers in cxl/), is that device lifetime is longer than module lifetime. The cxl_pci module should be free to come and go without needing to coordinate with devices that need the text associated with cxl_memdev_release() to stay resident. The move will fix a use after free bug when looping driver load / unload with CONFIG_DEBUG_KOBJECT_RELEASE=y. Another motivation for passing in file_operations to the core cxl_memdev creation flow is to allow for alternate drivers, like unit test code, to define their own ioctl backends. Signed-off-by: Ben Widawsky Reviewed-by: Jonathan Cameron Link: https://lore.kernel.org/r/162792539962.368511.2962268954245340288.stgit@dwillia2-desk3.amr.corp.intel.com Signed-off-by: Dan Williams Signed-off-by: Sasha Levin --- drivers/cxl/cxlmem.h | 15 ++++++++++ drivers/cxl/pci.c | 65 ++++++++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 8f02d02b26b4..0cd463de1342 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -34,6 +34,21 @@ */ #define CXL_MEM_MAX_DEVS 65536 +/** + * struct cdevm_file_operations - devm coordinated cdev file operations + * @fops: file operations that are synchronized against @shutdown + * @shutdown: disconnect driver data + * + * @shutdown is invoked in the devres release path to disconnect any + * driver instance data from @dev. It assumes synchronization with any + * fops operation that requires driver data. After @shutdown an + * operation may only reference @device data. + */ +struct cdevm_file_operations { + struct file_operations fops; + void (*shutdown)(struct device *dev); +}; + /** * struct cxl_memdev - CXL bus object representing a Type-3 Memory Device * @dev: driver core device object diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index a945c5fda292..f7a5ad5e1f4a 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -806,13 +806,30 @@ static int cxl_memdev_release_file(struct inode *inode, struct file *file) return 0; } -static const struct file_operations cxl_memdev_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = cxl_memdev_ioctl, - .open = cxl_memdev_open, - .release = cxl_memdev_release_file, - .compat_ioctl = compat_ptr_ioctl, - .llseek = noop_llseek, +static struct cxl_memdev *to_cxl_memdev(struct device *dev) +{ + return container_of(dev, struct cxl_memdev, dev); +} + +static void cxl_memdev_shutdown(struct device *dev) +{ + struct cxl_memdev *cxlmd = to_cxl_memdev(dev); + + down_write(&cxl_memdev_rwsem); + cxlmd->cxlm = NULL; + up_write(&cxl_memdev_rwsem); +} + +static const struct cdevm_file_operations cxl_memdev_fops = { + .fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = cxl_memdev_ioctl, + .open = cxl_memdev_open, + .release = cxl_memdev_release_file, + .compat_ioctl = compat_ptr_ioctl, + .llseek = noop_llseek, + }, + .shutdown = cxl_memdev_shutdown, }; static inline struct cxl_mem_command *cxl_mem_find_command(u16 opcode) @@ -1161,11 +1178,6 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm) return ret; } -static struct cxl_memdev *to_cxl_memdev(struct device *dev) -{ - return container_of(dev, struct cxl_memdev, dev); -} - static void cxl_memdev_release(struct device *dev) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); @@ -1281,24 +1293,22 @@ static const struct device_type cxl_memdev_type = { .groups = cxl_memdev_attribute_groups, }; -static void cxl_memdev_shutdown(struct cxl_memdev *cxlmd) -{ - down_write(&cxl_memdev_rwsem); - cxlmd->cxlm = NULL; - up_write(&cxl_memdev_rwsem); -} - static void cxl_memdev_unregister(void *_cxlmd) { struct cxl_memdev *cxlmd = _cxlmd; struct device *dev = &cxlmd->dev; + struct cdev *cdev = &cxlmd->cdev; + const struct cdevm_file_operations *cdevm_fops; + + cdevm_fops = container_of(cdev->ops, typeof(*cdevm_fops), fops); + cdevm_fops->shutdown(dev); cdev_device_del(&cxlmd->cdev, dev); - cxl_memdev_shutdown(cxlmd); put_device(dev); } -static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm) +static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm, + const struct file_operations *fops) { struct pci_dev *pdev = cxlm->pdev; struct cxl_memdev *cxlmd; @@ -1324,7 +1334,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm) device_set_pm_not_required(dev); cdev = &cxlmd->cdev; - cdev_init(cdev, &cxl_memdev_fops); + cdev_init(cdev, fops); return cxlmd; err: @@ -1332,15 +1342,16 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_mem *cxlm) return ERR_PTR(rc); } -static struct cxl_memdev *devm_cxl_add_memdev(struct device *host, - struct cxl_mem *cxlm) +static struct cxl_memdev * +devm_cxl_add_memdev(struct device *host, struct cxl_mem *cxlm, + const struct cdevm_file_operations *cdevm_fops) { struct cxl_memdev *cxlmd; struct device *dev; struct cdev *cdev; int rc; - cxlmd = cxl_memdev_alloc(cxlm); + cxlmd = cxl_memdev_alloc(cxlm, &cdevm_fops->fops); if (IS_ERR(cxlmd)) return cxlmd; @@ -1370,7 +1381,7 @@ static struct cxl_memdev *devm_cxl_add_memdev(struct device *host, * The cdev was briefly live, shutdown any ioctl operations that * saw that state. */ - cxl_memdev_shutdown(cxlmd); + cdevm_fops->shutdown(dev); put_device(dev); return ERR_PTR(rc); } @@ -1611,7 +1622,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; - cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm); + cxlmd = devm_cxl_add_memdev(&pdev->dev, cxlm, &cxl_memdev_fops); if (IS_ERR(cxlmd)) return PTR_ERR(cxlmd); -- 2.30.2