From a3af58c152b48259a70e5aee6f52b6ccf6b282a5 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:14 -0800 Subject: [PATCH 01/17] platform/x86/intel/vsec: Remove unnecessary return MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit ace7b6f00870cea56460df335606e35ace3c07ac category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ace7b6f00870cea56460df335606e35ace3c07ac ------------------------------------------------- Intel-SIG: commit ace7b6f00870 platform/x86/intel/vsec: Remove unnecessary return. Backport intel tpmi base driver update for 5.10 In intel_vsec_add_aux(), just return from the last call to devm_add_action_or_reset() instead of checking its return value. Suggested-by: Ilpo Järvinen Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-3-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index 0df6b10ae7fe..3551a1182d90 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -167,12 +167,8 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, return ret; } - ret = devm_add_action_or_reset(parent, intel_vsec_remove_aux, + return devm_add_action_or_reset(parent, intel_vsec_remove_aux, auxdev); - if (ret < 0) - return ret; - - return 0; } EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); -- Gitee From 231ad7a7b857fa1ad9d2e3a606f5b125b8b7a2b0 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:15 -0800 Subject: [PATCH 02/17] platform/x86/intel/vsec: Move structures to header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit dbc01b0c86a7b23ffd06e14a84591500b04591ed category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=dbc01b0c86a7b23ffd06e14a84591500b04591ed ------------------------------------------------- Intel-SIG: commit dbc01b0c86a7 platform/x86/intel/vsec: Move structures to header. Backport intel tpmi base driver update for 5.10 In preparation for exporting an API to register Intel Vendor Specific Extended Capabilities (VSEC) from other drivers, move needed structures to the header file. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-4-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec.c | 34 ------------------------------ drivers/platform/x86/intel_vsec.h | 35 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index 3551a1182d90..0b5f1146bb05 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -24,13 +24,6 @@ #include "intel_vsec.h" -/* Intel DVSEC offsets */ -#define INTEL_DVSEC_ENTRIES 0xA -#define INTEL_DVSEC_SIZE 0xB -#define INTEL_DVSEC_TABLE 0xC -#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 PMT_XA_START 0 #define PMT_XA_MAX INT_MAX #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) @@ -38,33 +31,6 @@ static DEFINE_IDA(intel_vsec_ida); static DEFINE_XARRAY_ALLOC(auxdev_array); -/** - * struct intel_vsec_header - Common fields of Intel VSEC and DVSEC registers. - * @rev: Revision ID of the VSEC/DVSEC register space - * @length: Length of the VSEC/DVSEC register space - * @id: ID of the feature - * @num_entries: Number of instances of the feature - * @entry_size: Size of the discovery table for each feature - * @tbir: BAR containing the discovery tables - * @offset: BAR offset of start of the first discovery table - */ -struct intel_vsec_header { - u8 rev; - u16 length; - u16 id; - u8 num_entries; - u8 entry_size; - u8 tbir; - u32 offset; -}; - -enum intel_vsec_id { - VSEC_ID_TELEMETRY = 2, - VSEC_ID_WATCHER = 3, - VSEC_ID_CRASHLOG = 4, - VSEC_ID_TPMI = 66, -}; - static const char *intel_vsec_name(enum intel_vsec_id id) { switch (id) { diff --git a/drivers/platform/x86/intel_vsec.h b/drivers/platform/x86/intel_vsec.h index bb1514d3b4f0..f0ba6bc0dfe9 100644 --- a/drivers/platform/x86/intel_vsec.h +++ b/drivers/platform/x86/intel_vsec.h @@ -10,9 +10,44 @@ #define VSEC_CAP_CRASHLOG BIT(2) #define VSEC_CAP_TPMI BIT(4) +/* Intel DVSEC offsets */ +#define INTEL_DVSEC_ENTRIES 0xA +#define INTEL_DVSEC_SIZE 0xB +#define INTEL_DVSEC_TABLE 0xC +#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 + struct pci_dev; struct resource; +enum intel_vsec_id { + VSEC_ID_TELEMETRY = 2, + VSEC_ID_WATCHER = 3, + VSEC_ID_CRASHLOG = 4, + VSEC_ID_TPMI = 66, +}; + +/** + * struct intel_vsec_header - Common fields of Intel VSEC and DVSEC registers. + * @rev: Revision ID of the VSEC/DVSEC register space + * @length: Length of the VSEC/DVSEC register space + * @id: ID of the feature + * @num_entries: Number of instances of the feature + * @entry_size: Size of the discovery table for each feature + * @tbir: BAR containing the discovery tables + * @offset: BAR offset of start of the first discovery table + */ +struct intel_vsec_header { + u8 rev; + u16 length; + u16 id; + u8 num_entries; + u8 entry_size; + u8 tbir; + u32 offset; +}; + enum intel_vsec_quirks { /* Watcher feature not supported */ VSEC_QUIRK_NO_WATCHER = BIT(0), -- Gitee From f46f38183f3a2dbcf5c8ebc856b5d7e2731f2e82 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:16 -0800 Subject: [PATCH 03/17] platform/x86/intel/vsec: remove platform_info from vsec device structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 0a0a52abaa65b844afde3d7229c209a8cddc5a07 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0a0a52abaa65b844afde3d7229c209a8cddc5a07 ------------------------------------------------- Intel-SIG: commit 0a0a52abaa65 platform/x86/intel/vsec: remove platform_info from vsec device structure. Backport intel tpmi base driver update for 5.10 In preparation for exporting an API to register Intel Vendor Specific Extended Capabilities (VSEC) from other drivers, remove the pointer to platform_info from intel_vsec_device. This prevents a potential page fault when auxiliary drivers probe and attempt to dereference this pointer to access the needed quirks field. Instead, just add the quirks to intel_vsec_device. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-5-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_pmt_class.c | 2 +- drivers/platform/x86/intel_vsec.c | 2 +- drivers/platform/x86/intel_vsec.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_pmt_class.c b/drivers/platform/x86/intel_pmt_class.c index f6a199d3f650..7ffa2b8c841c 100644 --- a/drivers/platform/x86/intel_pmt_class.c +++ b/drivers/platform/x86/intel_pmt_class.c @@ -29,7 +29,7 @@ bool intel_pmt_is_early_client_hw(struct device *dev) * differences from the server platforms (which use the Out Of Band * Management Services Module OOBMSM). */ - return !!(ivdev->info->quirks & VSEC_QUIRK_EARLY_HW); + return !!(ivdev->quirks & VSEC_QUIRK_EARLY_HW); } EXPORT_SYMBOL_NS_GPL(intel_pmt_is_early_client_hw, INTEL_PMT); diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index 0b5f1146bb05..cffbadc759b1 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -187,7 +187,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he intel_vsec_dev->pcidev = pdev; intel_vsec_dev->resource = res; intel_vsec_dev->num_resources = header->num_entries; - intel_vsec_dev->info = info; + intel_vsec_dev->quirks = info->quirks; intel_vsec_dev->ida = &intel_vsec_ida; return intel_vsec_add_aux(pdev, NULL, intel_vsec_dev, diff --git a/drivers/platform/x86/intel_vsec.h b/drivers/platform/x86/intel_vsec.h index f0ba6bc0dfe9..73930dbc2cf3 100644 --- a/drivers/platform/x86/intel_vsec.h +++ b/drivers/platform/x86/intel_vsec.h @@ -77,11 +77,11 @@ struct intel_vsec_device { struct pci_dev *pcidev; struct resource *resource; struct ida *ida; - struct intel_vsec_platform_info *info; int num_resources; int id; /* xa */ void *priv_data; size_t priv_data_size; + unsigned long quirks; }; int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, -- Gitee From 3d0cfea2eaa72d4349676fcd38064b4d7e910d64 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:18 -0800 Subject: [PATCH 04/17] platform/x86/intel/vsec: Assign auxdev parent by argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 6dfc2514acee37e30ce59f1f25b1f8f6aa7c1b08 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6dfc2514acee37e30ce59f1f25b1f8f6aa7c1b08 ------------------------------------------------- Intel-SIG: commit 6dfc2514acee platform/x86/intel/vsec: Assign auxdev parent by argument. Backport intel tpmi base driver update for 5.10 Instead of checking for a NULL parent argument in intel_vsec_add_aux() and then assigning it to the probed device, remove this check and just pass the device in the call. Since this function is exported, return -EINVAL if the parent is not specified. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-7-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index cffbadc759b1..3ee77f1c644a 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -95,6 +95,9 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; int ret, id; + if (!parent) + return -EINVAL; + ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, PMT_XA_LIMIT, GFP_KERNEL); if (ret < 0) { @@ -113,9 +116,6 @@ int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, return id; } - if (!parent) - parent = &pdev->dev; - auxdev->id = id; auxdev->name = name; auxdev->dev.parent = parent; @@ -190,7 +190,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he intel_vsec_dev->quirks = info->quirks; intel_vsec_dev->ida = &intel_vsec_ida; - return intel_vsec_add_aux(pdev, NULL, intel_vsec_dev, + return intel_vsec_add_aux(pdev, &pdev->dev, intel_vsec_dev, intel_vsec_name(header->id)); } -- Gitee From 045360f5c497cbbb84804a5026eeb1eb26bccab1 Mon Sep 17 00:00:00 2001 From: Gayatri Kammela Date: Wed, 29 Nov 2023 14:21:19 -0800 Subject: [PATCH 05/17] platform/x86/intel/vsec: Add intel_vsec_register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 4edbd117ba3f7beacfb439aad60e8a5de77114b4 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4edbd117ba3f7beacfb439aad60e8a5de77114b4 ------------------------------------------------- Intel-SIG: commit 4edbd117ba3f platform/x86/intel/vsec: Add intel_vsec_register. Backport intel tpmi base driver update for 5.10 Add and export intel_vsec_register() to allow the registration of Intel extended capabilities from other drivers. Add check to look for memory conflicts before registering a new capability. Since the vsec provider may not be a PCI device, add a parent field to intel_vsec_platform_info() to allow specifying the parent device for device managed cleanup. Signed-off-by: Gayatri Kammela Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-8-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec.c | 24 +++++++++++++++++++++++- drivers/platform/x86/intel_vsec.h | 4 ++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index 3ee77f1c644a..bed695750f4d 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -143,9 +143,15 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he { struct intel_vsec_device *intel_vsec_dev; struct resource *res, *tmp; + struct device *parent; unsigned long quirks = info->quirks; int i; + if (info->parent) + parent = info->parent; + else + parent = &pdev->dev; + if (!intel_vsec_supported(header->id, info->caps)) return -EINVAL; @@ -182,6 +188,12 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he header->offset + i * (header->entry_size * sizeof(u32)); tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1; tmp->flags = IORESOURCE_MEM; + + /* Check resource is not in use */ + if (!request_mem_region(tmp->start, resource_size(tmp), "")) + return -EBUSY; + + release_mem_region(tmp->start, resource_size(tmp)); } intel_vsec_dev->pcidev = pdev; @@ -190,7 +202,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he intel_vsec_dev->quirks = info->quirks; intel_vsec_dev->ida = &intel_vsec_ida; - return intel_vsec_add_aux(pdev, &pdev->dev, intel_vsec_dev, + return intel_vsec_add_aux(pdev, parent, intel_vsec_dev, intel_vsec_name(header->id)); } @@ -308,6 +320,16 @@ static bool intel_vsec_walk_vsec(struct pci_dev *pdev, return have_devices; } +void intel_vsec_register(struct pci_dev *pdev, + struct intel_vsec_platform_info *info) +{ + if (!pdev || !info) + return; + + intel_vsec_walk_header(pdev, info); +} +EXPORT_SYMBOL_NS_GPL(intel_vsec_register, INTEL_VSEC); + static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct intel_vsec_platform_info *info; diff --git a/drivers/platform/x86/intel_vsec.h b/drivers/platform/x86/intel_vsec.h index 73930dbc2cf3..7f0811527f06 100644 --- a/drivers/platform/x86/intel_vsec.h +++ b/drivers/platform/x86/intel_vsec.h @@ -67,6 +67,7 @@ enum intel_vsec_quirks { /* Platform specific data */ struct intel_vsec_platform_info { + struct device *parent; struct intel_vsec_header **headers; unsigned long caps; unsigned long quirks; @@ -97,4 +98,7 @@ static inline struct intel_vsec_device *auxdev_to_ivdev(struct auxiliary_device { return container_of(auxdev, struct intel_vsec_device, auxdev); } + +void intel_vsec_register(struct pci_dev *pdev, + struct intel_vsec_platform_info *info); #endif -- Gitee From 51cd4cdb178e369d21744b53e9e6f3379f7c3dbf Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:20 -0800 Subject: [PATCH 06/17] platform/x86/intel/vsec: Add base address field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit e97ec7f621fbfdce07bf1b98a26883ee19281747 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e97ec7f621fbfdce07bf1b98a26883ee19281747 ------------------------------------------------- Intel-SIG: commit e97ec7f621fb platform/x86/intel/vsec: Add base address field. Backport intel tpmi base driver update for 5.10 Some devices may emulate PCI VSEC capabilities in MMIO. In such cases the BAR is not readable from a config space. Provide a field for drivers to indicate the base address to be used. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-9-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_pmt_class.c | 14 +++++++++++--- drivers/platform/x86/intel_vsec.c | 10 ++++++++-- drivers/platform/x86/intel_vsec.h | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_pmt_class.c b/drivers/platform/x86/intel_pmt_class.c index 7ffa2b8c841c..316a71444fd6 100644 --- a/drivers/platform/x86/intel_pmt_class.c +++ b/drivers/platform/x86/intel_pmt_class.c @@ -159,10 +159,11 @@ static struct class intel_pmt_class = { static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, struct intel_pmt_header *header, - struct device *dev, + struct intel_vsec_device *ivdev, struct resource *disc_res) { - struct pci_dev *pci_dev = to_pci_dev(dev->parent); + struct pci_dev *pci_dev = ivdev->pcidev; + struct device *dev = &ivdev->auxdev.dev; u8 bir; /* @@ -214,6 +215,13 @@ static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, break; case ACCESS_BARID: + /* Use the provided base address if it exists */ + if (ivdev->base_addr) { + entry->base_addr = ivdev->base_addr + + GET_ADDRESS(header->base_offset); + break; + } + /* * If another BAR was specified then the base offset * represents the offset within that BAR. SO retrieve the @@ -318,7 +326,7 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa if (ret) return ret; - ret = intel_pmt_populate_entry(entry, &header, dev, disc_res); + ret = intel_pmt_populate_entry(entry, &header, intel_vsec_dev, disc_res); if (ret) return ret; diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index bed695750f4d..a0492ef59c83 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -145,6 +145,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he struct resource *res, *tmp; struct device *parent; unsigned long quirks = info->quirks; + u64 base_addr; int i; if (info->parent) @@ -178,14 +179,18 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he if (quirks & VSEC_QUIRK_TABLE_SHIFT) header->offset >>= TABLE_OFFSET_SHIFT; + if (info->base_addr) + base_addr = info->base_addr; + else + base_addr = pdev->resource[header->tbir].start; + /* * The DVSEC/VSEC contains the starting offset and count for a block of * discovery tables. Create a resource array of these tables to the * auxiliary device driver. */ for (i = 0, tmp = res; i < header->num_entries; i++, tmp++) { - tmp->start = pdev->resource[header->tbir].start + - header->offset + i * (header->entry_size * sizeof(u32)); + tmp->start = base_addr + header->offset + i * (header->entry_size * sizeof(u32)); tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1; tmp->flags = IORESOURCE_MEM; @@ -200,6 +205,7 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he intel_vsec_dev->resource = res; intel_vsec_dev->num_resources = header->num_entries; intel_vsec_dev->quirks = info->quirks; + intel_vsec_dev->base_addr = info->base_addr; intel_vsec_dev->ida = &intel_vsec_ida; return intel_vsec_add_aux(pdev, parent, intel_vsec_dev, diff --git a/drivers/platform/x86/intel_vsec.h b/drivers/platform/x86/intel_vsec.h index 7f0811527f06..3e4fabb79874 100644 --- a/drivers/platform/x86/intel_vsec.h +++ b/drivers/platform/x86/intel_vsec.h @@ -71,6 +71,7 @@ struct intel_vsec_platform_info { struct intel_vsec_header **headers; unsigned long caps; unsigned long quirks; + u64 base_addr; }; struct intel_vsec_device { @@ -83,6 +84,7 @@ struct intel_vsec_device { void *priv_data; size_t priv_data_size; unsigned long quirks; + u64 base_addr; }; int intel_vsec_add_aux(struct pci_dev *pdev, struct device *parent, -- Gitee From 316fc3c12598999eefa737bca9fb99a3ae404cb0 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Tue, 27 Feb 2024 11:01:32 -0800 Subject: [PATCH 07/17] platform/x86/intel/vsec: Remove nuisance message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.9 commit 701d40af59373ac3a60c620cbd0ceff7b2b8e565 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=701d40af59373ac3a60c620cbd0ceff7b2b8e565 ------------------------------------------------- Intel-SIG: commit 701d40af5937 platform/x86/intel/vsec: Remove nuisance message. Backport intel tpmi base driver update for 5.10 intel_vsec_walk_header() is used to configure features from devices that don't provide a PCI VSEC or DVSEC structure. Some of these features may be unsupported and fail to load. Ignore them silently as we do for unsupported features described by VSEC/DVSEC. Signed-off-by: "David E. Box" Reviewed-by: Kuppuswamy Sathyanarayanan Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20240227190134.1592072-1-david.e.box@linux.intel.com Signed-off-by: Ilpo Järvinen [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_vsec.c b/drivers/platform/x86/intel_vsec.c index a0492ef59c83..9ca13296cd02 100644 --- a/drivers/platform/x86/intel_vsec.c +++ b/drivers/platform/x86/intel_vsec.c @@ -221,10 +221,7 @@ static bool intel_vsec_walk_header(struct pci_dev *pdev, for ( ; *header; header++) { ret = intel_vsec_add_dev(pdev, *header, info); - if (ret) - dev_info(&pdev->dev, "Could not add device for VSEC id %d\n", - (*header)->id); - else + if (!ret) have_devices = true; } -- Gitee From a517b401896f5aef249b6ceb015b745135df6b57 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Dec 2023 14:17:36 -0800 Subject: [PATCH 08/17] platform/x86/intel/tpmi: Don't create devices for disabled features MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit b87434f2e6fe81362d2ac57f3aba45ba89a11399 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b87434f2e6fe81362d2ac57f3aba45ba89a11399 ------------------------------------------------- Intel-SIG: commit b87434f2e6fe platform/x86/intel/tpmi: Don't create devices for disabled features. Backport intel tpmi base driver update for 5.10 If some TPMI features are disabled, don't create auxiliary devices. In this way feature drivers will not load. While creating auxiliary devices, call tpmi_read_feature_status() to check feature state and return if the feature is disabled without creating a device. Signed-off-by: Srinivas Pandruvada Reviewed-by: Hans de Goede Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231204221740.3645130-2-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index dbb0179d06cd..027d0b29b478 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -598,9 +598,21 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, struct intel_vsec_device *vsec_dev = tpmi_info->vsec_dev; char feature_id_name[TPMI_FEATURE_NAME_LEN]; struct intel_vsec_device *feature_vsec_dev; + struct tpmi_feature_state feature_state; struct resource *res, *tmp; const char *name; - int i; + int i, ret; + + ret = tpmi_read_feature_status(tpmi_info, pfs->pfs_header.tpmi_id, &feature_state); + if (ret) + return ret; + + /* + * If not enabled, continue to look at other features in the PFS, so return -EOPNOTSUPP. + * This will not cause failure of loading of this driver. + */ + if (!feature_state.enabled) + return -EOPNOTSUPP; name = intel_tpmi_name(pfs->pfs_header.tpmi_id); if (!name) -- Gitee From e7bd2784633fbb4825dc87767da9f2c6f0f8fb0b Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Dec 2023 14:17:37 -0800 Subject: [PATCH 09/17] platform/x86/intel/tpmi: Modify external interface to get read/write state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 72dd14d241e1c6e241fc5b265746c59f306c6aa3 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72dd14d241e1c6e241fc5b265746c59f306c6aa3 ------------------------------------------------- Intel-SIG: commit 72dd14d241e1 platform/x86/intel/tpmi: Modify external interface to get read/write state. Backport intel tpmi base driver update for 5.10 Modify the external interface tpmi_get_feature_status() to get read and write blocked instead of locked and disabled. Since auxiliary device is not created when disabled, no use of returning disabled state. Also locked state is not useful as feature driver can't use locked state in a meaningful way. Using read and write state, feature driver can decide which operations to restrict for that feature. Signed-off-by: Srinivas Pandruvada Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231204221740.3645130-3-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 8 ++++---- include/linux/intel_tpmi.h | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 027d0b29b478..52a5a56b9d3b 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -345,8 +345,8 @@ static int tpmi_read_feature_status(struct intel_tpmi_info *tpmi_info, int featu return ret; } -int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, - int *locked, int *disabled) +int tpmi_get_feature_status(struct auxiliary_device *auxdev, + int feature_id, bool *read_blocked, bool *write_blocked) { struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(auxdev->dev.parent); struct intel_tpmi_info *tpmi_info = auxiliary_get_drvdata(&intel_vsec_dev->auxdev); @@ -357,8 +357,8 @@ int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, if (ret) return ret; - *locked = feature_state.locked; - *disabled = !feature_state.enabled; + *read_blocked = feature_state.read_blocked; + *write_blocked = feature_state.write_blocked; return 0; } diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h index ee07393445f9..4f89c5bd8663 100644 --- a/include/linux/intel_tpmi.h +++ b/include/linux/intel_tpmi.h @@ -32,7 +32,6 @@ struct intel_tpmi_plat_info { struct intel_tpmi_plat_info *tpmi_get_platform_data(struct auxiliary_device *auxdev); struct resource *tpmi_get_resource_at_index(struct auxiliary_device *auxdev, int index); int tpmi_get_resource_count(struct auxiliary_device *auxdev); - -int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, int *locked, - int *disabled); +int tpmi_get_feature_status(struct auxiliary_device *auxdev, int feature_id, bool *read_blocked, + bool *write_blocked); #endif -- Gitee From 082c72441886d39980d02ab426eefed8c59199b1 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Dec 2023 14:17:38 -0800 Subject: [PATCH 10/17] platform/x86/intel/tpmi: Move TPMI ID definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 046d7be6210e7f870e53eb38fd410237e9d1d88f category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=046d7be6210e7f870e53eb38fd410237e9d1d88f ------------------------------------------------- Intel-SIG: commit 046d7be6210e platform/x86/intel/tpmi: Move TPMI ID definition. Backport intel tpmi base driver update for 5.10 Move TPMI ID definitions to common include file. In this way other feature drivers don't have to redefine. Signed-off-by: Srinivas Pandruvada Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231204221740.3645130-4-srinivas.pandruvada@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 13 ------------- include/linux/intel_tpmi.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 52a5a56b9d3b..8701f75b1192 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -170,19 +170,6 @@ struct tpmi_feature_state { u32 locked:1; } __packed; -/* - * List of supported TMPI IDs. - * Some TMPI IDs are not used by Linux, so the numbers are not consecutive. - */ -enum intel_tpmi_id { - TPMI_ID_RAPL = 0, /* Running Average Power Limit */ - TPMI_ID_PEM = 1, /* Power and Perf excursion Monitor */ - TPMI_ID_UNCORE = 2, /* Uncore Frequency Scaling */ - TPMI_ID_SST = 5, /* Speed Select Technology */ - TPMI_CONTROL_ID = 0x80, /* Special ID for getting feature status */ - TPMI_INFO_ID = 0x81, /* Special ID for PCI BDF and Package ID information */ -}; - /* * The size from hardware is in u32 units. This size is from a trusted hardware, * but better to verify for pre silicon platforms. Set size to 0, when invalid. diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h index 4f89c5bd8663..a3529b962be6 100644 --- a/include/linux/intel_tpmi.h +++ b/include/linux/intel_tpmi.h @@ -12,6 +12,19 @@ #define TPMI_MINOR_VERSION(val) FIELD_GET(GENMASK(4, 0), val) #define TPMI_MAJOR_VERSION(val) FIELD_GET(GENMASK(7, 5), val) +/* + * List of supported TMPI IDs. + * Some TMPI IDs are not used by Linux, so the numbers are not consecutive. + */ +enum intel_tpmi_id { + TPMI_ID_RAPL = 0, /* Running Average Power Limit */ + TPMI_ID_PEM = 1, /* Power and Perf excursion Monitor */ + TPMI_ID_UNCORE = 2, /* Uncore Frequency Scaling */ + TPMI_ID_SST = 5, /* Speed Select Technology */ + TPMI_CONTROL_ID = 0x80, /* Special ID for getting feature status */ + TPMI_INFO_ID = 0x81, /* Special ID for PCI BDF and Package ID information */ +}; + /** * struct intel_tpmi_plat_info - Platform information for a TPMI device instance * @package_id: CPU Package id -- Gitee From da6e938e658b243696e880a2a6d160f0c2f8b7f2 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 5 Mar 2024 11:46:44 -0800 Subject: [PATCH 11/17] platform/x86/intel/tpmi: Change vsec offset to u64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.9 commit 57221a07ff37ff356f9265acd228bc3c8744c8fc category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=57221a07ff37ff356f9265acd228bc3c8744c8fc ------------------------------------------------- Intel-SIG: commit 57221a07ff37 platform/x86/intel/tpmi: Change vsec offset to u64. Backport intel tpmi base driver update for 5.10 The vsec offset can be 64 bit long depending on the PFS start. So change type to u64. Also use 64 bit formatting for seq_printf. Fixes: 47731fd2865f ("platform/x86/intel: Intel TPMI enumeration driver") Signed-off-by: Srinivas Pandruvada Cc: stable@vger.kernel.org # v6.3+ Link: https://lore.kernel.org/r/20240305194644.2077867-1-srinivas.pandruvada@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 8701f75b1192..810a8a47591e 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -96,7 +96,7 @@ struct intel_tpmi_pfs_entry { */ struct intel_tpmi_pm_feature { struct intel_tpmi_pfs_entry pfs_header; - unsigned int vsec_offset; + u64 vsec_offset; struct intel_vsec_device *vsec_dev; }; @@ -376,7 +376,7 @@ static int tpmi_pfs_dbg_show(struct seq_file *s, void *unused) read_blocked = feature_state.read_blocked ? 'Y' : 'N'; write_blocked = feature_state.write_blocked ? 'Y' : 'N'; } - seq_printf(s, "0x%02x\t\t0x%02x\t\t0x%04x\t\t0x%04x\t\t0x%02x\t\t0x%08x\t%c\t%c\t\t%c\t\t%c\n", + seq_printf(s, "0x%02x\t\t0x%02x\t\t0x%04x\t\t0x%04x\t\t0x%02x\t\t0x%016llx\t%c\t%c\t\t%c\t\t%c\n", pfs->pfs_header.tpmi_id, pfs->pfs_header.num_entries, pfs->pfs_header.entry_size, pfs->pfs_header.cap_offset, pfs->pfs_header.attribute, pfs->vsec_offset, locked, disabled, @@ -395,7 +395,8 @@ static int tpmi_mem_dump_show(struct seq_file *s, void *unused) struct intel_tpmi_pm_feature *pfs = s->private; int count, ret = 0; void __iomem *mem; - u32 off, size; + u32 size; + u64 off; u8 *buffer; size = TPMI_GET_SINGLE_ENTRY_SIZE(pfs); @@ -411,7 +412,7 @@ static int tpmi_mem_dump_show(struct seq_file *s, void *unused) mutex_lock(&tpmi_dev_lock); for (count = 0; count < pfs->pfs_header.num_entries; ++count) { - seq_printf(s, "TPMI Instance:%d offset:0x%x\n", count, off); + seq_printf(s, "TPMI Instance:%d offset:0x%llx\n", count, off); mem = ioremap(off, size); if (!mem) { -- Gitee From a6f0b566372d3ba28c610b507f37a021f2e5a286 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 23 Apr 2024 13:46:10 -0700 Subject: [PATCH 12/17] platform/x86/intel/tpmi: Handle error from tpmi_process_info() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.10 commit 2920141fc149f71bad22361946417bc43783ed7f category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2920141fc149f71bad22361946417bc43783ed7f ------------------------------------------------- Intel-SIG: commit 2920141fc149 platform/x86/intel/tpmi: Handle error from tpmi_process_info(). Backport intel tpmi base driver update for 5.10 When tpmi_process_info() returns error, fail to load the driver. This can happen if call to ioremap() returns error. Signed-off-by: Srinivas Pandruvada Reviewed-by: Ilpo Järvinen Cc: stable@vger.kernel.org # v6.3+ Link: https://lore.kernel.org/r/20240423204619.3946901-2-srinivas.pandruvada@linux.intel.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 810a8a47591e..7f271696f06b 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -763,8 +763,11 @@ static int intel_vsec_tpmi_init(struct auxiliary_device *auxdev) * when actual device nodes created outside this * loop via tpmi_create_devices(). */ - if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) - tpmi_process_info(tpmi_info, pfs); + if (pfs->pfs_header.tpmi_id == TPMI_INFO_ID) { + ret = tpmi_process_info(tpmi_info, pfs); + if (ret) + return ret; + } if (pfs->pfs_header.tpmi_id == TPMI_CONTROL_ID) tpmi_set_control_base(auxdev, tpmi_info, pfs); -- Gitee From 76d0c263067b004b55b1e4fd941996b7f8b852e8 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 23 Apr 2024 13:46:11 -0700 Subject: [PATCH 13/17] platform/x86/intel/tpmi: Check major version change for TPMI Information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.10 commit 59eb0814d6a3541f55b1d6e3d52df1226de41f3e category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59eb0814d6a3541f55b1d6e3d52df1226de41f3e ------------------------------------------------- Intel-SIG: commit 59eb0814d6a3 platform/x86/intel/tpmi: Check major version change for TPMI Information. Backport intel tpmi base driver update for 5.10 Check the major version from TPMI information header and fail to load driver if the version is not supported. Signed-off-by: Srinivas Pandruvada Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20240423204619.3946901-3-srinivas.pandruvada@linux.intel.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 7f271696f06b..9903ea7eed48 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -666,28 +666,37 @@ static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) } #define TPMI_INFO_BUS_INFO_OFFSET 0x08 +#define TPMI_INFO_MAJOR_VERSION 0x00 static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, struct intel_tpmi_pm_feature *pfs) { struct tpmi_info_header header; void __iomem *info_mem; + u64 feature_header; + int ret = 0; - info_mem = ioremap(pfs->vsec_offset + TPMI_INFO_BUS_INFO_OFFSET, - pfs->pfs_header.entry_size * sizeof(u32) - TPMI_INFO_BUS_INFO_OFFSET); + info_mem = ioremap(pfs->vsec_offset, pfs->pfs_header.entry_size * sizeof(u32)); if (!info_mem) return -ENOMEM; - memcpy_fromio(&header, info_mem, sizeof(header)); + feature_header = readq(info_mem); + if (TPMI_MAJOR_VERSION(feature_header) != TPMI_INFO_MAJOR_VERSION) { + ret = -ENODEV; + goto error_info_header; + } + + memcpy_fromio(&header, info_mem + TPMI_INFO_BUS_INFO_OFFSET, sizeof(header)); tpmi_info->plat_info.package_id = header.pkg; tpmi_info->plat_info.bus_number = header.bus; tpmi_info->plat_info.device_number = header.dev; tpmi_info->plat_info.function_number = header.fn; +error_info_header: iounmap(info_mem); - return 0; + return ret; } static int tpmi_fetch_pfs_header(struct intel_tpmi_pm_feature *pfs, u64 start, int size) -- Gitee From c319e80c56cfec6c9892a0b4d4c6190d63ee3685 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 23 Apr 2024 13:46:12 -0700 Subject: [PATCH 14/17] platform/x86/intel/tpmi: Align comments in kernel-doc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.10 commit 1192534407d0f8ab9a0503052777260ae74968c3 category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1192534407d0f8ab9a0503052777260ae74968c3 ------------------------------------------------- Intel-SIG: commit 1192534407d0 platform/x86/intel/tpmi: Align comments in kernel-doc. Backport intel tpmi base driver update for 5.10 Align comments in kernel-doc for the struct intel_tpmi_plat_info. Signed-off-by: Srinivas Pandruvada Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20240423204619.3946901-4-srinivas.pandruvada@linux.intel.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- include/linux/intel_tpmi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h index a3529b962be6..685a41dddf82 100644 --- a/include/linux/intel_tpmi.h +++ b/include/linux/intel_tpmi.h @@ -27,9 +27,9 @@ enum intel_tpmi_id { /** * struct intel_tpmi_plat_info - Platform information for a TPMI device instance - * @package_id: CPU Package id - * @bus_number: PCI bus number - * @device_number: PCI device number + * @package_id: CPU Package id + * @bus_number: PCI bus number + * @device_number: PCI device number * @function_number: PCI function number * * Structure to store platform data for a TPMI device instance. This -- Gitee From 346962d32e70e4f50360d5f1470d86c5e4d8ed87 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 23 Apr 2024 13:46:13 -0700 Subject: [PATCH 15/17] platform/x86/intel/tpmi: Add additional TPMI header fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.10 commit c8405cc815151a8b2fa6f7510ede8256228e45da category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c8405cc815151a8b2fa6f7510ede8256228e45da ------------------------------------------------- Intel-SIG: commit c8405cc81515 platform/x86/intel/tpmi: Add additional TPMI header fields. Backport intel tpmi base driver update for 5.10 TPMI information header added additional fields in version 2. Some of the reserved fields in version 1 are used to define new fields. Parse new fields and export as part of platform data. These fields include: - PCI segment ID - Partition ID of the package: If a package is represented by more than one PCI device, then partition ID along with cdie_mask, describes the scope. For example to update get/set properties for a compute die, one of the PCI MMIO region is selected from the partition ID. - cdie_mask: Mask of all compute dies in this partition. Signed-off-by: Srinivas Pandruvada Reviewed-by: Andy Shevchenko Reviewed-by: Zhang Rui Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20240423204619.3946901-5-srinivas.pandruvada@linux.intel.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_vsec_tpmi.c | 15 ++++++++++++++- include/linux/intel_tpmi.h | 6 ++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel_vsec_tpmi.c b/drivers/platform/x86/intel_vsec_tpmi.c index 9903ea7eed48..daf90700aefa 100644 --- a/drivers/platform/x86/intel_vsec_tpmi.c +++ b/drivers/platform/x86/intel_vsec_tpmi.c @@ -128,6 +128,9 @@ struct intel_tpmi_info { * @dev: PCI device number * @bus: PCI bus number * @pkg: CPU Package id + * @segment: PCI segment id + * @partition: Package Partition id + * @cdie_mask: Bitmap of compute dies in the current partition * @reserved: Reserved for future use * @lock: When set to 1 the register is locked and becomes read-only * until next reset. Not for use by the OS driver. @@ -139,7 +142,10 @@ struct tpmi_info_header { u64 dev:5; u64 bus:8; u64 pkg:8; - u64 reserved:39; + u64 segment:8; + u64 partition:2; + u64 cdie_mask:16; + u64 reserved:13; u64 lock:1; } __packed; @@ -667,6 +673,7 @@ static int tpmi_create_devices(struct intel_tpmi_info *tpmi_info) #define TPMI_INFO_BUS_INFO_OFFSET 0x08 #define TPMI_INFO_MAJOR_VERSION 0x00 +#define TPMI_INFO_MINOR_VERSION 0x02 static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, struct intel_tpmi_pm_feature *pfs) @@ -693,6 +700,12 @@ static int tpmi_process_info(struct intel_tpmi_info *tpmi_info, tpmi_info->plat_info.device_number = header.dev; tpmi_info->plat_info.function_number = header.fn; + if (TPMI_MINOR_VERSION(feature_header) >= TPMI_INFO_MINOR_VERSION) { + tpmi_info->plat_info.cdie_mask = header.cdie_mask; + tpmi_info->plat_info.partition = header.partition; + tpmi_info->plat_info.segment = header.segment; + } + error_info_header: iounmap(info_mem); diff --git a/include/linux/intel_tpmi.h b/include/linux/intel_tpmi.h index 685a41dddf82..1e880cb0f454 100644 --- a/include/linux/intel_tpmi.h +++ b/include/linux/intel_tpmi.h @@ -27,7 +27,10 @@ enum intel_tpmi_id { /** * struct intel_tpmi_plat_info - Platform information for a TPMI device instance + * @cdie_mask: Mask of all compute dies in the partition * @package_id: CPU Package id + * @partition: Package partition id when multiple VSEC PCI devices per package + * @segment: PCI segment ID * @bus_number: PCI bus number * @device_number: PCI device number * @function_number: PCI function number @@ -36,7 +39,10 @@ enum intel_tpmi_id { * struct is used to return data via tpmi_get_platform_data(). */ struct intel_tpmi_plat_info { + u16 cdie_mask; u8 package_id; + u8 partition; + u8 segment; u8 bus_number; u8 device_number; u8 function_number; -- Gitee From e07c90d78cd57269b34090f5d8b9a976ce63f830 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:21 -0800 Subject: [PATCH 16/17] platform/x86/intel/pmt: Add header to struct intel_pmt_entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 4d1b7efee3fc703c64bacc37c4824888c5f26e8b category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4d1b7efee3fc703c64bacc37c4824888c5f26e8b ------------------------------------------------- Intel-SIG: commit 4d1b7efee3fc platform/x86/intel/pmt: Add header to struct intel_pmt_entry. Backport intel tpmi base driver update for 5.10 The PMT header is passed to several functions. Instead, store the header in struct intel_pmt_entry which is also passed to these functions and shorten the argument list. This simplifies the calls in preparation for later changes. While here also perform a newline cleanup. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-10-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_pmt_class.c | 8 +++----- drivers/platform/x86/intel_pmt_class.h | 16 ++++++++-------- drivers/platform/x86/intel_pmt_crashlog.c | 2 +- drivers/platform/x86/intel_pmt_telemetry.c | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/platform/x86/intel_pmt_class.c b/drivers/platform/x86/intel_pmt_class.c index 316a71444fd6..968606a277c6 100644 --- a/drivers/platform/x86/intel_pmt_class.c +++ b/drivers/platform/x86/intel_pmt_class.c @@ -158,12 +158,12 @@ static struct class intel_pmt_class = { }; static int intel_pmt_populate_entry(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, struct intel_vsec_device *ivdev, struct resource *disc_res) { struct pci_dev *pci_dev = ivdev->pcidev; struct device *dev = &ivdev->auxdev.dev; + struct intel_pmt_header *header = &entry->header; u8 bir; /* @@ -312,7 +312,6 @@ int intel_pmt_dev_create(struct intel_pmt_entry *entry, struct intel_pmt_namespa struct intel_vsec_device *intel_vsec_dev, int idx) { struct device *dev = &intel_vsec_dev->auxdev.dev; - struct intel_pmt_header header; struct resource *disc_res; int ret; @@ -322,16 +321,15 @@ 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); - ret = ns->pmt_header_decode(entry, &header, dev); + ret = ns->pmt_header_decode(entry, dev); if (ret) return ret; - ret = intel_pmt_populate_entry(entry, &header, intel_vsec_dev, disc_res); + ret = intel_pmt_populate_entry(entry, intel_vsec_dev, disc_res); if (ret) return ret; return intel_pmt_dev_register(entry, ns, dev); - } EXPORT_SYMBOL_NS_GPL(intel_pmt_dev_create, INTEL_PMT); diff --git a/drivers/platform/x86/intel_pmt_class.h b/drivers/platform/x86/intel_pmt_class.h index ca821eb8b197..20024190ef43 100644 --- a/drivers/platform/x86/intel_pmt_class.h +++ b/drivers/platform/x86/intel_pmt_class.h @@ -18,7 +18,15 @@ #define GET_BIR(v) ((v) & GENMASK(2, 0)) #define GET_ADDRESS(v) ((v) & GENMASK(31, 3)) +struct intel_pmt_header { + u32 base_offset; + u32 size; + u32 guid; + u8 access_type; +}; + struct intel_pmt_entry { + struct intel_pmt_header header; struct bin_attribute pmt_bin_attr; struct kobject *kobj; void __iomem *disc_table; @@ -29,19 +37,11 @@ struct intel_pmt_entry { int devid; }; -struct intel_pmt_header { - u32 base_offset; - u32 size; - u32 guid; - u8 access_type; -}; - struct intel_pmt_namespace { const char *name; struct xarray *xa; const struct attribute_group *attr_grp; int (*pmt_header_decode)(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, struct device *dev); }; diff --git a/drivers/platform/x86/intel_pmt_crashlog.c b/drivers/platform/x86/intel_pmt_crashlog.c index c552956736af..bd138952db32 100644 --- a/drivers/platform/x86/intel_pmt_crashlog.c +++ b/drivers/platform/x86/intel_pmt_crashlog.c @@ -223,10 +223,10 @@ static const struct attribute_group pmt_crashlog_group = { }; static int pmt_crashlog_header_decode(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, struct device *dev) { void __iomem *disc_table = entry->disc_table; + struct intel_pmt_header *header = &entry->header; struct crashlog_entry *crashlog; if (!pmt_crashlog_supported(entry)) diff --git a/drivers/platform/x86/intel_pmt_telemetry.c b/drivers/platform/x86/intel_pmt_telemetry.c index 6829544f0eba..439016bb9694 100644 --- a/drivers/platform/x86/intel_pmt_telemetry.c +++ b/drivers/platform/x86/intel_pmt_telemetry.c @@ -58,10 +58,10 @@ static bool pmt_telem_region_overlaps(struct intel_pmt_entry *entry, } static int pmt_telem_header_decode(struct intel_pmt_entry *entry, - struct intel_pmt_header *header, struct device *dev) { void __iomem *disc_table = entry->disc_table; + struct intel_pmt_header *header = &entry->header; if (pmt_telem_region_overlaps(entry, dev)) return 1; -- Gitee From 6933a84392a9c298947a6886996bab85bdc93e67 Mon Sep 17 00:00:00 2001 From: "David E. Box" Date: Wed, 29 Nov 2023 14:21:22 -0800 Subject: [PATCH 17/17] platform/x86/intel/pmt: telemetry: Export API to read telemetry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mainline inclusion from mainline-v6.8 commit 416eeb2e1fc7b60ab0c7ced26ab966dd7733357d category: bugfix bugzilla: https://gitee.com/openeuler/intel-kernel/issues/IB6QCG CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=416eeb2e1fc7b60ab0c7ced26ab966dd7733357d ------------------------------------------------- Intel-SIG: commit 416eeb2e1fc7 platform/x86/intel/pmt: telemetry: Export API to read telemetry. Backport intel tpmi base driver update for 5.10 Export symbols to allow access to Intel PMT Telemetry data on available devices. Provides APIs to search, register, and read telemetry using a kref managed pointer that serves as a handle to a telemetry endpoint. To simplify searching for present devices, have the IDA start at 1 instead of 0 so that 0 can be used to indicate end of search. Signed-off-by: David E. Box Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20231129222132.2331261-11-david.e.box@linux.intel.com Signed-off-by: Hans de Goede [ Yingbao Jia: amend commit log ] Signed-off-by: Yingbao Jia --- drivers/platform/x86/intel_pmt_class.c | 21 ++- drivers/platform/x86/intel_pmt_class.h | 14 ++ drivers/platform/x86/intel_pmt_telemetry.c | 191 ++++++++++++++++++++- drivers/platform/x86/intel_pmt_telemetry.h | 126 ++++++++++++++ 4 files changed, 344 insertions(+), 8 deletions(-) create mode 100644 drivers/platform/x86/intel_pmt_telemetry.h diff --git a/drivers/platform/x86/intel_pmt_class.c b/drivers/platform/x86/intel_pmt_class.c index 968606a277c6..817983521ab5 100644 --- a/drivers/platform/x86/intel_pmt_class.c +++ b/drivers/platform/x86/intel_pmt_class.c @@ -16,7 +16,7 @@ #include "intel_vsec.h" #include "intel_pmt_class.h" -#define PMT_XA_START 0 +#define PMT_XA_START 1 #define PMT_XA_MAX INT_MAX #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) #define GUID_SPR_PUNIT 0x9956f43f @@ -246,6 +246,7 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry, struct intel_pmt_namespace *ns, struct device *parent) { + struct intel_vsec_device *ivdev = dev_to_ivdev(parent); struct resource res = {0}; struct device *dev; int ret; @@ -269,7 +270,7 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry, if (ns->attr_grp) { ret = sysfs_create_group(entry->kobj, ns->attr_grp); if (ret) - goto fail_sysfs; + goto fail_sysfs_create_group; } /* if size is 0 assume no data buffer, so no file needed */ @@ -294,13 +295,23 @@ static int intel_pmt_dev_register(struct intel_pmt_entry *entry, entry->pmt_bin_attr.size = entry->size; ret = sysfs_create_bin_file(&dev->kobj, &entry->pmt_bin_attr); - if (!ret) - return 0; + if (ret) + goto fail_ioremap; + + if (ns->pmt_add_endpoint) { + ret = ns->pmt_add_endpoint(entry, ivdev->pcidev); + if (ret) + goto fail_add_endpoint; + } + + return 0; +fail_add_endpoint: + sysfs_remove_bin_file(entry->kobj, &entry->pmt_bin_attr); fail_ioremap: if (ns->attr_grp) sysfs_remove_group(entry->kobj, ns->attr_grp); -fail_sysfs: +fail_sysfs_create_group: device_unregister(dev); fail_dev_create: xa_erase(ns->xa, entry->devid); diff --git a/drivers/platform/x86/intel_pmt_class.h b/drivers/platform/x86/intel_pmt_class.h index 20024190ef43..3640ceb03e36 100644 --- a/drivers/platform/x86/intel_pmt_class.h +++ b/drivers/platform/x86/intel_pmt_class.h @@ -9,6 +9,7 @@ #include #include "intel_vsec.h" +#include "intel_pmt_telemetry.h" /* PMT access types */ #define ACCESS_BARID 2 @@ -18,6 +19,16 @@ #define GET_BIR(v) ((v) & GENMASK(2, 0)) #define GET_ADDRESS(v) ((v) & GENMASK(31, 3)) +struct pci_dev; + +struct telem_endpoint { + struct pci_dev *pcidev; + struct telem_header header; + void __iomem *base; + bool present; + struct kref kref; +}; + struct intel_pmt_header { u32 base_offset; u32 size; @@ -26,6 +37,7 @@ struct intel_pmt_header { }; struct intel_pmt_entry { + struct telem_endpoint *ep; struct intel_pmt_header header; struct bin_attribute pmt_bin_attr; struct kobject *kobj; @@ -43,6 +55,8 @@ struct intel_pmt_namespace { const struct attribute_group *attr_grp; int (*pmt_header_decode)(struct intel_pmt_entry *entry, struct device *dev); + int (*pmt_add_endpoint)(struct intel_pmt_entry *entry, + struct pci_dev *pdev); }; bool intel_pmt_is_early_client_hw(struct device *dev); diff --git a/drivers/platform/x86/intel_pmt_telemetry.c b/drivers/platform/x86/intel_pmt_telemetry.c index 439016bb9694..11f3957577f5 100644 --- a/drivers/platform/x86/intel_pmt_telemetry.c +++ b/drivers/platform/x86/intel_pmt_telemetry.c @@ -30,6 +30,15 @@ /* Used by client hardware to identify a fixed telemetry entry*/ #define TELEM_CLIENT_FIXED_BLOCK_GUID 0x10000000 +#define NUM_BYTES_QWORD(v) ((v) << 3) +#define SAMPLE_ID_OFFSET(v) ((v) << 3) + +#define NUM_BYTES_DWORD(v) ((v) << 2) +#define SAMPLE_ID_OFFSET32(v) ((v) << 2) + +/* Protects access to the xarray of telemetry endpoint handles */ +static DEFINE_MUTEX(ep_lock); + enum telem_type { TELEM_TYPE_PUNIT = 0, TELEM_TYPE_CRASHLOG, @@ -84,21 +93,195 @@ static int pmt_telem_header_decode(struct intel_pmt_entry *entry, return 0; } +static int pmt_telem_add_endpoint(struct intel_pmt_entry *entry, + struct pci_dev *pdev) +{ + struct telem_endpoint *ep; + + /* Endpoint lifetimes are managed by kref, not devres */ + entry->ep = kzalloc(sizeof(*(entry->ep)), GFP_KERNEL); + if (!entry->ep) + return -ENOMEM; + + ep = entry->ep; + ep->pcidev = pdev; + ep->header.access_type = entry->header.access_type; + ep->header.guid = entry->header.guid; + ep->header.base_offset = entry->header.base_offset; + ep->header.size = entry->header.size; + ep->base = entry->base; + ep->present = true; + + kref_init(&ep->kref); + + return 0; +} + static DEFINE_XARRAY_ALLOC(telem_array); static struct intel_pmt_namespace pmt_telem_ns = { .name = "telem", .xa = &telem_array, .pmt_header_decode = pmt_telem_header_decode, + .pmt_add_endpoint = pmt_telem_add_endpoint, }; +/* Called when all users unregister and the device is removed */ +static void pmt_telem_ep_release(struct kref *kref) +{ + struct telem_endpoint *ep; + + ep = container_of(kref, struct telem_endpoint, kref); + kfree(ep); +} + +unsigned long pmt_telem_get_next_endpoint(unsigned long start) +{ + struct intel_pmt_entry *entry; + unsigned long found_idx; + + mutex_lock(&ep_lock); + xa_for_each_start(&telem_array, found_idx, entry, start) { + /* + * Return first found index after start. + * 0 is not valid id. + */ + if (found_idx > start) + break; + } + mutex_unlock(&ep_lock); + + return found_idx == start ? 0 : found_idx; +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_get_next_endpoint, INTEL_PMT_TELEMETRY); + +struct telem_endpoint *pmt_telem_register_endpoint(int devid) +{ + struct intel_pmt_entry *entry; + unsigned long index = devid; + + mutex_lock(&ep_lock); + entry = xa_find(&telem_array, &index, index, XA_PRESENT); + if (!entry) { + mutex_unlock(&ep_lock); + return ERR_PTR(-ENXIO); + } + + kref_get(&entry->ep->kref); + mutex_unlock(&ep_lock); + + return entry->ep; +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_register_endpoint, INTEL_PMT_TELEMETRY); + +void pmt_telem_unregister_endpoint(struct telem_endpoint *ep) +{ + kref_put(&ep->kref, pmt_telem_ep_release); +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_unregister_endpoint, INTEL_PMT_TELEMETRY); + +int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info) +{ + struct intel_pmt_entry *entry; + unsigned long index = devid; + int err = 0; + + if (!info) + return -EINVAL; + + mutex_lock(&ep_lock); + entry = xa_find(&telem_array, &index, index, XA_PRESENT); + if (!entry) { + err = -ENXIO; + goto unlock; + } + + info->pdev = entry->ep->pcidev; + info->header = entry->ep->header; + +unlock: + mutex_unlock(&ep_lock); + return err; + +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_get_endpoint_info, INTEL_PMT_TELEMETRY); + +int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count) +{ + u32 offset, size; + + if (!ep->present) + return -ENODEV; + + offset = SAMPLE_ID_OFFSET(id); + size = ep->header.size; + + if (offset + NUM_BYTES_QWORD(count) > size) + return -EINVAL; + + memcpy_fromio(data, ep->base + offset, NUM_BYTES_QWORD(count)); + + return ep->present ? 0 : -EPIPE; +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_read, INTEL_PMT_TELEMETRY); + +int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count) +{ + u32 offset, size; + + if (!ep->present) + return -ENODEV; + + offset = SAMPLE_ID_OFFSET32(id); + size = ep->header.size; + + if (offset + NUM_BYTES_DWORD(count) > size) + return -EINVAL; + + memcpy_fromio(data, ep->base + offset, NUM_BYTES_DWORD(count)); + + return ep->present ? 0 : -EPIPE; +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_read32, INTEL_PMT_TELEMETRY); + +struct telem_endpoint * +pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, u32 guid, u16 pos) +{ + int devid = 0; + int inst = 0; + int err = 0; + + while ((devid = pmt_telem_get_next_endpoint(devid))) { + struct telem_endpoint_info ep_info; + + err = pmt_telem_get_endpoint_info(devid, &ep_info); + if (err) + return ERR_PTR(err); + + if (ep_info.header.guid == guid && ep_info.pdev == pcidev) { + if (inst == pos) + return pmt_telem_register_endpoint(devid); + ++inst; + } + } + + return ERR_PTR(-ENXIO); +} +EXPORT_SYMBOL_NS_GPL(pmt_telem_find_and_register_endpoint, INTEL_PMT_TELEMETRY); + static void pmt_telem_remove(struct auxiliary_device *auxdev) { struct pmt_telem_priv *priv = auxiliary_get_drvdata(auxdev); int i; - for (i = 0; i < priv->num_entries; i++) - intel_pmt_dev_destroy(&priv->entry[i], &pmt_telem_ns); -} + mutex_lock(&ep_lock); + for (i = 0; i < priv->num_entries; i++) { + struct intel_pmt_entry *entry = &priv->entry[i]; + + kref_put(&entry->ep->kref, pmt_telem_ep_release); + intel_pmt_dev_destroy(entry, &pmt_telem_ns); + } + mutex_unlock(&ep_lock); +}; static int pmt_telem_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id) { @@ -117,7 +300,9 @@ static int pmt_telem_probe(struct auxiliary_device *auxdev, const struct auxilia for (i = 0; i < intel_vsec_dev->num_resources; i++) { struct intel_pmt_entry *entry = &priv->entry[priv->num_entries]; + mutex_lock(&ep_lock); ret = intel_pmt_dev_create(entry, &pmt_telem_ns, intel_vsec_dev, i); + mutex_unlock(&ep_lock); if (ret < 0) goto abort_probe; if (ret) diff --git a/drivers/platform/x86/intel_pmt_telemetry.h b/drivers/platform/x86/intel_pmt_telemetry.h new file mode 100644 index 000000000000..d45af5512b4e --- /dev/null +++ b/drivers/platform/x86/intel_pmt_telemetry.h @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _TELEMETRY_H +#define _TELEMETRY_H + +/* Telemetry types */ +#define PMT_TELEM_TELEMETRY 0 +#define PMT_TELEM_CRASHLOG 1 + +struct telem_endpoint; +struct pci_dev; + +struct telem_header { + u8 access_type; + u16 size; + u32 guid; + u32 base_offset; +}; + +struct telem_endpoint_info { + struct pci_dev *pdev; + struct telem_header header; +}; + +/** + * pmt_telem_get_next_endpoint() - Get next device id for a telemetry endpoint + * @start: starting devid to look from + * + * This functions can be used in a while loop predicate to retrieve the devid + * of all available telemetry endpoints. Functions pmt_telem_get_next_endpoint() + * and pmt_telem_register_endpoint() can be used inside of the loop to examine + * endpoint info and register to receive a pointer to the endpoint. The pointer + * is then usable in the telemetry read calls to access the telemetry data. + * + * Return: + * * devid - devid of the next present endpoint from start + * * 0 - when no more endpoints are present after start + */ +unsigned long pmt_telem_get_next_endpoint(unsigned long start); + +/** + * pmt_telem_register_endpoint() - Register a telemetry endpoint + * @devid: device id/handle of the telemetry endpoint + * + * Increments the kref usage counter for the endpoint. + * + * Return: + * * endpoint - On success returns pointer to the telemetry endpoint + * * -ENXIO - telemetry endpoint not found + */ +struct telem_endpoint *pmt_telem_register_endpoint(int devid); + +/** + * pmt_telem_unregister_endpoint() - Unregister a telemetry endpoint + * @ep: ep structure to populate. + * + * Decrements the kref usage counter for the endpoint. + */ +void pmt_telem_unregister_endpoint(struct telem_endpoint *ep); + +/** + * pmt_telem_get_endpoint_info() - Get info for an endpoint from its devid + * @devid: device id/handle of the telemetry endpoint + * @info: Endpoint info structure to be populated + * + * Return: + * * 0 - Success + * * -ENXIO - telemetry endpoint not found for the devid + * * -EINVAL - @info is NULL + */ +int pmt_telem_get_endpoint_info(int devid, struct telem_endpoint_info *info); + +/** + * pmt_telem_find_and_register_endpoint() - Get a telemetry endpoint from + * pci_dev device, guid and pos + * @pdev: PCI device inside the Intel vsec + * @guid: GUID of the telemetry space + * @pos: Instance of the guid + * + * Return: + * * endpoint - On success returns pointer to the telemetry endpoint + * * -ENXIO - telemetry endpoint not found + */ +struct telem_endpoint *pmt_telem_find_and_register_endpoint(struct pci_dev *pcidev, + u32 guid, u16 pos); + +/** + * pmt_telem_read() - Read qwords from counter sram using sample id + * @ep: Telemetry endpoint to be read + * @id: The beginning sample id of the metric(s) to be read + * @data: Allocated qword buffer + * @count: Number of qwords requested + * + * Callers must ensure reads are aligned. When the call returns -ENODEV, + * the device has been removed and callers should unregister the telemetry + * endpoint. + * + * Return: + * * 0 - Success + * * -ENODEV - The device is not present. + * * -EINVAL - The offset is out bounds + * * -EPIPE - The device was removed during the read. Data written + * but should be considered invalid. + */ +int pmt_telem_read(struct telem_endpoint *ep, u32 id, u64 *data, u32 count); + +/** + * pmt_telem_read32() - Read qwords from counter sram using sample id + * @ep: Telemetry endpoint to be read + * @id: The beginning sample id of the metric(s) to be read + * @data: Allocated dword buffer + * @count: Number of dwords requested + * + * Callers must ensure reads are aligned. When the call returns -ENODEV, + * the device has been removed and callers should unregister the telemetry + * endpoint. + * + * Return: + * * 0 - Success + * * -ENODEV - The device is not present. + * * -EINVAL - The offset is out bounds + * * -EPIPE - The device was removed during the read. Data written + * but should be considered invalid. + */ +int pmt_telem_read32(struct telem_endpoint *ep, u32 id, u32 *data, u32 count); + +#endif -- Gitee