@@ -10,16 +10,25 @@ readonly KSFT_FAIL=1
1010readonly KSFT_XFAIL=2
1111readonly KSFT_SKIP=4
1212
13+ readonly CPU_SYSFS=" /sys/devices/system/cpu"
14+ readonly CPU_OFFLINE_SYSFS=" ${CPU_SYSFS} /offline"
1315readonly IMG_PATH=" /lib/firmware/intel/ifs_0"
1416readonly IFS_SCAN_MODE=" 0"
17+ readonly IFS_ARRAY_BIST_SCAN_MODE=" 1"
1518readonly IFS_PATH=" /sys/devices/virtual/misc/intel_ifs"
1619readonly IFS_SCAN_SYSFS_PATH=" ${IFS_PATH} _${IFS_SCAN_MODE} "
20+ readonly RUN_TEST=" run_test"
21+ readonly STATUS=" status"
22+ readonly DETAILS=" details"
23+ readonly STATUS_PASS=" pass"
1724readonly PASS=" PASS"
1825readonly FAIL=" FAIL"
1926readonly INFO=" INFO"
2027readonly XFAIL=" XFAIL"
2128readonly SKIP=" SKIP"
2229readonly IFS_NAME=" intel_ifs"
30+ readonly ALL=" all"
31+ readonly SIBLINGS=" siblings"
2332
2433# Matches arch/x86/include/asm/intel-family.h and
2534# drivers/platform/x86/intel/ifs/core.c requirement as follows
@@ -28,6 +37,7 @@ readonly EMERALDRAPIDS_X="cf"
2837
2938readonly INTEL_FAM6=" 06"
3039
40+ LOOP_TIMES=3
3141FML=" "
3242MODEL=" "
3343STEPPING=" "
@@ -36,18 +46,49 @@ TRUE="true"
3646FALSE=" false"
3747RESULT=$KSFT_PASS
3848IMAGE_NAME=" "
39- export INTERVAL_TIME=1
49+ INTERVAL_TIME=1
50+ OFFLINE_CPUS=" "
4051# For IFS cleanup tags
4152ORIGIN_IFS_LOADED=" "
4253IFS_IMAGE_NEED_RESTORE=$FALSE
4354IFS_LOG=" /tmp/ifs_logs.$$ "
55+ RANDOM_CPU=" "
4456DEFAULT_IMG_ID=" "
4557
4658append_log ()
4759{
4860 echo -e " $1 " | tee -a " $IFS_LOG "
4961}
5062
63+ online_offline_cpu_list ()
64+ {
65+ local on_off=$1
66+ local target_cpus=$2
67+ local cpu=" "
68+ local cpu_start=" "
69+ local cpu_end=" "
70+ local i=" "
71+
72+ if [[ -n " $target_cpus " ]]; then
73+ for cpu in $( echo " $target_cpus " | tr ' ,' ' ' ) ; do
74+ if [[ " $cpu " == * " -" * ]]; then
75+ cpu_start=" "
76+ cpu_end=" "
77+ i=" "
78+ cpu_start=$( echo " $cpu " | cut -d " -" -f 1)
79+ cpu_end=$( echo " $cpu " | cut -d " -" -f 2)
80+ for(( i= cpu_start;i<= cpu_end;i++ )) ; do
81+ append_log " [$INFO ] echo $on_off > \
82+ ${CPU_SYSFS} /cpu${i} /online"
83+ echo " $on_off " > " $CPU_SYSFS " /cpu" $i " /online
84+ done
85+ else
86+ set_target_cpu " $on_off " " $cpu "
87+ fi
88+ done
89+ fi
90+ }
91+
5192ifs_scan_result_summary ()
5293{
5394 local failed_info pass_num skip_num fail_num
@@ -80,6 +121,9 @@ ifs_cleanup()
80121 mv -f " $IMG_PATH " /" $IMAGE_NAME " _origin " $IMG_PATH " /" $IMAGE_NAME "
81122 }
82123
124+ # Restore the CPUs to the state before testing
125+ [[ -z " $OFFLINE_CPUS " ]] || online_offline_cpu_list " 0" " $OFFLINE_CPUS "
126+
83127 lsmod | grep -q " $IFS_NAME " && [[ " $ORIGIN_IFS_LOADED " == " $FALSE " ]] && {
84128 echo " [$INFO ] modprobe -r $IFS_NAME "
85129 modprobe -r " $IFS_NAME "
@@ -122,6 +166,23 @@ test_exit()
122166 ifs_cleanup
123167}
124168
169+ online_all_cpus ()
170+ {
171+ local off_cpus=" "
172+
173+ OFFLINE_CPUS=$( cat " $CPU_OFFLINE_SYSFS " )
174+ online_offline_cpu_list " 1" " $OFFLINE_CPUS "
175+
176+ off_cpus=$( cat " $CPU_OFFLINE_SYSFS " )
177+ if [[ -z " $off_cpus " ]]; then
178+ append_log " [$INFO ] All CPUs are online."
179+ else
180+ append_log " [$XFAIL ] There is offline cpu:$off_cpus after online all cpu!"
181+ RESULT=$KSFT_XFAIL
182+ ifs_cleanup
183+ fi
184+ }
185+
125186get_cpu_fms ()
126187{
127188 FML=$( grep -m 1 " family" /proc/cpuinfo | awk -F " :" ' {printf "%02x",$2;}' )
@@ -268,10 +329,135 @@ test_bad_and_origin_ifs_image()
268329 append_log " [$INFO ] Loading invalid IFS image and then loading initial image passed.\n"
269330}
270331
332+ ifs_test_cpu ()
333+ {
334+ local ifs_mode=$1
335+ local cpu_num=$2
336+ local image_id status details ret result result_info
337+
338+ echo " $cpu_num " > " $IFS_PATH " _" $ifs_mode " /" $RUN_TEST "
339+ ret=$?
340+
341+ status=$( cat " ${IFS_PATH} _${ifs_mode} /${STATUS} " )
342+ details=$( cat " ${IFS_PATH} _${ifs_mode} /${DETAILS} " )
343+
344+ if [[ " $ret " -eq 0 && " $status " == " $STATUS_PASS " ]]; then
345+ result=" $PASS "
346+ else
347+ result=" $FAIL "
348+ fi
349+
350+ cpu_num=$( cat " ${CPU_SYSFS} /cpu${cpu_num} /topology/thread_siblings_list" )
351+
352+ # There is no image file for IFS ARRAY BIST scan
353+ if [[ -e " ${IFS_PATH} _${ifs_mode} /current_batch" ]]; then
354+ image_id=$( cat " ${IFS_PATH} _${ifs_mode} /current_batch" )
355+ result_info=$( printf " [%s] ifs_%1d cpu(s):%s, current_batch:0x%02x, \
356+ ret:%2d, status:%s, details:0x%016x" \
357+ " $result " " $ifs_mode " " $cpu_num " " $image_id " " $ret " \
358+ " $status " " $details " )
359+ else
360+ result_info=$( printf " [%s] ifs_%1d cpu(s):%s, ret:%2d, status:%s, details:0x%016x" \
361+ " $result " " $ifs_mode " " $cpu_num " " $ret " " $status " " $details " )
362+ fi
363+
364+ append_log " $result_info "
365+ }
366+
367+ ifs_test_cpus ()
368+ {
369+ local cpus_type=$1
370+ local ifs_mode=$2
371+ local image_id=$3
372+ local cpu_max_num=" "
373+ local cpu_num=" "
374+
375+ case " $cpus_type " in
376+ " $ALL " )
377+ cpu_max_num=$(( $(nproc) - 1 ))
378+ cpus=$( seq 0 $cpu_max_num )
379+ ;;
380+ " $SIBLINGS " )
381+ cpus=$( cat ${CPU_SYSFS} /cpu* /topology/thread_siblings_list \
382+ | sed -e ' s/,.*//' \
383+ | sed -e ' s/-.*//' \
384+ | sort -n \
385+ | uniq)
386+ ;;
387+ * )
388+ test_exit " Invalid cpus_type:$cpus_type " " $KSFT_XFAIL "
389+ ;;
390+ esac
391+
392+ for cpu_num in $cpus ; do
393+ ifs_test_cpu " $ifs_mode " " $cpu_num "
394+ done
395+
396+ if [[ -z " $image_id " ]]; then
397+ append_log " [$INFO ] ifs_$ifs_mode test $cpus_type cpus completed\n"
398+ else
399+ append_log " [$INFO ] ifs_$ifs_mode $cpus_type cpus with $CPU_FMS -$image_id .scan \
400+ completed\n"
401+ fi
402+ }
403+
404+ test_ifs_same_cpu_loop ()
405+ {
406+ local ifs_mode=$1
407+ local cpu_num=$2
408+ local loop_times=$3
409+
410+ append_log " [$INFO ] Test ifs mode $ifs_mode on CPU:$cpu_num for $loop_times rounds:"
411+ [[ " $ifs_mode " == " $IFS_SCAN_MODE " ]] && {
412+ load_image " $DEFAULT_IMG_ID " || return $?
413+ }
414+ for (( i= 1 ; i<= loop_times; i++ )) ; do
415+ append_log " [$INFO ] Loop iteration: $i in total of $loop_times "
416+ # Only IFS scan needs the interval time
417+ if [[ " $ifs_mode " == " $IFS_SCAN_MODE " ]]; then
418+ do_cmd " sleep $INTERVAL_TIME "
419+ elif [[ " $ifs_mode " == " $IFS_ARRAY_BIST_SCAN_MODE " ]]; then
420+ true
421+ else
422+ test_exit " Invalid ifs_mode:$ifs_mode " " $KSFT_XFAIL "
423+ fi
424+
425+ ifs_test_cpu " $ifs_mode " " $cpu_num "
426+ done
427+ append_log " [$INFO ] $loop_times rounds of ifs_$ifs_mode test on CPU:$cpu_num completed.\n"
428+ }
429+
430+ test_ifs_scan_available_imgs ()
431+ {
432+ local image_ids=" "
433+ local image_id=" "
434+
435+ append_log " [$INFO ] Test ifs scan with available images:"
436+ image_ids=$( find " $IMG_PATH " -maxdepth 1 -name " ${CPU_FMS} -[0-9a-fA-F][0-9a-fA-F].scan" \
437+ 2> /dev/null \
438+ | sort \
439+ | awk -F " -" ' {print $NF}' \
440+ | cut -d " ." -f 1)
441+
442+ for image_id in $image_ids ; do
443+ load_image " $image_id " || return $?
444+
445+ ifs_test_cpus " $SIBLINGS " " $IFS_SCAN_MODE " " $image_id "
446+ # IFS scan requires time interval for the scan on the same CPU
447+ do_cmd " sleep $INTERVAL_TIME "
448+ done
449+ }
450+
271451prepare_ifs_test_env ()
272452{
453+ local max_cpu=" "
454+
273455 check_cpu_ifs_support_interval_time
274456
457+ online_all_cpus
458+ max_cpu=$(( $(nproc) - 1 ))
459+ RANDOM_CPU=$( shuf -i 0-$max_cpu -n 1)
460+
275461 DEFAULT_IMG_ID=$( find $IMG_PATH -maxdepth 1 -name " ${CPU_FMS} -[0-9a-fA-F][0-9a-fA-F].scan" \
276462 2> /dev/null \
277463 | sort \
@@ -290,6 +476,8 @@ test_ifs()
290476 append_log " [$SKIP ] No proper ${IMG_PATH} /${CPU_FMS} -*.scan, skip ifs_0 scan"
291477 else
292478 test_bad_and_origin_ifs_image " $DEFAULT_IMG_ID "
479+ test_ifs_scan_available_imgs
480+ test_ifs_same_cpu_loop " $IFS_SCAN_MODE " " $RANDOM_CPU " " $LOOP_TIMES "
293481 fi
294482}
295483
0 commit comments