mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
platform/x86/intel/pmt/telemetry: Add API to retrieve telemetry regions by feature
Introduce a new API, intel_pmt_get_regions_by_feature(), that gathers telemetry regions based on a provided capability flag. This API enables retrieval of regions with various capabilities (for example, RMID-based telemetry) and provides a unified interface for accessing them. Resource management is handled via reference counting using intel_pmt_put_feature_group(). Signed-off-by: David E. Box <david.e.box@linux.intel.com> Link: https://lore.kernel.org/r/20250703022832.1302928-15-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>
This commit is contained in:
committed by
Ilpo Järvinen
parent
86fc85c75b
commit
42dabe5442
@@ -9,16 +9,21 @@
|
||||
*/
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/err.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/mutex.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/overflow.h>
|
||||
#include <linux/xarray.h>
|
||||
|
||||
#include "class.h"
|
||||
|
||||
@@ -209,6 +214,87 @@ unlock:
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(pmt_telem_get_endpoint_info, "INTEL_PMT_TELEMETRY");
|
||||
|
||||
static int pmt_copy_region(struct telemetry_region *region,
|
||||
struct intel_pmt_entry *entry)
|
||||
{
|
||||
|
||||
struct oobmsm_plat_info *plat_info;
|
||||
|
||||
plat_info = intel_vsec_get_mapping(entry->ep->pcidev);
|
||||
if (IS_ERR(plat_info))
|
||||
return PTR_ERR(plat_info);
|
||||
|
||||
region->plat_info = *plat_info;
|
||||
region->guid = entry->guid;
|
||||
region->addr = entry->ep->base;
|
||||
region->size = entry->size;
|
||||
region->num_rmids = entry->num_rmids;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pmt_feature_group_release(struct kref *kref)
|
||||
{
|
||||
struct pmt_feature_group *feature_group;
|
||||
|
||||
feature_group = container_of(kref, struct pmt_feature_group, kref);
|
||||
kfree(feature_group);
|
||||
}
|
||||
|
||||
struct pmt_feature_group *intel_pmt_get_regions_by_feature(enum pmt_feature_id id)
|
||||
{
|
||||
struct pmt_feature_group *feature_group __free(kfree) = NULL;
|
||||
struct telemetry_region *region;
|
||||
struct intel_pmt_entry *entry;
|
||||
unsigned long idx;
|
||||
int count = 0;
|
||||
size_t size;
|
||||
|
||||
if (!pmt_feature_id_is_valid(id))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
guard(mutex)(&ep_lock);
|
||||
xa_for_each(&telem_array, idx, entry) {
|
||||
if (entry->feature_flags & BIT(id))
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
size = struct_size(feature_group, regions, count);
|
||||
feature_group = kzalloc(size, GFP_KERNEL);
|
||||
if (!feature_group)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
feature_group->count = count;
|
||||
|
||||
region = feature_group->regions;
|
||||
xa_for_each(&telem_array, idx, entry) {
|
||||
int ret;
|
||||
|
||||
if (!(entry->feature_flags & BIT(id)))
|
||||
continue;
|
||||
|
||||
ret = pmt_copy_region(region, entry);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
region++;
|
||||
}
|
||||
|
||||
kref_init(&feature_group->kref);
|
||||
|
||||
return no_free_ptr(feature_group);
|
||||
}
|
||||
EXPORT_SYMBOL(intel_pmt_get_regions_by_feature);
|
||||
|
||||
void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group)
|
||||
{
|
||||
kref_put(&feature_group->kref, pmt_feature_group_release);
|
||||
}
|
||||
EXPORT_SYMBOL(intel_pmt_put_feature_group);
|
||||
|
||||
int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count)
|
||||
{
|
||||
u32 offset, size;
|
||||
@@ -353,3 +439,4 @@ MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
|
||||
MODULE_DESCRIPTION("Intel PMT Telemetry driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_IMPORT_NS("INTEL_PMT");
|
||||
MODULE_IMPORT_NS("INTEL_VSEC");
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/intel_pmt_features.h>
|
||||
|
||||
/*
|
||||
@@ -218,4 +219,21 @@ static inline struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pd
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_INTEL_PMT_TELEMETRY)
|
||||
struct pmt_feature_group *
|
||||
intel_pmt_get_regions_by_feature(enum pmt_feature_id id);
|
||||
|
||||
void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group);
|
||||
#else
|
||||
static inline struct pmt_feature_group *
|
||||
intel_pmt_get_regions_by_feature(enum pmt_feature_id id)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
static inline void
|
||||
intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user