Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 41 additions & 5 deletions dracut/modules.d/90qubes-pciback/qubes-pciback.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,38 @@
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
unset re HIDE_PCI usb_in_dom0 dev skip exposed

resolve_dev() {
local dev="$1"
local segment="0000"
local bridge bus bus_offset

case "$dev" in
# device path to resolve
[0-9a-f][0-9a-f][0-9a-f][0-9a-f]_*_*.*)
segment=${dev%%_*}
dev="${dev#*_}"
;;
*_*.*) ;;
# (S)BDF directly
*:*:*.*) echo "$dev"; return ;;
*:*.*) echo "0000:$dev"; return;;
*) echo "Invalid device format: $dev" >&2; return ;;
esac

while [[ "$dev" = *-* ]]; do
bridge="${dev%%-*}"
bridge="${bridge//_/:}"
dev="${dev#*-}"
# this is in hex
bus="${dev%%_*}"
# this is in dec
bus_offset=$(<"/sys/bus/pci/devices/$segment:$bridge/secondary_bus_number") || return
bus=$(printf "%02x" $(( "0x$bus" + bus_offset )) )
dev="${bus}_${dev#*_}"
done
echo "$segment:${dev//_/:}"
}

usb_in_dom0=false

if getargbool 0 rd.qubes.hide_all_usb; then
Expand All @@ -22,17 +54,17 @@ HIDE_PCI=$(set -o pipefail; { lspci -mm -n | awk "/^[^ ]* \"$re/ {print \$1}";})

manual_pcidevs=$(getarg rd.qubes.hide_pci)
case $manual_pcidevs in
(*[!0-9a-f.:,]*) warn 'Bogus rd.qubes.hide_pci option - fix your kernel command line!';;
(*[!0-9a-f_.:,-]*) warn 'Bogus rd.qubes.hide_pci option - fix your kernel command line!';;
esac
HIDE_PCI="$HIDE_PCI ${manual_pcidevs//,/ }"

# XXX should this be fatal?
ws=$' \n'
[[ $HIDE_PCI =~ ^[0-9a-f.:$ws]+$ ]] ||
[[ $HIDE_PCI =~ ^[0-9a-f_.:$ws-]+$ ]] ||
die 'Bogus PCI device list - fix your kernel command line!'
modprobe xen-pciback 2>/dev/null || :
dom0_usb=$(getarg rd.qubes.dom0_usb)
if [[ "$dom0_usb" == *[!0-9a-f.:,]* ]] ; then
if [[ "$dom0_usb" == *[!0-9a-f_.:,-]* ]] ; then
warn 'Bogus rd.qubes.dom0_usb option - fix your kernel command line!'
dom0_usb=""
elif [ -n "$dom0_usb" ] ; then
Expand All @@ -44,12 +76,16 @@ fi
set -e
# ... and hide them so that Dom0 doesn't load drivers for them
for dev in $HIDE_PCI; do
BDF=$(resolve_dev "$dev")
if [ -z "$BDF" ]; then
die "Cannot find device '$dev' to hide"
fi
skip=false
for exposed in $dom0_usb; do
if [ "$dev" = "$exposed" ]; then skip=true; fi
exposed=$(resolve_dev "$exposed")
if [ "$BDF" = "$exposed" ]; then skip=true; fi
done
if [ "$skip" = true ]; then continue; fi
BDF=0000:$dev
if [ -e "/sys/bus/pci/devices/$BDF/driver" ]; then
echo -n "$BDF" > "/sys/bus/pci/devices/$BDF/driver/unbind"
fi
Expand Down