diff mbox series

[v3,2/5] MFD: intel_pmt: Support non-PMT capabilities

Message ID 20210922213007.2738388-3-david.e.box@linux.intel.com (mailing list archive)
State Deferred, archived
Headers show
Series Add general DVSEC/VSEC support | expand

Commit Message

David E. Box Sept. 22, 2021, 9:30 p.m. UTC
Intel Platform Monitoring Technology (PMT) support is indicated by presence
of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
structures may also be used by Intel to indicate support for other
capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
and non-PMT capabilities. In order to support these capabilities it is
necessary to modify the intel_pmt driver to handle the creation of platform
devices more generically.

Currently PMT devices are named by their capability (e.g. pmt_telemetry).
Instead, generically name them by their capability ID (e.g.
intel-extended-cap-2). This allows the IDs to be created automatically,
minimizing the code needed to support future capabilities. However, to
ensure that unsupported devices aren't created, use an allow list to
specify supported capabilities.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---

V3: 	No change

V2:	Drop new driver. Keep changes in intel_pmt.c


 drivers/mfd/intel_pmt.c                    | 95 ++++++++++++++--------
 drivers/platform/x86/intel/pmt/crashlog.c  |  2 +-
 drivers/platform/x86/intel/pmt/telemetry.c |  2 +-
 3 files changed, 62 insertions(+), 37 deletions(-)

Comments

Greg KH Sept. 27, 2021, 5:36 p.m. UTC | #1
On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> Intel Platform Monitoring Technology (PMT) support is indicated by presence
> of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> structures may also be used by Intel to indicate support for other
> capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> and non-PMT capabilities. In order to support these capabilities it is
> necessary to modify the intel_pmt driver to handle the creation of platform
> devices more generically.

I said this on your other driver submission, but why are you turning a
PCIe device into a set of platform devices and craming it into the MFD
subsystem?

PCIe devices are NOT platform devices.

Why not use the auxiliary bus for this thing if you have individual
drivers that need to "bind" to the different attributes that this single
PCIe device is exporting.

Or why not just fix the hardware to report individual PCIe devices, like
a sane system would do?  Has this shipped in any devices yet?  If not,
can that be fixed first?  It's just a firmware change, right?

thanks,

greg k-h
David E. Box Sept. 27, 2021, 6:40 p.m. UTC | #2
On Mon, 2021-09-27 at 19:36 +0200, Greg KH wrote:
> On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> > Intel Platform Monitoring Technology (PMT) support is indicated by presence
> > of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> > structures may also be used by Intel to indicate support for other
> > capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> > and non-PMT capabilities. In order to support these capabilities it is
> > necessary to modify the intel_pmt driver to handle the creation of platform
> > devices more generically.
> 
> I said this on your other driver submission, but why are you turning a
> PCIe device into a set of platform devices and craming it into the MFD
> subsystem?
> 
> PCIe devices are NOT platform devices.

But they *are* used to create platform devices when the PCIe device is multi-functional, which is
what intel_pmt is.

> 
> Why not use the auxiliary bus for this thing if you have individual
> drivers that need to "bind" to the different attributes that this single
> PCIe device is exporting.

It wasn't clear in the beginning how this would evolve. MFD made sense for the PMT (platform
monitoring technology) driver. PMT has 3 related but individually enumerable devices on the same IP,
like lpss. But the same IP is now being used for other features too like SDSi. We could work on
converting this to the auxiliary bus and then covert the cell drivers.

> 
> Or why not just fix the hardware to report individual PCIe devices, like
> a sane system would do?

We have some systems with 1000+ PCIe devices. Each PCIe device adds cost to HW. So increasingly
VSEC/DVSEC is used to expose features which are handled by the same micro-controller in the HW.

>   Has this shipped in any devices yet?  If not,
> can that be fixed first?  It's just a firmware change, right?

PMT has been shipped for over a year. It's not just a firmware change.

David 
> 
> thanks,
> 
> greg k-h
Greg KH Sept. 28, 2021, 5:01 a.m. UTC | #3
On Mon, Sep 27, 2021 at 11:40:37AM -0700, David E. Box wrote:
> On Mon, 2021-09-27 at 19:36 +0200, Greg KH wrote:
> > On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> > > Intel Platform Monitoring Technology (PMT) support is indicated by presence
> > > of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> > > structures may also be used by Intel to indicate support for other
> > > capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> > > and non-PMT capabilities. In order to support these capabilities it is
> > > necessary to modify the intel_pmt driver to handle the creation of platform
> > > devices more generically.
> > 
> > I said this on your other driver submission, but why are you turning a
> > PCIe device into a set of platform devices and craming it into the MFD
> > subsystem?
> > 
> > PCIe devices are NOT platform devices.
> 
> But they *are* used to create platform devices when the PCIe device is multi-functional, which is
> what intel_pmt is.

