# SPDX-License-Identifier: GPL-2.0-or-later # Global variables initialized in main() and then used during cleanup() when # the script exits. declare DEVICE_BDF declare NEW_DRIVER declare OLD_DRIVER declare OLD_NUMVFS declare DRIVER_OVERRIDE function write_to() { # Unfortunately set -x does not show redirects so use echo to manually # tell the user what commands are being run. echo "+ echo \"${2}\" > ${1}" echo "${2}" > ${1} } function bind() { write_to /sys/bus/pci/drivers/${2}/bind ${1} } function unbind() { write_to /sys/bus/pci/drivers/${2}/unbind ${1} } function set_sriov_numvfs() { write_to /sys/bus/pci/devices/${1}/sriov_numvfs ${2} } function set_driver_override() { write_to /sys/bus/pci/devices/${1}/driver_override ${2} } function clear_driver_override() { set_driver_override ${1} "" } function cleanup() { if [ "${NEW_DRIVER}" ]; then unbind ${DEVICE_BDF} ${NEW_DRIVER} ; fi if [ "${DRIVER_OVERRIDE}" ]; then clear_driver_override ${DEVICE_BDF} ; fi if [ "${OLD_DRIVER}" ]; then bind ${DEVICE_BDF} ${OLD_DRIVER} ; fi if [ "${OLD_NUMVFS}" ]; then set_sriov_numvfs ${DEVICE_BDF} ${OLD_NUMVFS} ; fi } function usage() { echo "usage: $0 [-d segment:bus:device.function] [-s] [-h] [cmd ...]" >&2 echo >&2 echo " -d: The BDF of the device to use for the test (required)" >&2 echo " -h: Show this help message" >&2 echo " -s: Drop into a shell rather than running a command" >&2 echo >&2 echo " cmd: The command to run and arguments to pass to it." >&2 echo " Required when not using -s. The SBDF will be " >&2 echo " appended to the argument list." >&2 exit 1 } function main() { local shell while getopts "d:hs" opt; do case $opt in d) DEVICE_BDF="$OPTARG" ;; s) shell=true ;; *) usage ;; esac done # Shift past all optional arguments. shift $((OPTIND - 1)) # Check that the user passed in the command to run. [ ! "${shell}" ] && [ $# = 0 ] && usage # Check that the user passed in a BDF. [ "${DEVICE_BDF}" ] || usage trap cleanup EXIT set -e test -d /sys/bus/pci/devices/${DEVICE_BDF} if [ -f /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs ]; then OLD_NUMVFS=$(cat /sys/bus/pci/devices/${DEVICE_BDF}/sriov_numvfs) set_sriov_numvfs ${DEVICE_BDF} 0 fi if [ -L /sys/bus/pci/devices/${DEVICE_BDF}/driver ]; then OLD_DRIVER=$(basename $(readlink -m /sys/bus/pci/devices/${DEVICE_BDF}/driver)) unbind ${DEVICE_BDF} ${OLD_DRIVER} fi set_driver_override ${DEVICE_BDF} vfio-pci DRIVER_OVERRIDE=true bind ${DEVICE_BDF} vfio-pci NEW_DRIVER=vfio-pci echo if [ "${shell}" ]; then echo "Dropping into ${SHELL} with VFIO_SELFTESTS_BDF=${DEVICE_BDF}" VFIO_SELFTESTS_BDF=${DEVICE_BDF} ${SHELL} else "$@" ${DEVICE_BDF} fi echo } main "$@"