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