That is an abuse of platform devices, as that is not what they are for.

> > Why not use the auxiliary bus for this thing if you have individual
> > drivers that need to "bind" to the different attributes that this single
> > PCIe device is exporting.
> 
> It wasn't clear in the beginning how this would evolve. MFD made sense for the PMT (platform
> monitoring technology) driver. PMT has 3 related but individually enumerable devices on the same IP,
> like lpss. But the same IP is now being used for other features too like SDSi. We could work on
> converting this to the auxiliary bus and then covert the cell drivers.

Please do so.

> > Or why not just fix the hardware to report individual PCIe devices, like
> > a sane system would do?
> 
> We have some systems with 1000+ PCIe devices. Each PCIe device adds cost to HW. So increasingly
> VSEC/DVSEC is used to expose features which are handled by the same micro-controller in the HW.

A PCIe device is a virtual thing, what HW cost do they have?

Anyway, a platform device should NOT ever be a child of a PCI device,
that is not ok and should be fixed here please.

A platform device is just that, something that the platform provides on
a non-discoverable bus.  A PCIe device is NOT that type of device at
all and never has been.

thanks,

greg k-h
Lee Jones Sept. 28, 2021, 7:54 a.m. UTC | #4
On Mon, 27 Sep 2021, David E. Box wrote:

> On Mon, 2021-09-27 at 19:36 +0200, Greg KH wrote:
> > On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> > > Intel Platform Monitoring Technology (PMT) support is indicated by presence
> > > of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> > > structures may also be used by Intel to indicate support for other
> > > capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> > > and non-PMT capabilities. In order to support these capabilities it is
> > > necessary to modify the intel_pmt driver to handle the creation of platform
> > > devices more generically.
> > 
> > I said this on your other driver submission, but why are you turning a
> > PCIe device into a set of platform devices and craming it into the MFD
> > subsystem?
> > 
> > PCIe devices are NOT platform devices.
> 
> But they *are* used to create platform devices when the PCIe device is multi-functional, which is
> what intel_pmt is.
> 
> > 
> > Why not use the auxiliary bus for this thing if you have individual
> > drivers that need to "bind" to the different attributes that this single
> > PCIe device is exporting.
> 
> It wasn't clear in the beginning how this would evolve. MFD made sense for the PMT (platform
> monitoring technology) driver. PMT has 3 related but individually enumerable devices on the same IP,
> like lpss. But the same IP is now being used for other features too like SDSi. We could work on
> converting this to the auxiliary bus and then covert the cell drivers.

I see this as subsequent work.  It should not affect this submission.

FWIW, I still plan to review this set for inclusion into MFD.
Greg KH Sept. 28, 2021, 9:10 a.m. UTC | #5
On Tue, Sep 28, 2021 at 08:54:45AM +0100, Lee Jones wrote:
> On Mon, 27 Sep 2021, David E. Box wrote:
> 
> > On Mon, 2021-09-27 at 19:36 +0200, Greg KH wrote:
> > > On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> > > > Intel Platform Monitoring Technology (PMT) support is indicated by presence
> > > > of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> > > > structures may also be used by Intel to indicate support for other
> > > > capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> > > > and non-PMT capabilities. In order to support these capabilities it is
> > > > necessary to modify the intel_pmt driver to handle the creation of platform
> > > > devices more generically.
> > > 
> > > I said this on your other driver submission, but why are you turning a
> > > PCIe device into a set of platform devices and craming it into the MFD
> > > subsystem?
> > > 
> > > PCIe devices are NOT platform devices.
> > 
> > But they *are* used to create platform devices when the PCIe device is multi-functional, which is
> > what intel_pmt is.
> > 
> > > 
> > > Why not use the auxiliary bus for this thing if you have individual
> > > drivers that need to "bind" to the different attributes that this single
> > > PCIe device is exporting.
> > 
> > It wasn't clear in the beginning how this would evolve. MFD made sense for the PMT (platform
> > monitoring technology) driver. PMT has 3 related but individually enumerable devices on the same IP,
> > like lpss. But the same IP is now being used for other features too like SDSi. We could work on
> > converting this to the auxiliary bus and then covert the cell drivers.
> 
> I see this as subsequent work.  It should not affect this submission.
> 
> FWIW, I still plan to review this set for inclusion into MFD.

That's fine, but as the add-on submission that builds on top of this is
a broken mess (which is what caused me to have to review this series), I
can't recommend that be taken yet as it needs work to prevent systems
from doing bad things.

thanks,

