linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org
Cc: "Rick Wertenbroek" <rick.wertenbroek@gmail.com>,
	"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
	"Krzysztof Wilczyński" <kw@linux.com>,
	"Manivannan Sadhasivam" <mani@kernel.org>,
	"Kishon Vijay Abraham I" <kishon@kernel.org>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>
Subject: [PATCH v2 01/16] PCI: endpoint: Automatically create a function specific attributes group
Date: Wed,  8 Mar 2023 18:02:58 +0900	[thread overview]
Message-ID: <20230308090313.1653-2-damien.lemoal@opensource.wdc.com> (raw)
In-Reply-To: <20230308090313.1653-1-damien.lemoal@opensource.wdc.com>

A PCI endpoint function driver can define function specific attributes
under its function configfs directory using the add_cfs() endpoint
driver operation. This is done by tighing up the mkdir operation for
the function configfs directory to a call to the add_cfs() operation.
However, there are no checks preventing the user from repeatedly
creating function specific attribute directories with different names,
resulting in the same endpoing specific attributes group being added
multiple times, which also result in an invalid refernce counting for
the attribute groups. E.g., using the pci-epf-ntb function driver as an
example, the user creates the function as follows:

 modprobe pci-epf-ntb
func0/
|-- baseclass_code
|-- cache_line_size
|-- ...
`-- vendorid

func0/
|-- attrs
|   |-- db_count
|   |-- mw1
|   |-- mw2
|   |-- mw3
|   |-- mw4
|   |-- num_mws
|   `-- spad_count
|-- baseclass_code
|-- cache_line_size
|-- ...
`-- vendorid

At this point, the function can be started by linking the EP controller.
However, if the user mistakenly creates again a directory:

func0/
|-- attrs
|   |-- db_count
|   |-- mw1
|   |-- mw2
|   |-- mw3
|   |-- mw4
|   |-- num_mws
|   `-- spad_count
|-- attrs2
|   |-- db_count
|   |-- mw1
|   |-- mw2
|   |-- mw3
|   |-- mw4
|   |-- num_mws
|   `-- spad_count
|-- baseclass_code
|-- cache_line_size
|-- ...
`-- vendorid

The function specific attributes are duplicated and cause a crash when
the function is tore down:

[ 9740.729598] ------------[ cut here ]------------
[ 9740.730071] refcount_t: addition on 0; use-after-free.
[ 9740.730564] WARNING: CPU: 2 PID: 834 at lib/refcount.c:25 refcount_warn_saturate+0xc8/0x144
[ 9740.735593] CPU: 2 PID: 834 Comm: rmdir Not tainted 6.3.0-rc1 #1
[ 9740.736133] Hardware name: Pine64 RockPro64 v2.1 (DT)
[ 9740.736586] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 9740.737210] pc : refcount_warn_saturate+0xc8/0x144
[ 9740.737648] lr : refcount_warn_saturate+0xc8/0x144
[ 9740.738085] sp : ffff800009cebc90
[ 9740.738385] x29: ffff800009cebc90 x28: ffff0000019ed700 x27: ffff0000040c3900
[ 9740.739032] x26: 0000000000000000 x25: ffff800009325320 x24: ffff0000012da000
[ 9740.739678] x23: ffff000003bd9a80 x22: ffff000005ee9580 x21: ffff000003bd9ad8
[ 9740.740324] x20: ffff0000f36cd2c8 x19: ffff0000012da2b8 x18: 0000000000000006
[ 9740.740969] x17: 0000000000000000 x16: 0000000000000000 x15: 0765076507720766
[ 9740.741615] x14: 072d077207650774 x13: ffff800009281000 x12: 000000000000056d
[ 9740.742261] x11: 00000000000001cf x10: ffff8000092d9000 x9 : ffff800009281000
[ 9740.742906] x8 : 00000000ffffefff x7 : ffff8000092d9000 x6 : 80000000fffff000
[ 9740.743552] x5 : ffff0000f7771b88 x4 : 0000000000000000 x3 : 0000000000000027
[ 9740.744197] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0000019ed700
[ 9740.744842] Call trace:
[ 9740.745068]  refcount_warn_saturate+0xc8/0x144
[ 9740.745475]  config_item_get+0x7c/0x80
[ 9740.745822]  configfs_rmdir+0x17c/0x30c
[ 9740.746174]  vfs_rmdir+0x8c/0x204
[ 9740.746482]  do_rmdir+0x158/0x184
[ 9740.746787]  __arm64_sys_unlinkat+0x64/0x80
[ 9740.747171]  invoke_syscall+0x48/0x114
[ 9740.747519]  el0_svc_common.constprop.0+0x44/0xec
[ 9740.747948]  do_el0_svc+0x38/0x98
[ 9740.748255]  el0_svc+0x2c/0x84
[ 9740.748541]  el0t_64_sync_handler+0xf4/0x120
[ 9740.748932]  el0t_64_sync+0x190/0x194
[ 9740.749269] ---[ end trace 0000000000000000 ]---
[ 9740.749754] ------------[ cut here ]------------

