xref: /illumos-gate/usr/src/test/os-tests/tests/xsave/proc_writes.ksh (revision a89c0811c892ec231725fe10817ef95dda813c06)
1#!/usr/bin/ksh
2#
3#
4# This file and its contents are supplied under the terms of the
5# Common Development and Distribution License ("CDDL"), version 1.0.
6# You may only use this file in accordance with the terms of version
7# 1.0 of the CDDL.
8#
9# A full copy of the text of the CDDL should have accompanied this
10# source.  A copy of the CDDL is also available via the Internet at
11# http://www.illumos.org/license/CDDL.
12#
13
14#
15# Copyright 2023 Oxide Computer Company
16#
17
18#
19# This shell script is a runner that tries to verify that if we write to
20# a target program's xregs via /proc, that it actualy sees the same
21# register contents that we put in. There are four different pieces to
22# this:
23#
24#  o The 'proc_xregs_set' binaries which sets the registers of the target.
25#    Right now we expect the bitness to match whatever it is running against.
26#  o The 'xregs_dump' binaries which dump the FPU state that they have in a
27#    bespoke format.
28#  o The output data files that we use to try to match what is generated.
29#  o The 'xsu_hwtype' binaries which tell us what data format we should expect.
30#
31# We have to discover what kind of hardware our target is running on and then
32# that allows us to ensure that we can match up the right input and output
33# files. We always run both the 32-bit and 64-bit versions of this; however,
34# because 32-bit programs have access to fewer registers, they have a different
35# data file to match against.
36#
37# We also reprat the process of 'proc_xregs_set' using the fpregs binary
38# instead. That allows us to also verify some of the same behavior, but also
39# pieces of fpregs functionality.
40#
41
42unalias -a
43set -o pipefail
44export LANG=C.UTF-8
45
46pw_exit=0;
47pw_arg0="$(basename $0)"
48pw_dir="$(dirname $0)"
49pw_datadir="$pw_dir/data"
50
51#
52# The starting value is used to determine the way that the regiser contents are
53# set in the target's FPU. If you change this value, the check files must be
54# updated.
55#
56typeset -A pw_start
57pw_start["xregs32"]="0xc120ff06"
58pw_start["xregs64"]="0xfaceecaf"
59pw_start["fpregs32"]="0x20190909"
60pw_start["fpregs64"]="0x28186002"
61
62typeset -A pw_hwtypes
63typeset -A pw_dump
64typeset -A pw_prog
65pw_hwtypes["32"]="$pw_dir/xsu_hwtype.32"
66pw_hwtypes["64"]="$pw_dir/xsu_hwtype.64"
67pw_dump["32"]="$pw_dir/xregs_dump.32"
68pw_dump["64"]="$pw_dir/xregs_dump.64"
69pw_prog["xregs32"]="$pw_dir/proc_xregs_set.32"
70pw_prog["xregs64"]="$pw_dir/proc_xregs_set.64"
71pw_prog["fpregs32"]="$pw_dir/fpregs.32"
72pw_prog["fpregs64"]="$pw_dir/fpregs.64"
73
74#
75# All our victim programs are usually the same here and have a single breakpoint
76# we want. This should become an associative array if this changes in the
77# future.
78#
79pw_bkpt="xsu_getfpu"
80
81warn()
82{
83	typeset msg="$*"
84	echo "TEST FAILED: $msg" >&2
85	pw_exit=1
86}
87
88run_single()
89{
90	typeset prog="$1"
91	typeset arch="$2"
92	typeset comb="$prog$arch"
93	typeset fpu_type=
94	typeset start=${pw_start[$comb]}
95	typeset hwtype=${pw_hwtypes[$arch]}
96	typeset dump=${pw_dump[$arch]}
97	typeset exe=${pw_prog[$comb]}
98	typeset output=
99	typeset check=
100
101	if ! fpu_type=$($hwtype 2>/dev/null); then
102		warn "failed to determine $arch-bit FPU type"
103		return
104	fi
105
106	printf "Discovered FPU: %s %s-bit\n" $fpu_type $arch
107	output="/tmp/$prog.$fpu_type.$arch.$$"
108	check="$pw_datadir/proc_writes.$prog.$fpu_type.$arch"
109
110	if ! [[ -r $check ]]; then
111		warn "missing expected output file $check"
112		return;
113	fi
114
115	printf "Running %s %s %s %s\n" $exe $dump $output $start
116	if ! $exe $dump $output $start $pw_bkpt; then
117		warn "$exe did not execute successfully"
118		rm -f $output
119	fi
120
121	if ! diff -q $check $output; then
122		diff -u $check $output
123		warn "$fpu_type $arch-bit FPU regs did not match expected " \
124		    "output"
125	else
126		printf "TEST PASSED: %s %s-bit FPU regs matched /proc write\n" \
127		    $fpu_type $arch
128	fi
129
130	rm -f $output
131}
132
133run_single xregs 32
134run_single xregs 64
135run_single fpregs 32
136run_single fpregs 64
137
138if (( pw_exit == 0 )); then
139	printf "All tests passed successfully\n"
140fi
141
142exit $pw_exit
143