mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: "David E. Box" <david.e.box@linux.intel.com>
Cc: "Rajneesh Bhardwaj" <irenic.rajneesh@gmail.com>,
	"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
	"Hans de Goede" <hansg@kernel.org>,
	platform-driver-x86@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	"Xi Pardee" <xi.pardee@linux.intel.com>,
	"Srinivas Pandruvada" <srinivas.pandruvada@linux.intel.com>
Subject: Re: [PATCH v5 06/16] platform/x86/intel/pmt: Unify header fetch and add ACPI source
Date: Fri, 22 May 2026 13:21:29 +0300 (EEST)	[thread overview]
Message-ID: <071b5732-591f-d228-2a11-1f3f16e21673@linux.intel.com> (raw)
In-Reply-To: <20260522022147.4137494-7-david.e.box@linux.intel.com>

On Thu, 21 May 2026, David E. Box wrote:

> Allow the PMT class to read discovery headers from either PCI MMIO or
> ACPI-provided entries, depending on the discovery source. The new
> source-aware fetch helper retrieves the first two QWORDs for both paths
> while keeping the mapped discovery table available for users such as
> crashlog.
> 
> Split intel_pmt_populate_entry() into source-specific resolvers:
>   - pmt_resolve_access_pci(): handles both ACCESS_LOCAL and ACCESS_BARID
>     for PCI-backed devices and sets entry->pcidev. Same existing
>     functionality.
>   - pmt_resolve_access_acpi(): handles only ACCESS_BARID for ACPI-backed
>     devices, rejecting ACCESS_LOCAL which has no valid semantics without
>     a physical discovery resource.
> 
> Also, when copying discovery headers, bind the copy size to the canonical
> discovery header definition instead of relying on separate literals.
> 
> This maintains existing PCI behavior and makes no functional changes
> for PCI devices.
> 
> Assisted-by: GitHub-Copilot:claude-opus-4.7
> Signed-off-by: David E. Box <david.e.box@linux.intel.com>
> ---
> V5 changes:
>   - Cap memcpy_fromio() in pmt_get_headers() PCI branch to
>     resource_size() of the discovery resource, matching the cap
>     added in the cache-introducing patch.
>   - Documented in the ACPI branch that disc_table is intentionally
>     NULL on that source, so consumers that dereference disc_table
>     must only be wired to INTEL_VSEC_DISC_PCI namespaces.

Please rebase this on top of the most recent for-next code as it seems to 
have developed a context conflict with a recently applied change.

