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