Merge branch 'dev' to add support for mkinitcpio and dracut

This commit is contained in:
HikariKnight 2022-03-12 21:11:22 +01:00
commit f3c538ee7e
No known key found for this signature in database
GPG key ID: E8B239063B022F5A
16 changed files with 407 additions and 193 deletions

View file

@ -2,8 +2,6 @@
A project to simplify setting up GPU passthrough on your Linux host for [QuickEMU](https://github.com/quickemu-project/quickemu)(vfio support not developed yet) and libvirt/virt-manager A project to simplify setting up GPU passthrough on your Linux host for [QuickEMU](https://github.com/quickemu-project/quickemu)(vfio support not developed yet) and libvirt/virt-manager
Currently this project works with systems using initramfs-tools, if you want support for systems using other initrd image builders like dracut, consider contributing!
You can use it by simply running You can use it by simply running
```bash ```bash
@ -18,7 +16,7 @@ cd quickpassthrough
* Enable and configure vfio modules * Enable and configure vfio modules
* Configure 2nd GPU for GPU Passthrough * Configure 2nd GPU for GPU Passthrough
* Dump the selected GPU rom (as some cards require a romfile for passthrough to work), however no rom patching support planned. * Dump the selected GPU rom (as some cards require a romfile for passthrough to work), however no rom patching support planned.
* Enable and configure the correct kernel modules and load them early (initramfs-tools only for now) * Enable and configure the correct kernel modules and load them early (initramfs-tools, dracut and mkinitcpio)
* Configure kernel arguments for systemd-boot (using kernelstub) * Configure kernel arguments for systemd-boot (using kernelstub)
* Configure kernel arguments for grub2 * Configure kernel arguments for grub2
* Provides you with the correct kernel arguments to add to your bootloader entry if a supported bootloader is not found * Provides you with the correct kernel arguments to add to your bootloader entry if a supported bootloader is not found

View file

@ -6,39 +6,108 @@ function make_BACKUP () {
if [ ! -d "$BACKUPDIR" ]; if [ ! -d "$BACKUPDIR" ];
then then
# Make the backup directories # Make the backup directories and backup the files
mkdir -p "$BACKUPDIR/etc/initramfs-tools" if [ -d "/etc/initramfs-tools" ];
mkdir -p "$BACKUPDIR/etc/modprobe.d"
mkdir -p "$BACKUPDIR/etc/default"
# Backup system files
sudo cp -v "/etc/modules" "$BACKUPDIR/etc/modules"
sudo cp -v "/etc/initramfs-tools/modules" "$BACKUPDIR/etc/initramfs-tools/modules"
sudp cp -v "/etc/default/grub" "$BACKUPDIR/etc/default/grub"
# If a vfio.conf file exists, backup that too
if [ -f "/etc/modprobe.d/vfio.conf" ];
then then
sudo cp -v "/etc/modprobe.d/vfio.conf" "$BACKUPDIR/etc/modprobe.d/vfio.conf" mkdir -p "$BACKUPDIR/etc/initramfs-tools"
cp -v "/etc/initramfs-tools/modules" "$BACKUPDIR/etc/initramfs-tools/modules"
cp -v "/etc/modules" "$BACKUPDIR/etc/modules"
elif [ -d "/etc/dracut.conf" ];
then
mkdir -p "$BACKUPDIR/etc/dracut.conf.d"
if [ -f "/etc/dracut.conf.d/10-vfio.conf" ];
then
cp -v "/etc/dracut.conf.d/10-vfio.conf" "$BACKUPDIR/etc/dracut.conf.d/10-vfio.conf"
fi
elif [ -f "/etc/mkinitcpio.conf" ];
then
mkdir -p "$BACKUPDIR/etc"
cp -v "/etc/mkinitcpio.conf" "$BACKUPDIR/etc/mkinitcpio.conf"
fi fi
echo "Backup completed!" if [ -f "/etc/default/grub" ];
then
mkdir -p "$BACKUPDIR/etc/default"
cp -v "/etc/default/grub" "$BACKUPDIR/etc/default/grub"
fi
if [ -d "/etc/modprobe.d" ];
then
mkdir -p "$BACKUPDIR/etc/modprobe.d"
# If a vfio.conf file exists, backup that too
if [ -f "/etc/modprobe.d/vfio.conf" ];
then
cp -v "/etc/modprobe.d/vfio.conf" "$BACKUPDIR/etc/modprobe.d/vfio.conf"
fi
fi
printf "Backup completed!\n"
else else
echo "A backup already exists! echo "
backup skipped." A backup already exists!
backup skipped.
"
fi fi
} }
function copy_FILES () { function copy_FILES () {
echo "Starting copying files to the system!" echo "Starting copying files to the system!"
sudo cp -v "$SCRIPTDIR/$ETCMODULES" "/etc/modules"
sudo cp -v "$SCRIPTDIR/$INITRAMFS/modules" "/etc/initramfs-tools/modules"
sudo cp -v "$SCRIPTDIR/$MODPROBE/vfio.conf" "/etc/modprobe.d/vfio.conf"
echo "" if [ -d "/etc/modprobe.d" ];
echo "Rebuilding initramfs" then
sudo update-initramfs -u sudo cp -v "$SCRIPTDIR/$MODPROBE/vfio.conf" "/etc/modprobe.d/vfio.conf"
fi
if [ -d "/etc/initramfs-tools" ];
then
sudo cp -v "$SCRIPTDIR/$ETCMODULES" "/etc/modules"
sudo cp -v "$SCRIPTDIR/$INITRAMFS/modules" "/etc/initramfs-tools/modules"
echo "
Rebuilding initramfs"
sudo update-initramfs -u
elif [ -f "/etc/dracut.conf" ];
then
cp -v "$SCRIPTDIR/$DRACUT/10-vfio.conf" "/etc/dracut.conf.d/10-vfio.conf"
echo "
Rebuilding initramfs"
sudo dracut -f -v --kver "$(uname -r)"
elif [ -f "/etc/mkinitcpio.conf" ];
then
cp -v "$SCRIPTDIR/$MKINITCPIO" "/etc/mkinitcpio.conf"
echo "
Rebuilding initramfs"
sudo mkinitcpio -P
else
echo "
Unsupported initramfs infrastructure
In order to make vfio work, please add these modules to your
initramfs and make them load early, then rebuild initramfs.
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
Press ENTER to continue once you have done the above."
read -r
fi
} }
function apply_CHANGES () { function apply_CHANGES () {
@ -55,18 +124,18 @@ By proceeding, a backup of your system's version of these files will be placed i
$SCRIPTDIR/backup $SCRIPTDIR/backup
unless a backup already exist. unless a backup already exist.
Then the files above will be copied to your system followed by running \"update-initramfs -u\" Then the files above will be copied to your system followed by running followed by updating your
to build your new initrd image (all of this will require sudo permissions!)" initramfs and then attempt adding new kernel arguments to your bootloader."
read -p "Do you want to proceed with the installation of the files? (no=skip) [Y/n]: " YESNO read -p "Do you want to proceed with the installation of the files? (no=quit) [Y/n]: " YESNO
case "${YESNO}" in case "${YESNO}" in
[Yy]*) [Nn]*)
make_BACKUP exit 1
copy_FILES
exec "$SCRIPTDIR/lib/set_CMDLINE.sh"
;; ;;
*) *)
make_BACKUP
copy_FILES
exec "$SCRIPTDIR/lib/set_CMDLINE.sh" exec "$SCRIPTDIR/lib/set_CMDLINE.sh"
;; ;;
esac esac
@ -74,7 +143,8 @@ to build your new initrd image (all of this will require sudo permissions!)"
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
apply_CHANGES apply_CHANGES
} }