Fix this by modifying pci_epf_cfs_work() to execute the new function
pci_ep_cfs_add_type_group() which itself calls pci_epf_type_add_cfs()
to obtain the function specific attribute group and the group name
(directory name) from the endpoint function driver. If the function
driver defines an attribute group, pci_ep_cfs_add_type_group() then
proceeds to register this group using configfs_register_group(), thus
automatically exposing the function type pecific onfigfs attributes to
the user. E.g.:

func0/
|-- baseclass_code
|-- cache_line_size
|-- ...
|-- pci_epf_ntb.0
|   |-- db_count
|   |-- mw1
|   |-- mw2
|   |-- mw3
|   |-- mw4
|   |-- num_mws
|   `-- spad_count
|-- primary
|-- ...
`-- vendorid

With this change, there is no need for the user to create/delete
directories in the endpoint function configfs directory. The
pci_epf_type_group_ops group operations are thus removed.

Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
---
 drivers/pci/endpoint/pci-ep-cfs.c | 41 ++++++++++++++-----------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index 4b8ac0ac84d5..b16fc6093c20 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -23,6 +23,7 @@ struct pci_epf_group {
 	struct config_group group;
 	struct config_group primary_epc_group;
 	struct config_group secondary_epc_group;
+	struct config_group *type_group;
 	struct delayed_work cfs_work;
 	struct pci_epf *epf;
 	int index;
@@ -502,34 +503,28 @@ static struct configfs_item_operations pci_epf_ops = {
 	.release		= pci_epf_release,
 };
 
-static struct config_group *pci_epf_type_make(struct config_group *group,
-					      const char *name)
-{
-	struct pci_epf_group *epf_group = to_pci_epf_group(&group->cg_item);
-	struct config_group *epf_type_group;
-
-	epf_type_group = pci_epf_type_add_cfs(epf_group->epf, group);
-	return epf_type_group;
-}
-
-static void pci_epf_type_drop(struct config_group *group,
-			      struct config_item *item)
-{
-	config_item_put(item);
-}
-
-static struct configfs_group_operations pci_epf_type_group_ops = {
-	.make_group     = &pci_epf_type_make,
-	.drop_item      = &pci_epf_type_drop,
-};
-
 static const struct config_item_type pci_epf_type = {
-	.ct_group_ops	= &pci_epf_type_group_ops,
 	.ct_item_ops	= &pci_epf_ops,
 	.ct_attrs	= pci_epf_attrs,
 	.ct_owner	= THIS_MODULE,
 };
 
+static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)
+{
+	struct config_group *group;
+
+	group = pci_epf_type_add_cfs(epf_group->epf, &epf_group->group);
+	if (!group)
+		return;
+
+	if (IS_ERR(group)) {
+		pr_err("failed to create epf type specific attributes\n");
+		return;
+	}
+
+	configfs_register_group(&epf_group->group, group);
+}
+
 static void pci_epf_cfs_work(struct work_struct *work)
 {
 	struct pci_epf_group *epf_group;
@@ -547,6 +542,8 @@ static void pci_epf_cfs_work(struct work_struct *work)
 		pr_err("failed to create 'secondary' EPC interface\n");
 		return;
 	}
