1f08c3bdfSopenharmony_ci#
2f08c3bdfSopenharmony_ci# MCE library: provide MCE specific functions
3f08c3bdfSopenharmony_ci#
4f08c3bdfSopenharmony_ci# Copyright (C) 2008, Intel Corp.
5f08c3bdfSopenharmony_ci#   Author: Huang Ying <ying.huang@intel.com>
6f08c3bdfSopenharmony_ci#
7f08c3bdfSopenharmony_ci# This file is released under the GPLv2.
8f08c3bdfSopenharmony_ci#
9f08c3bdfSopenharmony_ci
10f08c3bdfSopenharmony_ciextract_mce_from_log()
11f08c3bdfSopenharmony_ci{
12f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for extract_mce_from_log"
13f08c3bdfSopenharmony_ci    local log="$1"
14f08c3bdfSopenharmony_ci    local outf="$2"
15f08c3bdfSopenharmony_ci
16f08c3bdfSopenharmony_ci    sed '1,/HARDWARE ERROR/d' "$log" | \
17f08c3bdfSopenharmony_ci	mcelog --no-dmi --dump-raw-ascii --ascii > "$outf"
18f08c3bdfSopenharmony_ci}
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_cimce_reformat()
21f08c3bdfSopenharmony_ci{
22f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for mce_reformat"
23f08c3bdfSopenharmony_ci    local org="$1"
24f08c3bdfSopenharmony_ci    local outf="$2"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci    mce-inject --dump "$org" > "$outf"
27f08c3bdfSopenharmony_ci}
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_cimce_reformat_for_cmp()
30f08c3bdfSopenharmony_ci{
31f08c3bdfSopenharmony_ci    local inf="$1"
32f08c3bdfSopenharmony_ci    local outf="$2"
33f08c3bdfSopenharmony_ci    local removes="$3"
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_ci    local tmpf=$WDIR/mce_reformat_for_cmp
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci    mce-inject --dump "$inf" > $tmpf
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci    if [ -n "$removes" ]; then
40f08c3bdfSopenharmony_ci	for remove in $removes; do
41f08c3bdfSopenharmony_ci	    sed "/$remove/d" -i $tmpf
42f08c3bdfSopenharmony_ci	done
43f08c3bdfSopenharmony_ci    fi
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ci    cat $tmpf | tr '\n' '#' | sed '1,$s/##/\n/g' | \
46f08c3bdfSopenharmony_ci	grep -v '#STATUS 0x0#' | \
47f08c3bdfSopenharmony_ci	grep -v '#STATUS 0x800000000000000#' | sort > "$outf"
48f08c3bdfSopenharmony_ci}
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_cimce_cmp()
51f08c3bdfSopenharmony_ci{
52f08c3bdfSopenharmony_ci    [ $# -eq 3 ] || die "missing parameter for mce_cmp"
53f08c3bdfSopenharmony_ci    local m1="$1"
54f08c3bdfSopenharmony_ci    local m2="$2"
55f08c3bdfSopenharmony_ci    local removes="$3"
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci    local tmpf1=$WDIR/mce_cmp_1
58f08c3bdfSopenharmony_ci    local tmpf2=$WDIR/mce_cmp_2
59f08c3bdfSopenharmony_ci
60f08c3bdfSopenharmony_ci    mce_reformat_for_cmp "$m1" $tmpf1 "$removes"
61f08c3bdfSopenharmony_ci    mce_reformat_for_cmp "$m2" $tmpf2 "$removes"
62f08c3bdfSopenharmony_ci    diff $tmpf1 $tmpf2 > /dev/null
63f08c3bdfSopenharmony_ci}
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ciget_mcelog_from_dev()
66f08c3bdfSopenharmony_ci{
67f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for get_mcelog_from_dev"
68f08c3bdfSopenharmony_ci    local mcelog_result="$1"
69f08c3bdfSopenharmony_ci    if mcelog --dump-raw-ascii > "$mcelog_result"; then
70f08c3bdfSopenharmony_ci	true
71f08c3bdfSopenharmony_ci    else
72f08c3bdfSopenharmony_ci	echo "  Failed: can not get mce log from /dev/mcelog"
73f08c3bdfSopenharmony_ci    fi
74f08c3bdfSopenharmony_ci}
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci# extract mcelog from kernel log
77f08c3bdfSopenharmony_ciget_mcelog_from_klog()
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for get_mcelog_from_klog"
80f08c3bdfSopenharmony_ci    local klog="$1"
81f08c3bdfSopenharmony_ci    local mcelog_result="$2"
82f08c3bdfSopenharmony_ci    if [ -f "$klog" ] && extract_mce_from_log "$klog" "$mcelog_result"; then
83f08c3bdfSopenharmony_ci	true
84f08c3bdfSopenharmony_ci    else
85f08c3bdfSopenharmony_ci	echo "  Failed: Can not extract mcelog from console log"
86f08c3bdfSopenharmony_ci    fi
87f08c3bdfSopenharmony_ci}
88f08c3bdfSopenharmony_ci
89f08c3bdfSopenharmony_cimcelog_filter()
90f08c3bdfSopenharmony_ci{
91f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for mcelog_filter"
92f08c3bdfSopenharmony_ci    local inf="$1"
93f08c3bdfSopenharmony_ci    local pat="$2"
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci    mce-inject --dump "$inf" | tr '\n' '#' | sed '1,$s/##/\n/g' | \
96f08c3bdfSopenharmony_ci	grep -e "$pat"
97f08c3bdfSopenharmony_ci}
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_cichk_gcov()
100f08c3bdfSopenharmony_ci{
101f08c3bdfSopenharmony_ci    if [ -z "$GCOV" ]; then
102f08c3bdfSopenharmony_ci	return 1
103f08c3bdfSopenharmony_ci    fi
104f08c3bdfSopenharmony_ci
105f08c3bdfSopenharmony_ci    if [ -f /sys/kernel/debug/gcov/reset ] && which gcov > /dev/null; then
106f08c3bdfSopenharmony_ci	return 0
107f08c3bdfSopenharmony_ci    else
108f08c3bdfSopenharmony_ci	return 1
109f08c3bdfSopenharmony_ci    fi
110f08c3bdfSopenharmony_ci}
111f08c3bdfSopenharmony_ci
112f08c3bdfSopenharmony_cireset_gcov()
113f08c3bdfSopenharmony_ci{
114f08c3bdfSopenharmony_ci    if [ -z "$GCOV" ]; then
115f08c3bdfSopenharmony_ci	return
116f08c3bdfSopenharmony_ci    fi
117f08c3bdfSopenharmony_ci    case $GCOV in
118f08c3bdfSopenharmony_ci	copy)
119f08c3bdfSopenharmony_ci	    echo 1 > /sys/kernel/debug/gcov/reset
120f08c3bdfSopenharmony_ci	    ;;
121f08c3bdfSopenharmony_ci	dump)
122f08c3bdfSopenharmony_ci	    true;
123f08c3bdfSopenharmony_ci	    ;;
124f08c3bdfSopenharmony_ci	*)
125f08c3bdfSopenharmony_ci	    echo "  Failed: can not reset gcov, invalid GCOV=$GCOV"
126f08c3bdfSopenharmony_ci	    return
127f08c3bdfSopenharmony_ci	    ;;
128f08c3bdfSopenharmony_ci    esac
129f08c3bdfSopenharmony_ci}
130f08c3bdfSopenharmony_ci
131f08c3bdfSopenharmony_ciget_gcov()
132f08c3bdfSopenharmony_ci{
133f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for get_gcov"
134f08c3bdfSopenharmony_ci    local src_path=$1
135f08c3bdfSopenharmony_ci    local src_fn=$(basename $src_path)
136f08c3bdfSopenharmony_ci    local src_dir=$(dirname $src_path)
137f08c3bdfSopenharmony_ci    if [ -z "$GCOV" ]; then
138f08c3bdfSopenharmony_ci	return
139f08c3bdfSopenharmony_ci    fi
140f08c3bdfSopenharmony_ci    local abs_dir=$(cd -P $KSRC_DIR/$src_dir; pwd)
141f08c3bdfSopenharmony_ci    case $GCOV in
142f08c3bdfSopenharmony_ci	copy)
143f08c3bdfSopenharmony_ci	    for f in /sys/kernel/debug/gcov/$abs_dir/*.gc*; do
144f08c3bdfSopenharmony_ci		bf=$(basename $f)
145f08c3bdfSopenharmony_ci		cat $f > $abs_dir/$bf
146f08c3bdfSopenharmony_ci	    done
147f08c3bdfSopenharmony_ci	    ;;
148f08c3bdfSopenharmony_ci	dump)
149f08c3bdfSopenharmony_ci	    true
150f08c3bdfSopenharmony_ci	    ;;
151f08c3bdfSopenharmony_ci	*)
152f08c3bdfSopenharmony_ci	    echo "  Failed: can not get gcov path, invalid GCOV=$GCOV"
153f08c3bdfSopenharmony_ci	    return
154f08c3bdfSopenharmony_ci	    ;;
155f08c3bdfSopenharmony_ci    esac
156f08c3bdfSopenharmony_ci    if ! (cd $KSRC_DIR; gcov -o $src_dir $src_fn &> /dev/null) || \
157f08c3bdfSopenharmony_ci	! [ -s $KSRC_DIR/$src_fn.gcov ]; then
158f08c3bdfSopenharmony_ci	echo "  Failed: can not get gcov graph"
159f08c3bdfSopenharmony_ci	return
160f08c3bdfSopenharmony_ci    fi
161f08c3bdfSopenharmony_ci    cp $KSRC_DIR/$src_fn.gcov $RDIR/$this_case
162f08c3bdfSopenharmony_ci}
163f08c3bdfSopenharmony_ci
164f08c3bdfSopenharmony_cireset_severity_cov()
165f08c3bdfSopenharmony_ci{
166f08c3bdfSopenharmony_ci    echo 1 > /sys/kernel/debug/mce/severities-coverage
167f08c3bdfSopenharmony_ci}
168f08c3bdfSopenharmony_ci
169f08c3bdfSopenharmony_ciget_severity_cov()
170f08c3bdfSopenharmony_ci{
171f08c3bdfSopenharmony_ci    local sev_cor=/sys/kernel/debug/mce/severities-coverage
172f08c3bdfSopenharmony_ci    if [ ! -f $sev_cor ]; then
173f08c3bdfSopenharmony_ci	echo "  Failed: can not get severities_coverage"
174f08c3bdfSopenharmony_ci	return
175f08c3bdfSopenharmony_ci    fi
176f08c3bdfSopenharmony_ci    cp $sev_cor $RDIR/$this_case
177f08c3bdfSopenharmony_ci}
178f08c3bdfSopenharmony_ci
179f08c3bdfSopenharmony_civerify_klog()
180f08c3bdfSopenharmony_ci{
181f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for verify_klog"
182f08c3bdfSopenharmony_ci    local klog="$1"
183f08c3bdfSopenharmony_ci    if [ -f "$klog" ]; then
184f08c3bdfSopenharmony_ci	if check_kern_warning_bug "$klog"; then
185f08c3bdfSopenharmony_ci	    echo "  Failed: kernel warning or bug during MCE"
186f08c3bdfSopenharmony_ci	else
187f08c3bdfSopenharmony_ci	    echo "  Passed: No kernel warning or bug"
188f08c3bdfSopenharmony_ci	fi
189f08c3bdfSopenharmony_ci    else
190f08c3bdfSopenharmony_ci	echo "  Failed: no kernel log"
191f08c3bdfSopenharmony_ci    fi
192f08c3bdfSopenharmony_ci}
193f08c3bdfSopenharmony_ci
194f08c3bdfSopenharmony_civerify_panic_via_klog()
195f08c3bdfSopenharmony_ci{
196f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for verify_panic"
197f08c3bdfSopenharmony_ci    local klog="$1"
198f08c3bdfSopenharmony_ci    local mce_panic="$2"
199f08c3bdfSopenharmony_ci    if [ ! -f "$klog" ]; then
200f08c3bdfSopenharmony_ci	echo "  Failed: no kernel log for checking panic"
201f08c3bdfSopenharmony_ci	return -1
202f08c3bdfSopenharmony_ci    fi
203f08c3bdfSopenharmony_ci
204f08c3bdfSopenharmony_ci    if grep "panic" "$klog" | grep "$mce_panic" > /dev/null; then
205f08c3bdfSopenharmony_ci	echo "  Passed: correct panic"
206f08c3bdfSopenharmony_ci    else
207f08c3bdfSopenharmony_ci	echo "  Failed: uncorrect panic, expected: $mce_panic"
208f08c3bdfSopenharmony_ci    fi
209f08c3bdfSopenharmony_ci}
210f08c3bdfSopenharmony_ci
211f08c3bdfSopenharmony_civerify_timeout_via_klog()
212f08c3bdfSopenharmony_ci{
213f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for verify_timeout"
214f08c3bdfSopenharmony_ci    local klog="$1"
215f08c3bdfSopenharmony_ci    if [ ! -f "$klog" ]; then
216f08c3bdfSopenharmony_ci	echo "  Failed: No kernel log for checking timeout"
217f08c3bdfSopenharmony_ci	return -1
218f08c3bdfSopenharmony_ci    fi
219f08c3bdfSopenharmony_ci
220f08c3bdfSopenharmony_ci    if grep "Some CPUs didn't answer in synchronization" "$klog" \
221f08c3bdfSopenharmony_ci	> /dev/null; then
222f08c3bdfSopenharmony_ci	echo "  Passed: timeout detected"
223f08c3bdfSopenharmony_ci    else
224f08c3bdfSopenharmony_ci	echo "  Failed: no timeout detected"
225f08c3bdfSopenharmony_ci    fi
226f08c3bdfSopenharmony_ci}
227f08c3bdfSopenharmony_ci
228f08c3bdfSopenharmony_civerify_exp_via_klog()
229f08c3bdfSopenharmony_ci{
230f08c3bdfSopenharmony_ci    [ $# -ge 2 ] || die "missing parameter for verrify_exp_via_klog"
231f08c3bdfSopenharmony_ci    local klog="$1"
232f08c3bdfSopenharmony_ci    shift
233f08c3bdfSopenharmony_ci    if [ ! -f "$klog" ]; then
234f08c3bdfSopenharmony_ci	echo "  Failed: No kernel log for checking MCE exp"
235f08c3bdfSopenharmony_ci	return -1
236f08c3bdfSopenharmony_ci    fi
237f08c3bdfSopenharmony_ci
238f08c3bdfSopenharmony_ci    for exp in "$@"; do
239f08c3bdfSopenharmony_ci	if grep "Machine check: " "$klog" | grep "$exp" > /dev/null; then
240f08c3bdfSopenharmony_ci	    echo "  Passed: correct MCE exp"
241f08c3bdfSopenharmony_ci	    return
242f08c3bdfSopenharmony_ci	fi
243f08c3bdfSopenharmony_ci    done
244f08c3bdfSopenharmony_ci    echo "  Failed:  uncorrected MCE exp, expected: $exp"
245f08c3bdfSopenharmony_ci}
246f08c3bdfSopenharmony_ci
247f08c3bdfSopenharmony_ciget_panic_from_mcelog()
248f08c3bdfSopenharmony_ci{
249f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for get_panic_from_mcelog"
250f08c3bdfSopenharmony_ci    local mcelog="$1"
251f08c3bdfSopenharmony_ci    local tmpf=$WDIR/get_panic_from_mcelog
252f08c3bdfSopenharmony_ci    local addr
253f08c3bdfSopenharmony_ci    if mcelog_filter $mcelog "#BANK 219#" | head -1 > $tmpf; then
254f08c3bdfSopenharmony_ci	local F="$(sed '1,$s/#/\n/g' $tmpf | awk '/MISC / { print $2 }')"
255f08c3bdfSopenharmony_ci	case "$F" in
256f08c3bdfSopenharmony_ci	    0x1) echo "Fatal machine check" ;;
257f08c3bdfSopenharmony_ci	    0x2) echo "Machine check from unknown source" ;;
258f08c3bdfSopenharmony_ci	    0x3) echo "Uncorrected data corruption machine check" ;;
259f08c3bdfSopenharmony_ci	    0x4) echo "Fatal machine check" ;;
260f08c3bdfSopenharmony_ci	    *) echo unknown panic $F ;;
261f08c3bdfSopenharmony_ci	esac
262f08c3bdfSopenharmony_ci    fi
263f08c3bdfSopenharmony_ci}
264f08c3bdfSopenharmony_ci
265f08c3bdfSopenharmony_civerify_panic_msg()
266f08c3bdfSopenharmony_ci{
267f08c3bdfSopenharmony_ci    [ $# -eq 2 ] || die "missing parameter for verify_panic_msg"
268f08c3bdfSopenharmony_ci    local panic_msg="$1"
269f08c3bdfSopenharmony_ci    local mce_panic="$2"
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci    if echo ": $panic_msg" | grep -e "$mce_panic" &> /dev/null; then
272f08c3bdfSopenharmony_ci	echo "  Passed: correct panic"
273f08c3bdfSopenharmony_ci    else
274f08c3bdfSopenharmony_ci	echo "  Failed: uncorrect panic, expected: $mce_panic"
275f08c3bdfSopenharmony_ci    fi
276f08c3bdfSopenharmony_ci}
277f08c3bdfSopenharmony_ci
278f08c3bdfSopenharmony_civerify_timeout_via_mcelog()
279f08c3bdfSopenharmony_ci{
280f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for verify_timeout"
281f08c3bdfSopenharmony_ci    local mcelog="$1"
282f08c3bdfSopenharmony_ci
283f08c3bdfSopenharmony_ci    if mcelog_filter $mcelog "#BANK 218#" &> /dev/null; then
284f08c3bdfSopenharmony_ci	echo "  Passed: timeout detected"
285f08c3bdfSopenharmony_ci    else
286f08c3bdfSopenharmony_ci	echo "  Failed: no timeout detected"
287f08c3bdfSopenharmony_ci    fi
288f08c3bdfSopenharmony_ci}
289f08c3bdfSopenharmony_ci
290f08c3bdfSopenharmony_ciset_tolerant()
291f08c3bdfSopenharmony_ci{
292f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for set_tolerant"
293f08c3bdfSopenharmony_ci    echo -n $1 > /sys/devices/system/machinecheck/machinecheck0/tolerant
294f08c3bdfSopenharmony_ci}
295f08c3bdfSopenharmony_ci
296f08c3bdfSopenharmony_ciget_tolerant()
297f08c3bdfSopenharmony_ci{
298f08c3bdfSopenharmony_ci    cat /sys/devices/system/machinecheck/machinecheck0/tolerant
299f08c3bdfSopenharmony_ci}
300f08c3bdfSopenharmony_ci
301f08c3bdfSopenharmony_cicheck_debugfs()
302f08c3bdfSopenharmony_ci{
303f08c3bdfSopenharmony_ci	mount|grep /sys/kernel/debug > /dev/null 2>&1
304f08c3bdfSopenharmony_ci	[ ! $? -eq 0 ] && mount -t debugfs none /sys/kernel/debug
305f08c3bdfSopenharmony_ci	mount|grep /sys/kernel/debug > /dev/null 2>&1
306f08c3bdfSopenharmony_ci	[ ! $? -eq 0 ] && die "Kernel without debugfs support ?"
307f08c3bdfSopenharmony_ci}
308f08c3bdfSopenharmony_ci
309f08c3bdfSopenharmony_ci# should be called after check_debugfs
310f08c3bdfSopenharmony_cicheck_mce()
311f08c3bdfSopenharmony_ci{
312f08c3bdfSopenharmony_ci    DEBUGFS=`mount | grep debugfs | cut -d ' ' -f3 | head -1`
313f08c3bdfSopenharmony_ci    [ ! -d ${DEBUGFS}/mce ] && die "Kernel without CONFIG_X86_MCE_INJECT ?"
314f08c3bdfSopenharmony_ci}
315f08c3bdfSopenharmony_ci
316f08c3bdfSopenharmony_ciset_fake_panic()
317f08c3bdfSopenharmony_ci{
318f08c3bdfSopenharmony_ci    check_debugfs
319f08c3bdfSopenharmony_ci    check_mce
320f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for set_fake_panic"
321f08c3bdfSopenharmony_ci    echo -n $1 > /sys/kernel/debug/mce/fake_panic
322f08c3bdfSopenharmony_ci}
323f08c3bdfSopenharmony_ci
324f08c3bdfSopenharmony_ciset_panic_on_oops()
325f08c3bdfSopenharmony_ci{
326f08c3bdfSopenharmony_ci    [ $# -eq 1 ] || die "missing parameter for set_panic_on_oops"
327f08c3bdfSopenharmony_ci    echo -n $1 > /proc/sys/kernel/panic_on_oops
328f08c3bdfSopenharmony_ci}
329