View file

@ -15,14 +15,14 @@ does not belong to itself. Both cards must also have unique hardware ids [xxxx:y
Press q to quit Press q to quit
" "
read -p "Which group number do you want to check?: " IOMMU_GROUP read -r -p "Which group number do you want to check?: " IOMMU_GROUP
case "${IOMMU_GROUP}" in case "${IOMMU_GROUP}" in
[1-9]*) [1-9]*)
exec "$SCRIPTDIR/lib/get_GPU_GROUP.sh" $IOMMU_GROUP exec "$SCRIPTDIR/lib/get_GPU_GROUP.sh" "$IOMMU_GROUP"
;; ;;
[Qq]*) [Qq]*)
printf "Aborted, your setup is incomplete! echo "Aborted, your setup is incomplete!
DO NOT use any of the files from $SCRIPTDIR/config ! DO NOT use any of the files from $SCRIPTDIR/config !
" "
;; ;;
@ -33,7 +33,7 @@ DO NOT use any of the files from $SCRIPTDIR/config !
} }
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
get_GPU get_GPU
} }

View file

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
function get_GROUP () { function get_GPU_GROUP () {
clear clear
# Get the config paths # Get the config paths
source "$SCRIPTDIR/lib/paths.sh" source "$SCRIPTDIR/lib/paths.sh"
@ -24,32 +24,49 @@ To use any of these devices for passthrough ALL of them has to be passed through
To return to the previous page just press ENTER without typing in anything. To return to the previous page just press ENTER without typing in anything.
" "
read -p "Do you want to use these devices for passthrough? [y/N]: " YESNO read -r -p "Do you want to use these devices for passthrough? [y/N]: " YESNO
case "${YESNO}" in case "${YESNO}" in
[Yy]*) [Yy]*)
# Get the hardware ids from the selected group # Get the hardware ids from the selected group
local GPU_DEVID local GPU_DEVID
GPU_DEVID=$($SCRIPTDIR/utils/ls-iommu | grep -i "group $1" | perl -pe "s/.+\[([0-9a-f]{4}:[0-9a-f]{4})\].+/\1/" | perl -pe "s/\n/,/" | perl -pe "s/,$/\n/") GPU_DEVID=$("$SCRIPTDIR/utils/ls-iommu" | grep -i "group $1" | perl -pe "s/.+\[([0-9a-f]{4}:[0-9a-f]{4})\].+/\1/" | perl -pe "s/\n/,/" | perl -pe "s/,$/\n/")
# Get the PCI ids # Get the PCI ids
local PCI_ID local PCI_ID
PCI_ID=$($SCRIPTDIR/utils/ls-iommu | grep -i "group $1" | cut -d " " -f 4 | perl -pe "s/([0-9a-f]{2}:[0-9a-f]{2}.[0-9a-f]{1})\n/\"\1\" /" | perl -pe "s/\s$//") PCI_ID=$("$SCRIPTDIR/utils/ls-iommu" | grep -i "group $1" | cut -d " " -f 4 | perl -pe "s/([0-9a-f]{2}:[0-9a-f]{2}.[0-9a-f]{1})\n/\"\1\" /" | perl -pe "s/\s$//")
# Write the GPU_PCI_IDs to the config that quickemu might make use of in the future # Write the GPU_PCI_IDs to the config that quickemu might make use of in the future
printf "GPU_PCI_ID=($PCI_ID) echo "GPU_PCI_ID=($PCI_ID)
USB_CTL_ID=() USB_CTL_ID=()
" > "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf" " > "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf"
# Get the rom PCI_ID # Get the rom PCI_ID
local ROM_PCI_ID local ROM_PCI_ID
ROM_PCI_ID=$($SCRIPTDIR/utils/ls-iommu | grep -i "vga" | grep -i "group $1" | cut -d " " -f 4) ROM_PCI_ID=$("$SCRIPTDIR/utils/ls-iommu" | grep -i "vga" | grep -i "group $1" | cut -d " " -f 4)
# Get the GPU ROM # Get the GPU ROM
"$SCRIPTDIR/lib/get_GPU_ROM.sh" "$ROM_PCI_ID" "$SCRIPTDIR/lib/get_GPU_ROM.sh" "$ROM_PCI_ID"
# Start setting up modules # Start setting up modules
exec "$SCRIPTDIR/lib/set_MODULES.sh" $GPU_DEVID if [ -d "/etc/initramfs-tools" ];
then
exec "$SCRIPTDIR/lib/set_INITRAMFSTOOLS.sh" "$GPU_DEVID"
elif [ -d "/etc/dracut.conf" ];
then
exec "$SCRIPTDIR/lib/set_DRACUT.sh" "$GPU_DEVID"
elif [ -f "/etc/mkinitcpio.conf" ];
then
exec "$SCRIPTDIR/lib/set_MKINITCPIO.sh" "$GPU_DEVID"
else
# Bind GPU to VFIO
"$SCRIPTDIR/lib/set_VFIO.sh" "$1"
# Configure modprobe
"$SCRIPTDIR/lib/set_MODPROBE.sh" "$1"
fi
;; ;;
*) *)
exec "$SCRIPTDIR/lib/get_GPU.sh" exec "$SCRIPTDIR/lib/get_GPU.sh"
@ -58,9 +75,9 @@ USB_CTL_ID=()
} }
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
get_GROUP $1 get_GPU_GROUP "$1"
} }
main $1 main "$1"

