The guest OS will see passed through cards as if these were plugged into it as on a real
machine, thus it needs appropriate guest drivers for these cards. This also means that
passthrough cards have to be removed from the host driver and assigned to the
vfio-pci
driver instead, which means the host cannot use them any more and
the guest will take full control of those cards. That also means you cannot pass through
the video card or network card that the host uses for its output or network but may need
a second card you don't use on the host to pass through or live with loosing graphics
output from the host while the guest is running if you only have one GPU for example
(that makes it more difficult to set up, so probably start with a second card first
before trying more advanced setups).
There are several guides online for setting up GPU passthrough, mostly for Windows guest for gaming and using KVM. They also often suggest using high level tools such as libvirt and virt-manager which is supposed to make it simple but in reality just makes it more complicated than it needs to be. Reading the original presentation on VFIO one can see that this is actually quite simple. What makes it complex is all the differences between motherboards, CPUs, Linux distros and cards to be passed through. Additionally, GPU passthrough is more difficult because these have peculiarities that need to be considered and also the situation with GPU support on AmigaNG machines and different drivers on Amiga like OSes adds another level of complexity on top of that.
This page attempts to give a simple overview and demystify setup of passthrough of GPUs and other cards to Amiga like OSes running on QEMU, but it is not a "for dummies" or "quickly and easily" guide. You will still need to know what you are doing to achieve this, but hopefully will have more understanding after reading this (and linked) pages.
intel_iommu=on iommu=ptThis should work for both Intel and AMD. Intel needs explicit option to enable IOMMU. For AMD it is enabled by default and ignores the Intel option, hence no option for that. The
iommu=pt
part may or may not help, it should also work without
that.lspci -vvnn
and an
overview of how they are connected withlspci -tvnn; ls /sys/kernel/iommu_groups/*/devicesIf you see no IOMMU groups listed, go back to prerequisites.
vfio-pci
. GPUs usually have another function for HDMI audio so you'll see
at least two entries (plus maybe the root bridge). If there are more devices in the
group you may have to move the card to a different slot or enable ACS option in firmware
setup if available. Grouping is dependent on motherboard
type so find a combination where the devices you want to pass through are in their
own group. Note the [vendor:device] PCI IDs (shown after the name) of the
devices in the IOMMU group for passthrough.vfio-pci
. Create a file
/etc/modprobe.d/vfio.conf
with the contentsoptions vfio-pci ids=1002:6779,1002:aa98 softdep drm pre: vfio-pci softdep snd_hda_intel pre: vfio-pciwhere the
vfio-pci ids
are the vendor:device values for all
devices (except the root PCI bridge) in the IOMMU group. The softdep
lines
ensure that vfio-pci
is loaded before other drivers that may bind to these
devices. If passing through something else than a GPU, you may need to add similar line
for the driver used by that card.update-initramfs -u
) if
needed and reboot. Then check with lspci -vvnn
that the driver in use for
all cards in the IOMMU group to be passed through is vfio-pci
(except root
ports that use driver pcieport
or similar). Ensure this is working before
continuing.-vga none -device vfio-pci,host=01:00.0,multifunction=on,x-vga=on -device vfio-pci,host=01:00.1where the host values are the bus:device.function address of the device. The graphics card has two functions so you need
multifunction=on
for the first
function to let it know that there are other functions and it is a VGA card with legacy
VGA resources that are to be passed through with x-vga=on
to replace the
emulated VGA which is disabled with -vga none
otherwise it had conflicting
VGA resources. You also need to run QEMU as root to be able to access VFIO devices.
After this the card should appear in the guest virtual machine as a PCI device and the
guest OS can use it as other PCI devices.In principle that is all there is to it and this also works most of the time for simpler devices such as network or SATA cards. It may be a good idea to get such a simpler card working first just to see how it works generally before trying to get GPU passthrough work.
Some knowledge of the theory of operation of graphics cards on real machines is also
useful. I try to give a quick summary here. Most graphics cards are made for x86
compatible PCs. These have an option
ROM that is run by BIOS on a PC to initialise the card when the machine is switched
on. To use such PC card on an AmigaNG machine, the machine's firmware has an x86 and
BIOS emulator that runs this ROM. This emulator is not perfect and often crashes on
newer cards (or the QEMU default video bios of the emulated cards) but despite of that
it may run enough to get the card working, but then you will get no output until the OS
driver loads. The OS driver may need the firmware to run the card's ROM first so if you
boot with -kernel bboot
and not with -bios machine.rom
it may
not work. But some newer Radeon cards have
AtomBIOS
which some drivers may know how to run so with some luck those cards may work even
without the BIOS emulator in firmware run first. In short, you may need to use the
firmware ROM for the machine if passing through GPUs to correctly initialise the card,
so this may be more difficult than just getting AmigaOS boot on QEMU with BBoot. The
sam460ex
has the firmware included in QEMU. For amigaone
and
pegasos2
there is
info here on how to
get firmware ROM.
Other considerations specific for machines emulated by QEMU:
amigaone
-device sm501
and add driver from Enhancer Software before passthrough.
Has oldest firmware so may have problems with newer cards. Least tested but was improved
with QEMU v10.0.0 so now it may be the easiest to use.pegasos2
bus=pci.0
which did not work before QEMU v9.2.0.sam460ex
According to
this
article Intel iGPU may not work with x-vga=on
but the card ROM may not
work without VGA resources. (Windows guests usually avoid this using OVMF as guest
firmware with newer cards that have UEFI ROMs and don't need the VGA resources but
that's not an option for AmigaNG.) The work around patch might fix it but may disable 3D
acceleration on the host. Cards with AtomBIOS may still work without VGA regions but the
card may not be fully initialised which may lead to problems later. With
x-vga=on
this may corrupt host display or cause the host to freeze as those
regions still go to the Intel iGPU even when it told to release them. There seems to be
no good solution other than using another graphics card and disable the iGPU.
As described
here
and
here you may get an error if
the guest's memory map overlaps reserved regions. You can check reserved regions on the
host with cat /sys/kernel/iommu_groups/0/reserved_regions
replacing 0 with
the appropriate IOMMU group number and the host memory map with info mtree
in QEMU Monitor. This may be the reason why some cards need bus=pci.0
on
pegasos2
and may be less likely to happen on amigaone
due to
the different memory map. Disabling resizable BARs may also be related but I'm not
sure. Using another host machine may also help as it may have different reserved
regions.
Some Radeon cards do not support Function Level Reset so only work for the first start of the machine but cannot get back to a sane state when the guest stops, so next boot of guest fails until the host is reset which also resets the card. There is an out of tree Linux kernel module to fix this for some cards which may be needed to avoid this problem with those cards.
As a work around you may need to disable interrupts which can be done adding
INTERRUPT=no tool type to the monitor file for the graphics card which is created on
first boot. After the freeze remove the -device vfio-pci
lines and add
-device sm501
and boot with that to set the tool type which may fix this
with somewhat lowered performance but the cause and proper fix is not understood
yet.
Since with GPU pass through the guest is not visible in a window but outputs to the
passed through card you need some way to provide input to it. You can either add
-device bochs-display
to get a window that you can use for input (you can
make it full screen with Crtl+Alt+F to control the guest without limits) or add options
like -device usb-host,vendorid=0xaaaa,productid=0xbbbb
where
0xaaaa
and 0xbbbb
are USB IDs to pass through for keyboard and
mouse. You can check available IDs with info usbhost
in QEMU Monitor or
lsusb
from Linux.
pegasos2
firmware
When the pegasos2
firmware crashes with errors when trying to run the ROM
of the card it still tries to output to it instead of serial but you won't see that.
Typing in the guest just results in more errors but that's how you know it still works.
To get the ok prompt back on serial blindly press Enter and then type
" /failsafe" ioexactly like this, with a space between the first quote and slash. You only have one chance to type it correctly as it may break input if you type it wrong but if worked you should see the ok prompt on serial and you can continue to type there. If unsuccessful, restart guest and try again.