greg k-h
Lee Jones Sept. 28, 2021, 10:03 a.m. UTC | #6
On Tue, 28 Sep 2021, Greg KH wrote:

> On Tue, Sep 28, 2021 at 08:54:45AM +0100, Lee Jones wrote:
> > On Mon, 27 Sep 2021, David E. Box wrote:
> > 
> > > On Mon, 2021-09-27 at 19:36 +0200, Greg KH wrote:
> > > > On Wed, Sep 22, 2021 at 02:30:04PM -0700, David E. Box wrote:
> > > > > Intel Platform Monitoring Technology (PMT) support is indicated by presence
> > > > > of an Intel defined PCIe DVSEC structure with a PMT ID. However DVSEC
> > > > > structures may also be used by Intel to indicate support for other
> > > > > capabilities unrelated to PMT.  OOBMSM is a device that can have both PMT
> > > > > and non-PMT capabilities. In order to support these capabilities it is
> > > > > necessary to modify the intel_pmt driver to handle the creation of platform
> > > > > devices more generically.
> > > > 
> > > > I said this on your other driver submission, but why are you turning a
> > > > PCIe device into a set of platform devices and craming it into the MFD
> > > > subsystem?
> > > > 
> > > > PCIe devices are NOT platform devices.
> > > 
> > > But they *are* used to create platform devices when the PCIe device is multi-functional, which is
> > > what intel_pmt is.
> > > 
> > > > 
> > > > Why not use the auxiliary bus for this thing if you have individual
> > > > drivers that need to "bind" to the different attributes that this single
> > > > PCIe device is exporting.
> > > 
> > > It wasn't clear in the beginning how this would evolve. MFD made sense for the PMT (platform
> > > monitoring technology) driver. PMT has 3 related but individually enumerable devices on the same IP,
> > > like lpss. But the same IP is now being used for other features too like SDSi. We could work on
> > > converting this to the auxiliary bus and then covert the cell drivers.
> > 
> > I see this as subsequent work.  It should not affect this submission.
> > 
> > FWIW, I still plan to review this set for inclusion into MFD.
> 
> That's fine, but as the add-on submission that builds on top of this is
> a broken mess (which is what caused me to have to review this series), I
> can't recommend that be taken yet as it needs work to prevent systems
> from doing bad things.

Understood.  Deferred.
diff mbox series

Patch

diff --git a/drivers/mfd/intel_pmt.c b/drivers/mfd/intel_pmt.c
index dd7eb614c28e..08cd3357577e 100644
--- a/drivers/mfd/intel_pmt.c
+++ b/drivers/mfd/intel_pmt.c
@@ -27,9 +27,18 @@ 
 #define INTEL_DVSEC_ENTRY_SIZE		4
 
 /* PMT capabilities */