View file

@ -6,7 +6,7 @@ function get_GPU_ROM () {
source "$SCRIPTDIR/lib/paths.sh" source "$SCRIPTDIR/lib/paths.sh"
VBIOS_PATH=$(find /sys/devices -name rom | grep "$1") VBIOS_PATH=$(find /sys/devices -name rom | grep "$1")
printf "We will now attempt to dump the vbios of your selected GPU. echo "We will now attempt to dump the vbios of your selected GPU.
Passing a VBIOS rom to the card used for passthrough is required for some cards, but not all. Passing a VBIOS rom to the card used for passthrough is required for some cards, but not all.
Some cards also requires you to patch your VBIOS romfile, check online if this is neccessary for your card. Some cards also requires you to patch your VBIOS romfile, check online if this is neccessary for your card.
The VBIOS will be read from $VBIOS_PATH The VBIOS will be read from $VBIOS_PATH
@ -17,17 +17,19 @@ sudo cat $VBIOS_PATH > $SCRIPTDIR/$QUICKEMU/vfio_card.rom
echo 0 | sudo tee $VBIOS_PATH echo 0 | sudo tee $VBIOS_PATH
" "
read -p "Do you want to dump the VBIOS, choosing N will skip this step [y/N]: " YESNO read -r -p "Do you want to dump the VBIOS, choosing N will skip this step [y/N]: " YESNO
case "${YESNO}" in case "${YESNO}" in
[Yy]*) [Yy]*)
echo 1 | sudo tee "$VBIOS_PATH" echo 1 | sudo tee "$VBIOS_PATH"
sudo cat "$VBIOS_PATH" > "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" sudo cat "$VBIOS_PATH" > "$SCRIPTDIR/$QUICKEMU/vfio_card.rom"
sudo md5sum "$VBIOS_PATH" | cut -d " " -f 1 > "$SCRIPTDIR/$QUICKEMU/vfio_card.rom.md5" sudo md5sum "$VBIOS_PATH" | cut -d " " -f 1 > "$SCRIPTDIR/$QUICKEMU/vfio_card.rom.md5"
local ROM_MD5=$(sudo md5sum "$VBIOS_PATH" | cut -d " " -f 1) local ROM_MD5
ROM_MD5=$(sudo md5sum "$VBIOS_PATH" | cut -d " " -f 1)
echo 0 | sudo tee "$VBIOS_PATH" echo 0 | sudo tee "$VBIOS_PATH"
local ROMFILE_MD5=$(md5sum "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" | cut -d " " -f 1) local ROMFILE_MD5
ROMFILE_MD5=$(md5sum "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" | cut -d " " -f 1)
if [ -f "$SCRIPTDIR"/$QUICKEMU/vfio_card.rom ]; if [ -f "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" ];
then then
if [ "$ROM_MD5" == "$ROMFILE_MD5" ]; if [ "$ROM_MD5" == "$ROMFILE_MD5" ];
then then
@ -35,14 +37,14 @@ echo 0 | sudo tee $VBIOS_PATH
echo "Dumping of VBIOS successful!" echo "Dumping of VBIOS successful!"
echo 'GPU_ROMFILE="vfio_card.rom"' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf" echo 'GPU_ROMFILE="vfio_card.rom"' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf"
read -p "Press ENTER to continue." ENTER read -r -p "Press ENTER to continue."
else else
echo "Checksums does not match!" echo "Checksums does not match!"
echo "Dumping of VBIOS failed, skipping romfile" echo "Dumping of VBIOS failed, skipping romfile"
mv "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" "$SCRIPTDIR/$QUICKEMU/vfio_card.rom.fail" mv "$SCRIPTDIR/$QUICKEMU/vfio_card.rom" "$SCRIPTDIR/$QUICKEMU/vfio_card.rom.fail"
echo 'GPU_ROMFILE=""' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf" echo 'GPU_ROMFILE=""' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf"
read -p "Press ENTER to continue." ENTER read -r -p "Press ENTER to continue."
fi fi
else else
echo 'GPU_ROMFILE=""' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf" echo 'GPU_ROMFILE=""' >> "$SCRIPTDIR/$QUICKEMU/qemu-vfio_vars.conf"
@ -59,9 +61,9 @@ echo 0 | sudo tee $VBIOS_PATH
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
get_GPU_ROM $1 get_GPU_ROM "$1"
} }
main $1 main "$1"