> V4 changes:
>   - Added discovery header width macro, INTEL_VSEC_ACPI_DISC_DWORDS, in
>     shared intel_vsec header and in definitions.
>   - Aliased to PMT_DISC_HEADER_DWORDS and converted PMT discovery header
>     arrays to use it.
>   - Replaced literal header copy sizes with entry->disc_header size in
>     pmt_get_headers() for PCI and ACPI paths.
> 
> V3 changes:
>   - Folded the header fetch rework back into intel_pmt_dev_create() after
>     dropping the previous common header decode helper patch
>   - Cleaned up line wrapping/indentation
> 
> V2 changes:
>   - In pmt_resolve_access_acpi(), moved dev_err() call to single line
>     instead of split across two lines
>   - Restructured error handling in intel_pmt_populate_entry(), moving error
>     returns from after switch/case into each case statement for better
>     readability
>   - Addressed Ilpo's feedback on error message formatting and error
>     handling patterns
> 
>  drivers/platform/x86/intel/pmt/class.c | 157 +++++++++++++++++++++----
>  drivers/platform/x86/intel/pmt/class.h |   3 +-
>  include/linux/intel_vsec.h             |   5 +-
>  3 files changed, 142 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/platform/x86/intel/pmt/class.c b/drivers/platform/x86/intel/pmt/class.c
> index 246e11837800..1a77709edc6a 100644
> --- a/drivers/platform/x86/intel/pmt/class.c
> +++ b/drivers/platform/x86/intel/pmt/class.c
> @@ -204,9 +204,9 @@ struct class intel_pmt_class = {
>  };
>  EXPORT_SYMBOL_GPL(intel_pmt_class);
>  
> -static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
> -				    struct intel_vsec_device *ivdev,
> -				    int idx)
> +static int pmt_resolve_access_pci(struct intel_pmt_entry *entry,
> +				  struct intel_vsec_device *ivdev,
> +				  int idx)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(ivdev->dev);
>  	struct device *dev = &ivdev->auxdev.dev;
> @@ -286,6 +286,81 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
>  	}
>  
>  	entry->pcidev = pci_dev;
> +
> +	return 0;
> +}
> +
> +static int pmt_resolve_access_acpi(struct intel_pmt_entry *entry,
> +				   struct intel_vsec_device *ivdev)
> +{
> +	struct pci_dev *pci_dev = NULL;
> +	struct device *dev = &ivdev->auxdev.dev;
> +	struct intel_pmt_header *header = &entry->header;
> +	u8 bir;
> +
> +	if (dev_is_pci(ivdev->dev))
> +		pci_dev = to_pci_dev(ivdev->dev);
> +
> +	/*
> +	 * The base offset should always be 8 byte aligned.
> +	 *
> +	 * For non-local access types the lower 3 bits of base offset
> +	 * contains the index of the base address register where the
> +	 * telemetry can be found.
> +	 */
> +	bir = GET_BIR(header->base_offset);
> +
> +	switch (header->access_type) {
> +	case ACCESS_BARID:
> +		/* ACPI platform drivers use base_addr */
> +		if (ivdev->base_addr) {
> +			entry->base_addr = ivdev->base_addr +
> +					   GET_ADDRESS(header->base_offset);
> +			break;
> +		}
> +
> +		/* If base_addr is not provided, then this is an ACPI companion device */
> +		if (!pci_dev) {
> +			dev_err(dev, "ACCESS_BARID requires PCI BAR resources or base_addr\n");
> +			return -EINVAL;
> +		}
> +
> +		entry->base_addr = pci_resource_start(pci_dev, bir) +
> +			GET_ADDRESS(header->base_offset);
> +		break;
> +	default:
> +		dev_err(dev, "Unsupported access type %d for ACPI based PMT\n",
> +			header->access_type);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int intel_pmt_populate_entry(struct intel_pmt_entry *entry,
> +				    struct intel_vsec_device *ivdev,
> +				    int idx)
> +{
> +	struct intel_pmt_header *header = &entry->header;
> +	struct device *dev = &ivdev->auxdev.dev;
> +	int ret;
> +
> +	switch (ivdev->src) {
> +	case INTEL_VSEC_DISC_PCI:
> +		ret = pmt_resolve_access_pci(entry, ivdev, idx);
> +		if (ret)
> +			return ret;
> +		break;
> +	case INTEL_VSEC_DISC_ACPI:
> +		ret = pmt_resolve_access_acpi(entry, ivdev);
> +		if (ret)
> +			return ret;
> +		break;
> +	default:
> +		dev_err(dev, "Unknown discovery source: %d\n", ivdev->src);
> +		return -EINVAL;
> +	}
> +
>  	entry->guid = header->guid;
>  	entry->size = header->size;
>  	entry->cb = ivdev->priv_data;
> @@ -370,29 +445,71 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry,
>  	return ret;
>  }
>  
> +static int pmt_get_headers(struct intel_vsec_device *ivdev, int idx,
> +			   struct intel_pmt_entry *entry,
> +			   u32 headers[PMT_DISC_HEADER_DWORDS])
> +{
> +	struct device *dev = &ivdev->auxdev.dev;
> +	size_t header_bytes = sizeof(entry->disc_header);
> +
> +	switch (ivdev->src) {
> +	case INTEL_VSEC_DISC_PCI: {
> +		struct resource *disc_res = &ivdev->resource[idx];
> +		void __iomem *disc_table;
> +
> +		disc_table = devm_ioremap_resource(dev, disc_res);
> +		if (IS_ERR(disc_table))
> +			return PTR_ERR(disc_table);
> +
> +		/*
> +		 * The mapped resource is sized by the namespace's DVSEC
> +		 * entry_size (in dwords), which can be less than
> +		 * PMT_DISC_HEADER_DWORDS (e.g. telemetry uses entry_size = 3,
> +		 * 12 bytes). Cap the copy to resource_size() to avoid reading
> +		 * past the mapped region; any unread dwords stay zero from
> +		 * the zero-initialized allocation of the containing struct.
> +		 */
> +		memcpy_fromio(headers, disc_table,
> +			      min_t(size_t, header_bytes,
> +				    resource_size(disc_res)));
> +		memcpy(entry->disc_header, headers, header_bytes);
> +
> +		/* Used by crashlog driver */
> +		entry->disc_table = disc_table;
> +
> +		return 0;
> +	}
> +	case INTEL_VSEC_DISC_ACPI: {
> +		memcpy(headers, &ivdev->acpi_disc[idx][0], header_bytes);
> +		memcpy(entry->disc_header, headers, header_bytes);
> +		/*
> +		 * No MMIO mapping exists on the ACPI source path; the cached
> +		 * headers are the only view of the discovery record. Consumers
> +		 * that dereference disc_table (e.g. crashlog) must therefore
> +		 * only be wired to namespaces backed by INTEL_VSEC_DISC_PCI.
> +		 */
> +		entry->disc_table = NULL;
> +
> +		return 0;
> +	}
> +	default:
> +		dev_err(dev, "Unknown discovery source type: %d\n", ivdev->src);
> +		break;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns,
>  			 struct intel_vsec_device *intel_vsec_dev, int idx)
>  {
>  	struct device *dev = &intel_vsec_dev->auxdev.dev;
> -	struct resource	*disc_res;
> +	u32 headers[PMT_DISC_HEADER_DWORDS];
>  	int ret;
>  
> -	disc_res = &intel_vsec_dev->resource[idx];
> -
> -	entry->disc_table = devm_ioremap_resource(dev, disc_res);
> -	if (IS_ERR(entry->disc_table))
> -		return PTR_ERR(entry->disc_table);
> -
> -	/*
> -	 * The mapped discovery resource may be smaller than disc_header (its
> -	 * size is the namespace's DVSEC entry_size in dwords, which can be
> -	 * less than 4). Cap the copy to the actual resource size to avoid
> -	 * reading past the mapped region; any unread dwords stay zero from
> -	 * the zero-initialized allocation of the containing struct.
> -	 */
> -	memcpy_fromio(entry->disc_header, entry->disc_table,
> -		      min_t(size_t, sizeof(entry->disc_header),
> -			    resource_size(disc_res)));
> +	ret = pmt_get_headers(intel_vsec_dev, idx, entry, headers);

Why do you pass headers to it as this function seems to not need them?

(This could be a leftover from the common decoding approach which is no 
longer pursued, I don't remember how it worked here).

Please also note the sashiko's uninitialized headers comment (which 
changes assumptions made in patch 5) which I also mentioned in patch 5 
comments. But it looks to me pmt_get_headers() could copy directly to 
->disc_header and avoid that problem altogether (the entry reuse still 
looks a problem though which can leave pseudogarbage into the tail of 
->disc_header).

-- 
 i.

> +	if (ret)
> +		return ret;
>  
>  	if (ns->pmt_pre_decode) {
>  		ret = ns->pmt_pre_decode(intel_vsec_dev, entry);
> diff --git a/drivers/platform/x86/intel/pmt/class.h b/drivers/platform/x86/intel/pmt/class.h
> index 84202fc7920c..950fa4ee300d 100644
> --- a/drivers/platform/x86/intel/pmt/class.h
> +++ b/drivers/platform/x86/intel/pmt/class.h
> @@ -18,6 +18,7 @@
>  /* PMT discovery base address/offset register layout */
>  #define GET_BIR(v)		((v) & GENMASK(2, 0))
>  #define GET_ADDRESS(v)		((v) & GENMASK(31, 3))
> +#define PMT_DISC_HEADER_DWORDS INTEL_VSEC_ACPI_DISC_DWORDS
>  
>  struct device;
>  struct pci_dev;
> @@ -44,7 +45,7 @@ struct intel_pmt_entry {
>  	struct telem_endpoint	*ep;
>  	struct pci_dev		*pcidev;
>  	struct intel_pmt_header	header;
> -	u32			disc_header[4];
> +	u32			disc_header[PMT_DISC_HEADER_DWORDS];
>  	struct bin_attribute	pmt_bin_attr;
>  	const struct attribute_group *attr_grp;
>  	struct kobject		*kobj;
> diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
> index 1fe5665a9d02..4c58a7f5031e 100644
> --- a/include/linux/intel_vsec.h
> +++ b/include/linux/intel_vsec.h
> @@ -28,6 +28,7 @@
>  #define INTEL_DVSEC_TABLE_BAR(x)	((x) & GENMASK(2, 0))
>  #define INTEL_DVSEC_TABLE_OFFSET(x)	((x) & GENMASK(31, 3))
>  #define TABLE_OFFSET_SHIFT		3
> +#define INTEL_VSEC_ACPI_DISC_DWORDS	4
>  
>  struct device;
>  struct pci_dev;
> @@ -122,7 +123,7 @@ struct intel_vsec_platform_info {
>  	struct device *parent;
>  	struct intel_vsec_header **headers;
>  	const struct vsec_feature_dependency *deps;
> -	u32 (*acpi_disc)[4];
> +	u32 (*acpi_disc)[INTEL_VSEC_ACPI_DISC_DWORDS];
>  	enum intel_vsec_disc_source src;
>  	void *priv_data;
>  	unsigned long caps;
> @@ -154,7 +155,7 @@ struct intel_vsec_device {
>  	struct auxiliary_device auxdev;
>  	struct device *dev;
>  	struct resource *resource;
> -	u32 (*acpi_disc)[4];
> +	u32 (*acpi_disc)[INTEL_VSEC_ACPI_DISC_DWORDS];
>  	enum intel_vsec_disc_source src;
>  	struct ida *ida;
>  	int num_resources;
> 

  reply	other threads:[~2026-05-22 10:21 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-22  2:21 [PATCH v5 00/16] Add ACPI-based PMT discovery support for Intel PMC David E. Box
2026-05-22  2:21 ` [PATCH v5 01/16] platform/x86/intel/pmt: Add pre/post decode hooks around header parsing David E. Box
2026-05-22  2:21 ` [PATCH v5 02/16] platform/x86/intel/pmt/crashlog: Split init into pre-decode David E. Box
2026-05-22  2:21 ` [PATCH v5 03/16] platform/x86/intel/pmt/telemetry: Move overlap check to post-decode hook David E. Box
2026-05-22  2:21 ` [PATCH v5 04/16] platform/x86/intel/pmt: Pass discovery index instead of resource David E. Box
2026-05-22  2:21 ` [PATCH v5 05/16] platform/x86/intel/pmt: Cache the telemetry discovery header David E. Box
2026-05-22 10:08   ` Ilpo Järvinen
2026-05-22  2:21 ` [PATCH v5 06/16] platform/x86/intel/pmt: Unify header fetch and add ACPI source David E. Box
2026-05-22 10:21   ` Ilpo Järvinen [this message]
2026-05-28 18:37     ` David Box
2026-05-22  2:21 ` [PATCH v5 07/16] platform/x86/intel/pmc: Add PMC SSRAM Kconfig description David E. Box
2026-05-22  2:21 ` [PATCH v5 08/16] platform/x86/intel/pmc: Add ACPI PWRM telemetry driver for Nova Lake S David E. Box
2026-05-22  2:21 ` [PATCH v5 09/16] platform/x86/intel/pmc/ssram: Rename probe and PCI ID table for consistency David E. Box
2026-05-22  2:21 ` [PATCH v5 10/16] platform/x86/intel/pmc/ssram: Use fixed-size static pmc array David E. Box
2026-05-22 10:37   ` Ilpo Järvinen
2026-05-22 19:49     ` David Box
2026-05-28 19:56       ` David Box
2026-05-22  2:21 ` [PATCH v5 11/16] platform/x86/intel/pmc/ssram: Refactor DEVID/PWRMBASE extraction into helper David E. Box
2026-05-22  2:21 ` [PATCH v5 12/16] platform/x86/intel/pmc/ssram: Add PCI platform data David E. Box
2026-05-22  2:21 ` [PATCH v5 13/16] platform/x86/intel/pmc/ssram: Refactor memory barrier for reentrant probe David E. Box
2026-05-29  2:39   ` David Box
2026-05-22  2:21 ` [PATCH v5 14/16] platform/x86/intel/pmc/ssram: Add ACPI discovery scaffolding David E. Box
2026-05-22  2:21 ` [PATCH v5 15/16] platform/x86/intel/pmc/ssram: Make PMT registration optional David E. Box
2026-05-22  2:21 ` [PATCH v5 16/16] platform/x86/intel/pmc: Add NVL PCI IDs for SSRAM telemetry discovery David E. Box
2026-05-22 10:07   ` Ilpo Järvinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=071b5732-591f-d228-2a11-1f3f16e21673@linux.intel.com \
    --to=ilpo.jarvinen@linux.intel.com \
    --cc=david.e.box@linux.intel.com \
    --cc=hansg@kernel.org \
    --cc=irenic.rajneesh@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=srinivas.pandruvada@linux.intel.com \
    --cc=xi.pardee@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome