Unverified Commit 570b6bca authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!411 intel: backport isst issue fix and other update to align with upstream 6.0

Merge Pull Request from: @jiayingbao 
 
there is write cpu power error reported in recent test and the issue found fix patch platform-x86-ISST-Allow-configurable-offset-range needed.
and there is other important fix on platform-x86-ISST-PUNIT-device-mapping-with-Sub-NUMA.
so with this PR, it will align isst driver with upstream 6.0.
update: add one more fix d36d4a1d

upstream patch list:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1e42de8e53d32bbd7a732df49d872a30b4f888b4
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aa2ddd24257213bdfd2f65058531810ac57455dc
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d36d4a1d75d2a8bd14ec00d5cb0ce166f6886146
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a552f204b050b213b1e41a5134a0d2726c9a2ec1
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=761f0ee0e84b4c18535c6d17890ccc9f5c617e8d
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7c88ab5715a265d5dde06e4e1b0dd4370d911372
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0cd3f561efa9adce840140720e0581355db3e554
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55879dc4d095232609fe81498c1b43f042708eef
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9a1aac8a96dc014bec49806a7a964bf2fdbd315f
 
 
Link:https://gitee.com/openeuler/kernel/pulls/411

 

Reviewed-by: default avatarJason Zeng <jason.zeng@intel.com>
Reviewed-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents c75d4a85 a6c6598d
Loading
Loading
Loading
Loading
+100 −11
Original line number Diff line number Diff line
@@ -265,9 +265,9 @@ static int isst_if_get_platform_info(void __user *argp)
{
	struct isst_if_platform_info info;

	info.api_version = ISST_IF_API_VERSION,
	info.driver_version = ISST_IF_DRIVER_VERSION,
	info.max_cmds_per_ioctl = ISST_IF_CMD_LIMIT,
	info.api_version = ISST_IF_API_VERSION;
	info.driver_version = ISST_IF_DRIVER_VERSION;
	info.max_cmds_per_ioctl = ISST_IF_CMD_LIMIT;
	info.mbox_supported = punit_callbacks[ISST_IF_DEV_MBOX].registered;
	info.mmio_supported = punit_callbacks[ISST_IF_DEV_MMIO].registered;

@@ -277,14 +277,88 @@ static int isst_if_get_platform_info(void __user *argp)
	return 0;
}

#define ISST_MAX_BUS_NUMBER	2

struct isst_if_cpu_info {
	/* For BUS 0 and BUS 1 only, which we need for PUNIT interface */
	int bus_info[2];
	int bus_info[ISST_MAX_BUS_NUMBER];
	struct pci_dev *pci_dev[ISST_MAX_BUS_NUMBER];
	int punit_cpu_id;
	int numa_node;
};

struct isst_if_pkg_info {
	struct pci_dev *pci_dev[ISST_MAX_BUS_NUMBER];
};

static struct isst_if_cpu_info *isst_cpu_info;
static struct isst_if_pkg_info *isst_pkg_info;

#define ISST_MAX_PCI_DOMAINS	8

static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
{
	struct pci_dev *matched_pci_dev = NULL;
	struct pci_dev *pci_dev = NULL;
	int no_matches = 0, pkg_id;
	int i, bus_number;

	if (bus_no < 0 || bus_no >= ISST_MAX_BUS_NUMBER || cpu < 0 ||
	    cpu >= nr_cpu_ids || cpu >= num_possible_cpus())
		return NULL;

	pkg_id = topology_physical_package_id(cpu);

	bus_number = isst_cpu_info[cpu].bus_info[bus_no];
	if (bus_number < 0)
		return NULL;

	for (i = 0; i < ISST_MAX_PCI_DOMAINS; ++i) {
		struct pci_dev *_pci_dev;
		int node;

		_pci_dev = pci_get_domain_bus_and_slot(i, bus_number, PCI_DEVFN(dev, fn));
		if (!_pci_dev)
			continue;

		++no_matches;
		if (!matched_pci_dev)
			matched_pci_dev = _pci_dev;

		node = dev_to_node(&_pci_dev->dev);
		if (node == NUMA_NO_NODE) {
			pr_info("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n",
				cpu, bus_no, dev, fn);
			continue;
		}

		if (node == isst_cpu_info[cpu].numa_node) {
			isst_pkg_info[pkg_id].pci_dev[bus_no] = _pci_dev;

			pci_dev = _pci_dev;
			break;
		}
	}

	/*
	 * If there is no numa matched pci_dev, then there can be following cases:
	 * 1. CONFIG_NUMA is not defined: In this case if there is only single device
	 *    match, then we don't need numa information. Simply return last match.
	 *    Othewise return NULL.
	 * 2. NUMA information is not exposed via _SEG method. In this case it is similar
	 *    to case 1.
	 * 3. Numa information doesn't match with CPU numa node and more than one match
	 *    return NULL.
	 */
	if (!pci_dev && no_matches == 1)
		pci_dev = matched_pci_dev;

	/* Return pci_dev pointer for any matched CPU in the package */
	if (!pci_dev)
		pci_dev = isst_pkg_info[pkg_id].pci_dev[bus_no];

	return pci_dev;
}