View file

@ -15,11 +15,11 @@ is only needed if you intend to use other devices than just mouse and keyboard w
Press q to quit Press q to quit
" "
read -p "Which group number do you want to check?: " IOMMU_GROUP read -r -p "Which group number do you want to check?: " IOMMU_GROUP
case "${IOMMU_GROUP}" in case "${IOMMU_GROUP}" in
[1-9]*) [1-9]*)
exec "$SCRIPTDIR/lib/get_USB_CTL_GROUP.sh" $IOMMU_GROUP exec "$SCRIPTDIR/lib/get_USB_CTL_GROUP.sh" "$IOMMU_GROUP"
;; ;;
[Qq]*) [Qq]*)
exec "$SCRIPTDIR/lib/apply_CHANGES.sh" exec "$SCRIPTDIR/lib/apply_CHANGES.sh"
@ -31,7 +31,7 @@ Press q to quit
} }
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
get_USB_CTL get_USB_CTL
} }

View file

@ -20,7 +20,7 @@ To use any of the devices shown for passthrough, all of them have to be passed t
To return to the previous page just press ENTER. To return to the previous page just press ENTER.
" "
read -p "Do you want to use the displayed devices for passthrough? [y/N]: " YESNO read -r -p "Do you want to use the displayed devices for passthrough? [y/N]: " YESNO
case "${YESNO}" in case "${YESNO}" in
[Yy]*) [Yy]*)
@ -39,7 +39,7 @@ To return to the previous page just press ENTER.
} }
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
get_USB_CTL_GROUP $1 get_USB_CTL_GROUP $1
} }

View file

@ -3,4 +3,6 @@ MODPROBE="config/etc/modprobe.d"
INITRAMFS="config/etc/initramfs-tools" INITRAMFS="config/etc/initramfs-tools"
ETCMODULES="config/etc/modules" ETCMODULES="config/etc/modules"
DEFAULT="config/etc/default" DEFAULT="config/etc/default"
QUICKEMU="config/quickemu" QUICKEMU="config/quickemu"
DRACUT="config/etc/dracut.conf.d"
MKINITCPIO="config/etc/mkinitcpio.conf"

View file

@ -48,17 +48,17 @@ function set_GRUB () {
local GRUB_CMDLINE_LINUX local GRUB_CMDLINE_LINUX
# Check if there is a GRUB_CMDLINE_LINUX_DEFAULT line in grub config # Check if there is a GRUB_CMDLINE_LINUX_DEFAULT line in grub config
if grep -q "GRUB_CMDLINE_LINUX_DEFAULT=" "$SCRIPTDIR/config/etc/default/grub" ; if grep -q "GRUB_CMDLINE_LINUX_DEFAULT=" "$SCRIPTDIR/$DEFAULT/grub" ;
then then
# Update the GRUB_CMDLINE_LINUX_DEFAULT line # Update the GRUB_CMDLINE_LINUX_DEFAULT line
GRUB_CMDLINE=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX_DEFAULT" | perl -pe "s/GRUB_CMDLINE_LINUX_DEFAULT=\"(.+)\"/\1/" | perl -pe "s/iommu=(pt|on)|amd_iommu=on|vfio_pci.ids=.+|vfio_pci.disable_vga=\d{1}//g" | perl -pe "s/(^\s+|\s+$)//g") GRUB_CMDLINE=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX_DEFAULT" | perl -pe "s/GRUB_CMDLINE_LINUX_DEFAULT=\"(.+)\"/\1/" | perl -pe "s/iommu=(pt|on)|amd_iommu=on|vfio_pci.ids=.+|vfio_pci.disable_vga=\d{1}//g" | perl -pe "s/(^\s+|\s+$)//g")
GRUB_CMDLINE_LINUX=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX_DEFAULT") GRUB_CMDLINE_LINUX=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX_DEFAULT")
perl -pi -e "s/${GRUB_CMDLINE_LINUX}/GRUB_CMDLINE_LINUX_DEFAULT=\"${GRUB_CMDLINE} ${CMDLINE}\"/" "${SCRIPTDIR}/config/etc/default/grub" perl -pi -e "s/${GRUB_CMDLINE_LINUX}/GRUB_CMDLINE_LINUX_DEFAULT=\"${GRUB_CMDLINE} ${CMDLINE}\"/" "${SCRIPTDIR}/$DEFAULT/grub"
else else
# Update the GRUB_CMDLINE_LINUX line # Update the GRUB_CMDLINE_LINUX line
GRUB_CMDLINE=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX" | perl -pe "s/GRUB_CMDLINE_LINUX=\"(.+)\"/\1/" | perl -pe "s/iommu=(pt|on)|amd_iommu=on|vfio_pci.ids=.+|vfio_pci.disable_vga=\d{1}//g" | perl -pe "s/(^\s+|\s+$)//g") GRUB_CMDLINE=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX" | perl -pe "s/GRUB_CMDLINE_LINUX=\"(.+)\"/\1/" | perl -pe "s/iommu=(pt|on)|amd_iommu=on|vfio_pci.ids=.+|vfio_pci.disable_vga=\d{1}//g" | perl -pe "s/(^\s+|\s+$)//g")
GRUB_CMDLINE_LINUX=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX") GRUB_CMDLINE_LINUX=$(cat "/etc/default/grub" | grep -P "^GRUB_CMDLINE_LINUX")
perl -pi -e "s/${GRUB_CMDLINE_LINUX}/GRUB_CMDLINE_LINUX=\"${GRUB_CMDLINE} ${CMDLINE}\"/" "${SCRIPTDIR}/config/etc/default/grub" perl -pi -e "s/${GRUB_CMDLINE_LINUX}/GRUB_CMDLINE_LINUX=\"${GRUB_CMDLINE} ${CMDLINE}\"/" "${SCRIPTDIR}/$DEFAULT/grub"
fi fi
@ -69,7 +69,7 @@ $SCRIPTDIR/backup/etc/default/grub
" "
read -r -p "Press ENTER to continue" read -r -p "Press ENTER to continue"
sudo cp -v "$SCRIPTDIR/config/etc/default/grub" "/etc/default/grub" sudo cp -v "$SCRIPTDIR/$DEFAULT/grub" "/etc/default/grub"
# Generate grub.cfg # Generate grub.cfg
if [ -d "/boot/grub" ]; if [ -d "/boot/grub" ];
@ -116,8 +116,8 @@ proceed to add it to your virtual machines.
A backup the files we replaced on your system can be found inside A backup the files we replaced on your system can be found inside
$SCRIPTDIR/backup/ $SCRIPTDIR/backup/
In order to restore these files just copy them back to your system and run In order to restore these files just copy them back to your system and
\"sudo update-initramfs -u\" rebuild your initramfs image.
You can remove the the vfio_pci kernel arguments from the linux line in your bootloader You can remove the the vfio_pci kernel arguments from the linux line in your bootloader
to disable/unbind the graphic card from the vfio driver on boot. to disable/unbind the graphic card from the vfio driver on boot.
@ -125,7 +125,7 @@ to disable/unbind the graphic card from the vfio driver on boot.
The files inside \"$SCRIPTDIR/$QUICKEMU\" are currently unused files, however they provide The files inside \"$SCRIPTDIR/$QUICKEMU\" are currently unused files, however they provide
the required information that the QuickEMU project can hook into and use to add support for VFIO enabled VMs. the required information that the QuickEMU project can hook into and use to add support for VFIO enabled VMs.
The PCI Devices with these IDs are what you should add to your VMs: The PCI Devices with these IDs are what you should add to your VMs using Virt Manager:
NOTE: Some AMD GPUs will require the vendor-reset kernel module from https://github.com/gnif/vendor-reset to be installed!" NOTE: Some AMD GPUs will require the vendor-reset kernel module from https://github.com/gnif/vendor-reset to be installed!"
source "${SCRIPTDIR}/config/quickemu/qemu-vfio_vars.conf" source "${SCRIPTDIR}/config/quickemu/qemu-vfio_vars.conf"
@ -139,7 +139,17 @@ NOTE: Some AMD GPUs will require the vendor-reset kernel module from https://git
echo "* $dev" echo "* $dev"
done done
echo "For performance tuning and advanced configuration look at: echo "
To add the graphic card to your VM using qemu directly, use the following arguments:"
for dev in "${GPU_PCI_ID[@]}"
do
echo -n "-device vfio-pci,host=$dev "
done
printf "\n"
echo "
For performance tuning and advanced configuration look at:
https://github.com/HikariKnight/vfio-setup-docs/wiki" https://github.com/HikariKnight/vfio-setup-docs/wiki"
} }
@ -149,7 +159,7 @@ function set_CMDLINE () {
BOOTLOADER_AUTOCONFIG=0 BOOTLOADER_AUTOCONFIG=0
# If kernelstub is detected (program to manage systemd-boot) # If kernelstub is detected (program to manage systemd-boot)
if which kernelstub ; if which kernelstub > /dev/null 2>&1 ;
then then
# Configure kernelstub # Configure kernelstub
set_KERNELSTUB set_KERNELSTUB
@ -157,7 +167,7 @@ function set_CMDLINE () {
fi fi
# If grub exists # If grub exists
if which grub-mkconfig ; if which grub-mkconfig > /dev/null 2>&1 ;
then then
# Configure grub # Configure grub
set_GRUB set_GRUB
@ -169,7 +179,8 @@ function set_CMDLINE () {
function main () { function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//") SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_CMDLINE set_CMDLINE
} }

28
lib/set_DRACUT.sh Executable file
View file

@ -0,0 +1,28 @@
#!/bin/bash
function set_DRACUT () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Write the dracut config
echo "add_drivers+=\" vfio_pci vfio vfio_iommu_type1 vfio_virqfd \"" > "$SCRIPTDIR/$DRACUT/10-vfio.conf"
# Get the kernel_args file content
CMDLINE=$(cat "$SCRIPTDIR/config/kernel_args")
# Update kernel_args to load the vfio_pci module early in dracut (as dracut uses kernel arguments for early loading)
echo "$CMDLINE rd.driver.pre=vfio_pci" > "$SCRIPTDIR/config/kernel_args"
# Bind GPU to VFIO
"$SCRIPTDIR/lib/set_VFIO.sh" "$1"
# Configure modprobe
exec "$SCRIPTDIR/lib/set_MODPROBE.sh" "$1"
}
function main () {
SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_DRACUT "$1"
}
main "$1"

65
lib/set_INITRAMFSTOOLS.sh Executable file
View file

@ -0,0 +1,65 @@
#!/bin/bash
function insert_INITRAMFSTOOLS() {
# Get the header and enabled modules separately from the /etc/modules file
local MODULES_HEADER
local MODULES_ENABLED
local VENDOR_RESET
MODULES_HEADER=$(head -n $1 "$2" | grep -P "^#" | grep -v "# Added by quickpassthrough")
MODULES_ENABLED=$(cat "$2" | grep -vP "^#" | grep -v "vendor-reset")
VENDOR_RESET=0
# If vendor-reset is present
if grep -q "vendor-reset" "$2" ;
then
VENDOR_RESET=1
fi
# Write header
echo "$MODULES_HEADER" > "$2"
# If vendor-reset existed from before
if [ $VENDOR_RESET == 1 ];
then
# Write vendor-reset as the first module!
echo "vendor-reset" >> "$2"
fi
# Append vfio
printf "
# Added by quickpassthrough #
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
#############################
" >> "$2"
# Write the previously enabled modules under vfio in the load order
echo "$MODULES_ENABLED" >> "$2"
}
function set_INITRAMFSTOOLS () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Insert modules in the correct locations as early as possible without
# conflicting with vendor-reset module if it is enabled
insert_INITRAMFSTOOLS 4 "$SCRIPTDIR/$ETCMODULES"
insert_INITRAMFSTOOLS 11 "$SCRIPTDIR/$INITRAMFS/modules"
# Bind GPU to VFIO
"$SCRIPTDIR/lib/set_VFIO.sh" "$1"
# Configure modprobe
exec "$SCRIPTDIR/lib/set_MODPROBE.sh" "$1"
}
function main () {
SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_INITRAMFSTOOLS "$1"
}
main "$1"

