xref: /linux/tools/testing/selftests/vfio/run.sh (revision 55a42f78ffd386e01a5404419f8c5ded7db70a21)
1# SPDX-License-Identifier: GPL-2.0-or-later
2
3# Global variables initialized in main() and then used during cleanup() when
4# the script exits.
5declare DEVICE_BDF
6declare NEW_DRIVER
7declare OLD_DRIVER
8declare OLD_NUMVFS
9declare DRIVER_OVERRIDE
10
11function write_to() {
12	# Unfortunately set -x does not show redirects so use echo to manually
13	# tell the user what commands are being run.
14	echo "+ echo \"${2}\" > ${1}"
15	echo "${2}" > ${1}
16}
17
18function bind() {
19	write_to /sys/bus/pci/drivers/${2}/bind ${1}
20}
21
22function unbind() {
23	write_to /sys/bus/pci/drivers/${2}/unbind ${1}
24}
25
26function set_sriov_numvfs() {
27	write_to /sys/bus/pci/devices/${1}/sriov_numvfs ${2}
28}
29
30function set_driver_override() {
31	write_to /sys/bus/pci/devices/${1}/driver_override ${2}
32}
33
34function clear_driver_override() {
35	set_driver_override ${1} ""
36}
37
38function cleanup() {
39	if [ "${NEW_DRIVER}"      ]; then unbind ${DEVICE_BDF} ${NEW_DRIVER} ; fi
40	if [ "${DRIVER_OVERRIDE}" ]; then clear_driver_override ${DEVICE_BDF} ; fi
41	if [ "${OLD_DRIVER}"      ]; then bind ${DEVICE_BDF} ${OLD_DRIVER} ; fi
42	if [ "${OLD_NUMVFS}"      ]; then set_sriov_numvfs ${DEVICE_BDF} ${OLD_NUMVFS} ; fi
43}
44
45function usage() {
46	echo "usage: $0 [-d segment:bus:device.function] [-s] [-h] [cmd ...]" >&2
47	echo >&2
48	echo "  -d: The BDF of the device to use for the test (required)" >&2
49	echo "  -h: Show this help message" >&2
50	echo "  -s: Drop into a shell rather than running a command" >&2
51	echo >&2
52	echo "   cmd: The command to run and arguments to pass to it." >&2
53	echo "        Required when not using -s. The SBDF will be " >&2
54	echo "        appended to the argument list." >&2
55	exit 1
56}
57
58function main() {
59	local shell
60
61	while getopts "d:hs" opt; do
62		case $opt in
63			d) DEVICE_BDF="$OPTARG" ;;
64			s) shell=true ;;
65			*) usage ;;
66		esac
67	done
68
69	# Shift past all optional arguments.
70	shift $((OPTIND - 1))
71
72	# Check that the user passed in the command to run.
73	[ ! "${shell}" ] && [ $# = 0 ] && usage
74
75	# Check that the user passed in a BDF.
76	[ "${DEVICE_BDF}" ] || usage
77
78	trap cleanup EXIT
79	set -e
80
81	test -d /sys/bus/pci/devices/${DEVICE_BDF}
82
83	if [ -f /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs ]; then
84		OLD_NUMVFS=$(cat /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs)
85		set_sriov_numvfs ${DEVICE_BDF} 0
86	fi
87
88	if [ -L /sys/bus/pci/devices/${DEVICE_BDF}/driver ]; then
89		OLD_DRIVER=$(basename $(readlink -m /sys/bus/pci/devices/${DEVICE_BDF}/driver))
90		unbind ${DEVICE_BDF} ${OLD_DRIVER}
91	fi
92
93	set_driver_override ${DEVICE_BDF} vfio-pci
94	DRIVER_OVERRIDE=true
95
96	bind ${DEVICE_BDF} vfio-pci
97	NEW_DRIVER=vfio-pci
98
99	echo
100	if [ "${shell}" ]; then
101		echo "Dropping into ${SHELL} with VFIO_SELFTESTS_BDF=${DEVICE_BDF}"
102		VFIO_SELFTESTS_BDF=${DEVICE_BDF} ${SHELL}
103	else
104		"$@" ${DEVICE_BDF}
105	fi
106	echo
107}
108
109main "$@"
110