Bind lib.bash : A script that makes pciback with modules easier to use

From Xen
Description

A script that makes pciback with modules easier than with recompiling the kernel and using the boot loader line.

It is based on the info from this email.

Icon Info.png In Xen 4.2 with the xl toolstack this functionality is integrated into the toolstack


Instructions

This script should be run like this:

   . bind_lib.bash

And then call the functions yourself, for example:

   modprobe xen-pciback
   bindback "0000:04:00.0"

This script is tested with a Radeon 6770 card, using pciback, with "pci_passthru=0" and "stdvga=1". Using this method, you don't need to blacklist radeon.


The functions:

bind_lib.bash

   #!/bin/bash
   #
   # License: GPLv2
   # Author: Peter Maloney
   #
   # Script to bind devices to pciback (or pci-stub)
   
   find_new_id() {
       device="$1"
       len=${#device}
       if [ "$len" -eq 12 ]; then
           device="${device:5:12}"
       fi
       lspci -n | grep "${device}" | cut -d' ' -f3 | sed -r "s/:/ /"
   }
   
   bindstub() {
       device="$1"
       echo "binddevice $device"
       
       if [ ! -e "/sys/bus/pci/devices/$device" ]; then
           echo "    ERROR: Device does not exist... cancelling"
           return
       fi
       
       # with pci-stub, you do new_id, then unbind, then bind
       
       echo "create new_id"
       chmod +w /sys/bus/pci/drivers/pci-stub/new_id
       new_id="$(find_new_id "$device")"
       echo "    echo \"$new_id\" > /sys/bus/pci/drivers/pci-stub/new_id"
       echo "$new_id" > /sys/bus/pci/drivers/pci-stub/new_id
       
       echo "unbind"
       if [ ! -e "/sys/bus/pci/devices/$device/driver" ]; then
           echo "    no driver to unbind"
       else
           chmod +w "/sys/bus/pci/devices/${device}/driver/unbind"
           echo "    echo -n \"$device\" > \"/sys/bus/pci/devices/$device/driver/unbind\""
           echo -n "$device" > "/sys/bus/pci/devices/$device/driver/unbind"
       fi
       
       echo "bind"
       chmod +w /sys/bus/pci/drivers/pci-stub/bind
       echo "    echo -n \"$device\" > /sys/bus/pci/drivers/pci-stub/bind"
       echo -n "$device" > /sys/bus/pci/drivers/pci-stub/bind
       
       echo
   }
   
   bindback() {
       device="$1"
       echo "binddevice $device"
       
       if [ ! -e "/sys/bus/pci/devices/$device" ]; then
           echo "ERROR: Device does not exist... cancelling"
           return
       fi
       
       # with pciback, you do unbind, then new_slot, then bind
       
       echo "unbind"
       if [ ! -e "/sys/bus/pci/devices/$device/driver" ]; then
           echo "    no driver to unbind"
       else
           chmod +w "/sys/bus/pci/devices/${device}/driver/unbind"
           echo "    echo -n \"$device\" > \"/sys/bus/pci/devices/$device/driver/unbind\""
           echo -n "$device" > "/sys/bus/pci/devices/$device/driver/unbind"
       fi
       
       echo "create new_slot"
       chmod +w /sys/bus/pci/drivers/pciback/new_slot
       echo "    echo -n \"$device\" > /sys/bus/pci/drivers/pciback/new_slot"
       echo -n "$device" > /sys/bus/pci/drivers/pciback/new_slot
       
       echo "bind"
       chmod +w /sys/bus/pci/drivers/pciback/bind
       echo "    echo -n \"$device\" > /sys/bus/pci/drivers/pciback/bind"
       echo -n "$device" > /sys/bus/pci/drivers/pciback/bind
       
       echo
   }


Examples for binding devices (with hardcoded PCI address examples):

   modprobe pci-stub
   # vga2
   bindstub "0000:04:00.0"
   
   # vga2 audio
   bindstub "0000:04:00.1"
   
   # usb2
   bindstub "0000:00:12.0"
   bindstub "0000:00:12.2"
   
   # usb3
   bindstub "0000:02:00.0"
   
   
   # Check results
   ls -l /sys/bus/pci/devices/{0000:01:00.0,0000:01:00.1,0000:04:00.0,0000:04:00.1,0000:00:12.0,0000:00:12.2,0000:02:00.0}/driver
   xm pci-list-assignable-devices

   modprobe xen-pciback
   # vga2
   bindback "0000:04:00.0"
   
   # vga2 audio
   bindback "0000:04:00.1"
   
   # usb2
   bindback "0000:00:12.0"
   bindback "0000:00:12.2"
   
   # usb3
   bindback "0000:02:00.0"
   
   # Check results
   ls -l /sys/bus/pci/devices/{0000:01:00.0,0000:01:00.1,0000:04:00.0,0000:04:00.1,0000:00:12.0,0000:00:12.2,0000:02:00.0}/driver
   xm pci-list-assignable-devices