-#define DVSEC_INTEL_ID_TELEMETRY	2
-#define DVSEC_INTEL_ID_WATCHER		3
-#define DVSEC_INTEL_ID_CRASHLOG		4
+#define INTEL_EXT_CAP_ID_TELEMETRY	2
+#define INTEL_EXT_CAP_ID_WATCHER	3
+#define INTEL_EXT_CAP_ID_CRASHLOG	4
+
+#define INTEL_EXT_CAP_PREFIX		"intel_extnd_cap"
+#define FEATURE_ID_NAME_LENGTH		25
+
+static int intel_ext_cap_allow_list[] = {
+	INTEL_EXT_CAP_ID_TELEMETRY,
+	INTEL_EXT_CAP_ID_WATCHER,
+	INTEL_EXT_CAP_ID_CRASHLOG,
+};
 
 struct intel_dvsec_header {
 	u16	length;
@@ -84,42 +93,58 @@  static const struct pmt_platform_info dg1_info = {
 	.capabilities = dg1_capabilities,
 };
 
-static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header,
-		       unsigned long quirks)
+static bool intel_ext_cap_allowed(u16 id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(intel_ext_cap_allow_list); i++)
+		if (intel_ext_cap_allow_list[i] == id)
+			return true;
+
+	return false;
+}
+
+static bool intel_ext_cap_disabled(u16 id, unsigned long quirks)
+{
+	switch (id) {
+	case INTEL_EXT_CAP_ID_WATCHER:
+		return !!(quirks & PMT_QUIRK_NO_WATCHER);
+
+	case INTEL_EXT_CAP_ID_CRASHLOG:
+		return !!(quirks & PMT_QUIRK_NO_CRASHLOG);
+
+	default:
+		return false;
+	}
+}
+
+static int intel_ext_cap_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header,
+				 unsigned long quirks)
 {
 	struct device *dev = &pdev->dev;
 	struct resource *res, *tmp;
 	struct mfd_cell *cell;
-	const char *name;
+	char feature_id_name[FEATURE_ID_NAME_LENGTH];
 	int count = header->num_entries;
 	int size = header->entry_size;
 	int id = header->id;
 	int i;
 
-	switch (id) {
-	case DVSEC_INTEL_ID_TELEMETRY:
-		name = "pmt_telemetry";
-		break;
-	case DVSEC_INTEL_ID_WATCHER:
-		if (quirks & PMT_QUIRK_NO_WATCHER) {
-			dev_info(dev, "Watcher not supported\n");
-			return -EINVAL;
-		}
-		name = "pmt_watcher";
-		break;
-	case DVSEC_INTEL_ID_CRASHLOG:
-		if (quirks & PMT_QUIRK_NO_CRASHLOG) {
-			dev_info(dev, "Crashlog not supported\n");
-			return -EINVAL;
-		}
-		name = "pmt_crashlog";
-		break;
-	default:
+	if (!intel_ext_cap_allowed(id))
+		return -EINVAL;
+
+	if (intel_ext_cap_disabled(id, quirks))
+		return -EINVAL;
+
+	snprintf(feature_id_name, sizeof(feature_id_name), "%s_%d", INTEL_EXT_CAP_PREFIX, id);
+
+	if (!header->num_entries) {
+		dev_err(dev, "Invalid 0 entry count for %s header\n", feature_id_name);
 		return -EINVAL;
 	}
 
-	if (!header->num_entries || !header->entry_size) {
-		dev_err(dev, "Invalid count or size for %s header\n", name);
+	if (!header->entry_size) {
+		dev_err(dev, "Invalid 0 entry size for %s header\n", feature_id_name);
 		return -EINVAL;
 	}
 
@@ -135,26 +160,26 @@  static int pmt_add_dev(struct pci_dev *pdev, struct intel_dvsec_header *header,
 		header->offset >>= 3;
 
 	/*
-	 * The PMT DVSEC contains the starting offset and count for a block of
+	 * The DVSEC contains the starting offset and count for a block of
 	 * discovery tables, each providing access to monitoring facilities for
 	 * a section of the device. Create a resource list of these tables to
 	 * provide to the driver.
 	 */
 	for (i = 0, tmp = res; i < count; i++, tmp++) {
 		tmp->start = pdev->resource[header->tbir].start +
-			     header->offset + i * (size << 2);
-		tmp->end = tmp->start + (size << 2) - 1;
+			     header->offset + i * (size * sizeof(u32));
+		tmp->end = tmp->start + (size * sizeof(u32)) - 1;
 		tmp->flags = IORESOURCE_MEM;
 	}
 
 	cell->resources = res;
 	cell->num_resources = count;
-	cell->name = name;
+	cell->name = feature_id_name;
 
-	return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0,
-				    NULL);
+	return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL);
 }
 
+
 static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct pmt_platform_info *info;
@@ -176,7 +201,7 @@  static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 		header = info->capabilities;
 		while (*header) {
-			ret = pmt_add_dev(pdev, *header, quirks);
+			ret = intel_ext_cap_add_dev(pdev, *header, quirks);
 			if (ret)
 				dev_warn(&pdev->dev,
 					 "Failed to add device for DVSEC id %d\n",
@@ -212,7 +237,7 @@  static int pmt_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 			header.tbir = INTEL_DVSEC_TABLE_BAR(table);
 			header.offset = INTEL_DVSEC_TABLE_OFFSET(table);
 
-			ret = pmt_add_dev(pdev, &header, quirks);
+			ret = intel_ext_cap_add_dev(pdev, &header, quirks);
 			if (ret)
 				continue;
 
diff --git a/drivers/platform/x86/intel/pmt/crashlog.c b/drivers/platform/x86/intel/pmt/crashlog.c
index 1c1021f04d3c..86c4b016af59 100644
--- a/drivers/platform/x86/intel/pmt/crashlog.c
+++ b/drivers/platform/x86/intel/pmt/crashlog.c
@@ -17,7 +17,7 @@ 
 
 #include "class.h"
 
-#define DRV_NAME		"pmt_crashlog"
+#define DRV_NAME		"intel_extnd_cap_4"
 
 /* Crashlog discovery header types */
 #define CRASH_TYPE_OOBMSM	1
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index 38d52651c572..d93d02672679 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -17,7 +17,7 @@ 
 
 #include "class.h"
 
-#define TELEM_DEV_NAME		"pmt_telemetry"
+#define TELEM_DEV_NAME		"intel_extnd_cap_2"
 
 #define TELEM_SIZE_OFFSET	0x0
 #define TELEM_GUID_OFFSET	0x4