33
lib/set_MKINITCPIO.sh Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
function set_MKINITCPIO () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Grab the current modules but exclude vfio and vendor-reset
CURRENTMODULES=$(grep -P "^MODULES" "$SCRIPTDIR/$MKINITCPIO" | perl -pe "s/MODULES=\((.+)\)/\1/")
MODULES="$(grep -P "^MODULES" "$SCRIPTDIR/$MKINITCPIO" | perl -pe "s/MODULES=\((.+)\)/\1/" | perl -pe "s/\s?(vfio_iommu_type1|vfio_pci|vfio_virqfd|vfio|vendor-reset)\s?//g")"
# Check if vendor-reset is present
if [[ $CURRENTMODULES =~ "vendor-reset" ]];
then
# Inject vfio modules with vendor-reset
perl -pi -e "s/MODULES=\(${CURRENTMODULES}\)/MODULES=\(vendor-reset vfio vfio_iommu_type1 vfio_pci vfio_virqfd ${MODULES}\)/" "$SCRIPTDIR/$MKINITCPIO"
else
# Inject vfio modules
perl -pi -e "s/MODULES=\(${CURRENTMODULES}\)/MODULES=\(vfio vfio_iommu_type1 vfio_pci vfio_virqfd ${MODULES}\)/" "$SCRIPTDIR/$MKINITCPIO"
fi
# Bind GPU to VFIO
"$SCRIPTDIR/lib/set_VFIO.sh" "$1"
# Configure modprobe
exec "$SCRIPTDIR/lib/set_MODPROBE.sh" "$1"
}
function main () {
SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_MKINITCPIO "$1"
}
main "$1"

39
lib/set_MODPROBE.sh Executable file
View file