+
+	pci_ep_cfs_add_type_group(epf_group);
 }
 
 static struct config_group *pci_epf_make(struct config_group *group,
-- 
2.39.2


  reply	other threads:[~2023-03-08  9:04 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-08  9:02 [PATCH v2 00/16] PCI endpoint fixes and improvements Damien Le Moal
2023-03-08  9:02 ` Damien Le Moal [this message]
2023-03-15 14:27   ` [PATCH v2 01/16] PCI: endpoint: Automatically create a function specific attributes group Manivannan Sadhasivam
2023-03-08  9:02 ` [PATCH v2 02/16] PCI: endpoint: Move pci_epf_type_add_cfs() code Damien Le Moal
2023-03-15 15:01   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 03/16] PCI: epf-test: Fix DMA transfer completion initialization Damien Le Moal
2023-03-15 15:03   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 04/16] PCI: epf-test: Fix DMA transfer completion detection Damien Le Moal
2023-03-15 15:20   ` Manivannan Sadhasivam
2023-03-15 23:46     ` Damien Le Moal
2023-03-08  9:03 ` [PATCH v2 05/16] PCI: epf-test: Use dmaengine_submit() to initiate DMA transfer Damien Le Moal
2023-03-15 15:21   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 06/16] PCI: epf-test: Simplify read/write/copy test functions Damien Le Moal
2023-03-15 15:24   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 07/16] PCI: epf-test: Simply pci_epf_test_raise_irq() Damien Le Moal
2023-03-15 15:27   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 08/16] PCI: epf-test: Simplify IRQ test commands execution Damien Le Moal
2023-03-15 15:37   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 09/16] PCI: epf-test: Improve handling of command and status registers Damien Le Moal
2023-03-15 15:51   ` Manivannan Sadhasivam
2023-03-15 23:49     ` Damien Le Moal
2023-03-16 15:25     ` Arnd Bergmann
2023-03-16 16:31       ` Manivannan Sadhasivam
2023-03-16 16:32   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 10/16] PCI: epf-test: Cleanup pci_epf_test_cmd_handler() Damien Le Moal
2023-03-15 15:52   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 11/16] PCI: epf-test: Simplify dma support checks Damien Le Moal
2023-03-15 15:57   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 12/16] PCI: epf-test: Simplify transfers result print Damien Le Moal
2023-03-08  9:03 ` [PATCH v2 13/16] misc: pci_endpoint_test: Free IRQs before removing the device Damien Le Moal
2023-03-08  9:03 ` [PATCH v2 14/16] misc: pci_endpoint_test: Re-init completion for every test Damien Le Moal
2023-03-15 15:55   ` Manivannan Sadhasivam
2023-03-08  9:03 ` [PATCH v2 15/16] misc: pci_endpoint_test: Do not write status in IRQ handler Damien Le Moal
2023-03-08  9:03 ` [PATCH v2 16/16] misc: pci_endpoint_test: Simplify pci_endpoint_test_msi_irq() Damien Le Moal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230308090313.1653-2-damien.lemoal@opensource.wdc.com \
    --to=damien.lemoal@opensource.wdc.com \
    --cc=arnd@arndb.de \
    --cc=bhelgaas@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=kishon@kernel.org \
    --cc=kw@linux.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=lpieralisi@kernel.org \
    --cc=mani@kernel.org \
    --cc=rick.wertenbroek@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).