~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/drivers/platform/x86/intel/ifs/test_ifs.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/bash
  2 # SPDX-License-Identifier: GPL-2.0
  3 #
  4 # Test the functionality of the Intel IFS(In Field Scan) driver.
  5 #
  6 
  7 # Matched with kselftest framework: tools/testing/selftests/kselftest.h
  8 readonly KSFT_PASS=0
  9 readonly KSFT_FAIL=1
 10 readonly KSFT_XFAIL=2
 11 readonly KSFT_SKIP=4
 12 
 13 readonly CPU_SYSFS="/sys/devices/system/cpu"
 14 readonly CPU_OFFLINE_SYSFS="${CPU_SYSFS}/offline"
 15 readonly IMG_PATH="/lib/firmware/intel/ifs_0"
 16 readonly IFS_SCAN_MODE="0"
 17 readonly IFS_ARRAY_BIST_SCAN_MODE="1"
 18 readonly IFS_PATH="/sys/devices/virtual/misc/intel_ifs"
 19 readonly IFS_SCAN_SYSFS_PATH="${IFS_PATH}_${IFS_SCAN_MODE}"
 20 readonly IFS_ARRAY_BIST_SYSFS_PATH="${IFS_PATH}_${IFS_ARRAY_BIST_SCAN_MODE}"
 21 readonly RUN_TEST="run_test"
 22 readonly STATUS="status"
 23 readonly DETAILS="details"
 24 readonly STATUS_PASS="pass"
 25 readonly PASS="PASS"
 26 readonly FAIL="FAIL"
 27 readonly INFO="INFO"
 28 readonly XFAIL="XFAIL"
 29 readonly SKIP="SKIP"
 30 readonly IFS_NAME="intel_ifs"
 31 readonly ALL="all"
 32 readonly SIBLINGS="siblings"
 33 
 34 # Matches arch/x86/include/asm/intel-family.h and
 35 # drivers/platform/x86/intel/ifs/core.c requirement as follows
 36 readonly SAPPHIRERAPIDS_X="8f"
 37 readonly EMERALDRAPIDS_X="cf"
 38 
 39 readonly INTEL_FAM6="06"
 40 
 41 LOOP_TIMES=3
 42 FML=""
 43 MODEL=""
 44 STEPPING=""
 45 CPU_FMS=""
 46 TRUE="true"
 47 FALSE="false"
 48 RESULT=$KSFT_PASS
 49 IMAGE_NAME=""
 50 INTERVAL_TIME=1
 51 OFFLINE_CPUS=""
 52 # For IFS cleanup tags
 53 ORIGIN_IFS_LOADED=""
 54 IFS_IMAGE_NEED_RESTORE=$FALSE
 55 IFS_LOG="/tmp/ifs_logs.$$"
 56 RANDOM_CPU=""
 57 DEFAULT_IMG_ID=""
 58 
 59 append_log()
 60 {
 61         echo -e "$1" | tee -a "$IFS_LOG"
 62 }
 63 
 64 online_offline_cpu_list()
 65 {
 66         local on_off=$1
 67         local target_cpus=$2
 68         local cpu=""
 69         local cpu_start=""
 70         local cpu_end=""
 71         local i=""
 72 
 73         if [[ -n "$target_cpus" ]]; then
 74                 for cpu in $(echo "$target_cpus" | tr ',' ' '); do
 75                         if [[ "$cpu" == *"-"* ]]; then
 76                                 cpu_start=""
 77                                 cpu_end=""
 78                                 i=""
 79                                 cpu_start=$(echo "$cpu" | cut -d "-" -f 1)
 80                                 cpu_end=$(echo "$cpu" | cut -d "-" -f 2)
 81                                 for((i=cpu_start;i<=cpu_end;i++)); do
 82                                         append_log "[$INFO] echo $on_off > \
 83 ${CPU_SYSFS}/cpu${i}/online"
 84                                         echo "$on_off" > "$CPU_SYSFS"/cpu"$i"/online
 85                                 done
 86                         else
 87                                 set_target_cpu "$on_off" "$cpu"
 88                         fi
 89                 done
 90         fi
 91 }
 92 
 93 ifs_scan_result_summary()
 94 {
 95         local failed_info pass_num skip_num fail_num
 96 
 97         if [[ -e "$IFS_LOG" ]]; then
 98                 failed_info=$(grep ^"\[${FAIL}\]" "$IFS_LOG")
 99                 fail_num=$(grep -c ^"\[${FAIL}\]" "$IFS_LOG")
100                 skip_num=$(grep -c ^"\[${SKIP}\]" "$IFS_LOG")
101                 pass_num=$(grep -c ^"\[${PASS}\]" "$IFS_LOG")
102 
103                 if [[ "$fail_num" -ne 0 ]]; then
104                         RESULT=$KSFT_FAIL
105                         echo "[$INFO] IFS test failure summary:"
106                         echo "$failed_info"
107                 elif [[ "$skip_num" -ne 0 ]]; then
108                         RESULT=$KSFT_SKIP
109                 fi
110                         echo "[$INFO] IFS test pass:$pass_num, skip:$skip_num, fail:$fail_num"
111         else
112                 echo "[$INFO] No file $IFS_LOG for IFS scan summary"
113         fi
114 }
115 
116 ifs_cleanup()
117 {
118         echo "[$INFO] Restore environment after IFS test"
119 
120         # Restore ifs origin image if origin image backup step is needed
121         [[ "$IFS_IMAGE_NEED_RESTORE" == "$TRUE" ]] && {
122                 mv -f "$IMG_PATH"/"$IMAGE_NAME"_origin "$IMG_PATH"/"$IMAGE_NAME"
123         }
124 
125         # Restore the CPUs to the state before testing
126         [[ -z "$OFFLINE_CPUS" ]] || online_offline_cpu_list "0" "$OFFLINE_CPUS"
127 
128         lsmod | grep -q "$IFS_NAME" && [[ "$ORIGIN_IFS_LOADED" == "$FALSE" ]] && {
129                 echo "[$INFO] modprobe -r $IFS_NAME"
130                 modprobe -r "$IFS_NAME"
131         }
132 
133         ifs_scan_result_summary
134         [[ -e "$IFS_LOG" ]] && rm -rf "$IFS_LOG"
135 
136         echo "[RESULT] IFS test exit with $RESULT"
137         exit "$RESULT"
138 }
139 
140 do_cmd()
141 {
142         local cmd=$*
143         local ret=""
144 
145         append_log "[$INFO] $cmd"
146         eval "$cmd"
147         ret=$?
148         if [[ $ret -ne 0 ]]; then
149                 append_log "[$FAIL] $cmd failed. Return code is $ret"
150                 RESULT=$KSFT_XFAIL
151                 ifs_cleanup
152         fi
153 }
154 
155 test_exit()
156 {
157         local info=$1
158         RESULT=$2
159 
160         declare -A EXIT_MAP
161         EXIT_MAP[$KSFT_PASS]=$PASS
162         EXIT_MAP[$KSFT_FAIL]=$FAIL
163         EXIT_MAP[$KSFT_XFAIL]=$XFAIL
164         EXIT_MAP[$KSFT_SKIP]=$SKIP
165 
166         append_log "[${EXIT_MAP[$RESULT]}] $info"
167         ifs_cleanup
168 }
169 
170 online_all_cpus()
171 {
172         local off_cpus=""
173 
174         OFFLINE_CPUS=$(cat "$CPU_OFFLINE_SYSFS")
175         online_offline_cpu_list "1" "$OFFLINE_CPUS"
176 
177         off_cpus=$(cat "$CPU_OFFLINE_SYSFS")
178         if [[ -z "$off_cpus" ]]; then
179                 append_log "[$INFO] All CPUs are online."
180         else
181                 append_log "[$XFAIL] There is offline cpu:$off_cpus after online all cpu!"
182                 RESULT=$KSFT_XFAIL
183                 ifs_cleanup
184         fi
185 }
186 
187 get_cpu_fms()
188 {
189         FML=$(grep -m 1 "family" /proc/cpuinfo | awk -F ":" '{printf "%02x",$2;}')
190         MODEL=$(grep -m 1 "model" /proc/cpuinfo | awk -F ":" '{printf "%02x",$2;}')
191         STEPPING=$(grep -m 1 "stepping" /proc/cpuinfo | awk -F ":" '{printf "%02x",$2;}')
192         CPU_FMS="${FML}-${MODEL}-${STEPPING}"
193 }
194 
195 check_cpu_ifs_support_interval_time()
196 {
197         get_cpu_fms
198 
199         if [[ "$FML" != "$INTEL_FAM6" ]]; then
200                 test_exit "CPU family:$FML does not support IFS" "$KSFT_SKIP"
201         fi
202 
203         # Ucode has time interval requirement for IFS scan on same CPU as follows:
204         case $MODEL in
205                 "$SAPPHIRERAPIDS_X")
206                         INTERVAL_TIME=180;
207                         ;;
208                 "$EMERALDRAPIDS_X")
209                         INTERVAL_TIME=30;
210                         ;;
211                 *)
212                         # Set default interval time for other platforms
213                         INTERVAL_TIME=1;
214                         append_log "[$INFO] CPU FML:$FML model:0x$MODEL, default: 1s interval time"
215                         ;;
216         esac
217 }
218 
219 check_ifs_loaded()
220 {
221         local ifs_info=""
222 
223         ifs_info=$(lsmod | grep "$IFS_NAME")
224         if [[ -z "$ifs_info" ]]; then
225                 append_log "[$INFO] modprobe $IFS_NAME"
226                 modprobe "$IFS_NAME" || {
227                         test_exit "Check if CONFIG_INTEL_IFS is set to m or \
228 platform doesn't support ifs" "$KSFT_SKIP"
229                 }
230                 ifs_info=$(lsmod | grep "$IFS_NAME")
231                 [[ -n "$ifs_info" ]] || test_exit "No ifs module listed by lsmod" "$KSFT_FAIL"
232         fi
233 }
234 
235 test_ifs_scan_entry()
236 {
237         local ifs_info=""
238 
239         ifs_info=$(lsmod | grep "$IFS_NAME")
240 
241         if [[ -z "$ifs_info" ]]; then
242                 ORIGIN_IFS_LOADED="$FALSE"
243                 check_ifs_loaded
244         else
245                 ORIGIN_IFS_LOADED="$TRUE"
246                 append_log "[$INFO] Module $IFS_NAME is already loaded"
247         fi
248 
249         if [[ -d "$IFS_SCAN_SYSFS_PATH" ]]; then
250                 append_log "[$PASS] IFS sysfs $IFS_SCAN_SYSFS_PATH entry is created\n"
251         else
252                 test_exit "No sysfs entry in $IFS_SCAN_SYSFS_PATH" "$KSFT_FAIL"
253         fi
254 }
255 
256 load_image()
257 {
258         local image_id=$1
259         local image_info=""
260         local ret=""
261 
262         check_ifs_loaded
263         if [[ -e "${IMG_PATH}/${IMAGE_NAME}" ]]; then
264                 append_log "[$INFO] echo 0x$image_id > ${IFS_SCAN_SYSFS_PATH}/current_batch"
265                 echo "0x$image_id" > "$IFS_SCAN_SYSFS_PATH"/current_batch 2>/dev/null
266                 ret=$?
267                 [[ "$ret" -eq 0 ]] || {
268                         append_log "[$FAIL] Load ifs image $image_id failed with ret:$ret\n"
269                         return "$ret"
270                 }
271                 image_info=$(cat ${IFS_SCAN_SYSFS_PATH}/current_batch)
272                 if [[ "$image_info" == 0x"$image_id" ]]; then
273                         append_log "[$PASS] load IFS current_batch:$image_info"
274                 else
275                         append_log "[$FAIL] current_batch:$image_info is not expected:$image_id"
276                         return "$KSFT_FAIL"
277                 fi
278         else
279                 append_log "[$FAIL] No IFS image file ${IMG_PATH}/${IMAGE_NAME}"\
280                 return "$KSFT_FAIL"
281         fi
282         return 0
283 }
284 
285 test_load_origin_ifs_image()
286 {
287         local image_id=$1
288 
289         IMAGE_NAME="${CPU_FMS}-${image_id}.scan"
290 
291         load_image "$image_id" || return $?
292         return 0
293 }
294 
295 test_load_bad_ifs_image()
296 {
297         local image_id=$1
298 
299         IMAGE_NAME="${CPU_FMS}-${image_id}.scan"
300 
301         do_cmd "mv -f ${IMG_PATH}/${IMAGE_NAME} ${IMG_PATH}/${IMAGE_NAME}_origin"
302 
303         # Set IFS_IMAGE_NEED_RESTORE to true before corrupt the origin ifs image file
304         IFS_IMAGE_NEED_RESTORE=$TRUE
305         do_cmd "dd if=/dev/urandom of=${IMG_PATH}/${IMAGE_NAME} bs=1K count=6 2>/dev/null"
306 
307         # Use the specified judgment for negative testing
308         append_log "[$INFO] echo 0x$image_id > ${IFS_SCAN_SYSFS_PATH}/current_batch"
309         echo "0x$image_id" > "$IFS_SCAN_SYSFS_PATH"/current_batch 2>/dev/null
310         ret=$?
311         if [[ "$ret" -ne 0 ]]; then
312                 append_log "[$PASS] Load invalid ifs image failed with ret:$ret not 0 as expected"
313         else
314                 append_log "[$FAIL] Load invalid ifs image ret:$ret unexpectedly"
315         fi
316 
317         do_cmd "mv -f ${IMG_PATH}/${IMAGE_NAME}_origin ${IMG_PATH}/${IMAGE_NAME}"
318         IFS_IMAGE_NEED_RESTORE=$FALSE
319 }
320 
321 test_bad_and_origin_ifs_image()
322 {
323         local image_id=$1
324 
325         append_log "[$INFO] Test loading bad and then loading original IFS image:"
326         test_load_origin_ifs_image "$image_id" || return $?
327         test_load_bad_ifs_image "$image_id"
328         # Load origin image again and make sure it's worked
329         test_load_origin_ifs_image "$image_id" || return $?
330         append_log "[$INFO] Loading invalid IFS image and then loading initial image passed.\n"
331 }
332 
333 ifs_test_cpu()
334 {
335         local ifs_mode=$1
336         local cpu_num=$2
337         local image_id status details ret result result_info
338 
339         echo "$cpu_num" > "$IFS_PATH"_"$ifs_mode"/"$RUN_TEST"
340         ret=$?
341 
342         status=$(cat "${IFS_PATH}_${ifs_mode}/${STATUS}")
343         details=$(cat "${IFS_PATH}_${ifs_mode}/${DETAILS}")
344 
345         if [[ "$ret" -eq 0 && "$status" == "$STATUS_PASS" ]]; then
346                 result="$PASS"
347         else
348                 result="$FAIL"
349         fi
350 
351         cpu_num=$(cat "${CPU_SYSFS}/cpu${cpu_num}/topology/thread_siblings_list")
352 
353         # There is no image file for IFS ARRAY BIST scan
354         if [[ -e "${IFS_PATH}_${ifs_mode}/current_batch" ]]; then
355                 image_id=$(cat "${IFS_PATH}_${ifs_mode}/current_batch")
356                 result_info=$(printf "[%s] ifs_%1d cpu(s):%s, current_batch:0x%02x, \
357 ret:%2d, status:%s, details:0x%016x" \
358                              "$result" "$ifs_mode" "$cpu_num" "$image_id" "$ret" \
359                              "$status" "$details")
360         else
361                 result_info=$(printf "[%s] ifs_%1d cpu(s):%s, ret:%2d, status:%s, details:0x%016x" \
362                              "$result" "$ifs_mode" "$cpu_num" "$ret" "$status" "$details")
363         fi
364 
365         append_log "$result_info"
366 }
367 
368 ifs_test_cpus()
369 {
370         local cpus_type=$1
371         local ifs_mode=$2
372         local image_id=$3
373         local cpu_max_num=""
374         local cpu_num=""
375 
376         case "$cpus_type" in
377                 "$ALL")
378                         cpu_max_num=$(($(nproc) - 1))
379                         cpus=$(seq 0 $cpu_max_num)
380                         ;;
381                 "$SIBLINGS")
382                         cpus=$(cat ${CPU_SYSFS}/cpu*/topology/thread_siblings_list \
383                                 | sed -e 's/,.*//' \
384                                 | sed -e 's/-.*//' \
385                                 | sort -n \
386                                 | uniq)
387                         ;;
388                 *)
389                         test_exit "Invalid cpus_type:$cpus_type" "$KSFT_XFAIL"
390                         ;;
391         esac
392 
393         for cpu_num in $cpus; do
394                 ifs_test_cpu "$ifs_mode" "$cpu_num"
395         done
396 
397         if [[ -z "$image_id" ]]; then
398                 append_log "[$INFO] ifs_$ifs_mode test $cpus_type cpus completed\n"
399         else
400                 append_log "[$INFO] ifs_$ifs_mode $cpus_type cpus with $CPU_FMS-$image_id.scan \
401 completed\n"
402         fi
403 }
404 
405 test_ifs_same_cpu_loop()
406 {
407         local ifs_mode=$1
408         local cpu_num=$2
409         local loop_times=$3
410 
411         append_log "[$INFO] Test ifs mode $ifs_mode on CPU:$cpu_num for $loop_times rounds:"
412         [[ "$ifs_mode" == "$IFS_SCAN_MODE" ]] && {
413                 load_image "$DEFAULT_IMG_ID" || return $?
414         }
415         for (( i=1; i<=loop_times; i++ )); do
416                 append_log "[$INFO] Loop iteration: $i in total of $loop_times"
417                 # Only IFS scan needs the interval time
418                 if [[ "$ifs_mode" == "$IFS_SCAN_MODE" ]]; then
419                         do_cmd "sleep $INTERVAL_TIME"
420                 elif [[ "$ifs_mode" == "$IFS_ARRAY_BIST_SCAN_MODE" ]]; then
421                         true
422                 else
423                         test_exit "Invalid ifs_mode:$ifs_mode" "$KSFT_XFAIL"
424                 fi
425 
426                 ifs_test_cpu "$ifs_mode" "$cpu_num"
427         done
428         append_log "[$INFO] $loop_times rounds of ifs_$ifs_mode test on CPU:$cpu_num completed.\n"
429 }
430 
431 test_ifs_scan_available_imgs()
432 {
433         local image_ids=""
434         local image_id=""
435 
436         append_log "[$INFO] Test ifs scan with available images:"
437         image_ids=$(find "$IMG_PATH" -maxdepth 1 -name "${CPU_FMS}-[0-9a-fA-F][0-9a-fA-F].scan" \
438                     2>/dev/null \
439                     | sort \
440                     | awk -F "-" '{print $NF}' \
441                     | cut -d "." -f 1)
442 
443         for image_id in $image_ids; do
444                 load_image "$image_id" || return $?
445 
446                 ifs_test_cpus "$SIBLINGS" "$IFS_SCAN_MODE" "$image_id"
447                 # IFS scan requires time interval for the scan on the same CPU
448                 do_cmd "sleep $INTERVAL_TIME"
449         done
450 }
451 
452 prepare_ifs_test_env()
453 {
454         local max_cpu=""
455 
456         check_cpu_ifs_support_interval_time
457 
458         online_all_cpus
459         max_cpu=$(($(nproc) - 1))
460         RANDOM_CPU=$(shuf -i 0-$max_cpu -n 1)
461 
462         DEFAULT_IMG_ID=$(find $IMG_PATH -maxdepth 1 -name "${CPU_FMS}-[0-9a-fA-F][0-9a-fA-F].scan" \
463                          2>/dev/null \
464                          | sort \
465                          | head -n 1 \
466                          | awk -F "-" '{print $NF}' \
467                          | cut -d "." -f 1)
468 }
469 
470 test_ifs()
471 {
472         prepare_ifs_test_env
473 
474         test_ifs_scan_entry
475 
476         if [[ -z "$DEFAULT_IMG_ID" ]]; then
477                 append_log "[$SKIP] No proper ${IMG_PATH}/${CPU_FMS}-*.scan, skip ifs_0 scan"
478         else
479                 test_bad_and_origin_ifs_image "$DEFAULT_IMG_ID"
480                 test_ifs_scan_available_imgs
481                 test_ifs_same_cpu_loop "$IFS_SCAN_MODE" "$RANDOM_CPU" "$LOOP_TIMES"
482         fi
483 
484         if [[ -d "$IFS_ARRAY_BIST_SYSFS_PATH" ]]; then
485                 ifs_test_cpus "$SIBLINGS" "$IFS_ARRAY_BIST_SCAN_MODE"
486                 test_ifs_same_cpu_loop "$IFS_ARRAY_BIST_SCAN_MODE" "$RANDOM_CPU" "$LOOP_TIMES"
487         else
488                 append_log "[$SKIP] No $IFS_ARRAY_BIST_SYSFS_PATH, skip IFS ARRAY BIST scan"
489         fi
490 }
491 
492 trap ifs_cleanup SIGTERM SIGINT
493 test_ifs
494 ifs_cleanup

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php