@ -0,0 +1,39 @@
#!/bin/bash
function set_MODPROBE () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Assign the GPU device ids to a variable
GPU_DEVID="$1"
# If VGA is disabled
if grep -q "vfio_pci.disable_vga=1" "$SCRIPTDIR/config/kernel_args" ;
then
# Modify our GPU_DEVID line to containe disable_vga=1
GPU_DEVID="${GPU_DEVID} disable_vga=1"
fi
# Write the vfio modprobe config
printf "## This is an autogenerated file that stubs your graphic card for use with vfio
## This file should be placed inside /etc/modprobe.d/
# Uncomment the line below to \"hardcode\" your graphic card to be bound to the vfio-pci driver.
# In most cases this should not be neccessary, it will also prevent you from turning off vfio in the bootloader.
#options vfio_pci ids=%s
# Make sure vfio_pci is loaded before these modules: nvidia, nouveau, amdgpu and radeon
softdep nvidia pre: vfio vfio_pci
softdep nouveau pre: vfio vfio_pci
softdep amdgpu pre: vfio vfio_pci
softdep radeon pre: vfio vfio_pci
" "${GPU_DEVID}" > "$SCRIPTDIR/$MODPROBE/vfio.conf"
exec "$SCRIPTDIR/lib/get_USB_CTL.sh"
}
function main () {
SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_MODPROBE "$1"
}
main "$1"

View file

@ -1,106 +0,0 @@
#!/bin/bash
function insert_MODULES() {
# Get the header and enabled modules separately from the /etc/modules file
local MODULES_HEADER
local MODULES_ENABLED
local VENDOR_RESET
MODULES_HEADER=$(head -n $1 "$2" | grep -P "^#" | grep -v "# Added by quickpassthrough")
MODULES_ENABLED=$(cat "$2" | grep -vP "^#" | grep -v "vendor-reset")
VENDOR_RESET=0
# If vendor-reset is present
if grep -q "vendor-reset" "$2" ;
then
VENDOR_RESET=1
fi
# Write header
echo "$MODULES_HEADER" > "$2"
# If vendor-reset existed from before
if [ $VENDOR_RESET == 1 ];
then
# Write vendor-reset as the first module!
echo "vendor-reset" >> "$2"
fi
# Append vfio
printf "
# Added by quickpassthrough #
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
#############################
" >> "$2"
# Write the previously enabled modules under vfio in the load order
echo "$MODULES_ENABLED" >> "$2"
}
function set_MODULES () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Insert modules in the correct locations as early as possible without
# conflicting with vendor-reset module if it is enabled
insert_MODULES 4 "$SCRIPTDIR/$ETCMODULES"
insert_MODULES 11 "$SCRIPTDIR/$INITRAMFS/modules"
# Assign the GPU device ids to a variable
GPU_DEVID="$1"
# Get the kernel_args file content
CMDLINE=$(cat "$SCRIPTDIR/config/kernel_args")
# Ask if we shall disable video output on this card
echo "
Disabling video output in Linux for the card you want to use in a VM
will make it easier to successfully do the passthrough without issues."
read -p "Do you want to force disable video output in linux on this card? [Y/n]: " DISABLE_VGA
case "${DISABLE_VGA}" in
[Yy]*)
# Update kernel_args file
echo "${CMDLINE} vfio_pci.ids=${GPU_DEVID} vfio_pci.disable_vga=1" > "$SCRIPTDIR/config/kernel_args"
# Update GPU_DEVID
GPU_DEVID="$GPU_DEVID disable_vga=1"
;;
[Nn]*)
echo ""
;;
*)
# Update kernel_args file
echo "${CMDLINE} vfio_pci.ids=${GPU_DEVID} vfio_pci.disable_vga=1" > "$SCRIPTDIR/config/kernel_args"
# Update GPU_DEVID
GPU_DEVID="$GPU_DEVID disable_vga=1"
;;
esac
# Write the vfio modprobe config
printf "## This is an autogenerated file that stubs your graphic card for use with vfio
## This file should be placed inside /etc/modprobe.d/
# Uncomment the line below to \"hardcode\" your graphic card to be bound to the vfio-pci driver.
# In most cases this should not be neccessary, it will also prevent you from turning off vfio in the bootloader.
#options vfio_pci ids=%s
# Make sure vfio_pci is loaded before these modules: nvidia, nouveau, amdgpu and radeon
softdep nvidia pre: vfio vfio_pci
softdep nouveau pre: vfio vfio_pci
softdep amdgpu pre: vfio vfio_pci
softdep radeon pre: vfio vfio_pci
" "${GPU_DEVID}" > "$SCRIPTDIR/$MODPROBE/vfio.conf"
exec "$SCRIPTDIR/lib/get_USB_CTL.sh"
}
function main () {
SCRIPTDIR=$(dirname "$(which $0)" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_MODULES "$1"
}
main "$1"

45
lib/set_VFIO.sh Executable file
View file

@ -0,0 +1,45 @@
#!/bin/bash
function set_VFIO () {
# Get the config paths
source "$SCRIPTDIR/lib/paths.sh"
# Assign the GPU device ids to a variable
GPU_DEVID="$1"
# Get the kernel_args file content
CMDLINE=$(cat "$SCRIPTDIR/config/kernel_args")
# Ask if we shall disable video output on this card
echo "
Disabling video output in Linux for the card you want to use in a VM
will make it easier to successfully do the passthrough without issues."
read -r -p "Do you want to force disable video output in linux on this card? [Y/n]: " DISABLE_VGA
case "${DISABLE_VGA}" in
[Yy]*)
# Update kernel_args file
echo "${CMDLINE} vfio_pci.ids=${GPU_DEVID} vfio_pci.disable_vga=1" > "$SCRIPTDIR/config/kernel_args"
# Update GPU_DEVID
GPU_DEVID="$GPU_DEVID disable_vga=1"
;;
[Nn]*)
# Update kernel_args file
echo "${CMDLINE} vfio_pci.ids=${GPU_DEVID}" > "$SCRIPTDIR/config/kernel_args"
;;
*)
# Update kernel_args file
echo "${CMDLINE} vfio_pci.ids=${GPU_DEVID} vfio_pci.disable_vga=1" > "$SCRIPTDIR/config/kernel_args"
# Update GPU_DEVID
GPU_DEVID="$GPU_DEVID disable_vga=1"
;;
esac
}
function main () {
SCRIPTDIR=$(dirname "$(realpath "$0")" | perl -pe "s/\/\.\.\/lib//" | perl -pe "s/\/lib$//")
set_VFIO "$1"
}
main "$1"

