Skip to content

Commit 42dabe5

Browse files
debox1ij-intel
authored andcommitted
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>
1 parent 86fc85c commit 42dabe5

2 files changed

Lines changed: 106 additions & 1 deletion

File tree

drivers/platform/x86/intel/pmt/telemetry.c

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@
99
*/
1010

1111
#include <linux/auxiliary_bus.h>
12+
#include <linux/bitops.h>
13+
#include <linux/cleanup.h>
14+
#include <linux/err.h>
1215
#include <linux/intel_pmt_features.h>
1316
#include <linux/intel_vsec.h>
1417
#include <linux/kernel.h>
1518
#include <linux/kref.h>
1619
#include <linux/module.h>
20+
#include <linux/mutex.h>
21+
#include <linux/overflow.h>
1722
#include <linux/pci.h>
1823
#include <linux/slab.h>
1924
#include <linux/types.h>
2025
#include <linux/uaccess.h>
21-
#include <linux/overflow.h>
26+
#include <linux/xarray.h>
2227

2328
#include "class.h"
2429

@@ -209,6 +214,87 @@ int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info)
209214
}
210215
EXPORT_SYMBOL_NS_GPL(pmt_telem_get_endpoint_info, "INTEL_PMT_TELEMETRY");
211216

217+
static int pmt_copy_region(struct telemetry_region *region,
218+
struct intel_pmt_entry *entry)
219+
{
220+
221+
struct oobmsm_plat_info *plat_info;
222+
223+
plat_info = intel_vsec_get_mapping(entry->ep->pcidev);
224+
if (IS_ERR(plat_info))
225+
return PTR_ERR(plat_info);
226+
227+
region->plat_info = *plat_info;
228+
region->guid = entry->guid;
229+
region->addr = entry->ep->base;
230+
region->size = entry->size;
231+
region->num_rmids = entry->num_rmids;
232+
233+
return 0;
234+
}
235+
236+
static void pmt_feature_group_release(struct kref *kref)
237+
{
238+
struct pmt_feature_group *feature_group;
239+
240+
feature_group = container_of(kref, struct pmt_feature_group, kref);
241+
kfree(feature_group);
242+
}
243+
244+
struct pmt_feature_group *intel_pmt_get_regions_by_feature(enum pmt_feature_id id)
245+
{
246+
struct pmt_feature_group *feature_group __free(kfree) = NULL;
247+
struct telemetry_region *region;
248+
struct intel_pmt_entry *entry;
249+
unsigned long idx;
250+
int count = 0;
251+
size_t size;
252+
253+
if (!pmt_feature_id_is_valid(id))
254+
return ERR_PTR(-EINVAL);
255+
256+
guard(mutex)(&ep_lock);
257+
xa_for_each(&telem_array, idx, entry) {
258+
if (entry->feature_flags & BIT(id))
259+
count++;
260+
}
261+
262+
if (!count)
263+
return ERR_PTR(-ENOENT);
264+
265+
size = struct_size(feature_group, regions, count);
266+
feature_group = kzalloc(size, GFP_KERNEL);
267+
if (!feature_group)
268+
return ERR_PTR(-ENOMEM);
269+
270+
feature_group->count = count;
271+
272+
region = feature_group->regions;
273+
xa_for_each(&telem_array, idx, entry) {
274+
int ret;
275+
276+
if (!(entry->feature_flags & BIT(id)))
277+
continue;
278+
279+
ret = pmt_copy_region(region, entry);
280+
if (ret)
281+
return ERR_PTR(ret);
282+
283+
region++;
284+
}
285+
286+
kref_init(&feature_group->kref);
287+
288+
return no_free_ptr(feature_group);
289+
}
290+
EXPORT_SYMBOL(intel_pmt_get_regions_by_feature);
291+
292+
void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group)
293+
{
294+
kref_put(&feature_group->kref, pmt_feature_group_release);
295+
}
296+
EXPORT_SYMBOL(intel_pmt_put_feature_group);
297+
212298
int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count)
213299
{
214300
u32 offset, size;
@@ -353,3 +439,4 @@ MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
353439
MODULE_DESCRIPTION("Intel PMT Telemetry driver");
354440
MODULE_LICENSE("GPL v2");
355441
MODULE_IMPORT_NS("INTEL_PMT");
442+
MODULE_IMPORT_NS("INTEL_VSEC");

include/linux/intel_vsec.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/auxiliary_bus.h>
66
#include <linux/bits.h>
7+
#include <linux/err.h>
78
#include <linux/intel_pmt_features.h>
89

910
/*
@@ -218,4 +219,21 @@ static inline struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pd
218219
return ERR_PTR(-ENODEV);
219220
}
220221
#endif
222+
223+
#if IS_ENABLED(CONFIG_INTEL_PMT_TELEMETRY)
224+
struct pmt_feature_group *
225+
intel_pmt_get_regions_by_feature(enum pmt_feature_id id);
226+
227+
void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group);
228+
#else
229+
static inline struct pmt_feature_group *
230+
intel_pmt_get_regions_by_feature(enum pmt_feature_id id)
231+
{
232+
return ERR_PTR(-ENODEV);
233+
}
234+
235+
static inline void
236+
intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
237+
#endif
238+
221239
#endif

0 commit comments

Comments
 (0)