Commit 8945c86d authored by Yicong Yang's avatar Yicong Yang Committed by xia-bing1
Browse files

hwtracing: hisi_ptt: Check duplicate filters before allocation

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBNZ64


CVE: NA

--------------------------------

Abnormally it's reported duplicated filters added in the filter list,
though the filter we created should be unique maintained by the PCIe
framework. Add a duplicate filters check before allocation to prevent
this case.

Fixes: 6373c463 ("hwtracing: hisi_ptt: Export available filters through sysfs")
Signed-off-by: default avatarYicong Yang <yangyicong@hisilicon.com>
Signed-off-by: default avatarlujunhua <lujunhua7@h-partners.com>
parent 049045f4
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -381,6 +381,32 @@ static ssize_t hisi_ptt_filter_show(struct device *dev, struct device_attribute
	return sysfs_emit(buf, "0x%05lx\n", filter_val);
}

static int hisi_ptt_check_duplicated_filters(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
{
	struct hisi_ptt_filter_desc *filter;
	struct list_head *target_list;
	u8 devfn = devid & 0xff;

	if (is_port)
		target_list = &hisi_ptt->port_filters;
	else
		target_list = &hisi_ptt->req_filters;

	list_for_each_entry(filter, target_list, list) {
		if (filter->devid == devid) {
			pci_warn(hisi_ptt->pdev,
				 "ignore duplicated filter %04x:%02x:%02x.%d\n",
				 pci_domain_nr(hisi_ptt->pdev->bus),
				 PCI_BUS_NUM(devid), PCI_SLOT(devfn),
				 PCI_FUNC(devfn));

			return -EEXIST;
		}
	}

	return 0;
}

static struct hisi_ptt_filter_desc *
hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
{
@@ -388,6 +414,9 @@ hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
	u8 devfn = devid & 0xff;
	char *filter_name;

	if (hisi_ptt_check_duplicated_filters(hisi_ptt, devid, is_port))
		return NULL;

	filter_name = kasprintf(GFP_KERNEL, "%04x:%02x:%02x.%d", pci_domain_nr(hisi_ptt->pdev->bus),
				 PCI_BUS_NUM(devid), PCI_SLOT(devfn), PCI_FUNC(devfn));
	if (!filter_name) {