* [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids
@ 2026-10-26 18:38 Ehab Ababneh
2026-10-26 18:38 ` [PATCH 01/17] platform/x86/intel/ifs: Revert SBAF feature Ehab Ababneh
` (16 more replies)
0 siblings, 17 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
Some Intel Xeon processors, starting with Diamond Rapids (DMR), share
one SCAN test engine between multiple CPU cores in a module (Dual-Core
Module, DCM), instead of only between the threads of a single core. All
logical processors that share an engine must start the In-Field Scan
(IFS) test at the same time. The current driver assumes the sharing
domain is cpu_smt_mask(), which does not hold on these systems. Also,
although the cores in a module are tested together, each core gets its
own result: on a DCM, one core can pass while the other fails.
This series:
- Patch 1 removes the SBAF test, which is not planned for any CPU and
whose test images were never published.
- Patches 2-6 are cleanups and preparatory refactoring (comment fixes,
clearer MSR bit names, u64 MSR bitfields, early return on image
errors, a generic Array BIST parameter struct). Patches 2-4 have no
functional change.
- Patch 7 adds stop_cluster_cpuslocked(), the cluster-level counterpart
of stop_core_cpuslocked(), so that all threads of a cluster can
rendezvous and issue WRMSR at the same time.
- Patches 8-10 enumerate ALL_LP_JOIN_NEEDED, select the CPUs to test
together from topology_cluster_cpumask(), and check at driver init
that TID_BIT_SHIFT matches that mask.
- Patches 11-13 record per-CPU results for group tests and expose them
through new sysfs files (status_list, details_list, cpus_ran_list,
addnl_details_list). The existing status and details files remain,
but now report the result of the CPU written to run_test rather than
the first CPU in the group.
- Patch 14 adds Diamond Rapids to the CPU match table.
- Patch 15 removes the 256 limit on the batch file number.
- Patches 16-17 update the IFS documentation and ABI document.
Most of this series was developed by Jithu Joseph and Qiuxu Zhuo, who
have both since left Intel. I have taken over upstreaming it, so please
send questions and review comments to me. The patches keep their
original authorship and Signed-off-by tags. Where Qiuxu changed a patch
written by someone else, the change is noted in brackets in the commit
message, and I have added my Signed-off-by to every patch.
Jithu Joseph (7):
platform/x86/intel/ifs: Refactor Array BIST function interface
platform/x86/intel/ifs: Enumerate the bit to determine if CPUs need to
join for IFS tests
platform/x86/intel/ifs: Select CPUs from topology_cluster_cpumask()
for simultaneous IFS tests
platform/x86/intel/ifs: Track and report scan results on a per-CPU
basis
platform/x86/intel/ifs: Add new sysfs interfaces {status, details,
cpus_ran}_list
platform/x86/intel/ifs: Add additional details sysfs interface
platform/x86/intel/ifs: Add Intel Diamond Rapids server support
Qiuxu Zhuo (9):
platform/x86/intel/ifs: Revert SBAF feature
platform/x86/intel/ifs: Fix IFS sysfs interfaces in the comments
platform/x86/intel/ifs: Clarify In-Field Scan MSR bit macro
definitions
platform/x86/intel/ifs: Use u64 to define the bits of IFS MSR
registers
platform/x86/intel/ifs: Early return on the IFS image hash/chunk error
stop_machine: Add stop_cluster_cpuslocked() for per-cluster operations
platform/x86/intel/ifs: Validate TID_BIT_SHIFT matches
topology_cluster_cpumask()
platform/x86/intel/ifs: Update IFS documentation
Documentation/ABI: Update IFS ABI doc
Tony Luck (1):
platform/x86/intel/ifs: Remove limit on number of batch files
.../ABI/testing/sysfs-platform-intel-ifs | 28 +-
arch/x86/include/asm/msr-index.h | 17 +-
drivers/platform/x86/intel/ifs/core.c | 97 +++--
drivers/platform/x86/intel/ifs/ifs.h | 223 +++++-----
drivers/platform/x86/intel/ifs/load.c | 52 +--
drivers/platform/x86/intel/ifs/runtest.c | 394 ++++++------------
drivers/platform/x86/intel/ifs/sysfs.c | 104 ++++-
include/linux/stop_machine.h | 15 +
include/trace/events/intel_ifs.h | 27 --
kernel/stop_machine.c | 35 +-
tools/arch/x86/include/asm/msr-index.h | 14 +-
11 files changed, 487 insertions(+), 519 deletions(-)
base-commit: 98f039265e580291d5e76a11b2072541fbb1c393
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 01/17] platform/x86/intel/ifs: Revert SBAF feature
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 02/17] platform/x86/intel/ifs: Fix IFS sysfs interfaces in the comments Ehab Ababneh
` (15 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Structural Based Functional Test at Field (SBAF) test was initially
expected to be supported in Granite Rapids (GNR) CPUs. However, due to
recent roadmap changes, the SBAF test support will not be included in
GNR and is unlikely to be included in future CPUs.
Additionally, Intel has never published the SBAF scan files, and the
SBAF feature and its interface [1] are not utilized. Therefore, it's
safe to remove them. Given this, remove the SBAF test from the In-Field
Scan (IFS) driver by reverting the following commits:
commit 1e701372d7ac ("platform/x86/intel/ifs: Fix SBAF title underline length")
commit 61b74964536e ("trace: platform/x86/intel/ifs: Add SBAF trace support")
commit 3c4d06bd6e37 ("platform/x86/intel/ifs: Add SBAF test support")
commit 0a3e4e94d137 ("platform/x86/intel/ifs: Add SBAF test image loading support")
commit 744a6a1f2a83 ("tools arch x86: Sync the msr-index.h copy with the kernel sources")
[1] /sys/devices/virtual/misc/intel_ifs_2
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
arch/x86/include/asm/msr-index.h | 2 -
drivers/platform/x86/intel/ifs/core.c | 24 ---
drivers/platform/x86/intel/ifs/ifs.h | 65 +------
drivers/platform/x86/intel/ifs/load.c | 16 +-
drivers/platform/x86/intel/ifs/runtest.c | 233 -----------------------
include/trace/events/intel_ifs.h | 27 ---
tools/arch/x86/include/asm/msr-index.h | 2 -
7 files changed, 5 insertions(+), 364 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 3a8e51a0c9e8..ac73dadb44e0 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -280,8 +280,6 @@
#define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_SBAF_BIT 8
-#define MSR_INTEGRITY_CAPS_SBAF BIT(MSR_INTEGRITY_CAPS_SBAF_BIT)
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
#define MSR_LBR_NHM_FROM 0x00000680
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index 3dafa28a1010..574f2a366d06 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -34,7 +34,6 @@ bool *ifs_pkg_auth;
static const struct ifs_test_caps scan_test = {
.integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
.test_num = IFS_TYPE_SAF,
- .image_suffix = "scan",
};
static const struct ifs_test_caps array_test = {
@@ -50,20 +49,6 @@ static const struct ifs_test_msrs scan_msrs = {
.test_ctrl = MSR_SAF_CTRL,
};
-static const struct ifs_test_msrs sbaf_msrs = {
- .copy_hashes = MSR_COPY_SBAF_HASHES,
- .copy_hashes_status = MSR_SBAF_HASHES_STATUS,
- .copy_chunks = MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK,
- .copy_chunks_status = MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS,
- .test_ctrl = MSR_SBAF_CTRL,
-};
-
-static const struct ifs_test_caps sbaf_test = {
- .integrity_cap_bit = MSR_INTEGRITY_CAPS_SBAF_BIT,
- .test_num = IFS_TYPE_SBAF,
- .image_suffix = "sbft",
-};
-
static struct ifs_device ifs_devices[] = {
[IFS_TYPE_SAF] = {
.test_caps = &scan_test,
@@ -82,15 +67,6 @@ static struct ifs_device ifs_devices[] = {
.groups = plat_ifs_array_groups,
},
},
- [IFS_TYPE_SBAF] = {
- .test_caps = &sbaf_test,
- .test_msrs = &sbaf_msrs,
- .misc = {
- .name = "intel_ifs_2",
- .minor = MISC_DYNAMIC_MINOR,
- .groups = plat_ifs_groups,
- },
- },
};
#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index f369fb0d3d82..f55528ac517b 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -127,38 +127,11 @@
* 2) Hardware allows for some number of cores to be tested in parallel.
* The driver does not make use of this, it only tests one core at a time.
*
- * Structural Based Functional Test at Field (SBAF):
- * -------------------------------------------------
- *
- * SBAF is a new type of testing that provides comprehensive core test
- * coverage complementing Scan at Field (SAF) testing. SBAF mimics the
- * manufacturing screening environment and leverages the same test suite.
- * It makes use of Design For Test (DFT) observation sites and features
- * to maximize coverage in minimum time.
- *
- * Similar to the SAF test, SBAF isolates the core under test from the
- * rest of the system during execution. Upon completion, the core
- * seamlessly resets to its pre-test state and resumes normal operation.
- * Any machine checks or hangs encountered during the test are confined to
- * the isolated core, preventing disruption to the overall system.
- *
- * Like the SAF test, the SBAF test is also divided into multiple batches,
- * and each batch test can take hundreds of milliseconds (100-200 ms) to
- * complete. If such a lengthy interruption is undesirable, it is
- * recommended to relocate the time-sensitive applications to other cores.
*/
#include <linux/device.h>
#include <linux/miscdevice.h>
#define MSR_ARRAY_BIST 0x00000105
-
-#define MSR_COPY_SBAF_HASHES 0x000002b8
-#define MSR_SBAF_HASHES_STATUS 0x000002b9
-#define MSR_AUTHENTICATE_AND_COPY_SBAF_CHUNK 0x000002ba
-#define MSR_SBAF_CHUNKS_AUTHENTICATION_STATUS 0x000002bb
-#define MSR_ACTIVATE_SBAF 0x000002bc
-#define MSR_SBAF_STATUS 0x000002bd
-
#define MSR_COPY_SCAN_HASHES 0x000002c2
#define MSR_SCAN_HASHES_STATUS 0x000002c3
#define MSR_AUTHENTICATE_AND_COPY_CHUNK 0x000002c4
@@ -168,7 +141,6 @@
#define MSR_ARRAY_TRIGGER 0x000002d6
#define MSR_ARRAY_STATUS 0x000002d7
#define MSR_SAF_CTRL 0x000004f0
-#define MSR_SBAF_CTRL 0x000004f8
#define SCAN_NOT_TESTED 0
#define SCAN_TEST_PASS 1
@@ -176,7 +148,6 @@
#define IFS_TYPE_SAF 0
#define IFS_TYPE_ARRAY_BIST 1
-#define IFS_TYPE_SBAF 2
#define ARRAY_GEN0 0
#define ARRAY_GEN1 1
@@ -226,8 +197,7 @@ union ifs_chunks_auth_status_gen2 {
u16 valid_chunks;
u16 total_chunks;
u32 error_code :8;
- u32 rsvd2 :8;
- u32 max_bundle :16;
+ u32 rsvd2 :24;
};
};
@@ -284,34 +254,6 @@ union ifs_array {
};
};
-/* MSR_ACTIVATE_SBAF bit fields */
-union ifs_sbaf {
- u64 data;
- struct {
- u32 bundle_idx :9;
- u32 rsvd1 :5;
- u32 pgm_idx :2;
- u32 rsvd2 :16;
- u32 delay :31;
- u32 sigmce :1;
- };
-};
-
-/* MSR_SBAF_STATUS bit fields */
-union ifs_sbaf_status {
- u64 data;
- struct {
- u32 bundle_idx :9;
- u32 rsvd1 :5;
- u32 pgm_idx :2;
- u32 rsvd2 :16;
- u32 error_code :8;
- u32 rsvd3 :21;
- u32 test_fail :1;
- u32 sbaf_status :2;
- };
-};
-
/*
* Driver populated error-codes
* 0xFD: Test timed out before completing all the chunks.
@@ -320,12 +262,9 @@ union ifs_sbaf_status {
#define IFS_SW_TIMEOUT 0xFD
#define IFS_SW_PARTIAL_COMPLETION 0xFE
-#define IFS_SUFFIX_SZ 5
-
struct ifs_test_caps {
int integrity_cap_bit;
int test_num;
- char image_suffix[IFS_SUFFIX_SZ];
};
/**
@@ -356,7 +295,6 @@ struct ifs_test_msrs {
* @generation: IFS test generation enumerated by hardware
* @chunk_size: size of a test chunk
* @array_gen: test generation of array test
- * @max_bundle: maximum bundle index
*/
struct ifs_data {
int loaded_version;
@@ -369,7 +307,6 @@ struct ifs_data {
u32 generation;
u32 chunk_size;
u32 array_gen;
- u32 max_bundle;
};
struct ifs_work {
diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c
index 50f1fdf7dfed..329400908cb2 100644
--- a/drivers/platform/x86/intel/ifs/load.c
+++ b/drivers/platform/x86/intel/ifs/load.c
@@ -262,22 +262,20 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
return -EIO;
}
ifsd->valid_chunks = valid_chunks;
- ifsd->max_bundle = chunk_status.max_bundle;
return 0;
}
static int validate_ifs_metadata(struct device *dev)
{
- const struct ifs_test_caps *test = ifs_get_test_caps(dev);
struct ifs_data *ifsd = ifs_get_data(dev);
union meta_data *ifs_meta;
char test_file[64];
int ret = -EINVAL;
- snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.%s",
+ snprintf(test_file, sizeof(test_file), "%02x-%02x-%02x-%02x.scan",
boot_cpu_data.x86, boot_cpu_data.x86_model,
- boot_cpu_data.x86_stepping, ifsd->cur_batch, test->image_suffix);
+ boot_cpu_data.x86_stepping, ifsd->cur_batch);
ifs_meta = (union meta_data *)find_meta_data(ifs_header_ptr, META_TYPE_IFS);
if (!ifs_meta) {
@@ -307,12 +305,6 @@ static int validate_ifs_metadata(struct device *dev)
return ret;
}
- if (ifs_meta->test_type != test->test_num) {
- dev_warn(dev, "Metadata test_type %d mismatches with device type\n",
- ifs_meta->test_type);
- return ret;
- }
-
return 0;
}
@@ -400,9 +392,9 @@ int ifs_load_firmware(struct device *dev)
char scan_path[64];
int ret;
- snprintf(scan_path, sizeof(scan_path), "intel/ifs_%d/%02x-%02x-%02x-%02x.%s",
+ snprintf(scan_path, sizeof(scan_path), "intel/ifs_%d/%02x-%02x-%02x-%02x.scan",
test->test_num, boot_cpu_data.x86, boot_cpu_data.x86_model,
- boot_cpu_data.x86_stepping, ifsd->cur_batch, test->image_suffix);
+ boot_cpu_data.x86_stepping, ifsd->cur_batch);
ret = request_firmware_direct(&fw, scan_path, dev);
if (ret) {
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index dfc119d7354d..1762eab7fe5c 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -30,13 +30,6 @@ struct run_params {
union ifs_status status;
};
-struct sbaf_run_params {
- struct ifs_data *ifsd;
- int *retry_cnt;
- union ifs_sbaf *activate;
- union ifs_sbaf_status status;
-};
-
/*
* Number of TSC cycles that a logical CPU will wait for the other
* logical CPU on the core in the WRMSR(ACTIVATE_SCAN).
@@ -154,7 +147,6 @@ static bool can_restart(union ifs_status status)
#define SPINUNIT 100 /* 100 nsec */
static atomic_t array_cpus_in;
static atomic_t scan_cpus_in;
-static atomic_t sbaf_cpus_in;
/*
* Simplified cpu sibling rendezvous loop based on microcode loader __wait_for_cpus()
@@ -396,225 +388,6 @@ static void ifs_array_test_gen1(int cpu, struct device *dev)
ifsd->status = SCAN_TEST_PASS;
}
-#define SBAF_STATUS_PASS 0
-#define SBAF_STATUS_SIGN_FAIL 1
-#define SBAF_STATUS_INTR 2
-#define SBAF_STATUS_TEST_FAIL 3
-
-enum sbaf_status_err_code {
- IFS_SBAF_NO_ERROR = 0,
- IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN = 1,
- IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS = 2,
- IFS_SBAF_UNASSIGNED_ERROR_CODE3 = 3,
- IFS_SBAF_INVALID_BUNDLE_INDEX = 4,
- IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS = 5,
- IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY = 6,
- IFS_SBAF_UNASSIGNED_ERROR_CODE7 = 7,
- IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT = 8,
- IFS_SBAF_INTERRUPTED_DURING_EXECUTION = 9,
- IFS_SBAF_INVALID_PROGRAM_INDEX = 0xA,
- IFS_SBAF_CORRUPTED_CHUNK = 0xB,
- IFS_SBAF_DID_NOT_START = 0xC,
-};
-
-static const char * const sbaf_test_status[] = {
- [IFS_SBAF_NO_ERROR] = "SBAF no error",
- [IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN] = "Other thread could not join.",
- [IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS] = "Interrupt occurred prior to SBAF coordination.",
- [IFS_SBAF_UNASSIGNED_ERROR_CODE3] = "Unassigned error code 0x3",
- [IFS_SBAF_INVALID_BUNDLE_INDEX] = "Non-valid sbaf bundles. Reload test image",
- [IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS] = "Mismatch in arguments between threads T0/T1.",
- [IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY] = "Core not capable of performing SBAF currently",
- [IFS_SBAF_UNASSIGNED_ERROR_CODE7] = "Unassigned error code 0x7",
- [IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT] = "Exceeded number of Logical Processors (LP) allowed to run Scan-At-Field concurrently",
- [IFS_SBAF_INTERRUPTED_DURING_EXECUTION] = "Interrupt occurred prior to SBAF start",
- [IFS_SBAF_INVALID_PROGRAM_INDEX] = "SBAF program index not valid",
- [IFS_SBAF_CORRUPTED_CHUNK] = "SBAF operation aborted due to corrupted chunk",
- [IFS_SBAF_DID_NOT_START] = "SBAF operation did not start",
-};
-
-static void sbaf_message_not_tested(struct device *dev, int cpu, u64 status_data)
-{
- union ifs_sbaf_status status = (union ifs_sbaf_status)status_data;
-
- if (status.error_code < ARRAY_SIZE(sbaf_test_status)) {
- dev_info(dev, "CPU(s) %*pbl: SBAF operation did not start. %s\n",
- cpumask_pr_args(cpu_smt_mask(cpu)),
- sbaf_test_status[status.error_code]);
- } else if (status.error_code == IFS_SW_TIMEOUT) {
- dev_info(dev, "CPU(s) %*pbl: software timeout during scan\n",
- cpumask_pr_args(cpu_smt_mask(cpu)));
- } else if (status.error_code == IFS_SW_PARTIAL_COMPLETION) {
- dev_info(dev, "CPU(s) %*pbl: %s\n",
- cpumask_pr_args(cpu_smt_mask(cpu)),
- "Not all SBAF bundles executed. Maximum forward progress retries exceeded");
- } else {
- dev_info(dev, "CPU(s) %*pbl: SBAF unknown status %llx\n",
- cpumask_pr_args(cpu_smt_mask(cpu)), status.data);
- }
-}
-
-static void sbaf_message_fail(struct device *dev, int cpu, union ifs_sbaf_status status)
-{
- /* Failed signature check is set when SBAF signature did not match the expected value */
- if (status.sbaf_status == SBAF_STATUS_SIGN_FAIL) {
- dev_err(dev, "CPU(s) %*pbl: Failed signature check\n",
- cpumask_pr_args(cpu_smt_mask(cpu)));
- }
-
- /* Failed to reach end of test */
- if (status.sbaf_status == SBAF_STATUS_TEST_FAIL) {
- dev_err(dev, "CPU(s) %*pbl: Failed to complete test\n",
- cpumask_pr_args(cpu_smt_mask(cpu)));
- }
-}
-
-static bool sbaf_bundle_completed(union ifs_sbaf_status status)
-{
- return !(status.sbaf_status || status.error_code);
-}
-
-static bool sbaf_can_restart(union ifs_sbaf_status status)
-{
- enum sbaf_status_err_code err_code = status.error_code;
-
- /* Signature for chunk is bad, or scan test failed */
- if (status.sbaf_status == SBAF_STATUS_SIGN_FAIL ||
- status.sbaf_status == SBAF_STATUS_TEST_FAIL)
- return false;
-
- switch (err_code) {
- case IFS_SBAF_NO_ERROR:
- case IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN:
- case IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS:
- case IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT:
- case IFS_SBAF_INTERRUPTED_DURING_EXECUTION:
- return true;
- case IFS_SBAF_UNASSIGNED_ERROR_CODE3:
- case IFS_SBAF_INVALID_BUNDLE_INDEX:
- case IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS:
- case IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY:
- case IFS_SBAF_UNASSIGNED_ERROR_CODE7:
- case IFS_SBAF_INVALID_PROGRAM_INDEX:
- case IFS_SBAF_CORRUPTED_CHUNK:
- case IFS_SBAF_DID_NOT_START:
- break;
- }
- return false;
-}
-
-/*
- * Execute the SBAF test. Called "simultaneously" on all threads of a core
- * at high priority using the stop_cpus mechanism.
- */
-static int dosbaf(void *data)
-{
- struct sbaf_run_params *run_params = data;
- int cpu = smp_processor_id();
- union ifs_sbaf_status status;
- struct ifs_data *ifsd;
- int first;
-
- ifsd = run_params->ifsd;
-
- /* Only the first logical CPU on a core reports result */
- first = cpumask_first(cpu_smt_mask(cpu));
- wait_for_sibling_cpu(&sbaf_cpus_in, NSEC_PER_SEC);
-
- /*
- * This WRMSR will wait for other HT threads to also write
- * to this MSR (at most for activate.delay cycles). Then it
- * starts scan of each requested bundle. The core test happens
- * during the "execution" of the WRMSR.
- */
- wrmsrq(MSR_ACTIVATE_SBAF, run_params->activate->data);
- rdmsrq(MSR_SBAF_STATUS, status.data);
- trace_ifs_sbaf(ifsd->cur_batch, *run_params->activate, status);
-
- /* Pass back the result of the test */
- if (cpu == first)
- run_params->status = status;
-
- return 0;
-}
-
-static void ifs_sbaf_test_core(int cpu, struct device *dev)
-{
- struct sbaf_run_params run_params;
- union ifs_sbaf_status status = {};
- union ifs_sbaf activate;
- unsigned long timeout;
- struct ifs_data *ifsd;
- int stop_bundle;
- int retries;
-
- ifsd = ifs_get_data(dev);
-
- activate.data = 0;
- activate.delay = IFS_THREAD_WAIT;
-
- timeout = jiffies + 2 * HZ;
- retries = MAX_IFS_RETRIES;
- activate.bundle_idx = 0;
- stop_bundle = ifsd->max_bundle;
-
- while (activate.bundle_idx <= stop_bundle) {
- if (time_after(jiffies, timeout)) {
- status.error_code = IFS_SW_TIMEOUT;
- break;
- }
-
- atomic_set(&sbaf_cpus_in, 0);
-
- run_params.ifsd = ifsd;
- run_params.activate = &activate;
- run_params.retry_cnt = &retries;
- stop_core_cpuslocked(cpu, dosbaf, &run_params);
-
- status = run_params.status;
-
- if (sbaf_bundle_completed(status)) {
- activate.bundle_idx = status.bundle_idx + 1;
- activate.pgm_idx = 0;
- retries = MAX_IFS_RETRIES;
- continue;
- }
-
- /* Some cases can be retried, give up for others */
- if (!sbaf_can_restart(status))
- break;
-
- if (status.pgm_idx == activate.pgm_idx) {
- /* If no progress retry */
- if (--retries == 0) {
- if (status.error_code == IFS_NO_ERROR)
- status.error_code = IFS_SW_PARTIAL_COMPLETION;
- break;
- }
- } else {
- /* if some progress, more pgms remaining in bundle, reset retries */
- retries = MAX_IFS_RETRIES;
- activate.bundle_idx = status.bundle_idx;
- activate.pgm_idx = status.pgm_idx;
- }
- }
-
- /* Update status for this core */
- ifsd->scan_details = status.data;
-
- if (status.sbaf_status == SBAF_STATUS_SIGN_FAIL ||
- status.sbaf_status == SBAF_STATUS_TEST_FAIL) {
- ifsd->status = SCAN_TEST_FAIL;
- sbaf_message_fail(dev, cpu, status);
- } else if (status.error_code || status.sbaf_status == SBAF_STATUS_INTR ||
- (activate.bundle_idx < stop_bundle)) {
- ifsd->status = SCAN_NOT_TESTED;
- sbaf_message_not_tested(dev, cpu, status.data);
- } else {
- ifsd->status = SCAN_TEST_PASS;
- }
-}
-
/*
* Initiate per core test. It wakes up work queue threads on the target cpu and
* its sibling cpu. Once all sibling threads wake up, the scan test gets executed and
@@ -648,12 +421,6 @@ int do_core_test(int cpu, struct device *dev)
else
ifs_array_test_gen1(cpu, dev);
break;
- case IFS_TYPE_SBAF:
- if (!ifsd->loaded)
- ret = -EPERM;
- else
- ifs_sbaf_test_core(cpu, dev);
- break;
default:
ret = -EINVAL;
}
diff --git a/include/trace/events/intel_ifs.h b/include/trace/events/intel_ifs.h
index 70323acde1de..0d88ebf2c980 100644
--- a/include/trace/events/intel_ifs.h
+++ b/include/trace/events/intel_ifs.h
@@ -35,33 +35,6 @@ TRACE_EVENT(ifs_status,
__entry->status)
);
-TRACE_EVENT(ifs_sbaf,
-
- TP_PROTO(int batch, union ifs_sbaf activate, union ifs_sbaf_status status),
-
- TP_ARGS(batch, activate, status),
-
- TP_STRUCT__entry(
- __field( u64, status )
- __field( int, batch )
- __field( u16, bundle )
- __field( u16, pgm )
- ),
-
- TP_fast_assign(
- __entry->status = status.data;
- __entry->batch = batch;
- __entry->bundle = activate.bundle_idx;
- __entry->pgm = activate.pgm_idx;
- ),
-
- TP_printk("batch: 0x%.2x, bundle_idx: 0x%.4x, pgm_idx: 0x%.4x, status: 0x%.16llx",
- __entry->batch,
- __entry->bundle,
- __entry->pgm,
- __entry->status)
-);
-
#endif /* _TRACE_IFS_H */
/* This part must be outside protection */
diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
index 18c4be75e927..d70f160425a2 100644
--- a/tools/arch/x86/include/asm/msr-index.h
+++ b/tools/arch/x86/include/asm/msr-index.h
@@ -280,8 +280,6 @@
#define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_SBAF_BIT 8
-#define MSR_INTEGRITY_CAPS_SBAF BIT(MSR_INTEGRITY_CAPS_SBAF_BIT)
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
#define MSR_LBR_NHM_FROM 0x00000680
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 02/17] platform/x86/intel/ifs: Fix IFS sysfs interfaces in the comments
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
2026-10-26 18:38 ` [PATCH 01/17] platform/x86/intel/ifs: Revert SBAF feature Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 03/17] platform/x86/intel/ifs: Clarify In-Field Scan MSR bit macro definitions Ehab Ababneh
` (14 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
The sysfs interfaces in the comments in sysfs.c are incorrect. Fix them.
Additionally, improve some IFS comments and fix some typos in the comments
such as: s/cpu/CPU, s/intel/Intel, s/ifs/IFS.
No functional changes.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/ifs.h | 16 ++++++++--------
drivers/platform/x86/intel/ifs/load.c | 2 +-
drivers/platform/x86/intel/ifs/runtest.c | 8 ++++----
drivers/platform/x86/intel/ifs/sysfs.c | 23 +++++++++++------------
4 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index f55528ac517b..0f5cdc1ad14d 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -35,10 +35,10 @@
* IFS Image Loading
* -----------------
*
- * The driver loads the tests into memory reserved BIOS local to each CPU
- * socket in a two step process using writes to MSRs to first load the
- * SHA hashes for the test. Then the tests themselves. Status MSRs provide
- * feedback on the success/failure of these steps.
+ * The driver loads the tests into memory reserved by BIOS, local to each CPU
+ * socket in a two-step process. It first writes to MSRs to load the SHA hashes
+ * for the test, followed by the tests themselves. Status MSRs provide feedback
+ * on the success or failure of these steps.
*
* The test files are kept in a fixed location: /lib/firmware/intel/ifs_<n>/
* For e.g if there are 3 test files, they would be named in the following
@@ -83,14 +83,14 @@
*
* Test a specific core::
*
- * # echo <cpu#> > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
+ * # echo <CPU#> > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
*
- * when HT is enabled any of the sibling cpu# can be specified to test
+ * when HT is enabled any of the sibling CPU# can be specified to test
* its corresponding physical core. Since the tests are per physical core,
* the result of testing any thread is same. All siblings must be online
* to run a core test. It is only necessary to test one thread.
*
- * For e.g. to test core corresponding to cpu5
+ * For e.g. to test core corresponding to CPU5
*
* # echo 5 > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
*
@@ -284,7 +284,7 @@ struct ifs_test_msrs {
};
/**
- * struct ifs_data - attributes related to intel IFS driver
+ * struct ifs_data - attributes related to Intel IFS driver
* @loaded_version: stores the currently loaded ifs image version.
* @loaded: If a valid test binary has been loaded into the memory
* @loading_error: Error occurred on another CPU while loading image
diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c
index 329400908cb2..dde3f5eb379f 100644
--- a/drivers/platform/x86/intel/ifs/load.c
+++ b/drivers/platform/x86/intel/ifs/load.c
@@ -108,7 +108,7 @@ static void auth_err_message(struct device *dev, u32 err_code)
}
/*
- * To copy scan hashes and authenticate test chunks, the initiating cpu must point
+ * To copy scan hashes and authenticate test chunks, the initiating CPU must point
* to the EDX:EAX to the test image in linear address.
* Run wrmsr(MSR_COPY_SCAN_HASHES) for scan hash copy and run wrmsr(MSR_AUTHENTICATE_AND_COPY_CHUNK)
* for scan hash copy and test chunk authentication.
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index 1762eab7fe5c..96b538c665f4 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -149,7 +149,7 @@ static atomic_t array_cpus_in;
static atomic_t scan_cpus_in;
/*
- * Simplified cpu sibling rendezvous loop based on microcode loader __wait_for_cpus()
+ * Simplified CPU sibling rendezvous loop based on microcode loader wait_for_cpus()
*/
static void wait_for_sibling_cpu(atomic_t *t, long long timeout)
{
@@ -389,8 +389,8 @@ static void ifs_array_test_gen1(int cpu, struct device *dev)
}
/*
- * Initiate per core test. It wakes up work queue threads on the target cpu and
- * its sibling cpu. Once all sibling threads wake up, the scan test gets executed and
+ * Initiate per core test. It wakes up work queue threads on the target CPU and
+ * its sibling CPU. Once all sibling threads wake up, the scan test gets executed and
* wait for all sibling threads to finish the scan test.
*/
int do_core_test(int cpu, struct device *dev)
@@ -403,7 +403,7 @@ int do_core_test(int cpu, struct device *dev)
cpus_read_lock();
if (!cpu_online(cpu)) {
- dev_info(dev, "cannot test on the offline cpu %d\n", cpu);
+ dev_info(dev, "cannot test on the offline CPU %d\n", cpu);
ret = -EINVAL;
goto out;
}
diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/intel/ifs/sysfs.c
index 01b7502f46b0..287f96bb033e 100644
--- a/drivers/platform/x86/intel/ifs/sysfs.c
+++ b/drivers/platform/x86/intel/ifs/sysfs.c
@@ -10,14 +10,14 @@
#include "ifs.h"
/*
- * Protects against simultaneous tests on multiple cores, or
- * reloading can file while a test is in progress
+ * Protect against simultaneous tests on multiple cores and prevent
+ * the reloading of IFS image file while a test is in progress.
*/
static DEFINE_SEMAPHORE(ifs_sem, 1);
/*
- * The sysfs interface to check additional details of last test
- * cat /sys/devices/system/platform/ifs/details
+ * The sysfs interface to check additional details of the last test:
+ * cat /sys/devices/virtual/misc/intel_ifs_<n>/details
*/
static ssize_t details_show(struct device *dev,
struct device_attribute *attr,
@@ -37,9 +37,8 @@ static const char * const status_msg[] = {
};
/*
- * The sysfs interface to check the test status:
- * To check the status of last test
- * cat /sys/devices/platform/ifs/status
+ * The sysfs interface to check the last test status:
+ * cat /sys/devices/virtual/misc/intel_ifs_<n>/status
*/
static ssize_t status_show(struct device *dev,
struct device_attribute *attr,
@@ -53,12 +52,12 @@ static ssize_t status_show(struct device *dev,
static DEVICE_ATTR_RO(status);
/*
- * The sysfs interface for single core testing
- * To start test, for example, cpu5
- * echo 5 > /sys/devices/platform/ifs/run_test
+ * The sysfs interface for single-core testing.
+ * To start a test, for example on CPU5:
+ * echo 5 > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
* To check the result:
- * cat /sys/devices/platform/ifs/result
- * The sibling core gets tested at the same time.
+ * cat /sys/devices/virtual/misc/intel_ifs_<n>/status
+ * The sibling thread gets tested at the same time.
*/
static ssize_t run_test_store(struct device *dev,
struct device_attribute *attr,
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 03/17] platform/x86/intel/ifs: Clarify In-Field Scan MSR bit macro definitions
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
2026-10-26 18:38 ` [PATCH 01/17] platform/x86/intel/ifs: Revert SBAF feature Ehab Ababneh
2026-10-26 18:38 ` [PATCH 02/17] platform/x86/intel/ifs: Fix IFS sysfs interfaces in the comments Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 04/17] platform/x86/intel/ifs: Use u64 to define the bits of IFS MSR registers Ehab Ababneh
` (13 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Current macros for Intel In-Field Scan MSR bits are confusing. They don't
clearly distinguish between testing types (Scan At Field vs. Array BIST)
or testing timing (processor startup vs. Linux Intel IFS driver at
runtime).
Clarify these macros by adopting the naming convention from [1]:
- PERIODIC (vs. STARTUP) indicates testing capability at runtime.
- SCAN_BIST indicates Scan At Field testing capability.
- ARRAY_BIST indicates Array BIST testing capability [2].
Additionally, align these macros vertically for better readability.
No functional changes.
[1] Intel 64 and IA-32 Architectures Software Developer's Manual (SDM),
Vol. 4, "Additional MSRs Supported by the Intel Xeon 6 P-Core
Processors".
[2] Use ARRAY_BIST instead of MEM_BIST used in [1], which is confusing
with DDR memory.
Suggested-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
arch/x86/include/asm/msr-index.h | 12 ++++++------
drivers/platform/x86/intel/ifs/core.c | 4 ++--
tools/arch/x86/include/asm/msr-index.h | 12 ++++++------
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index ac73dadb44e0..660b0c332be2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -275,12 +275,12 @@
#define MSR_IA32_POWER_CTL_BIT_EE 19
/* Abbreviated from Intel SDM name IA32_INTEGRITY_CAPABILITIES */
-#define MSR_INTEGRITY_CAPS 0x000002d9
-#define MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT 2
-#define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
-#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
+#define MSR_INTEGRITY_CAPS 0x000002d9
+#define MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST_BIT 2
+#define MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST_BIT)
+#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT 4
+#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT)
+#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
#define MSR_LBR_NHM_FROM 0x00000680
#define MSR_LBR_NHM_TO 0x000006c0
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index 574f2a366d06..85a04ecc9dbe 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -32,12 +32,12 @@ ATTRIBUTE_GROUPS(plat_ifs_array);
bool *ifs_pkg_auth;
static const struct ifs_test_caps scan_test = {
- .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT,
+ .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT,
.test_num = IFS_TYPE_SAF,
};
static const struct ifs_test_caps array_test = {
- .integrity_cap_bit = MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT,
+ .integrity_cap_bit = MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST_BIT,
.test_num = IFS_TYPE_ARRAY_BIST,
};
diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h
index d70f160425a2..8c4424c43a4a 100644
--- a/tools/arch/x86/include/asm/msr-index.h
+++ b/tools/arch/x86/include/asm/msr-index.h
@@ -275,12 +275,12 @@
#define MSR_IA32_POWER_CTL_BIT_EE 19
/* Abbreviated from Intel SDM name IA32_INTEGRITY_CAPABILITIES */
-#define MSR_INTEGRITY_CAPS 0x000002d9
-#define MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT 2
-#define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
-#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
-#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
+#define MSR_INTEGRITY_CAPS 0x000002d9
+#define MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST_BIT 2
+#define MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_ARRAY_BIST_BIT)
+#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT 4
+#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT)
+#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
#define MSR_LBR_NHM_FROM 0x00000680
#define MSR_LBR_NHM_TO 0x000006c0
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 04/17] platform/x86/intel/ifs: Use u64 to define the bits of IFS MSR registers
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (2 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 03/17] platform/x86/intel/ifs: Clarify In-Field Scan MSR bit macro definitions Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 05/17] platform/x86/intel/ifs: Early return on the IFS image hash/chunk error Ehab Ababneh
` (12 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
The IFS (In-Field Scan) related MSR registers are all 64-bit wide.
Use a single u64 within a struct to define the bits of an IFS MSR
register in a more compact form, instead of using {u16, u32} for
each bit, to enhance readability.
No functional changes.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/ifs.h | 66 ++++++++++++++--------------
1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index 0f5cdc1ad14d..f52287745366 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -156,26 +156,26 @@
union ifs_scan_hashes_status {
u64 data;
struct {
- u32 chunk_size :16;
- u32 num_chunks :8;
- u32 rsvd1 :8;
- u32 error_code :8;
- u32 rsvd2 :11;
- u32 max_core_limit :12;
- u32 valid :1;
+ u64 chunk_size : 16,
+ num_chunks : 8,
+ rsvd1 : 8,
+ error_code : 8,
+ rsvd2 : 11,
+ max_core_limit : 12,
+ valid : 1;
};
};
union ifs_scan_hashes_status_gen2 {
u64 data;
struct {
- u16 chunk_size;
- u16 num_chunks;
- u32 error_code :8;
- u32 chunks_in_stride :9;
- u32 rsvd :2;
- u32 max_core_limit :12;
- u32 valid :1;
+ u64 chunk_size : 16,
+ num_chunks : 16,
+ error_code : 8,
+ chunks_in_stride : 9,
+ rsvd : 2,
+ max_core_limit : 12,
+ valid : 1;
};
};
@@ -183,21 +183,21 @@ union ifs_scan_hashes_status_gen2 {
union ifs_chunks_auth_status {
u64 data;
struct {
- u32 valid_chunks :8;
- u32 total_chunks :8;
- u32 rsvd1 :16;
- u32 error_code :8;
- u32 rsvd2 :24;
+ u64 valid_chunks : 8,
+ total_chunks : 8,
+ rsvd1 : 16,
+ error_code : 8,
+ rsvd2 : 24;
};
};
union ifs_chunks_auth_status_gen2 {
u64 data;
struct {
- u16 valid_chunks;
- u16 total_chunks;
- u32 error_code :8;
- u32 rsvd2 :24;
+ u64 valid_chunks : 16,
+ total_chunks : 16,
+ error_code : 8,
+ rsvd2 : 24;
};
};
@@ -216,8 +216,8 @@ union ifs_scan {
u16 stop;
} gen2;
};
- u32 delay :31;
- u32 sigmce :1;
+ u32 delay : 31,
+ sigmce : 1;
};
};
@@ -236,10 +236,10 @@ union ifs_status {
u16 chunk_stop_index;
} gen2;
};
- u32 error_code :8;
- u32 rsvd2 :22;
- u32 control_error :1;
- u32 signature_error :1;
+ u32 error_code : 8,
+ rsvd2 : 22,
+ control_error : 1,
+ signature_error : 1;
};
};
@@ -247,10 +247,10 @@ union ifs_status {
union ifs_array {
u64 data;
struct {
- u32 array_bitmask;
- u16 array_bank;
- u16 rsvd :15;
- u16 ctrl_result :1;
+ u64 array_bitmask : 32,
+ array_bank : 16,
+ rsvd : 15,
+ ctrl_result : 1;
};
};
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 05/17] platform/x86/intel/ifs: Early return on the IFS image hash/chunk error
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (3 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 04/17] platform/x86/intel/ifs: Use u64 to define the bits of IFS MSR registers Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 06/17] platform/x86/intel/ifs: Refactor Array BIST function interface Ehab Ababneh
` (11 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Return immediately upon encountering a hash error or chunk error in the
IFS (In-Field Scan) test image to avoid meaningless assignments following
these errors.
Additionally, assign the boolean value 'true' instead of '1' to the
boolean variable 'ifs_pkg_auth', and use SZ_1K macro instead of '1024'
for better readability.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/load.c | 34 ++++++++++++---------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/load.c b/drivers/platform/x86/intel/ifs/load.c
index dde3f5eb379f..0edbf9eedc12 100644
--- a/drivers/platform/x86/intel/ifs/load.c
+++ b/drivers/platform/x86/intel/ifs/load.c
@@ -123,7 +123,6 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
int i, num_chunks, chunk_size;
struct ifs_data *ifsd;
u64 linear_addr, base;
- u32 err_code;
ifsd = ifs_get_data(dev);
msrs = ifs_get_test_msrs(dev);
@@ -131,17 +130,16 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
wrmsrq(msrs->copy_hashes, ifs_hash_ptr);
rdmsrq(msrs->copy_hashes_status, hashes_status.data);
- /* enumerate the scan image information */
- num_chunks = hashes_status.num_chunks;
- chunk_size = hashes_status.chunk_size * 1024;
- err_code = hashes_status.error_code;
-
if (!hashes_status.valid) {
ifsd->loading_error = true;
- hashcopy_err_message(dev, err_code);
+ hashcopy_err_message(dev, hashes_status.error_code);
goto done;
}
+ /* enumerate the scan image information */
+ num_chunks = hashes_status.num_chunks;
+ chunk_size = hashes_status.chunk_size * SZ_1K;
+
/* base linear address to the scan data */
base = ifs_test_image_ptr;
@@ -153,14 +151,13 @@ static void copy_hashes_authenticate_chunks(struct work_struct *work)
wrmsrq(msrs->copy_chunks, linear_addr);
rdmsrq(msrs->copy_chunks_status, chunk_status.data);
- ifsd->valid_chunks = chunk_status.valid_chunks;
- err_code = chunk_status.error_code;
-
- if (err_code) {
+ if (chunk_status.error_code) {
ifsd->loading_error = true;
- auth_err_message(dev, err_code);
+ auth_err_message(dev, chunk_status.error_code);
goto done;
}
+
+ ifsd->valid_chunks = chunk_status.valid_chunks;
}
done:
complete(&ifs_done);
@@ -199,16 +196,15 @@ static int copy_hashes_authenticate_chunks_gen2(struct device *dev)
wrmsrq(msrs->copy_hashes, ifs_hash_ptr);
rdmsrq(msrs->copy_hashes_status, hashes_status.data);
+ if (!hashes_status.valid) {
+ hashcopy_err_message(dev, hashes_status.error_code);
+ return -EIO;
+ }
+
/* enumerate the scan image information */
chunk_size = hashes_status.chunk_size * SZ_1K;
- err_code = hashes_status.error_code;
-
num_chunks = get_num_chunks(ifsd->generation, hashes_status);
- if (!hashes_status.valid) {
- hashcopy_err_message(dev, err_code);
- return -EIO;
- }
ifsd->loaded_version = ifs_header_ptr->rev;
ifsd->chunk_size = chunk_size;
} else {
@@ -344,7 +340,7 @@ static int scan_chunks_sanity_check(struct device *dev)
ret = -EIO;
goto out;
}
- ifs_pkg_auth[curr_pkg] = 1;
+ ifs_pkg_auth[curr_pkg] = true;
}
ret = 0;
ifsd->loaded_version = ifs_header_ptr->rev;
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 06/17] platform/x86/intel/ifs: Refactor Array BIST function interface
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (4 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 05/17] platform/x86/intel/ifs: Early return on the IFS image hash/chunk error Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 07/17] stop_machine: Add stop_cluster_cpuslocked() for per-cluster operations Ehab Ababneh
` (10 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
In preparation for upcoming changes, refactor the Array BIST test to use a
more generic structure (run_array_params) when passing parameters to the
caller function.
This change enhances maintainability and flexibility for future
modifications.
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/runtest.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index 96b538c665f4..c6a4d6dcccf1 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -30,6 +30,11 @@ struct run_params {
union ifs_status status;
};
+struct run_array_params {
+ struct ifs_data *ifsd;
+ union ifs_array *command;
+};
+
/*
* Number of TSC cycles that a logical CPU will wait for the other
* logical CPU on the core in the WRMSR(ACTIVATE_SCAN).
@@ -302,10 +307,12 @@ static void ifs_test_core(int cpu, struct device *dev)
static int do_array_test(void *data)
{
- union ifs_array *command = data;
+ struct run_array_params *params = data;
int cpu = smp_processor_id();
+ union ifs_array *command;
int first;
+ command = params->command;
wait_for_sibling_cpu(&array_cpus_in, NSEC_PER_SEC);
/*
@@ -324,12 +331,14 @@ static int do_array_test(void *data)
static void ifs_array_test_core(int cpu, struct device *dev)
{
+ struct run_array_params params;
union ifs_array command = {};
bool timed_out = false;
struct ifs_data *ifsd;
unsigned long timeout;
ifsd = ifs_get_data(dev);
+ params.ifsd = ifsd;
command.array_bitmask = ~0U;
timeout = jiffies + HZ / 2;
@@ -340,7 +349,8 @@ static void ifs_array_test_core(int cpu, struct device *dev)
break;
}
atomic_set(&array_cpus_in, 0);
- stop_core_cpuslocked(cpu, do_array_test, &command);
+ params.command = &command;
+ stop_core_cpuslocked(cpu, do_array_test, ¶ms);
if (command.ctrl_result)
break;
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 07/17] stop_machine: Add stop_cluster_cpuslocked() for per-cluster operations
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (5 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 06/17] platform/x86/intel/ifs: Refactor Array BIST function interface Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 08/17] platform/x86/intel/ifs: Enumerate the bit to determine if CPUs need to join for IFS tests Ehab Ababneh
` (9 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck, Peter Zijlstra, Thomas Gleixner,
Ingo Molnar
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, bp,
dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, sathyanarayanan.kuppuswamy, pengfei.xu,
ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
There is already stop_core_cpuslocked() for hardware core-level testing
features, which requires near-simultaneous execution of the WRMSR
instruction on all threads of a core to initiate a test. However, some
hardware requires this simultaneous execution of WRMSR at the cluster
level.
Add stop_cluster_cpuslocked(), a customized version of
stop_machine_cpuslocked() for operating solely on the threads of a
single cluster.
Suggested-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
include/linux/stop_machine.h | 15 +++++++++++++++
kernel/stop_machine.c | 35 ++++++++++++++++++++++-------------
2 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/include/linux/stop_machine.h b/include/linux/stop_machine.h
index 84e7fb627ba4..a189f405a4f2 100644
--- a/include/linux/stop_machine.h
+++ b/include/linux/stop_machine.h
@@ -157,6 +157,21 @@ int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, const struct cpumask *
*/
int stop_core_cpuslocked(unsigned int cpu, cpu_stop_fn_t fn, void *data);
+/**
+ * stop_cluster_cpuslocked: - stop all threads on a CPU cluster
+ * @cpu: any CPU in the targeted cluster
+ * @fn: the function to run
+ * @data: the data ptr for @fn()
+ *
+ * Same as above, only the CPUs associated with a single CPU cluster are affected.
+ *
+ * Context: Must be called from within a cpus_read_lock() protected region.
+ *
+ * Return: 0 if all executions of @fn returned 0, any non zero return
+ * value if any returned non zero.
+ */
+int stop_cluster_cpuslocked(unsigned int cpu, cpu_stop_fn_t fn, void *data);
+
int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data,
const struct cpumask *cpus);
#else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index d085ba1f4b44..1afda0ddfb90 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -630,32 +630,41 @@ int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus)
}
EXPORT_SYMBOL_GPL(stop_machine);
-#ifdef CONFIG_SCHED_SMT
-/*
- * INTEL_IFS is the only user of this API. That selftest can
- * only be compiled if SMP=y. On x86 it selects SCHED_SMT.
- * Keep the ifdefs for now.
- */
-int stop_core_cpuslocked(unsigned int cpu, cpu_stop_fn_t fn, void *data)
+static int stop_cpus_cpuslocked(const struct cpumask *cpus, cpu_stop_fn_t fn, void *data)
{
- const struct cpumask *smt_mask = cpu_smt_mask(cpu);
-
struct multi_stop_data msdata = {
.fn = fn,
.data = data,
- .num_threads = cpumask_weight(smt_mask),
- .active_cpus = smt_mask,
+ .num_threads = cpumask_weight(cpus),
+ .active_cpus = cpus,
};
lockdep_assert_cpus_held();
- /* Set the initial state and stop all online cpus. */
+ /* Set the initial state and stop all online @cpus. */
set_state(&msdata, MULTI_STOP_PREPARE);
- return stop_cpus(smt_mask, multi_cpu_stop, &msdata);
+ return stop_cpus(cpus, multi_cpu_stop, &msdata);
+}
+
+#ifdef CONFIG_SCHED_SMT
+/*
+ * INTEL_IFS is the only user of this API. That selftest can
+ * only be compiled if SMP=y. On x86 it selects SCHED_SMT.
+ * Keep the ifdefs for now.
+ */
+int stop_core_cpuslocked(unsigned int cpu, cpu_stop_fn_t fn, void *data)
+{
+ return stop_cpus_cpuslocked(cpu_smt_mask(cpu), fn, data);
}
EXPORT_SYMBOL_GPL(stop_core_cpuslocked);
#endif
+int stop_cluster_cpuslocked(unsigned int cpu, cpu_stop_fn_t fn, void *data)
+{
+ return stop_cpus_cpuslocked(topology_cluster_cpumask(cpu), fn, data);
+}
+EXPORT_SYMBOL_GPL(stop_cluster_cpuslocked);
+
/**
* stop_machine_from_inactive_cpu - stop_machine() from inactive CPU
* @fn: the function to run
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 08/17] platform/x86/intel/ifs: Enumerate the bit to determine if CPUs need to join for IFS tests
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (6 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 07/17] stop_machine: Add stop_cluster_cpuslocked() for per-cluster operations Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 09/17] platform/x86/intel/ifs: Select CPUs from topology_cluster_cpumask() for simultaneous " Ehab Ababneh
` (8 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
Starting with Granite Rapids (GNR), bit 21 (ALL_LP_JOIN_NEEDED) of
MSR_INTEGRITY_CAPABILITIES register [1] indicates whether all CPUs sharing
the scan test engine need to be tested together. These CPUs must join
using MSR_ACTIVATE_SCAN.
Add an enumeration of bit 21 to determine if CPUs need to join to run IFS
tests together.
[1] Vol. 4 "Table 2-56. Additional MSRs Supported by the Intel® Xeon®
6 P-Core Processors" in the Intel Software Developers' Manual,
March 2025.
[ Qiuxu: Elaborate commit message. ]
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
arch/x86/include/asm/msr-index.h | 2 ++
drivers/platform/x86/intel/ifs/core.c | 12 ++++++++++++
drivers/platform/x86/intel/ifs/ifs.h | 2 ++
3 files changed, 16 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 660b0c332be2..554ce662fdf4 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -281,6 +281,8 @@
#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT 4
#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT)
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
+#define MSR_INTEGRITY_CAPS_ALL_LP_JOIN_BIT 21
+#define MSR_INTEGRITY_CAPS_ALL_LP_JOIN BIT(MSR_INTEGRITY_CAPS_ALL_LP_JOIN_BIT)
#define MSR_LBR_NHM_FROM 0x00000680
#define MSR_LBR_NHM_TO 0x000006c0
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index 85a04ecc9dbe..f2d2caab0479 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -110,6 +110,18 @@ static int __init ifs_init(void)
continue;
ifs_devices[i].rw_data.generation = FIELD_GET(MSR_INTEGRITY_CAPS_SAF_GEN_MASK,
msrval);
+ /*
+ * For Sapphire Rapids and Emerald Rapids (SAF_GEN=0), the ALL_LP_JOIN
+ * indicator is unavailable. However, all the threads within a core still
+ * need to run IFS simultaneously, so the variable 'all_lp_join' is
+ * forced to true.
+ *
+ * For Granite Rapids and later generations (SAF_GEN=2), the ALL_LP_JOIN
+ * indicator is available, the variable 'all_lp_join' is determined by
+ * this indicator.
+ */
+ ifs_devices[i].rw_data.all_lp_join = ifs_devices[i].rw_data.generation ?
+ (msrval & MSR_INTEGRITY_CAPS_ALL_LP_JOIN) : true;
ifs_devices[i].rw_data.array_gen = (u32)m->driver_data;
ret = misc_register(&ifs_devices[i].misc);
if (ret)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index f52287745366..814ebac10a5d 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -295,6 +295,7 @@ struct ifs_test_msrs {
* @generation: IFS test generation enumerated by hardware
* @chunk_size: size of a test chunk
* @array_gen: test generation of array test
+ * @all_lp_join: all logical processors join test
*/
struct ifs_data {
int loaded_version;
@@ -307,6 +308,7 @@ struct ifs_data {
u32 generation;
u32 chunk_size;
u32 array_gen;
+ bool all_lp_join;
};
struct ifs_work {
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 09/17] platform/x86/intel/ifs: Select CPUs from topology_cluster_cpumask() for simultaneous IFS tests
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (7 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 08/17] platform/x86/intel/ifs: Enumerate the bit to determine if CPUs need to join for IFS tests Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 10/17] platform/x86/intel/ifs: Validate TID_BIT_SHIFT matches topology_cluster_cpumask() Ehab Ababneh
` (7 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
The current intel_ifs driver selects CPUs from cpu_smt_mask() to run
IFS test simultaneously. This approach works well for processors currently
supported by the intel_ifs driver, where threads in a CPU core share the
same SCAN test engine. However, it will not work for new Intel Xeon
processors, such as Diamond Rapids, where multiple CPU cores in a module
share the same SCAN test engine and must run IFS tests simultaneously.
Starting with Granite Rapids (GNR) and later generations, bit[20:16]
(TID_BIT_SHIFT) of MSR_INTEGRITY_CAPABILITIES register [1] contains the
number of bits to shift right on x2APICID to obtain a unique topology ID
for all logical processors that share a SCAN test engine. In theory,
computing a cpumask by this method and using a stop_machine() variant
with an arbitrary cpumask passed in to rendezvous CPUs for simultaneous
IFS tests should work for both cases where threads in a core or CPU
cores in a module share the same SCAN test engine. However, as per
Tony Luck's feedback and the previous discussion [2], the Linux community
is not in favor of a stop_machine() variant with an arbitrary cpumask.
Observations on existing Intel Xeon processors and the upcoming Diamond
Rapids with IFS capability show that the logical processors sharing the
same SCAN test engine are exactly the logical processors sharing the
same L2 cache.
topology_cluster_cpumask() returns the cpumask for CPUs sharing the same
L2 cache. Therefore, select CPUs from topology_cluster_cpumask() to run
IFS tests if simultaneous testing is required.
[ Qiuxu: Re-wrote the commit message. ]
[1] Vol. 4 "Table 2-56. Additional MSRs Supported by the Intel® Xeon®
6 P-Core Processors" in the Intel Software Developers' Manual,
March 2025.
[2] https://lore.kernel.org/all/20220505082824.GD2501@worktop.programming.kicks-ass.net/
Suggested-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/ifs.h | 2 +
drivers/platform/x86/intel/ifs/runtest.c | 48 +++++++++++++++++++-----
2 files changed, 40 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index 814ebac10a5d..365429fafe7a 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -285,6 +285,7 @@ struct ifs_test_msrs {
/**
* struct ifs_data - attributes related to Intel IFS driver
+ * @grp_cpumask: set of CPUs being tested simultaneously
* @loaded_version: stores the currently loaded ifs image version.
* @loaded: If a valid test binary has been loaded into the memory
* @loading_error: Error occurred on another CPU while loading image
@@ -298,6 +299,7 @@ struct ifs_test_msrs {
* @all_lp_join: all logical processors join test
*/
struct ifs_data {
+ cpumask_t grp_cpumask;
int loaded_version;
bool loaded;
bool loading_error;
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index c6a4d6dcccf1..09e7a81e9220 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -156,11 +156,9 @@ static atomic_t scan_cpus_in;
/*
* Simplified CPU sibling rendezvous loop based on microcode loader wait_for_cpus()
*/
-static void wait_for_sibling_cpu(atomic_t *t, long long timeout)
+static void wait_for_sibling_cpu(struct ifs_data *ifsd, atomic_t *t, long long timeout)
{
- int cpu = smp_processor_id();
- const struct cpumask *smt_mask = cpu_smt_mask(cpu);
- int all_cpus = cpumask_weight(smt_mask);
+ int all_cpus = cpumask_weight(&ifsd->grp_cpumask);
atomic_inc(t);
while (atomic_read(t) < all_cpus) {
@@ -195,9 +193,9 @@ static int doscan(void *data)
}
/* Only the first logical CPU on a core reports result */
- first = cpumask_first(cpu_smt_mask(cpu));
+ first = cpumask_first(&ifsd->grp_cpumask);
- wait_for_sibling_cpu(&scan_cpus_in, NSEC_PER_SEC);
+ wait_for_sibling_cpu(ifsd, &scan_cpus_in, NSEC_PER_SEC);
/*
* This WRMSR will wait for other HT threads to also write
@@ -265,7 +263,11 @@ static void ifs_test_core(int cpu, struct device *dev)
params.activate = &activate;
atomic_set(&scan_cpus_in, 0);
- stop_core_cpuslocked(cpu, doscan, ¶ms);
+
+ if (ifsd->all_lp_join)
+ stop_cluster_cpuslocked(cpu, doscan, ¶ms);
+ else
+ stop_core_cpuslocked(cpu, doscan, ¶ms);
status = params.status;
@@ -310,15 +312,18 @@ static int do_array_test(void *data)
struct run_array_params *params = data;
int cpu = smp_processor_id();
union ifs_array *command;
+ struct ifs_data *ifsd;
int first;
+ ifsd = params->ifsd;
+
command = params->command;
- wait_for_sibling_cpu(&array_cpus_in, NSEC_PER_SEC);
+ wait_for_sibling_cpu(ifsd, &array_cpus_in, NSEC_PER_SEC);
/*
* Only one logical CPU on a core needs to trigger the Array test via MSR write.
*/
- first = cpumask_first(cpu_smt_mask(cpu));
+ first = cpumask_first(&ifsd->grp_cpumask);
if (cpu == first) {
wrmsrq(MSR_ARRAY_BIST, command->data);
@@ -350,7 +355,11 @@ static void ifs_array_test_core(int cpu, struct device *dev)
}
atomic_set(&array_cpus_in, 0);
params.command = &command;
- stop_core_cpuslocked(cpu, do_array_test, ¶ms);
+
+ if (ifsd->all_lp_join)
+ stop_cluster_cpuslocked(cpu, do_array_test, ¶ms);
+ else
+ stop_core_cpuslocked(cpu, do_array_test, ¶ms);
if (command.ctrl_result)
break;
@@ -398,6 +407,24 @@ static void ifs_array_test_gen1(int cpu, struct device *dev)
ifsd->status = SCAN_TEST_PASS;
}
+static void build_cpugroup_mask(struct device *dev, int cpu)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+
+ cpumask_clear(&ifsd->grp_cpumask);
+
+ /*
+ * Some CPUs, such as Sierra Forest and Clearwater Forest, have multiple cores
+ * sharing the same SCAN test engine, but they don't require a rendezvous.
+ */
+ if (!ifsd->all_lp_join) {
+ cpumask_set_cpu(cpu, &ifsd->grp_cpumask);
+ return;
+ }
+
+ cpumask_copy(&ifsd->grp_cpumask, topology_cluster_cpumask(cpu));
+}
+
/*
* Initiate per core test. It wakes up work queue threads on the target CPU and
* its sibling CPU. Once all sibling threads wake up, the scan test gets executed and
@@ -411,6 +438,7 @@ int do_core_test(int cpu, struct device *dev)
/* Prevent CPUs from being taken offline during the scan test */
cpus_read_lock();
+ build_cpugroup_mask(dev, cpu);
if (!cpu_online(cpu)) {
dev_info(dev, "cannot test on the offline CPU %d\n", cpu);
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 10/17] platform/x86/intel/ifs: Validate TID_BIT_SHIFT matches topology_cluster_cpumask()
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (8 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 09/17] platform/x86/intel/ifs: Select CPUs from topology_cluster_cpumask() for simultaneous " Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 11/17] platform/x86/intel/ifs: Track and report scan results on a per-CPU basis Ehab Ababneh
` (6 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
The intel_ifs driver assumes logical processors indicated by TID_BIT_SHIFT
[1] that share the same SCAN test engine match topology_cluster_cpumask().
Validate this assumption during driver initialization and fail loading if
it doesn't hold.
[1] Vol. 4 "Table 2-56. Additional MSRs Supported by the Intel® Xeon®
6 P-Core Processors" in the Intel Software Developers' Manual,
March 2025.
Suggested-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
arch/x86/include/asm/msr-index.h | 1 +
drivers/platform/x86/intel/ifs/core.c | 48 +++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 554ce662fdf4..e93c76389ca5 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -281,6 +281,7 @@
#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT 4
#define MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_SCAN_BIST_BIT)
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
+#define MSR_INTEGRITY_CAPS_TID_BIT_SHIFT_MASK GENMASK_ULL(20, 16)
#define MSR_INTEGRITY_CAPS_ALL_LP_JOIN_BIT 21
#define MSR_INTEGRITY_CAPS_ALL_LP_JOIN BIT(MSR_INTEGRITY_CAPS_ALL_LP_JOIN_BIT)
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index f2d2caab0479..c830a02fe7b3 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2022 Intel Corporation. */
+#define pr_fmt(fmt) "intel_ifs: " fmt
+
#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/kdev_t.h>
@@ -69,6 +71,45 @@ static struct ifs_device ifs_devices[] = {
},
};
+/*
+ * Test whether logical processors indicated by TID_BIT_SHIFT that share the
+ * same SCAN test engine match the cpumask from topology_cluster_cpumask().
+ */
+static bool topology_cluster_matched(u32 msrval)
+{
+ u32 dist, shift = FIELD_GET(MSR_INTEGRITY_CAPS_TID_BIT_SHIFT_MASK, msrval);
+ const cpumask_t *cpumask = topology_cluster_cpumask(0);
+ u32 delta, step = 0, first = cpu_data(0).topo.apicid;
+ unsigned int cpu, cpus;
+
+ /* Get the minimal APIC ID step among the CPUs in the same cluster. */
+ for_each_cpu_andnot(cpu, cpumask, cpumask_of(0)) {
+ delta = abs(cpu_data(cpu).topo.apicid - first);
+
+ if (!step) {
+ step = delta;
+ continue;
+ }
+
+ if (step > delta)
+ step = delta;
+ }
+
+ /* A Hyper-Threading (HT) system with HT disabled. */
+ if (!step)
+ step = 2;
+
+ cpus = cpumask_weight(cpumask);
+ dist = step * cpus;
+
+ if (dist != (1 << shift)) {
+ pr_err_once("APICID step %u, group cpus %u, TID_BIT_SHIFT %u\n", step, cpus, shift);
+ return false;
+ }
+
+ return true;
+}
+
#define IFS_NUMTESTS ARRAY_SIZE(ifs_devices)
static void ifs_cleanup(void)
@@ -122,6 +163,13 @@ static int __init ifs_init(void)
*/
ifs_devices[i].rw_data.all_lp_join = ifs_devices[i].rw_data.generation ?
(msrval & MSR_INTEGRITY_CAPS_ALL_LP_JOIN) : true;
+
+ if (ifs_devices[i].rw_data.all_lp_join && !topology_cluster_matched(msrval)) {
+ pr_err_once("TID_BIT_SHIFT mismatched topology_cluster_cpumask().\n");
+ ret = -EINVAL;
+ goto err_exit;
+ }
+
ifs_devices[i].rw_data.array_gen = (u32)m->driver_data;
ret = misc_register(&ifs_devices[i].misc);
if (ret)
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 11/17] platform/x86/intel/ifs: Track and report scan results on a per-CPU basis
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (9 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 10/17] platform/x86/intel/ifs: Validate TID_BIT_SHIFT matches topology_cluster_cpumask() Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 12/17] platform/x86/intel/ifs: Add new sysfs interfaces {status, details, cpus_ran}_list Ehab Ababneh
` (5 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
IFS requires invoking the scan simultaneously within a group of CPUs, as
indicated in the MSR_INTEGRITY_CAPABILITIES (bits 20:16). When bit 21 is
set, it indicates that all threads in the groups need to trigger the test
at the same time.
When the tests are run simultaneously, record the test results in a
per-CPU structure. This reduces the need to redundantly repeat the test
for all thread in the same group.
There are several benefits:
- Reduced power consumption by avoiding multiple scans.
- Decreased time to complete a scan by 50% or more.
- These tests could take up to 200ms. Prevents taking these cores out
of circulation just to repeat tests that have already been conducted.
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/core.c | 10 +-
drivers/platform/x86/intel/ifs/ifs.h | 12 +++
drivers/platform/x86/intel/ifs/runtest.c | 117 ++++++++++++++++-------
3 files changed, 105 insertions(+), 34 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index c830a02fe7b3..08a3e519749b 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -51,6 +51,8 @@ static const struct ifs_test_msrs scan_msrs = {
.test_ctrl = MSR_SAF_CTRL,
};
+DEFINE_PER_CPU(struct ifs_test_output, ifs_scan_n);
+
static struct ifs_device ifs_devices[] = {
[IFS_TYPE_SAF] = {
.test_caps = &scan_test,
@@ -60,6 +62,9 @@ static struct ifs_device ifs_devices[] = {
.minor = MISC_DYNAMIC_MINOR,
.groups = plat_ifs_groups,
},
+ .rw_data = {
+ .result_ptr = &ifs_scan_n,
+ }
},
[IFS_TYPE_ARRAY_BIST] = {
.test_caps = &array_test,
@@ -127,7 +132,7 @@ static int __init ifs_init(void)
{
const struct x86_cpu_id *m;
u64 msrval;
- int i, ret;
+ int i, ret, cpu;
m = x86_match_cpu(ifs_cpu_ids);
if (!m)
@@ -175,6 +180,9 @@ static int __init ifs_init(void)
if (ret)
goto err_exit;
}
+
+ for_each_possible_cpu(cpu)
+ memset(per_cpu_ptr(&ifs_scan_n, cpu), 0, sizeof(struct ifs_test_output));
return 0;
err_exit:
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index 365429fafe7a..1043378c60e5 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -130,6 +130,7 @@
*/
#include <linux/device.h>
#include <linux/miscdevice.h>
+#include <linux/percpu-defs.h>
#define MSR_ARRAY_BIST 0x00000105
#define MSR_COPY_SCAN_HASHES 0x000002c2
@@ -290,6 +291,7 @@ struct ifs_test_msrs {
* @loaded: If a valid test binary has been loaded into the memory
* @loading_error: Error occurred on another CPU while loading image
* @valid_chunks: number of chunks which could be validated.
+ * @cpu: The CPU on which the test was triggered
* @status: it holds simple status pass/fail/untested
* @scan_details: opaque scan status code from h/w
* @cur_batch: number indicating the currently loaded test file
@@ -297,6 +299,7 @@ struct ifs_test_msrs {
* @chunk_size: size of a test chunk
* @array_gen: test generation of array test
* @all_lp_join: all logical processors join test
+ * @result_ptr: points to percpu result
*/
struct ifs_data {
cpumask_t grp_cpumask;
@@ -304,6 +307,7 @@ struct ifs_data {
bool loaded;
bool loading_error;
int valid_chunks;
+ int cpu;
int status;
u64 scan_details;
u32 cur_batch;
@@ -311,6 +315,7 @@ struct ifs_data {
u32 chunk_size;
u32 array_gen;
bool all_lp_join;
+ struct ifs_test_output __percpu *result_ptr;
};
struct ifs_work {
@@ -325,6 +330,13 @@ struct ifs_device {
struct miscdevice misc;
};
+struct ifs_test_output {
+ u64 test_details;
+ int test_result;
+};
+
+DECLARE_PER_CPU(struct ifs_test_output, ifs_scan_n);
+
static inline struct ifs_data *ifs_get_data(struct device *dev)
{
struct miscdevice *m = dev_get_drvdata(dev);
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index 09e7a81e9220..6c3d025817e7 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -83,25 +83,21 @@ static void message_not_tested(struct device *dev, int cpu, union ifs_status sta
* been corrupted. Reloading the image may fix this issue.
*/
if (status.control_error) {
- dev_warn(dev, "CPU(s) %*pbl: Scan controller error. Batch: %02x version: 0x%x\n",
- cpumask_pr_args(cpu_smt_mask(cpu)), ifsd->cur_batch, ifsd->loaded_version);
+ dev_warn(dev, "CPU %d: Scan controller error. Batch: %02x version: 0x%x\n", cpu,
+ ifsd->cur_batch, ifsd->loaded_version);
return;
}
if (status.error_code < ARRAY_SIZE(scan_test_status)) {
- dev_info(dev, "CPU(s) %*pbl: SCAN operation did not start. %s\n",
- cpumask_pr_args(cpu_smt_mask(cpu)),
+ dev_info(dev, "CPU %d: SCAN operation did not start. %s\n", cpu,
scan_test_status[status.error_code]);
} else if (status.error_code == IFS_SW_TIMEOUT) {
- dev_info(dev, "CPU(s) %*pbl: software timeout during scan\n",
- cpumask_pr_args(cpu_smt_mask(cpu)));
+ dev_info(dev, "CPU %d: software timeout during scan\n", cpu);
} else if (status.error_code == IFS_SW_PARTIAL_COMPLETION) {
- dev_info(dev, "CPU(s) %*pbl: %s\n",
- cpumask_pr_args(cpu_smt_mask(cpu)),
+ dev_info(dev, "CPU %d: %s\n", cpu,
"Not all scan chunks were executed. Maximum forward progress retries exceeded");
} else {
- dev_info(dev, "CPU(s) %*pbl: SCAN unknown status %llx\n",
- cpumask_pr_args(cpu_smt_mask(cpu)), status.data);
+ dev_info(dev, "CPU %d: SCAN unknown status %llx\n", cpu, status.data);
}
}
@@ -117,8 +113,8 @@ static void message_fail(struct device *dev, int cpu, union ifs_status status)
* the core being tested.
*/
if (status.signature_error) {
- dev_err(dev, "CPU(s) %*pbl: test signature incorrect. Batch: %02x version: 0x%x\n",
- cpumask_pr_args(cpu_smt_mask(cpu)), ifsd->cur_batch, ifsd->loaded_version);
+ dev_err(dev, "CPU %d: test signature incorrect. Batch: %02x version: 0x%x\n",
+ cpu, ifsd->cur_batch, ifsd->loaded_version);
}
}
@@ -177,12 +173,13 @@ static void wait_for_sibling_cpu(struct ifs_data *ifsd, atomic_t *t, long long t
static int doscan(void *data)
{
int cpu = smp_processor_id(), start, stop;
+ struct ifs_test_output *pcpu_scan;
struct run_params *params = data;
union ifs_status status;
struct ifs_data *ifsd;
- int first;
ifsd = params->ifsd;
+ pcpu_scan = this_cpu_ptr(ifsd->result_ptr);
if (ifsd->generation) {
start = params->activate->gen2.start;
@@ -192,9 +189,6 @@ static int doscan(void *data)
stop = params->activate->gen0.stop;
}
- /* Only the first logical CPU on a core reports result */
- first = cpumask_first(&ifsd->grp_cpumask);
-
wait_for_sibling_cpu(ifsd, &scan_cpus_in, NSEC_PER_SEC);
/*
@@ -211,12 +205,76 @@ static int doscan(void *data)
trace_ifs_status(ifsd->cur_batch, start, stop, status.data);
/* Pass back the result of the scan */
- if (cpu == first)
+ if (cpu == ifsd->cpu)
params->status = status;
+ pcpu_scan->test_details = status.data;
+
return 0;
}
+#define get_scan_status(stat) ((union ifs_status *)(&((stat)->test_details)))
+
+static void update_group_status(struct device *dev, int reason)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_scan;
+ union ifs_status *scan_status;
+ int lcpu;
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_scan = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ scan_status = get_scan_status(pcpu_scan);
+ scan_status->error_code = reason;
+ }
+}
+
+static bool can_restart_test_group(struct device *dev)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_scan;
+ union ifs_status *scan_status;
+ int lcpu;
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_scan = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ scan_status = get_scan_status(pcpu_scan);
+ if (!can_restart(*scan_status))
+ return false;
+ }
+ return true;
+}
+
+static void update_group_result(struct device *dev, int stop_chunk)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_scan;
+ union ifs_status *scan_status;
+ u32 reached_chunk;
+ int lcpu;
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_scan = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ scan_status = get_scan_status(pcpu_scan);
+ reached_chunk = ifsd->generation ? scan_status->gen2.chunk_num :
+ scan_status->gen0.chunk_num;
+
+ if (scan_status->signature_error) {
+ pcpu_scan->test_result = SCAN_TEST_FAIL;
+ message_fail(dev, lcpu, *scan_status);
+ } else if (scan_status->control_error || scan_status->error_code ||
+ reached_chunk <= stop_chunk) {
+ pcpu_scan->test_result = SCAN_NOT_TESTED;
+ message_not_tested(dev, lcpu, *scan_status);
+ } else {
+ pcpu_scan->test_result = SCAN_TEST_PASS;
+ }
+
+ if (lcpu == ifsd->cpu)
+ ifsd->status = pcpu_scan->test_result;
+ }
+}
+
/*
* Use stop_core_cpuslocked() to synchronize writing to MSR_ACTIVATE_SCAN
* on all threads of the core to be tested. Loop if necessary to complete
@@ -235,6 +293,7 @@ static void ifs_test_core(int cpu, struct device *dev)
int retries;
ifsd = ifs_get_data(dev);
+ ifsd->cpu = cpu;
activate.gen0.rsvd = 0;
activate.delay = IFS_THREAD_WAIT;
@@ -258,6 +317,7 @@ static void ifs_test_core(int cpu, struct device *dev)
while (to_start <= to_stop) {
if (time_after(jiffies, timeout)) {
status.error_code = IFS_SW_TIMEOUT;
+ update_group_status(dev, IFS_SW_TIMEOUT);
break;
}
@@ -272,15 +332,17 @@ static void ifs_test_core(int cpu, struct device *dev)
status = params.status;
/* Some cases can be retried, give up for others */
- if (!can_restart(status))
+ if (!can_restart_test_group(dev))
break;
status_chunk = ifsd->generation ? status.gen2.chunk_num : status.gen0.chunk_num;
if (status_chunk == to_start) {
/* Check for forward progress */
if (--retries == 0) {
- if (status.error_code == IFS_NO_ERROR)
+ if (status.error_code == IFS_NO_ERROR) {
status.error_code = IFS_SW_PARTIAL_COMPLETION;
+ update_group_status(dev, IFS_SW_PARTIAL_COMPLETION);
+ }
break;
}
} else {
@@ -295,16 +357,7 @@ static void ifs_test_core(int cpu, struct device *dev)
/* Update status for this core */
ifsd->scan_details = status.data;
-
- if (status.signature_error) {
- ifsd->status = SCAN_TEST_FAIL;
- message_fail(dev, cpu, status);
- } else if (status.control_error || status.error_code) {
- ifsd->status = SCAN_NOT_TESTED;
- message_not_tested(dev, cpu, status);
- } else {
- ifsd->status = SCAN_TEST_PASS;
- }
+ update_group_result(dev, to_stop);
}
static int do_array_test(void *data)
@@ -313,7 +366,6 @@ static int do_array_test(void *data)
int cpu = smp_processor_id();
union ifs_array *command;
struct ifs_data *ifsd;
- int first;
ifsd = params->ifsd;
@@ -323,9 +375,7 @@ static int do_array_test(void *data)
/*
* Only one logical CPU on a core needs to trigger the Array test via MSR write.
*/
- first = cpumask_first(&ifsd->grp_cpumask);
-
- if (cpu == first) {
+ if (cpu == ifsd->cpu) {
wrmsrq(MSR_ARRAY_BIST, command->data);
/* Pass back the result of the test */
rdmsrq(MSR_ARRAY_BIST, command->data);
@@ -343,6 +393,7 @@ static void ifs_array_test_core(int cpu, struct device *dev)
unsigned long timeout;
ifsd = ifs_get_data(dev);
+ ifsd->cpu = cpu;
params.ifsd = ifsd;
command.array_bitmask = ~0U;
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 12/17] platform/x86/intel/ifs: Add new sysfs interfaces {status, details, cpus_ran}_list
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (10 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 11/17] platform/x86/intel/ifs: Track and report scan results on a per-CPU basis Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 13/17] platform/x86/intel/ifs: Add additional details sysfs interface Ehab Ababneh
` (4 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
Problem
=======
The current legacy interface for Intel In-Field Scan is designed to
simultaneously test all CPUs in a group [1], but it only reports the
status of the primary CPU in this group and doesn't indicate that
secondary CPUs have been tested. This results in the following issues:
- All CPUs in a group can hold different statuses, but the user can
only see the status of the primary CPU, as any errors observed by
secondary CPUs are ignored.
- The topology of a group of CPUs may vary across systems. For example,
in a Hyper-Threading (HT) system, the group consists of all CPUs in
a core, while in a Dual-Core Module (DCM) based system (e.g., Intel
Diamond Rapids CPU), two cores in a module form a group. The user may
be unaware of the group topology and test each CPU of the system
individually, leading to duplicate test runs.
Solution
========
The user continues to write a single value to run_test, and while the
legacy sysfs reports results for the tested CPU to ensure backward
compatibility, new sysfs interfaces {status, details, cpus_run}_list
provide results for multiple related CPUs tested as part of a group.
The user can check for the presence of new sysfs interfaces to
understand that multiple results are available, read them, and identify
which CPUs have been tested to avoid duplicate tests.
intel_ifs_0
+---- run_test <--- Same legacy file
+---- current_batch
+---- details
+---- details_list <--- Details for all CPUs in the group (new)
+---- dev
+---- image_version
+---- status
+---- status_list <--- Status for all CPUs in the group (new)
+---- cpus_ran_list <--- CPUs in the group tested along with CPU written to run_test (new)
\---- uevent
Example of reading the cpus_ran_list to see the CPUs tested:
echo 0 > run_test
cat cpus_ran_list
0,96
cat status_list
pass pass
cat details_list
0x8086 0x8087
[1] Indicated by bits [20:16] of MSR_INTEGRITY_CAPABILITIES when bit 21 is set.
E.g., in Hyper-Threading (HT) systems, a group includes all threads in a core;
in Dual-Core Module (DCM) system, a group includes all CPU cores in a module.
[ Qiuxu: wrote the commit message. ]
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/sysfs.c | 56 ++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/intel/ifs/sysfs.c
index 287f96bb033e..82a603cd1fd3 100644
--- a/drivers/platform/x86/intel/ifs/sysfs.c
+++ b/drivers/platform/x86/intel/ifs/sysfs.c
@@ -135,6 +135,59 @@ static ssize_t image_version_show(struct device *dev,
static DEVICE_ATTR_RO(image_version);
+static ssize_t status_list_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_state;
+ int lcpu, len = 0;
+
+ if (cpumask_weight(&ifsd->grp_cpumask) == 0)
+ return sysfs_emit(buf, "%s\n", "none");
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_state = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ len += sysfs_emit_at(buf, len, "%s%s", (len > 0) ? " " : "",
+ status_msg[pcpu_state->test_result]);
+ }
+ len += sysfs_emit_at(buf, len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR_RO(status_list);
+
+static ssize_t details_list_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_state;
+ int lcpu, len = 0;
+
+ if (cpumask_weight(&ifsd->grp_cpumask) == 0)
+ return sysfs_emit(buf, "%s\n", "none");
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_state = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ len += sysfs_emit_at(buf, len, "%s%#llx", (len > 0) ? " " : "",
+ pcpu_state->test_details);
+ }
+ len += sysfs_emit_at(buf, len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR_RO(details_list);
+
+static ssize_t cpus_ran_list_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+
+ if (cpumask_weight(&ifsd->grp_cpumask) == 0)
+ return sysfs_emit(buf, "%s\n", "none");
+
+ return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(&ifsd->grp_cpumask));
+}
+
+static DEVICE_ATTR_RO(cpus_ran_list);
/* global scan sysfs attributes */
struct attribute *plat_ifs_attrs[] = {
&dev_attr_details.attr,
@@ -142,6 +195,9 @@ struct attribute *plat_ifs_attrs[] = {
&dev_attr_run_test.attr,
&dev_attr_current_batch.attr,
&dev_attr_image_version.attr,
+ &dev_attr_status_list.attr,
+ &dev_attr_details_list.attr,
+ &dev_attr_cpus_ran_list.attr,
NULL
};
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 13/17] platform/x86/intel/ifs: Add additional details sysfs interface
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (11 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 12/17] platform/x86/intel/ifs: Add new sysfs interfaces {status, details, cpus_ran}_list Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 14/17] platform/x86/intel/ifs: Add Intel Diamond Rapids server support Ehab Ababneh
` (3 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
The MSR_LAST_SAF_WP register provides information about the core when
the last WRMSR(ACTIVATE_SCAN) was executed. It is available only if
enumerated in bits [10:9] of MSR_INTEGRITY_CAPABILITIES.
Add a new sysfs interface, addnl_details_list, to the user space to
provide additional details about the last In-Field Scan testing.
[ Qiuxu: wrote the commit message. ]
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/ifs.h | 2 ++
drivers/platform/x86/intel/ifs/runtest.c | 4 ++++
drivers/platform/x86/intel/ifs/sysfs.c | 23 +++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index 1043378c60e5..3f11ae08dce1 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -139,6 +139,7 @@
#define MSR_CHUNKS_AUTHENTICATION_STATUS 0x000002c5
#define MSR_ACTIVATE_SCAN 0x000002c6
#define MSR_SCAN_STATUS 0x000002c7
+#define MSR_LAST_SAF_WP 0x000002c9
#define MSR_ARRAY_TRIGGER 0x000002d6
#define MSR_ARRAY_STATUS 0x000002d7
#define MSR_SAF_CTRL 0x000004f0
@@ -332,6 +333,7 @@ struct ifs_device {
struct ifs_test_output {
u64 test_details;
+ u64 addnl_details;
int test_result;
};
diff --git a/drivers/platform/x86/intel/ifs/runtest.c b/drivers/platform/x86/intel/ifs/runtest.c
index 6c3d025817e7..d5303dd72233 100644
--- a/drivers/platform/x86/intel/ifs/runtest.c
+++ b/drivers/platform/x86/intel/ifs/runtest.c
@@ -177,6 +177,7 @@ static int doscan(void *data)
struct run_params *params = data;
union ifs_status status;
struct ifs_data *ifsd;
+ u64 saf_wp = 0;
ifsd = params->ifsd;
pcpu_scan = this_cpu_ptr(ifsd->result_ptr);
@@ -202,6 +203,8 @@ static int doscan(void *data)
wrmsrq(MSR_ACTIVATE_SCAN, params->activate->data);
rdmsrq(MSR_SCAN_STATUS, status.data);
+ if (ifsd->generation)
+ rdmsrq(MSR_LAST_SAF_WP, saf_wp);
trace_ifs_status(ifsd->cur_batch, start, stop, status.data);
/* Pass back the result of the scan */
@@ -209,6 +212,7 @@ static int doscan(void *data)
params->status = status;
pcpu_scan->test_details = status.data;
+ pcpu_scan->addnl_details = saf_wp;
return 0;
}
diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/intel/ifs/sysfs.c
index 82a603cd1fd3..3cbab2acca72 100644
--- a/drivers/platform/x86/intel/ifs/sysfs.c
+++ b/drivers/platform/x86/intel/ifs/sysfs.c
@@ -188,6 +188,28 @@ static ssize_t cpus_ran_list_show(struct device *dev, struct device_attribute *a
}
static DEVICE_ATTR_RO(cpus_ran_list);
+
+static ssize_t addnl_details_list_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ifs_data *ifsd = ifs_get_data(dev);
+ struct ifs_test_output *pcpu_state;
+ int lcpu, len = 0;
+
+ if (cpumask_weight(&ifsd->grp_cpumask) == 0)
+ return sysfs_emit(buf, "%s\n", "none");
+
+ for_each_cpu(lcpu, &ifsd->grp_cpumask) {
+ pcpu_state = per_cpu_ptr(ifsd->result_ptr, lcpu);
+ len += sysfs_emit_at(buf, len, "%s%#llx", (len > 0) ? " " : "",
+ pcpu_state->addnl_details);
+ }
+ len += sysfs_emit_at(buf, len, "\n");
+
+ return len;
+}
+
+static DEVICE_ATTR_RO(addnl_details_list);
+
/* global scan sysfs attributes */
struct attribute *plat_ifs_attrs[] = {
&dev_attr_details.attr,
@@ -198,6 +220,7 @@ struct attribute *plat_ifs_attrs[] = {
&dev_attr_status_list.attr,
&dev_attr_details_list.attr,
&dev_attr_cpus_ran_list.attr,
+ &dev_attr_addnl_details_list.attr,
NULL
};
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 14/17] platform/x86/intel/ifs: Add Intel Diamond Rapids server support
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (12 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 13/17] platform/x86/intel/ifs: Add additional details sysfs interface Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 15/17] platform/x86/intel/ifs: Remove limit on number of batch files Ehab Ababneh
` (2 subsequent siblings)
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Jithu Joseph <jithu.joseph@intel.com>
Intel Diamond Rapids CPU is a Dual-Core Module (DCM) based system
where two cores in a module form a group that must simultaneously
run the In-Field Scan (IFS) testing. The intel_ifs driver already
supports IFS for this type of DCM-based system. Add the Diamond
Rapids CPU model ID for IFS support.
[ Qiuxu: wrote the commit message. ]
Signed-off-by: Jithu Joseph <jithu.joseph@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c
index 08a3e519749b..5c9c86e04837 100644
--- a/drivers/platform/x86/intel/ifs/core.c
+++ b/drivers/platform/x86/intel/ifs/core.c
@@ -24,6 +24,7 @@ static const struct x86_cpu_id ifs_cpu_ids[] __initconst = {
X86_MATCH(INTEL_GRANITERAPIDS_D, ARRAY_GEN0),
X86_MATCH(INTEL_ATOM_CRESTMONT_X, ARRAY_GEN1),
X86_MATCH(INTEL_ATOM_DARKMONT_X, ARRAY_GEN1),
+ X86_MATCH(INTEL_DIAMONDRAPIDS_X, ARRAY_GEN0),
{}
};
MODULE_DEVICE_TABLE(x86cpu, ifs_cpu_ids);
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 15/17] platform/x86/intel/ifs: Remove limit on number of batch files
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (13 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 14/17] platform/x86/intel/ifs: Add Intel Diamond Rapids server support Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 16/17] platform/x86/intel/ifs: Update IFS documentation Ehab Ababneh
2026-10-26 18:38 ` [PATCH 17/17] Documentation/ABI: Update IFS ABI doc Ehab Ababneh
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Tony Luck <tony.luck@intel.com>
Writing to the current_batch sysfs file rejects batch numbers above
0xff. That limit was expected to be enough, but Diamond Rapids needs
more than 256 IFS test image (batch) files.
Remove the limit check on the batch number supplied by the user.
[ Qiuxu: Update IFS ABI documentation to reflect the change. ]
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
Documentation/ABI/testing/sysfs-platform-intel-ifs | 9 ++++++---
drivers/platform/x86/intel/ifs/sysfs.c | 2 +-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-platform-intel-ifs b/Documentation/ABI/testing/sysfs-platform-intel-ifs
index 41b4d5b1e21c..76770648e63e 100644
--- a/Documentation/ABI/testing/sysfs-platform-intel-ifs
+++ b/Documentation/ABI/testing/sysfs-platform-intel-ifs
@@ -44,9 +44,12 @@ What: /sys/devices/virtual/misc/intel_ifs_<N>/current_batch
Date: Nov 16 2022
KernelVersion: 6.2
Contact: "Jithu Joseph" <jithu.joseph@intel.com>
-Description: Write a number less than or equal to 0xff to load an IFS test image.
- The number written treated as the 2 digit suffix in the following file name:
- /lib/firmware/intel/ifs_<N>/ff-mm-ss-02x.scan
+Description: Write a number to load an IFS test image.
+ The number written is used as the <batch> suffix in the following file name:
+ /lib/firmware/intel/ifs_<N>/ff-mm-ss-<batch>.scan
+ where ff, mm and ss are the CPU family, model and stepping, and <batch> is
+ the number written, in lowercase hex, zero-padded to at least 2 digits
+ (e.g. 02, ff, 100).
Reading the file will provide the suffix of the currently loaded IFS test image.
This file is present only for device instances where a test image is applicable.
Devices: intel_ifs_0
diff --git a/drivers/platform/x86/intel/ifs/sysfs.c b/drivers/platform/x86/intel/ifs/sysfs.c
index 3cbab2acca72..7b4c7f21000a 100644
--- a/drivers/platform/x86/intel/ifs/sysfs.c
+++ b/drivers/platform/x86/intel/ifs/sysfs.c
@@ -91,7 +91,7 @@ static ssize_t current_batch_store(struct device *dev,
int rc;
rc = kstrtouint(buf, 0, &cur_batch);
- if (rc < 0 || cur_batch > 0xff)
+ if (rc < 0)
return -EINVAL;
if (down_interruptible(&ifs_sem))
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 16/17] platform/x86/intel/ifs: Update IFS documentation
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (14 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 15/17] platform/x86/intel/ifs: Remove limit on number of batch files Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
2026-10-26 18:38 ` [PATCH 17/17] Documentation/ABI: Update IFS ABI doc Ehab Ababneh
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Update the simultaneous IFS testing domain in the IFS documentation from
a core to a group that shares the same SCAN engine, which works for both
the traditional Hyper-Threading (HT) systems and the Dual-Core Module (DCM)
based systems (e.g., Diamond Rapids).
Add documentation for the new sysfs interfaces {status, details,
additional_details, cpus_ran}_list.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
drivers/platform/x86/intel/ifs/ifs.h | 64 +++++++++++++++++++---------
1 file changed, 43 insertions(+), 21 deletions(-)
diff --git a/drivers/platform/x86/intel/ifs/ifs.h b/drivers/platform/x86/intel/ifs/ifs.h
index 3f11ae08dce1..551202f86cea 100644
--- a/drivers/platform/x86/intel/ifs/ifs.h
+++ b/drivers/platform/x86/intel/ifs/ifs.h
@@ -14,11 +14,11 @@
* Introduction
* ------------
*
- * In Field Scan (IFS) is a hardware feature to run circuit level tests on
- * a CPU core to detect problems that are not caught by parity or ECC checks.
- * Future CPUs will support more than one type of test which will show up
- * with a new platform-device instance-id.
- *
+ * In-Field Scan (IFS) is a hardware feature that runs circuit-level tests on
+ * all CPUs in a group, where all CPUs share the same SCAN test engine to
+ * detect problems that are not caught by parity or ECC checks. Future CPUs
+ * will support more than one type of test, which will show up with a new
+ * platform-device instance-id.
*
* IFS Image
* ---------
@@ -59,19 +59,19 @@
* Running tests
* -------------
*
- * Tests are run by the driver synchronizing execution of all threads on a
- * core and then writing to the ACTIVATE_SCAN MSR on all threads. Instruction
- * execution continues when:
+ * Tests are run by the driver synchronizing execution of all CPUs in a group
+ * that share the same SCAN test engine, then writing to the ACTIVATE_SCAN MSR
+ * on all CPUs. Instruction execution continues when:
*
* 1) All tests have completed.
* 2) Execution was interrupted.
* 3) A test detected a problem.
*
- * Note that ALL THREADS ON THE CORE ARE EFFECTIVELY OFFLINE FOR THE
+ * Note that ALL CPUs IN THE GROUP ARE EFFECTIVELY OFFLINE FOR THE
* DURATION OF THE TEST. This can be up to 200 milliseconds. If the system
- * is running latency sensitive applications that cannot tolerate an
+ * is running latency-sensitive applications that cannot tolerate an
* interruption of this magnitude, the system administrator must arrange
- * to migrate those applications to other cores before running a core test.
+ * to migrate those applications to other CPUs before running a group test.
* It may also be necessary to redirect interrupts to other CPUs.
*
* In all cases reading the corresponding test's STATUS MSR provides details on what
@@ -81,30 +81,52 @@
* The IFS driver provides sysfs interfaces via /sys/devices/virtual/misc/intel_ifs_<n>/
* to control execution:
*
- * Test a specific core::
+ * Test a specific group::
*
* # echo <CPU#> > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
*
- * when HT is enabled any of the sibling CPU# can be specified to test
- * its corresponding physical core. Since the tests are per physical core,
- * the result of testing any thread is same. All siblings must be online
- * to run a core test. It is only necessary to test one thread.
+ * Any CPU in the same group that shares the same SCAN test engin can be
+ * specified to test its corresponding group. All CPUs in the same group
+ * must be online to run a group test. It is only necessary to test one
+ * CPU in the group.
*
- * For e.g. to test core corresponding to CPU5
+ * For e.g. to test a group corresponding to CPU5
*
* # echo 5 > /sys/devices/virtual/misc/intel_ifs_<n>/run_test
*
- * Results of the last test is provided in /sys::
+ * The result of the last test for the primary CPU in the group is provided in /sys::
*
* $ cat /sys/devices/virtual/misc/intel_ifs_<n>/status
* pass
*
- * Status can be one of pass, fail, untested
+ * Status can be one of pass, fail, untested.
*
- * Additional details of the last test is provided by the details file::
+ * Additional details of the last test for the primary CPU in the group are provided in /sys::
*
* $ cat /sys/devices/virtual/misc/intel_ifs_<n>/details
- * 0x8081
+ * 0x7f0080
+ *
+ * For intel_ifs_0, there are following additional sysfs files:
+ *
+ * All CPUs in the same group that ran the test are provided in /sys::
+ *
+ * $ cat /sys/devices/virtual/misc/intel_ifs_0/cpus_ran_list
+ * 5,149
+ *
+ * The results of the last test for all CPUs in the same group are provided in /sys::
+ *
+ * $ cat /sys/devices/virtual/misc/intel_ifs_0/status_list
+ * pass pass
+ *
+ * Additional details of the last test for all CPUs in the same group are provided in /sys::
+ *
+ * $ cat /sys/devices/virtual/misc/intel_ifs_0/details_list
+ * 0x7f0080 0x7f0080
+ *
+ * More additional details of the last test for all CPUs in the same group are provided in /sys::
+ *
+ * $ cat /sys/devices/virtual/misc/intel_ifs_0/addnl_details_list
+ * 0xc44191a 0xc44191a
*
* The details file reports the hex value of the test specific status MSR.
* Hardware defined error codes are documented in volume 4 of the Intel
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 17/17] Documentation/ABI: Update IFS ABI doc
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
` (15 preceding siblings ...)
2026-10-26 18:38 ` [PATCH 16/17] platform/x86/intel/ifs: Update IFS documentation Ehab Ababneh
@ 2026-10-26 18:38 ` Ehab Ababneh
16 siblings, 0 replies; 18+ messages in thread
From: Ehab Ababneh @ 2026-10-26 18:38 UTC (permalink / raw)
To: ilpo.jarvinen, hansg, tony.luck
Cc: ashok.raj.linux, platform-driver-x86, linux-kernel, tglx, mingo,
bp, dave.hansen, x86, hpa, rostedt, mhiramat, mathieu.desnoyers,
linux-trace-kernel, peterz, sathyanarayanan.kuppuswamy,
pengfei.xu, ravi.v.shankar
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Add documentation for the new sysfs interfaces {status, details,
additional_details, cpus_ran}_list.
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Ehab Ababneh <ehab.ababneh@intel.com>
---
.../ABI/testing/sysfs-platform-intel-ifs | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-platform-intel-ifs b/Documentation/ABI/testing/sysfs-platform-intel-ifs
index 76770648e63e..dc33d8f62c3f 100644
--- a/Documentation/ABI/testing/sysfs-platform-intel-ifs
+++ b/Documentation/ABI/testing/sysfs-platform-intel-ifs
@@ -53,3 +53,27 @@ Description: Write a number to load an IFS test image.
Reading the file will provide the suffix of the currently loaded IFS test image.
This file is present only for device instances where a test image is applicable.
Devices: intel_ifs_0
+
+What: /sys/devices/virtual/misc/intel_ifs_<N>/cpus_ran_list
+Date: Mar 3 2025
+Contact: "Qiuxu Zhuo" <qiuxu.zhuo@intel.com>
+Description: The CPU list of the last test. These CPUs share the same SCAN test engine.
+Devices: intel_ifs_0
+
+What: /sys/devices/virtual/misc/intel_ifs_<N>/status_list
+Date: Mar 3 2025
+Contact: "Qiuxu Zhuo" <qiuxu.zhuo@intel.com>
+Description: The status list of the last test for CPUs sharing the same SCAN test engine.
+Devices: intel_ifs_0
+
+What: /sys/devices/virtual/misc/intel_ifs_<N>/details_list
+Date: Mar 3 2025
+Contact: "Qiuxu Zhuo" <qiuxu.zhuo@intel.com>
+Description: The detail status list of the last test for CPUs sharing the same SCAN test engine.
+Devices: intel_ifs_0
+
+What: /sys/devices/virtual/misc/intel_ifs_<N>/addnl_details_list
+Date: Mar 3 2025
+Contact: "Qiuxu Zhuo" <qiuxu.zhuo@intel.com>
+Description: The additional detail status list of the last test for CPUs sharing the same SCAN test engine.
+Devices: intel_ifs_0
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-10-26 18:35 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 18:38 [PATCH 00/17] platform/x86/intel/ifs: Support group-based In-Field Scan and Diamond Rapids Ehab Ababneh
2026-10-26 18:38 ` [PATCH 01/17] platform/x86/intel/ifs: Revert SBAF feature Ehab Ababneh
2026-10-26 18:38 ` [PATCH 02/17] platform/x86/intel/ifs: Fix IFS sysfs interfaces in the comments Ehab Ababneh
2026-10-26 18:38 ` [PATCH 03/17] platform/x86/intel/ifs: Clarify In-Field Scan MSR bit macro definitions Ehab Ababneh
2026-10-26 18:38 ` [PATCH 04/17] platform/x86/intel/ifs: Use u64 to define the bits of IFS MSR registers Ehab Ababneh
2026-10-26 18:38 ` [PATCH 05/17] platform/x86/intel/ifs: Early return on the IFS image hash/chunk error Ehab Ababneh
2026-10-26 18:38 ` [PATCH 06/17] platform/x86/intel/ifs: Refactor Array BIST function interface Ehab Ababneh
2026-10-26 18:38 ` [PATCH 07/17] stop_machine: Add stop_cluster_cpuslocked() for per-cluster operations Ehab Ababneh
2026-10-26 18:38 ` [PATCH 08/17] platform/x86/intel/ifs: Enumerate the bit to determine if CPUs need to join for IFS tests Ehab Ababneh
2026-10-26 18:38 ` [PATCH 09/17] platform/x86/intel/ifs: Select CPUs from topology_cluster_cpumask() for simultaneous " Ehab Ababneh
2026-10-26 18:38 ` [PATCH 10/17] platform/x86/intel/ifs: Validate TID_BIT_SHIFT matches topology_cluster_cpumask() Ehab Ababneh
2026-10-26 18:38 ` [PATCH 11/17] platform/x86/intel/ifs: Track and report scan results on a per-CPU basis Ehab Ababneh
2026-10-26 18:38 ` [PATCH 12/17] platform/x86/intel/ifs: Add new sysfs interfaces {status, details, cpus_ran}_list Ehab Ababneh
2026-10-26 18:38 ` [PATCH 13/17] platform/x86/intel/ifs: Add additional details sysfs interface Ehab Ababneh
2026-10-26 18:38 ` [PATCH 14/17] platform/x86/intel/ifs: Add Intel Diamond Rapids server support Ehab Ababneh
2026-10-26 18:38 ` [PATCH 15/17] platform/x86/intel/ifs: Remove limit on number of batch files Ehab Ababneh
2026-10-26 18:38 ` [PATCH 16/17] platform/x86/intel/ifs: Update IFS documentation Ehab Ababneh
2026-10-26 18:38 ` [PATCH 17/17] Documentation/ABI: Update IFS ABI doc Ehab Ababneh
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®