[PATCH V3 05/16] platform/x86/intel/pmt: Cache the telemetry discovery header

David E. Box
2026-05-01T23:11:04Z

pmt_telem_header_decode() only needs the discovery header dwords, but it
currently decodes them by reading directly from entry->disc_table.

Cache the discovery header in intel_pmt_entry when the device is created
and have telemetry decode use the cached values instead of performing MMIO
reads at decode time.

This keeps the telemetry header decode path independent of how the
discovery data is backed and avoids baking a direct MMIO assumption into
the feature-specific decode logic.

Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
V3 changes:
- New patch split out from PMT header-fetch rework to cache discovery
header data before downstream decode/population.
- Added to carry the post-v3 bug fix while preserving the original series
ordering intent.

drivers/platform/x86/intel/pmt/class.c | 3 +++
drivers/platform/x86/intel/pmt/class.h | 1 +
drivers/platform/x86/intel/pmt/telemetry.c | 12 ++++++------
3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
index 7da8279b54f8..61834cbe3764 100644
--- a/drivers/platform/x86/intel/pmt/class.c
+++ b/drivers/platform/x86/intel/pmt/class.c
@@ -383,6 +383,9 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa
if (IS_ERR(entry->disc_table))
return PTR_ERR(entry->disc_table);

+ memcpy_fromio(entry->disc_header, entry->disc_table,
+ sizeof(entry->disc_header));
+
if (ns->pmt_pre_decode) {
ret = ns->pmt_pre_decode(intel_vsec_dev, entry);
if (ret)
diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
index 8a0db0ef58c1..84202fc7920c 100644
--- a/drivers/platform/x86/intel/pmt/class.h
+++ b/drivers/platform/x86/intel/pmt/class.h
@@ -44,6 +44,7 @@ struct intel_pmt_entry {
struct telem_endpoint *ep;
struct pci_dev *pcidev;
struct intel_pmt_header header;
+ u32 disc_header[4];
struct bin_attribute pmt_bin_attr;
const struct attribute_group *attr_grp;
struct kobject *kobj;
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index d22f633638be..953f35b6daec 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -72,16 +72,16 @@ static bool pmt_telem_region_overlaps(struct device *dev, u32 guid, u32 type)
static int pmt_telem_header_decode(struct intel_pmt_entry *entry,
struct device *dev)
{
- void __iomem *disc_table = entry->disc_table;
struct intel_pmt_header *header = &entry->header;
+ u32 *disc_header = entry->disc_header;

- header->access_type = TELEM_ACCESS(readl(disc_table));
- header->guid = readl(disc_table + TELEM_GUID_OFFSET);
- header->base_offset = readl(disc_table + TELEM_BASE_OFFSET);
+ header->access_type = TELEM_ACCESS(disc_header[0]);
+ header->guid = disc_header[1];
+ header->base_offset = disc_header[2];

/* Size is measured in DWORDS, but accessor returns bytes */
- header->size = TELEM_SIZE(readl(disc_table));
- header->telem_type = TELEM_TYPE(readl(entry->disc_table));
+ header->size = TELEM_SIZE(disc_header[0]);
+ header->telem_type = TELEM_TYPE(disc_header[0]);

return 0;
}
--
2.43.0