/**
 * isst_if_get_pci_dev() - Get the PCI device instance for a CPU
@@ -300,17 +374,18 @@ static struct isst_if_cpu_info *isst_cpu_info;
 */
struct pci_dev *isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
{
	int bus_number;
	struct pci_dev *pci_dev;

	if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
	    cpu >= num_possible_cpus())
	if (bus_no < 0 || bus_no >= ISST_MAX_BUS_NUMBER  || cpu < 0 ||
	    cpu >= nr_cpu_ids || cpu >= num_possible_cpus())
		return NULL;

	bus_number = isst_cpu_info[cpu].bus_info[bus_no];
	if (bus_number < 0)
		return NULL;
	pci_dev = isst_cpu_info[cpu].pci_dev[bus_no];

	if (pci_dev && pci_dev->devfn == PCI_DEVFN(dev, fn))
		return pci_dev;

	return pci_get_domain_bus_and_slot(0, bus_number, PCI_DEVFN(dev, fn));
	return _isst_if_get_pci_dev(cpu, bus_no, dev, fn);
}
EXPORT_SYMBOL_GPL(isst_if_get_pci_dev);

@@ -319,6 +394,8 @@ static int isst_if_cpu_online(unsigned int cpu)
	u64 data;
	int ret;

	isst_cpu_info[cpu].numa_node = cpu_to_node(cpu);

	ret = rdmsrl_safe(MSR_CPU_BUS_NUMBER, &data);
	if (ret) {
		/* This is not a fatal error on MSR mailbox only I/F */
@@ -327,6 +404,8 @@ static int isst_if_cpu_online(unsigned int cpu)
	} else {
		isst_cpu_info[cpu].bus_info[0] = data & 0xff;
		isst_cpu_info[cpu].bus_info[1] = (data >> 8) & 0xff;
		isst_cpu_info[cpu].pci_dev[0] = _isst_if_get_pci_dev(cpu, 0, 0, 1);
		isst_cpu_info[cpu].pci_dev[1] = _isst_if_get_pci_dev(cpu, 1, 30, 1);
	}

	ret = rdmsrl_safe(MSR_THREAD_ID_INFO, &data);
@@ -353,10 +432,19 @@ static int isst_if_cpu_info_init(void)
	if (!isst_cpu_info)
		return -ENOMEM;

	isst_pkg_info = kcalloc(topology_max_packages(),
				sizeof(*isst_pkg_info),
				GFP_KERNEL);
	if (!isst_pkg_info) {
		kfree(isst_cpu_info);
		return -ENOMEM;
	}

	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
				"platform/x86/isst-if:online",
				isst_if_cpu_online, NULL);
	if (ret < 0) {
		kfree(isst_pkg_info);
		kfree(isst_cpu_info);
		return ret;
	}
@@ -369,6 +457,7 @@ static int isst_if_cpu_info_init(void)
static void isst_if_cpu_info_exit(void)
{
	cpuhp_remove_state(isst_if_online_id);
	kfree(isst_pkg_info);
	kfree(isst_cpu_info);
};

+4 −4
Original line number Diff line number Diff line
@@ -10,11 +10,11 @@
#ifndef __ISST_IF_COMMON_H
#define __ISST_IF_COMMON_H

#define INTEL_RAPL_PRIO_DEVID_0	0x3451
#define INTEL_CFG_MBOX_DEVID_0	0x3459
#define PCI_DEVICE_ID_INTEL_RAPL_PRIO_DEVID_0	0x3451
#define PCI_DEVICE_ID_INTEL_CFG_MBOX_DEVID_0	0x3459

