1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2022 Intel Corporation. */
5 #include <linux/delay.h>
8 #include <linux/slab.h>
9 #include <linux/stop_machine.h>
14 * Note all code and data in this file is protected by
15 * ifs_sem. On HT systems all threads on a core will
16 * execute together, but only the first thread on the
17 * core will update results of the test.
20 #define CREATE_TRACE_POINTS
21 #include <trace/events/intel_ifs.h>
23 /* Max retries on the same chunk */
24 #define MAX_IFS_RETRIES 5
27 struct ifs_data
*ifsd
;
28 union ifs_scan
*activate
;
29 union ifs_status status
;
32 struct sbaf_run_params
{
33 struct ifs_data
*ifsd
;
35 union ifs_sbaf
*activate
;
36 union ifs_sbaf_status status
;
40 * Number of TSC cycles that a logical CPU will wait for the other
41 * logical CPU on the core in the WRMSR(ACTIVATE_SCAN).
43 #define IFS_THREAD_WAIT 100000
45 enum ifs_status_err_code
{
47 IFS_OTHER_THREAD_COULD_NOT_JOIN
= 1,
48 IFS_INTERRUPTED_BEFORE_RENDEZVOUS
= 2,
49 IFS_POWER_MGMT_INADEQUATE_FOR_SCAN
= 3,
50 IFS_INVALID_CHUNK_RANGE
= 4,
51 IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS
= 5,
52 IFS_CORE_NOT_CAPABLE_CURRENTLY
= 6,
53 IFS_UNASSIGNED_ERROR_CODE
= 7,
54 IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT
= 8,
55 IFS_INTERRUPTED_DURING_EXECUTION
= 9,
56 IFS_UNASSIGNED_ERROR_CODE_0xA
= 0xA,
57 IFS_CORRUPTED_CHUNK
= 0xB,
60 static const char * const scan_test_status
[] = {
61 [IFS_NO_ERROR
] = "SCAN no error",
62 [IFS_OTHER_THREAD_COULD_NOT_JOIN
] = "Other thread could not join.",
63 [IFS_INTERRUPTED_BEFORE_RENDEZVOUS
] = "Interrupt occurred prior to SCAN coordination.",
64 [IFS_POWER_MGMT_INADEQUATE_FOR_SCAN
] =
65 "Core Abort SCAN Response due to power management condition.",
66 [IFS_INVALID_CHUNK_RANGE
] = "Non valid chunks in the range",
67 [IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS
] = "Mismatch in arguments between threads T0/T1.",
68 [IFS_CORE_NOT_CAPABLE_CURRENTLY
] = "Core not capable of performing SCAN currently",
69 [IFS_UNASSIGNED_ERROR_CODE
] = "Unassigned error code 0x7",
70 [IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT
] =
71 "Exceeded number of Logical Processors (LP) allowed to run Scan-At-Field concurrently",
72 [IFS_INTERRUPTED_DURING_EXECUTION
] = "Interrupt occurred prior to SCAN start",
73 [IFS_UNASSIGNED_ERROR_CODE_0xA
] = "Unassigned error code 0xA",
74 [IFS_CORRUPTED_CHUNK
] = "Scan operation aborted due to corrupted image. Try reloading",
77 static void message_not_tested(struct device
*dev
, int cpu
, union ifs_status status
)
79 struct ifs_data
*ifsd
= ifs_get_data(dev
);
82 * control_error is set when the microcode runs into a problem
83 * loading the image from the reserved BIOS memory, or it has
84 * been corrupted. Reloading the image may fix this issue.
86 if (status
.control_error
) {
87 dev_warn(dev
, "CPU(s) %*pbl: Scan controller error. Batch: %02x version: 0x%x\n",
88 cpumask_pr_args(cpu_smt_mask(cpu
)), ifsd
->cur_batch
, ifsd
->loaded_version
);
92 if (status
.error_code
< ARRAY_SIZE(scan_test_status
)) {
93 dev_info(dev
, "CPU(s) %*pbl: SCAN operation did not start. %s\n",
94 cpumask_pr_args(cpu_smt_mask(cpu
)),
95 scan_test_status
[status
.error_code
]);
96 } else if (status
.error_code
== IFS_SW_TIMEOUT
) {
97 dev_info(dev
, "CPU(s) %*pbl: software timeout during scan\n",
98 cpumask_pr_args(cpu_smt_mask(cpu
)));
99 } else if (status
.error_code
== IFS_SW_PARTIAL_COMPLETION
) {
100 dev_info(dev
, "CPU(s) %*pbl: %s\n",
101 cpumask_pr_args(cpu_smt_mask(cpu
)),
102 "Not all scan chunks were executed. Maximum forward progress retries exceeded");
104 dev_info(dev
, "CPU(s) %*pbl: SCAN unknown status %llx\n",
105 cpumask_pr_args(cpu_smt_mask(cpu
)), status
.data
);
109 static void message_fail(struct device
*dev
, int cpu
, union ifs_status status
)
111 struct ifs_data
*ifsd
= ifs_get_data(dev
);
114 * signature_error is set when the output from the scan chains does not
115 * match the expected signature. This might be a transient problem (e.g.
116 * due to a bit flip from an alpha particle or neutron). If the problem
117 * repeats on a subsequent test, then it indicates an actual problem in
118 * the core being tested.
120 if (status
.signature_error
) {
121 dev_err(dev
, "CPU(s) %*pbl: test signature incorrect. Batch: %02x version: 0x%x\n",
122 cpumask_pr_args(cpu_smt_mask(cpu
)), ifsd
->cur_batch
, ifsd
->loaded_version
);
126 static bool can_restart(union ifs_status status
)
128 enum ifs_status_err_code err_code
= status
.error_code
;
130 /* Signature for chunk is bad, or scan test failed */
131 if (status
.signature_error
|| status
.control_error
)
136 case IFS_OTHER_THREAD_COULD_NOT_JOIN
:
137 case IFS_INTERRUPTED_BEFORE_RENDEZVOUS
:
138 case IFS_POWER_MGMT_INADEQUATE_FOR_SCAN
:
139 case IFS_EXCEED_NUMBER_OF_THREADS_CONCURRENT
:
140 case IFS_INTERRUPTED_DURING_EXECUTION
:
142 case IFS_INVALID_CHUNK_RANGE
:
143 case IFS_MISMATCH_ARGUMENTS_BETWEEN_THREADS
:
144 case IFS_CORE_NOT_CAPABLE_CURRENTLY
:
145 case IFS_UNASSIGNED_ERROR_CODE
:
146 case IFS_UNASSIGNED_ERROR_CODE_0xA
:
147 case IFS_CORRUPTED_CHUNK
:
153 #define SPINUNIT 100 /* 100 nsec */
154 static atomic_t array_cpus_in
;
155 static atomic_t scan_cpus_in
;
156 static atomic_t sbaf_cpus_in
;
159 * Simplified cpu sibling rendezvous loop based on microcode loader __wait_for_cpus()
161 static void wait_for_sibling_cpu(atomic_t
*t
, long long timeout
)
163 int cpu
= smp_processor_id();
164 const struct cpumask
*smt_mask
= cpu_smt_mask(cpu
);
165 int all_cpus
= cpumask_weight(smt_mask
);
168 while (atomic_read(t
) < all_cpus
) {
169 if (timeout
< SPINUNIT
)
173 touch_nmi_watchdog();
178 * Execute the scan. Called "simultaneously" on all threads of a core
179 * at high priority using the stop_cpus mechanism.
181 static int doscan(void *data
)
183 int cpu
= smp_processor_id(), start
, stop
;
184 struct run_params
*params
= data
;
185 union ifs_status status
;
186 struct ifs_data
*ifsd
;
191 if (ifsd
->generation
) {
192 start
= params
->activate
->gen2
.start
;
193 stop
= params
->activate
->gen2
.stop
;
195 start
= params
->activate
->gen0
.start
;
196 stop
= params
->activate
->gen0
.stop
;
199 /* Only the first logical CPU on a core reports result */
200 first
= cpumask_first(cpu_smt_mask(cpu
));
202 wait_for_sibling_cpu(&scan_cpus_in
, NSEC_PER_SEC
);
205 * This WRMSR will wait for other HT threads to also write
206 * to this MSR (at most for activate.delay cycles). Then it
207 * starts scan of each requested chunk. The core scan happens
208 * during the "execution" of the WRMSR. This instruction can
209 * take up to 200 milliseconds (in the case where all chunks
210 * are processed in a single pass) before it retires.
212 wrmsrl(MSR_ACTIVATE_SCAN
, params
->activate
->data
);
213 rdmsrl(MSR_SCAN_STATUS
, status
.data
);
215 trace_ifs_status(ifsd
->cur_batch
, start
, stop
, status
.data
);
217 /* Pass back the result of the scan */
219 params
->status
= status
;
225 * Use stop_core_cpuslocked() to synchronize writing to MSR_ACTIVATE_SCAN
226 * on all threads of the core to be tested. Loop if necessary to complete
227 * run of all chunks. Include some defensive tests to make sure forward
228 * progress is made, and that the whole test completes in a reasonable time.
230 static void ifs_test_core(int cpu
, struct device
*dev
)
232 union ifs_status status
= {};
233 union ifs_scan activate
;
234 unsigned long timeout
;
235 struct ifs_data
*ifsd
;
236 int to_start
, to_stop
;
238 struct run_params params
;
241 ifsd
= ifs_get_data(dev
);
243 activate
.gen0
.rsvd
= 0;
244 activate
.delay
= IFS_THREAD_WAIT
;
247 to_stop
= ifsd
->valid_chunks
- 1;
249 params
.ifsd
= ifs_get_data(dev
);
251 if (ifsd
->generation
) {
252 activate
.gen2
.start
= to_start
;
253 activate
.gen2
.stop
= to_stop
;
255 activate
.gen0
.start
= to_start
;
256 activate
.gen0
.stop
= to_stop
;
259 timeout
= jiffies
+ HZ
/ 2;
260 retries
= MAX_IFS_RETRIES
;
262 while (to_start
<= to_stop
) {
263 if (time_after(jiffies
, timeout
)) {
264 status
.error_code
= IFS_SW_TIMEOUT
;
268 params
.activate
= &activate
;
269 atomic_set(&scan_cpus_in
, 0);
270 stop_core_cpuslocked(cpu
, doscan
, ¶ms
);
272 status
= params
.status
;
274 /* Some cases can be retried, give up for others */
275 if (!can_restart(status
))
278 status_chunk
= ifsd
->generation
? status
.gen2
.chunk_num
: status
.gen0
.chunk_num
;
279 if (status_chunk
== to_start
) {
280 /* Check for forward progress */
281 if (--retries
== 0) {
282 if (status
.error_code
== IFS_NO_ERROR
)
283 status
.error_code
= IFS_SW_PARTIAL_COMPLETION
;
287 retries
= MAX_IFS_RETRIES
;
288 if (ifsd
->generation
)
289 activate
.gen2
.start
= status_chunk
;
291 activate
.gen0
.start
= status_chunk
;
292 to_start
= status_chunk
;
296 /* Update status for this core */
297 ifsd
->scan_details
= status
.data
;
299 if (status
.signature_error
) {
300 ifsd
->status
= SCAN_TEST_FAIL
;
301 message_fail(dev
, cpu
, status
);
302 } else if (status
.control_error
|| status
.error_code
) {
303 ifsd
->status
= SCAN_NOT_TESTED
;
304 message_not_tested(dev
, cpu
, status
);
306 ifsd
->status
= SCAN_TEST_PASS
;
310 static int do_array_test(void *data
)
312 union ifs_array
*command
= data
;
313 int cpu
= smp_processor_id();
316 wait_for_sibling_cpu(&array_cpus_in
, NSEC_PER_SEC
);
319 * Only one logical CPU on a core needs to trigger the Array test via MSR write.
321 first
= cpumask_first(cpu_smt_mask(cpu
));
324 wrmsrl(MSR_ARRAY_BIST
, command
->data
);
325 /* Pass back the result of the test */
326 rdmsrl(MSR_ARRAY_BIST
, command
->data
);
332 static void ifs_array_test_core(int cpu
, struct device
*dev
)
334 union ifs_array command
= {};
335 bool timed_out
= false;
336 struct ifs_data
*ifsd
;
337 unsigned long timeout
;
339 ifsd
= ifs_get_data(dev
);
341 command
.array_bitmask
= ~0U;
342 timeout
= jiffies
+ HZ
/ 2;
345 if (time_after(jiffies
, timeout
)) {
349 atomic_set(&array_cpus_in
, 0);
350 stop_core_cpuslocked(cpu
, do_array_test
, &command
);
352 if (command
.ctrl_result
)
354 } while (command
.array_bitmask
);
356 ifsd
->scan_details
= command
.data
;
358 if (command
.ctrl_result
)
359 ifsd
->status
= SCAN_TEST_FAIL
;
360 else if (timed_out
|| command
.array_bitmask
)
361 ifsd
->status
= SCAN_NOT_TESTED
;
363 ifsd
->status
= SCAN_TEST_PASS
;
366 #define ARRAY_GEN1_TEST_ALL_ARRAYS 0x0ULL
367 #define ARRAY_GEN1_STATUS_FAIL 0x1ULL
369 static int do_array_test_gen1(void *status
)
371 int cpu
= smp_processor_id();
374 first
= cpumask_first(cpu_smt_mask(cpu
));
377 wrmsrl(MSR_ARRAY_TRIGGER
, ARRAY_GEN1_TEST_ALL_ARRAYS
);
378 rdmsrl(MSR_ARRAY_STATUS
, *((u64
*)status
));
384 static void ifs_array_test_gen1(int cpu
, struct device
*dev
)
386 struct ifs_data
*ifsd
= ifs_get_data(dev
);
389 stop_core_cpuslocked(cpu
, do_array_test_gen1
, &status
);
390 ifsd
->scan_details
= status
;
392 if (status
& ARRAY_GEN1_STATUS_FAIL
)
393 ifsd
->status
= SCAN_TEST_FAIL
;
395 ifsd
->status
= SCAN_TEST_PASS
;
398 #define SBAF_STATUS_PASS 0
399 #define SBAF_STATUS_SIGN_FAIL 1
400 #define SBAF_STATUS_INTR 2
401 #define SBAF_STATUS_TEST_FAIL 3
403 enum sbaf_status_err_code
{
404 IFS_SBAF_NO_ERROR
= 0,
405 IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN
= 1,
406 IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS
= 2,
407 IFS_SBAF_UNASSIGNED_ERROR_CODE3
= 3,
408 IFS_SBAF_INVALID_BUNDLE_INDEX
= 4,
409 IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS
= 5,
410 IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY
= 6,
411 IFS_SBAF_UNASSIGNED_ERROR_CODE7
= 7,
412 IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT
= 8,
413 IFS_SBAF_INTERRUPTED_DURING_EXECUTION
= 9,
414 IFS_SBAF_INVALID_PROGRAM_INDEX
= 0xA,
415 IFS_SBAF_CORRUPTED_CHUNK
= 0xB,
416 IFS_SBAF_DID_NOT_START
= 0xC,
419 static const char * const sbaf_test_status
[] = {
420 [IFS_SBAF_NO_ERROR
] = "SBAF no error",
421 [IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN
] = "Other thread could not join.",
422 [IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS
] = "Interrupt occurred prior to SBAF coordination.",
423 [IFS_SBAF_UNASSIGNED_ERROR_CODE3
] = "Unassigned error code 0x3",
424 [IFS_SBAF_INVALID_BUNDLE_INDEX
] = "Non-valid sbaf bundles. Reload test image",
425 [IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS
] = "Mismatch in arguments between threads T0/T1.",
426 [IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY
] = "Core not capable of performing SBAF currently",
427 [IFS_SBAF_UNASSIGNED_ERROR_CODE7
] = "Unassigned error code 0x7",
428 [IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT
] = "Exceeded number of Logical Processors (LP) allowed to run Scan-At-Field concurrently",
429 [IFS_SBAF_INTERRUPTED_DURING_EXECUTION
] = "Interrupt occurred prior to SBAF start",
430 [IFS_SBAF_INVALID_PROGRAM_INDEX
] = "SBAF program index not valid",
431 [IFS_SBAF_CORRUPTED_CHUNK
] = "SBAF operation aborted due to corrupted chunk",
432 [IFS_SBAF_DID_NOT_START
] = "SBAF operation did not start",
435 static void sbaf_message_not_tested(struct device
*dev
, int cpu
, u64 status_data
)
437 union ifs_sbaf_status status
= (union ifs_sbaf_status
)status_data
;
439 if (status
.error_code
< ARRAY_SIZE(sbaf_test_status
)) {
440 dev_info(dev
, "CPU(s) %*pbl: SBAF operation did not start. %s\n",
441 cpumask_pr_args(cpu_smt_mask(cpu
)),
442 sbaf_test_status
[status
.error_code
]);
443 } else if (status
.error_code
== IFS_SW_TIMEOUT
) {
444 dev_info(dev
, "CPU(s) %*pbl: software timeout during scan\n",
445 cpumask_pr_args(cpu_smt_mask(cpu
)));
446 } else if (status
.error_code
== IFS_SW_PARTIAL_COMPLETION
) {
447 dev_info(dev
, "CPU(s) %*pbl: %s\n",
448 cpumask_pr_args(cpu_smt_mask(cpu
)),
449 "Not all SBAF bundles executed. Maximum forward progress retries exceeded");
451 dev_info(dev
, "CPU(s) %*pbl: SBAF unknown status %llx\n",
452 cpumask_pr_args(cpu_smt_mask(cpu
)), status
.data
);
456 static void sbaf_message_fail(struct device
*dev
, int cpu
, union ifs_sbaf_status status
)
458 /* Failed signature check is set when SBAF signature did not match the expected value */
459 if (status
.sbaf_status
== SBAF_STATUS_SIGN_FAIL
) {
460 dev_err(dev
, "CPU(s) %*pbl: Failed signature check\n",
461 cpumask_pr_args(cpu_smt_mask(cpu
)));
464 /* Failed to reach end of test */
465 if (status
.sbaf_status
== SBAF_STATUS_TEST_FAIL
) {
466 dev_err(dev
, "CPU(s) %*pbl: Failed to complete test\n",
467 cpumask_pr_args(cpu_smt_mask(cpu
)));
471 static bool sbaf_bundle_completed(union ifs_sbaf_status status
)
473 return !(status
.sbaf_status
|| status
.error_code
);
476 static bool sbaf_can_restart(union ifs_sbaf_status status
)
478 enum sbaf_status_err_code err_code
= status
.error_code
;
480 /* Signature for chunk is bad, or scan test failed */
481 if (status
.sbaf_status
== SBAF_STATUS_SIGN_FAIL
||
482 status
.sbaf_status
== SBAF_STATUS_TEST_FAIL
)
486 case IFS_SBAF_NO_ERROR
:
487 case IFS_SBAF_OTHER_THREAD_COULD_NOT_JOIN
:
488 case IFS_SBAF_INTERRUPTED_BEFORE_RENDEZVOUS
:
489 case IFS_SBAF_EXCEED_NUMBER_OF_THREADS_CONCURRENT
:
490 case IFS_SBAF_INTERRUPTED_DURING_EXECUTION
:
492 case IFS_SBAF_UNASSIGNED_ERROR_CODE3
:
493 case IFS_SBAF_INVALID_BUNDLE_INDEX
:
494 case IFS_SBAF_MISMATCH_ARGS_BETWEEN_THREADS
:
495 case IFS_SBAF_CORE_NOT_CAPABLE_CURRENTLY
:
496 case IFS_SBAF_UNASSIGNED_ERROR_CODE7
:
497 case IFS_SBAF_INVALID_PROGRAM_INDEX
:
498 case IFS_SBAF_CORRUPTED_CHUNK
:
499 case IFS_SBAF_DID_NOT_START
:
506 * Execute the SBAF test. Called "simultaneously" on all threads of a core
507 * at high priority using the stop_cpus mechanism.
509 static int dosbaf(void *data
)
511 struct sbaf_run_params
*run_params
= data
;
512 int cpu
= smp_processor_id();
513 union ifs_sbaf_status status
;
514 struct ifs_data
*ifsd
;
517 ifsd
= run_params
->ifsd
;
519 /* Only the first logical CPU on a core reports result */
520 first
= cpumask_first(cpu_smt_mask(cpu
));
521 wait_for_sibling_cpu(&sbaf_cpus_in
, NSEC_PER_SEC
);
524 * This WRMSR will wait for other HT threads to also write
525 * to this MSR (at most for activate.delay cycles). Then it
526 * starts scan of each requested bundle. The core test happens
527 * during the "execution" of the WRMSR.
529 wrmsrl(MSR_ACTIVATE_SBAF
, run_params
->activate
->data
);
530 rdmsrl(MSR_SBAF_STATUS
, status
.data
);
531 trace_ifs_sbaf(ifsd
->cur_batch
, *run_params
->activate
, status
);
533 /* Pass back the result of the test */
535 run_params
->status
= status
;
540 static void ifs_sbaf_test_core(int cpu
, struct device
*dev
)
542 struct sbaf_run_params run_params
;
543 union ifs_sbaf_status status
= {};
544 union ifs_sbaf activate
;
545 unsigned long timeout
;
546 struct ifs_data
*ifsd
;
550 ifsd
= ifs_get_data(dev
);
553 activate
.delay
= IFS_THREAD_WAIT
;
555 timeout
= jiffies
+ 2 * HZ
;
556 retries
= MAX_IFS_RETRIES
;
557 activate
.bundle_idx
= 0;
558 stop_bundle
= ifsd
->max_bundle
;
560 while (activate
.bundle_idx
<= stop_bundle
) {
561 if (time_after(jiffies
, timeout
)) {
562 status
.error_code
= IFS_SW_TIMEOUT
;
566 atomic_set(&sbaf_cpus_in
, 0);
568 run_params
.ifsd
= ifsd
;
569 run_params
.activate
= &activate
;
570 run_params
.retry_cnt
= &retries
;
571 stop_core_cpuslocked(cpu
, dosbaf
, &run_params
);
573 status
= run_params
.status
;
575 if (sbaf_bundle_completed(status
)) {
576 activate
.bundle_idx
= status
.bundle_idx
+ 1;
577 activate
.pgm_idx
= 0;
578 retries
= MAX_IFS_RETRIES
;
582 /* Some cases can be retried, give up for others */
583 if (!sbaf_can_restart(status
))
586 if (status
.pgm_idx
== activate
.pgm_idx
) {
587 /* If no progress retry */
588 if (--retries
== 0) {
589 if (status
.error_code
== IFS_NO_ERROR
)
590 status
.error_code
= IFS_SW_PARTIAL_COMPLETION
;
594 /* if some progress, more pgms remaining in bundle, reset retries */
595 retries
= MAX_IFS_RETRIES
;
596 activate
.bundle_idx
= status
.bundle_idx
;
597 activate
.pgm_idx
= status
.pgm_idx
;
601 /* Update status for this core */
602 ifsd
->scan_details
= status
.data
;
604 if (status
.sbaf_status
== SBAF_STATUS_SIGN_FAIL
||
605 status
.sbaf_status
== SBAF_STATUS_TEST_FAIL
) {
606 ifsd
->status
= SCAN_TEST_FAIL
;
607 sbaf_message_fail(dev
, cpu
, status
);
608 } else if (status
.error_code
|| status
.sbaf_status
== SBAF_STATUS_INTR
||
609 (activate
.bundle_idx
< stop_bundle
)) {
610 ifsd
->status
= SCAN_NOT_TESTED
;
611 sbaf_message_not_tested(dev
, cpu
, status
.data
);
613 ifsd
->status
= SCAN_TEST_PASS
;
618 * Initiate per core test. It wakes up work queue threads on the target cpu and
619 * its sibling cpu. Once all sibling threads wake up, the scan test gets executed and
620 * wait for all sibling threads to finish the scan test.
622 int do_core_test(int cpu
, struct device
*dev
)
624 const struct ifs_test_caps
*test
= ifs_get_test_caps(dev
);
625 struct ifs_data
*ifsd
= ifs_get_data(dev
);
628 /* Prevent CPUs from being taken offline during the scan test */
631 if (!cpu_online(cpu
)) {
632 dev_info(dev
, "cannot test on the offline cpu %d\n", cpu
);
637 switch (test
->test_num
) {
642 ifs_test_core(cpu
, dev
);
644 case IFS_TYPE_ARRAY_BIST
:
645 if (ifsd
->array_gen
== ARRAY_GEN0
)
646 ifs_array_test_core(cpu
, dev
);
648 ifs_array_test_gen1(cpu
, dev
);
654 ifs_sbaf_test_core(cpu
, dev
);