]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
platform/x86/intel/pmt/discovery: Get telemetry attributes
authorDavid E. Box <david.e.box@linux.intel.com>
Thu, 3 Jul 2025 02:28:28 +0000 (19:28 -0700)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Thu, 3 Jul 2025 08:09:40 +0000 (11:09 +0300)
Add intel_pmt_get_features() in PMT Discovery to enable the PMT Telemetry
driver to obtain attributes of the aggregated telemetry spaces it
enumerates. The function gathers feature flags and associated data (like
the number of RMIDs) from each PMT entry, laying the groundwork for a
future kernel interface that will allow direct access to telemetry regions
based on their capabilities.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Link: https://lore.kernel.org/r/20250703022832.1302928-14-david.e.box@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/intel/pmt/Kconfig
drivers/platform/x86/intel/pmt/class.h
drivers/platform/x86/intel/pmt/discovery.c
drivers/platform/x86/intel/pmt/telemetry.c
include/linux/intel_vsec.h

index 0ad91b5112e9d6a6162e4a73f3ce238741826fdb..83ae17eab4623cbb71419e5f2afa9fae94703e96 100644 (file)
@@ -18,6 +18,7 @@ config INTEL_PMT_CLASS
 config INTEL_PMT_TELEMETRY
        tristate "Intel Platform Monitoring Technology (PMT) Telemetry driver"
        depends on INTEL_VSEC
+       select INTEL_PMT_DISCOVERY
        select INTEL_PMT_CLASS
        help
          The Intel Platform Monitory Technology (PMT) Telemetry driver provides
index 39c32357ee2c94e29cd1b00492f6de7fba746fc0..fdf7e79d8c0dcda1496247dfc2f39d20a5b370d8 100644 (file)
@@ -48,6 +48,7 @@ struct intel_pmt_entry {
        struct pmt_callbacks    *cb;
        unsigned long           base_addr;
        size_t                  size;
+       u64                     feature_flags;
        u32                     guid;
        u32                     num_rmids; /* Number of Resource Monitoring IDs */
        int                     devid;
@@ -71,4 +72,10 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry,
                         struct intel_vsec_device *dev, int idx);
 void intel_pmt_dev_destroy(struct intel_pmt_entry *entry,
                           struct intel_pmt_namespace *ns);
+#if IS_ENABLED(CONFIG_INTEL_PMT_DISCOVERY)
+void intel_pmt_get_features(struct intel_pmt_entry *entry);
+#else
+static inline void intel_pmt_get_features(struct intel_pmt_entry *entry) {}
+#endif
+
 #endif
index 4b4fa3137ad2ebe55e499bb3f9aad0df145ce636..e72d43b675b4646bfbb8904b461e953e5c1c028f 100644 (file)
@@ -583,6 +583,39 @@ abort_probe:
        return ret;
 }
 
+static void pmt_get_features(struct intel_pmt_entry *entry, struct feature *f)
+{
+       int num_guids = f->table.header.num_guids;
+       int i;
+
+       for (i = 0; i < num_guids; i++) {
+               if (f->table.guids[i] != entry->guid)
+                       continue;
+
+               entry->feature_flags |= BIT(f->id);
+
+               if (feature_layout[f->id] == LAYOUT_RMID)
+                       entry->num_rmids = f->table.rmid.num_rmids;
+               else
+                       entry->num_rmids = 0; /* entry is kzalloc but set anyway */
+       }
+}
+
+void intel_pmt_get_features(struct intel_pmt_entry *entry)
+{
+       struct feature *feature;
+
+       mutex_lock(&feature_list_lock);
+       list_for_each_entry(feature, &pmt_feature_list, list) {
+               if (feature->priv->parent != &entry->ep->pcidev->dev)
+                       continue;
+
+               pmt_get_features(entry, feature);
+       }
+       mutex_unlock(&feature_list_lock);
+}
+EXPORT_SYMBOL_NS_GPL(intel_pmt_get_features, "INTEL_PMT");
+
 static const struct auxiliary_device_id pmt_features_id_table[] = {
        { .name = "intel_vsec.discovery" },
        {}
index ac3a9bdf5601578ed01df3376903ce70caddfb10..58d06749e417231e5b07d8073bc0157cabb778af 100644 (file)
@@ -9,11 +9,14 @@
  */
 
 #include <linux/auxiliary_bus.h>
+#include <linux/intel_pmt_features.h>
 #include <linux/intel_vsec.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/types.h>
 #include <linux/uaccess.h>
 #include <linux/overflow.h>
 
@@ -311,6 +314,8 @@ static int pmt_telem_probe(struct auxiliary_device *auxdev, const struct auxilia
                        continue;
 
                priv->num_entries++;
+
+               intel_pmt_get_features(entry);
        }
 
        return 0;
index 4bd0c6e7857c0b312e7e114809e812f8daaca978..f185e9c01c905e955be0a633376b830631867ef1 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/auxiliary_bus.h>
 #include <linux/bits.h>
+#include <linux/intel_pmt_features.h>
 
 /*
  * VSEC_CAP_UNUSED is reserved. It exists to prevent zero initialized
@@ -166,6 +167,21 @@ struct oobmsm_plat_info {
        u8 function_number;
 };
 
+struct telemetry_region {
+       struct oobmsm_plat_info plat_info;
+       void __iomem            *addr;
+       size_t                  size;
+       u32                     guid;
+       u32                     num_rmids;
+};
+
+struct pmt_feature_group {
+       enum pmt_feature_id     id;
+       int                     count;
+       struct kref             kref;
+       struct telemetry_region regions[];
+};
+
 int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent,
                       struct intel_vsec_device *intel_vsec_dev,
                       const char *name);