#define INTEL_RAPL_PRIO_DEVID_1 0x3251
#define INTEL_CFG_MBOX_DEVID_1  0x3259
#define PCI_DEVICE_ID_INTEL_RAPL_PRIO_DEVID_1	0x3251
#define PCI_DEVICE_ID_INTEL_CFG_MBOX_DEVID_1	0x3259

/*
 * Validate maximum commands in a single request.
+2 −2
Original line number Diff line number Diff line
@@ -159,8 +159,8 @@ static long isst_if_mbox_proc_cmd(u8 *cmd_ptr, int *write_only, int resume)
}

static const struct pci_device_id isst_if_mbox_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_0)},
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_1)},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CFG_MBOX_DEVID_0)},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CFG_MBOX_DEVID_1)},
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, isst_if_mbox_ids);
+36 −13
Original line number Diff line number Diff line
@@ -20,15 +20,21 @@ struct isst_mmio_range {
	int end;
};

struct isst_mmio_range mmio_range[] = {
static struct isst_mmio_range mmio_range_devid_0[] = {
	{0x04, 0x14},
	{0x20, 0xD0},
};

static struct isst_mmio_range mmio_range_devid_1[] = {
	{0x04, 0x14},
	{0x20, 0x11C},
};

struct isst_if_device {
	void __iomem *punit_mmio;
	u32 range_0[5];
	u32 range_1[45];
	u32 range_1[64];
	struct isst_mmio_range *mmio_range;
	struct mutex mutex;
};

@@ -39,7 +45,8 @@ static long isst_if_mmio_rd_wr(u8 *cmd_ptr, int *write_only, int resume)
	struct pci_dev *pdev;

	io_reg = (struct isst_if_io_reg *)cmd_ptr;
	if (io_reg->reg < 0x04 || io_reg->reg > 0xD0)

	if (io_reg->reg % 4)
		return -EINVAL;

	if (io_reg->read_write && !capable(CAP_SYS_ADMIN))
@@ -53,6 +60,10 @@ static long isst_if_mmio_rd_wr(u8 *cmd_ptr, int *write_only, int resume)
	if (!punit_dev)
		return -EINVAL;

	if (io_reg->reg < punit_dev->mmio_range[0].beg ||
	    io_reg->reg > punit_dev->mmio_range[1].end)
		return -EINVAL;

	/*
	 * Ensure that operation is complete on a PCI device to avoid read
	 * write race by using per PCI device mutex.
@@ -71,8 +82,8 @@ static long isst_if_mmio_rd_wr(u8 *cmd_ptr, int *write_only, int resume)
}

static const struct pci_device_id isst_if_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_0)},
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_1)},
	{ PCI_DEVICE_DATA(INTEL, RAPL_PRIO_DEVID_0, &mmio_range_devid_0)},
	{ PCI_DEVICE_DATA(INTEL, RAPL_PRIO_DEVID_1, &mmio_range_devid_1)},
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, isst_if_ids);
@@ -109,6 +120,7 @@ static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	mutex_init(&punit_dev->mutex);
	pci_set_drvdata(pdev, punit_dev);
	punit_dev->mmio_range = (struct isst_mmio_range *) ent->driver_data;

	memset(&cb, 0, sizeof(cb));
	cb.cmd_size = sizeof(struct isst_if_io_reg);
@@ -138,10 +150,15 @@ static int __maybe_unused isst_if_suspend(struct device *device)

	for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
		punit_dev->range_0[i] = readl(punit_dev->punit_mmio +
						mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i)
		punit_dev->range_1[i] = readl(punit_dev->punit_mmio +
						mmio_range[1].beg + 4 * i);
						punit_dev->mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i) {
		u32 addr;

		addr = punit_dev->mmio_range[1].beg + 4 * i;
		if (addr > punit_dev->mmio_range[1].end)
			break;
		punit_dev->range_1[i] = readl(punit_dev->punit_mmio + addr);
	}

	return 0;
}
@@ -153,10 +170,16 @@ static int __maybe_unused isst_if_resume(struct device *device)

	for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
		writel(punit_dev->range_0[i], punit_dev->punit_mmio +
						mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i)
		writel(punit_dev->range_1[i], punit_dev->punit_mmio +
						mmio_range[1].beg + 4 * i);
						punit_dev->mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i) {
		u32 addr;

		addr = punit_dev->mmio_range[1].beg + 4 * i;
		if (addr > punit_dev->mmio_range[1].end)
			break;

		writel(punit_dev->range_1[i], punit_dev->punit_mmio + addr);
	}

	return 0;
}