View file

@ -1,15 +1,12 @@
#!/bin/bash #!/bin/bash
# Get the scripts directory # Get the scripts directory
SCRIPTDIR=$(dirname "$(which $0)") SCRIPTDIR=$(dirname "$(realpath "$0")")
cd "$SCRIPTDIR" cd "$SCRIPTDIR"
# Get the config paths # Get the config paths
source "$SCRIPTDIR/lib/paths.sh" source "$SCRIPTDIR/lib/paths.sh"
# Make sure all the scripts are executable
chmod +x "$SCRIPTDIR/lib/*"
# Get the CPU Vendor # Get the CPU Vendor
CPU_VENDOR=$(cat /proc/cpuinfo | grep vendor | head -1 | cut -f 2 | cut -d " " -f 2) CPU_VENDOR=$(cat /proc/cpuinfo | grep vendor | head -1 | cut -f 2 | cut -d " " -f 2)
CMDLINE="iommu=pt" CMDLINE="iommu=pt"
@ -91,35 +88,48 @@ fi
# Make the directories # Make the directories
mkdir -p "$SCRIPTDIR/$MODPROBE" mkdir -p "$SCRIPTDIR/$MODPROBE"
mkdir -p "$SCRIPTDIR/$DEFAULT"
mkdir -p "$SCRIPTDIR/$INITRAMFS"
mkdir -p "$SCRIPTDIR/$QUICKEMU" mkdir -p "$SCRIPTDIR/$QUICKEMU"
# Write the cmdline file # Write the cmdline file
echo "$CMDLINE" > "$SCRIPTDIR/config/kernel_args" echo "$CMDLINE" > "$SCRIPTDIR/config/kernel_args"
# Copy system configs into our config folder so we can safely edit them # Copy system configs that exists into our config folder so we can safely edit them
if [ -f "/etc/modules" ]; if [ -f "/etc/modules" ];
then then
# This copies /etc/modules without the vfio module lines # This copies /etc/modules without the vfio module lines
grep -v "vfio" "/etc/modules" > "$SCRIPTDIR/$ETCMODULES" grep -v "vfio" "/etc/modules" > "$SCRIPTDIR/$ETCMODULES"
else
touch "$SCRIPTDIR/$ETCMODULES"
fi fi
if [ -f "/etc/default/grub" ]; if [ -f "/etc/default/grub" ];
then then
# Create the default folder
mkdir -p "$SCRIPTDIR/$DEFAULT"
# Copy grub config # Copy grub config
cp "/etc/default/grub" "$SCRIPTDIR/$DEFAULT/grub" cp "/etc/default/grub" "$SCRIPTDIR/$DEFAULT/grub"
fi fi
if [ -f "/etc/initramfs-tools/modules" ]; if [ -f "/etc/initramfs-tools/modules" ];
then then
# Create the initramfs folder
mkdir -p "$SCRIPTDIR/$INITRAMFS"
# This copies /etc/initramfs-tools/modules without the vfio modules # This copies /etc/initramfs-tools/modules without the vfio modules
grep -v "vfio" "/etc/initramfs-tools/modules" > "$SCRIPTDIR/$INITRAMFS/modules" grep -v "vfio" "/etc/initramfs-tools/modules" > "$SCRIPTDIR/$INITRAMFS/modules"
else fi
touch "$SCRIPTDIR/$INITRAMFS"
if [ -f "/etc/mkinitcpio.conf" ];
then
# Copy mkinitcpio.conf to our config folder
cp "/etc/mkinitcpio.conf" "$SCRIPTDIR/$MKINITCPIO"
fi
if [ -f "/etc/dracut.conf" ];
then
# Create the dracut folder
mkdir -p "$SCRIPTDIR/$DRACUT"
# Create a dracut.conf.d file
touch "$SCRIPTDIR/$DRACUT/10-vfio.conf"
fi fi
# Run ls-iommu so we can verify that IOMMU properly working # Run ls-iommu so we can verify that IOMMU properly working